Изменение элементов табличной части справочника в цикле запроса
Добрый день. Есть вот такой запрос. Смысл в том, что я пытаюсь поменять цену товара в ТЧ "состав" справочника "номеклатура". Сам запрос отрабатывает норм, но в цикле я никак не могу установить новую цену для состав.цена, т.к. выдаёт ошибку: Поле объекта не обнаружено (Цена) НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра; Подскажите, что я не так делаю, а то вчера целый день убил на это. Заранее благодарен.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураСостав.Наименование КАК Наименование,
| НоменклатураСостав.Количество,
| НоменклатураСостав.Цена,
| НоменклатураСостав.Стоимость,
| СтоимостьМатериалаСрезПоследних.Цена КАК ЦенаРегистра,
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура.Состав КАК НоменклатураСостав
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтоимостьМатериала.СрезПоследних(&ПериодВыборки, Цена > 0) КАК СтоимостьМатериалаСрезПоследних
| ПО НоменклатураСостав.Наименование = СтоимостьМатериалаСрезПоследних.Наименование
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО НоменклатураСостав.Ссылка = Номенклатура.Ссылка
|
|СГРУППИРОВАТЬ ПО
| НоменклатураСостав.Наименование,
| НоменклатураСостав.Количество,
| НоменклатураСостав.Цена,
| НоменклатураСостав.Стоимость,
| СтоимостьМатериалаСрезПоследних.Цена,
| Номенклатура.Ссылка
|
|УПОРЯДОЧИТЬ ПО
| Наименование
|АВТОУПОРЯДОЧИВАНИЕ";
Запрос.УстановитьПараметр("ПериодВыборки", Объект.ПериодВыборки);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
НоменклатураОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
НоменклатураОбъект.Записать();
КонецЦикла;
ПоказатьПо теме из базы знаний
- Расчет итогов по группам справочника в прямом запросе.
- Отборы (поиск) в табличной части либо таблице значений (управляемые формы)
- Смотрим запросы 1С через Microsoft SQL Profiler по следам ошибок разработчиков, приводящих к проблемам производительности
- Новые возможности языка запросов в платформе 8.3.20
- Функция отбора элементов коллекции быстрым условием
Найденные решения
(1) в какой строке табличной части должна поменяться цена?
Сначала необходимо найти строку табличной части в которую нужно установить новое значение цены. Строку можно найти по значению реквизита "Наименование". Для простоты считаем, что наименования в ТЧ уникальны. Тогда код буде такой:
Код конечно не оптимальный. Номенклатура записывается после каждого изменения цены в строке ТЧ Состав. В запросе необходимо использовать итоги по Номенклатуре и строке табличной части. Тогда можно будет получив номенклатуру, перебрать все строки ТЧ Состав, установить в них цену, а затем один раз записать сделанные изменения.
НоменклатураОбъект.Состав
это табличная часть. Цена хранится в реквизите СТРОКИ табличной части. При выполнении кода НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
Сначала необходимо найти строку табличной части в которую нужно установить новое значение цены. Строку можно найти по значению реквизита "Наименование". Для простоты считаем, что наименования в ТЧ уникальны. Тогда код буде такой:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
//Получаем элемент справочника Номенклатура
НоменклатураОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
//Находим строку ТЧ Состав
НайденаяСтрока = НоменклатураОбъект.Состав.Найти(ВыборкаДетальныеЗаписи.Наименование, "Наименование");
//Если нашли строку, то меняем в ней цену
Если НайденаяСтрока <> Неопределено Тогда
НайденаяСтрока.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
КонецЕсли;
//Записываем
НоменклатураОбъект.Записать();
КонецЦикла;
ПоказатьКод конечно не оптимальный. Номенклатура записывается после каждого изменения цены в строке ТЧ Состав. В запросе необходимо использовать итоги по Номенклатуре и строке табличной части. Тогда можно будет получив номенклатуру, перебрать все строки ТЧ Состав, установить в них цену, а затем один раз записать сделанные изменения.
Остальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1)На сколько я понял, Вы пытаете изобразить что то типа прайса..В корне не правильный подход! Справочник должен хранить исключительно наименования позиций Вашего прайса, а для хранения цен и истории изменения, необходимо использовать периодический регистр сведений. Тогда, получив срез последних этого регистра, Вы сможете получить актуальные цены на дату среза.
(1) самое главное, что получен объект, но присваивание цены идет к табличной части. Именно к табличной части, а не к строке табличной части. Нужно указать какая строка табличной части изменяется. Для этого нужно в запросе еще получить и номер строки. И присваивать уже по номеру строки НоменклатураОбъект.Состав[ВыборкаДетальныеЗаписи.НомерСтроки].Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
А вот номенклатура, количество, стоимость далее не используется, не вижу смысла получать в запросе.
Далее по коду:
1. последнее левое соединение в общем-то и не требуется. Ссылка на документ есть в самой табличной части.
2. выгрузку из запроса нужно обходить через группировку по ссылке, и уже в ней делать выборку по строкам табличной части, чтоб на каждую строку не получать объект снова и снова.
А вот номенклатура, количество, стоимость далее не используется, не вижу смысла получать в запросе.
Далее по коду:
1. последнее левое соединение в общем-то и не требуется. Ссылка на документ есть в самой табличной части.
2. выгрузку из запроса нужно обходить через группировку по ссылке, и уже в ней делать выборку по строкам табличной части, чтоб на каждую строку не получать объект снова и снова.
(1) в какой строке табличной части должна поменяться цена?
Сначала необходимо найти строку табличной части в которую нужно установить новое значение цены. Строку можно найти по значению реквизита "Наименование". Для простоты считаем, что наименования в ТЧ уникальны. Тогда код буде такой:
Код конечно не оптимальный. Номенклатура записывается после каждого изменения цены в строке ТЧ Состав. В запросе необходимо использовать итоги по Номенклатуре и строке табличной части. Тогда можно будет получив номенклатуру, перебрать все строки ТЧ Состав, установить в них цену, а затем один раз записать сделанные изменения.
НоменклатураОбъект.Состав
это табличная часть. Цена хранится в реквизите СТРОКИ табличной части. При выполнении кода НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
Сначала необходимо найти строку табличной части в которую нужно установить новое значение цены. Строку можно найти по значению реквизита "Наименование". Для простоты считаем, что наименования в ТЧ уникальны. Тогда код буде такой:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
//Получаем элемент справочника Номенклатура
НоменклатураОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
//Находим строку ТЧ Состав
НайденаяСтрока = НоменклатураОбъект.Состав.Найти(ВыборкаДетальныеЗаписи.Наименование, "Наименование");
//Если нашли строку, то меняем в ней цену
Если НайденаяСтрока <> Неопределено Тогда
НайденаяСтрока.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
КонецЕсли;
//Записываем
НоменклатураОбъект.Записать();
КонецЦикла;
ПоказатьКод конечно не оптимальный. Номенклатура записывается после каждого изменения цены в строке ТЧ Состав. В запросе необходимо использовать итоги по Номенклатуре и строке табличной части. Тогда можно будет получив номенклатуру, перебрать все строки ТЧ Состав, установить в них цену, а затем один раз записать сделанные изменения.
У меня нет торговли под рукой, но то что делаешь это уже неправильно.
Можно изменить реквизиты объекта, но не реквизиты "вложенного объекта".
И по моему в торговле цена не хранится в справочнике, она хранится в регистре, поэтому надо изменять записи регистра, а не объекты справочника(то что пользователь видит на форме на самом деле может храниться в разных местах). На мой взгляд тебе нужно пройти или найти хоть какие-то минимальные курсы по программированию, а иначе у тебя будет много "таких вопросов".
НоменклатураОбъект.Состав.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
Можно изменить реквизиты объекта, но не реквизиты "вложенного объекта".
И по моему в торговле цена не хранится в справочнике, она хранится в регистре, поэтому надо изменять записи регистра, а не объекты справочника(то что пользователь видит на форме на самом деле может храниться в разных местах). На мой взгляд тебе нужно пройти или найти хоть какие-то минимальные курсы по программированию, а иначе у тебя будет много "таких вопросов".
Предыдущее сообщение обновил. Не все советы одинаково полезны, могут и тролить. Тогда нужно смотреть конфу чего там и как храниться, давай конфу скажу где искать. Но все же прислушайся к моему совету и поищи курсы, на сайте 1с можно пройти за 1300 руб, но они тебе сильно помогут и избавят от таких вопросов.
(4) ты чего шутишь? Зачем конфа? Он обращается к коллекции табличной части без перебора строк!
(1) После того как ты получил объект, тебе нужно найти нужно строку в табличной части "состав", для этого Для этого посмотри в сторону НайтиСтроки, по результату получил именно строку табличной части, а не коллекцию строк! И тогда поле цена будет обнаружено)
(1) После того как ты получил объект, тебе нужно найти нужно строку в табличной части "состав", для этого Для этого посмотри в сторону НайтиСтроки, по результату получил именно строку табличной части, а не коллекцию строк! И тогда поле цена будет обнаружено)
(10)Дело в том, что справочник "номенклатура" состоит из 2 ТЧ - состав и манипуляции. В тч "состав" висят материалы (товары), их количество, цена материалов из регистра сведений на дату и соответственно стоимость материалов для данной номенклатуры. В ТЧ манипуляции висят манипуляции, их кол-во и цена на манипуляции из регистра сведений. Сумма всех материалов и всех манипуляций = цена номенклатуры. Смысл в том, чтобы сделать обработку, которая пройдёт по всем номенклатурам и везде пересчитает стоимость матералов(товаров), используя актуальную цену из регистра сведений.
(13) явно не оптимальная модель. Идет дублирование цены на материалы в регистре и в справочнике. Попытка синхронизировать цены это костыль.
Скорее всего цена номенклатуры (та, что хранится в самом справочнике) используется в документах и на нее завязана бизнеслогика.
Обработкой синхронизации текущей цены пересчитали цену номенклатуры. Потом перепровели старые документы. Что в итоге получится?
Даже без перепроведения, просто распечатать старый документ... будет уже с новой ценой.
Согласен с (5). Переделывайте на хранение в периодических регистрах. Даже уже существующий регистр подойдет. Там где храните цены материалов.
Скорее всего цена номенклатуры (та, что хранится в самом справочнике) используется в документах и на нее завязана бизнеслогика.
Обработкой синхронизации текущей цены пересчитали цену номенклатуры. Потом перепровели старые документы. Что в итоге получится?
Даже без перепроведения, просто распечатать старый документ... будет уже с новой ценой.
Согласен с (5). Переделывайте на хранение в периодических регистрах. Даже уже существующий регистр подойдет. Там где храните цены материалов.
(9)
Я смотрю ты тут самый уверенный. Я не прочитал запрос, onetone не видит что цены хранятся в табличной части....
Тогда расскажи нам , для чего еще автор берет цены из регистра и записывает их в табличную часть если не для хранения? У меня тоже создалось впечатление, что цены хранятся в табличной части. По этому я и написал, что в справочнике их хранить не айс! Для этого существуют регистры.
А ты уверен что цена хранится в табличной части?
Я смотрю ты тут самый уверенный. Я не прочитал запрос, onetone не видит что цены хранятся в табличной части....
Тогда расскажи нам , для чего еще автор берет цены из регистра и записывает их в табличную часть если не для хранения? У меня тоже создалось впечатление, что цены хранятся в табличной части. По этому я и написал, что в справочнике их хранить не айс! Для этого существуют регистры.
Смотри, ты получил объект (НоменклатураОбъект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();)
Теперь тебе нужно цену(которую ты получил в запросе записать в таблицу "состав", скорей всего в этой таблице есть "ТипЦен"(или что-то типа того), тогда тебе по этому типу цен надо найти строку, затем в полученной строке поменять цену, если строк нет то добавить новую
короче что-то типа того:
Теперь тебе нужно цену(которую ты получил в запросе записать в таблицу "состав", скорей всего в этой таблице есть "ТипЦен"(или что-то типа того), тогда тебе по этому типу цен надо найти строку, затем в полученной строке поменять цену, если строк нет то добавить новую
короче что-то типа того:
Отбор = Новый Структура();
Отбор.Вставить("ТипЦен", ТвойТипЦен);
НайденноеЗначение = НоменклатураОбъект.состав.НайтиСтроки(Отбор);
Если НайденноеЗначение.Количество() Тогда
Для каждого стр из НайденноеЗначение Цикл //это если несколько строк, но если их там несколько то это косяк ;)
Стр.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
КонецЦикла;
Иначе
СтрокаСостава = НоменклатураОбъект.состав.Добавить();
СтрокаСостава.Цена = ВыборкаДетальныеЗаписи.ЦенаРегистра;
КонецЕсли;
Показать
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот