Изменение элементов табличной части справочника в цикле запроса

1. P1rate 02.12.16 08:54 Сейчас в теме
Добрый день. Есть вот такой запрос. Смысл в том, что я пытаюсь поменять цену товара в ТЧ "состав" справочника "номеклатура". Сам запрос отрабатывает норм, но в цикле я никак не могу установить новую цену для состав.цена, т.к. выдаёт ошибку: Поле объекта не обнаружено (Цена) НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра; Подскажите, что я не так делаю, а то вчера целый день убил на это. Заранее благодарен.



Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	НоменклатураСостав.Наименование КАК Наименование,
		|	НоменклатураСостав.Количество,
		|	НоменклатураСостав.Цена,
		|	НоменклатураСостав.Стоимость,
		|	СтоимостьМатериалаСрезПоследних.Цена КАК ЦенаРегистра,
		|	Номенклатура.Ссылка КАК Ссылка
		|ИЗ
		|	Справочник.Номенклатура.Состав КАК НоменклатураСостав
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтоимостьМатериала.СрезПоследних(&ПериодВыборки, Цена > 0) КАК СтоимостьМатериалаСрезПоследних
		|		ПО НоменклатураСостав.Наименование = СтоимостьМатериалаСрезПоследних.Наименование
		|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
		|		ПО НоменклатураСостав.Ссылка = Номенклатура.Ссылка
		|
		|СГРУППИРОВАТЬ ПО
		|	НоменклатураСостав.Наименование,
		|	НоменклатураСостав.Количество,
		|	НоменклатураСостав.Цена,
		|	НоменклатураСостав.Стоимость,
		|	СтоимостьМатериалаСрезПоследних.Цена,
		|	Номенклатура.Ссылка
		|
		|УПОРЯДОЧИТЬ ПО
		|	Наименование
		|АВТОУПОРЯДОЧИВАНИЕ";
	
	Запрос.УстановитьПараметр("ПериодВыборки", Объект.ПериодВыборки);
	
	РезультатЗапроса = Запрос.Выполнить();
	
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		  НоменклатураОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
		  НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
		  НоменклатураОбъект.Записать();
	КонецЦикла;
Показать
По теме из базы знаний
Найденные решения
16. kasper076 105 02.12.16 09:50 Сейчас в теме
(1)
НоменклатураОбъект.Состав
это табличная часть. Цена хранится в реквизите СТРОКИ табличной части. При выполнении кода
НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
в какой строке табличной части должна поменяться цена?

Сначала необходимо найти строку табличной части в которую нужно установить новое значение цены. Строку можно найти по значению реквизита "Наименование". Для простоты считаем, что наименования в ТЧ уникальны. Тогда код буде такой:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
          //Получаем элемент справочника Номенклатура
          НоменклатураОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
          //Находим строку ТЧ Состав
          НайденаяСтрока = НоменклатураОбъект.Состав.Найти(ВыборкаДетальныеЗаписи.Наименование, "Наименование");
          //Если нашли строку, то меняем в ней цену
          Если НайденаяСтрока <> Неопределено Тогда
                    НайденаяСтрока.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
          КонецЕсли;
          //Записываем
          НоменклатураОбъект.Записать();
    КонецЦикла;
Показать

Код конечно не оптимальный. Номенклатура записывается после каждого изменения цены в строке ТЧ Состав. В запросе необходимо использовать итоги по Номенклатуре и строке табличной части. Тогда можно будет получив номенклатуру, перебрать все строки ТЧ Состав, установить в них цену, а затем один раз записать сделанные изменения.
AlexandrDmC; +1 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
5. vovan_victory 63 02.12.16 09:18 Сейчас в теме
(1)На сколько я понял, Вы пытаете изобразить что то типа прайса..В корне не правильный подход! Справочник должен хранить исключительно наименования позиций Вашего прайса, а для хранения цен и истории изменения, необходимо использовать периодический регистр сведений. Тогда, получив срез последних этого регистра, Вы сможете получить актуальные цены на дату среза.
6. shnurov 02.12.16 09:22 Сейчас в теме
(5)
А запрос глянуть слабо? Он хоть и некорректный, но блин там регистр фигурирует.
8. spacecraft 02.12.16 09:27 Сейчас в теме
(1) самое главное, что получен объект, но присваивание цены идет к табличной части. Именно к табличной части, а не к строке табличной части. Нужно указать какая строка табличной части изменяется. Для этого нужно в запросе еще получить и номер строки. И присваивать уже по номеру строки НоменклатураОбъект.Состав[ВыборкаДетальныеЗаписи.НомерСтроки].Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
А вот номенклатура, количество, стоимость далее не используется, не вижу смысла получать в запросе.
Далее по коду:
1. последнее левое соединение в общем-то и не требуется. Ссылка на документ есть в самой табличной части.
2. выгрузку из запроса нужно обходить через группировку по ссылке, и уже в ней делать выборку по строкам табличной части, чтоб на каждую строку не получать объект снова и снова.
16. kasper076 105 02.12.16 09:50 Сейчас в теме
(1)
НоменклатураОбъект.Состав
это табличная часть. Цена хранится в реквизите СТРОКИ табличной части. При выполнении кода
НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
в какой строке табличной части должна поменяться цена?

Сначала необходимо найти строку табличной части в которую нужно установить новое значение цены. Строку можно найти по значению реквизита "Наименование". Для простоты считаем, что наименования в ТЧ уникальны. Тогда код буде такой:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
          //Получаем элемент справочника Номенклатура
          НоменклатураОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
          //Находим строку ТЧ Состав
          НайденаяСтрока = НоменклатураОбъект.Состав.Найти(ВыборкаДетальныеЗаписи.Наименование, "Наименование");
          //Если нашли строку, то меняем в ней цену
          Если НайденаяСтрока <> Неопределено Тогда
                    НайденаяСтрока.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
          КонецЕсли;
          //Записываем
          НоменклатураОбъект.Записать();
    КонецЦикла;
Показать

Код конечно не оптимальный. Номенклатура записывается после каждого изменения цены в строке ТЧ Состав. В запросе необходимо использовать итоги по Номенклатуре и строке табличной части. Тогда можно будет получив номенклатуру, перебрать все строки ТЧ Состав, установить в них цену, а затем один раз записать сделанные изменения.
AlexandrDmC; +1 Ответить
17. P1rate 02.12.16 10:02 Сейчас в теме
(16)Спасибо за информацию.
2. shnurov 02.12.16 09:05 Сейчас в теме
У меня нет торговли под рукой, но то что делаешь это уже неправильно.

НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра; 


Можно изменить реквизиты объекта, но не реквизиты "вложенного объекта".

И по моему в торговле цена не хранится в справочнике, она хранится в регистре, поэтому надо изменять записи регистра, а не объекты справочника(то что пользователь видит на форме на самом деле может храниться в разных местах). На мой взгляд тебе нужно пройти или найти хоть какие-то минимальные курсы по программированию, а иначе у тебя будет много "таких вопросов".
3. P1rate 02.12.16 09:10 Сейчас в теме
(2)Я учусь, это не торговля, а небольшая конфа для обучения. Самое интересное то, что
НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра; - Это мне вчера советовали, когда я задавал аналогичный вопрос.
4. shnurov 02.12.16 09:17 Сейчас в теме
Предыдущее сообщение обновил. Не все советы одинаково полезны, могут и тролить. Тогда нужно смотреть конфу чего там и как храниться, давай конфу скажу где искать. Но все же прислушайся к моему совету и поищи курсы, на сайте 1с можно пройти за 1300 руб, но они тебе сильно помогут и избавят от таких вопросов.
7. onetone 02.12.16 09:26 Сейчас в теме
(4) ты чего шутишь? Зачем конфа? Он обращается к коллекции табличной части без перебора строк!


(1) После того как ты получил объект, тебе нужно найти нужно строку в табличной части "состав", для этого Для этого посмотри в сторону НайтиСтроки, по результату получил именно строку табличной части, а не коллекцию строк! И тогда поле цена будет обнаружено)
9. shnurov 02.12.16 09:35 Сейчас в теме
(7)
А ты уверен что цена хранится в табличной части? Если конфа не типовая что там и где можно только гадать и можно давать тучу советов, но работать не будет.
10. spacecraft 02.12.16 09:39 Сейчас в теме
(9) если принять на веру, что запрос выполняется без ошибок, то в табличной части есть цена. См. запрос.
13. P1rate 02.12.16 09:47 Сейчас в теме
(10)Дело в том, что справочник "номенклатура" состоит из 2 ТЧ - состав и манипуляции. В тч "состав" висят материалы (товары), их количество, цена материалов из регистра сведений на дату и соответственно стоимость материалов для данной номенклатуры. В ТЧ манипуляции висят манипуляции, их кол-во и цена на манипуляции из регистра сведений. Сумма всех материалов и всех манипуляций = цена номенклатуры. Смысл в том, чтобы сделать обработку, которая пройдёт по всем номенклатурам и везде пересчитает стоимость матералов(товаров), используя актуальную цену из регистра сведений.
19. spacecraft 02.12.16 10:07 Сейчас в теме
(13) явно не оптимальная модель. Идет дублирование цены на материалы в регистре и в справочнике. Попытка синхронизировать цены это костыль.
Скорее всего цена номенклатуры (та, что хранится в самом справочнике) используется в документах и на нее завязана бизнеслогика.
Обработкой синхронизации текущей цены пересчитали цену номенклатуры. Потом перепровели старые документы. Что в итоге получится?
Даже без перепроведения, просто распечатать старый документ... будет уже с новой ценой.
Согласен с (5). Переделывайте на хранение в периодических регистрах. Даже уже существующий регистр подойдет. Там где храните цены материалов.
vovan_victory; +1 Ответить
11. onetone 02.12.16 09:44 Сейчас в теме
(9)Да, потому что запрос отрабатывает, если бы запрос не давал результат то и ошибки не было поле не обнаружено.
12. vovan_victory 63 02.12.16 09:45 Сейчас в теме
(9)
А ты уверен что цена хранится в табличной части?

Я смотрю ты тут самый уверенный. Я не прочитал запрос, onetone не видит что цены хранятся в табличной части....
Тогда расскажи нам , для чего еще автор берет цены из регистра и записывает их в табличную часть если не для хранения? У меня тоже создалось впечатление, что цены хранятся в табличной части. По этому я и написал, что в справочнике их хранить не айс! Для этого существуют регистры.
14. shnurov 02.12.16 09:49 Сейчас в теме
(12)
Я как раз ни в чем не уверен, потому не даю советы как это лучше реализовать. Мой единственный совет пройти курсы, посмотреть обучающие видео, разобраться с теорией.
15. P1rate 02.12.16 09:49 Сейчас в теме
В регистре сведений хранятся цены на материалы(товары), а цена самой номенклатуры хранится в справочнике.
18. Ганс 02.12.16 10:04 Сейчас в теме
Смотри, ты получил объект (НоменклатураОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();)

Теперь тебе нужно цену(которую ты получил в запросе записать в таблицу "состав", скорей всего в этой таблице есть "ТипЦен"(или что-то типа того), тогда тебе по этому типу цен надо найти строку, затем в полученной строке поменять цену, если строк нет то добавить новую
короче что-то типа того:

Отбор = Новый Структура();
Отбор.Вставить("ТипЦен", ТвойТипЦен);
НайденноеЗначение = НоменклатураОбъект.состав.НайтиСтроки(Отбор);

Если НайденноеЗначение.Количество() Тогда
Для каждого стр из НайденноеЗначение Цикл //это если несколько строк, но если их там несколько то это косяк ;)
Стр.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
КонецЦикла;
Иначе
СтрокаСостава = НоменклатураОбъект.состав.Добавить();
СтрокаСостава.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
КонецЕсли;
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот