При разработке функционала для документов 1С часто возникает необходимость отображать розничную цену товара непосредственно в табличной части. Это позволяет пользователю сразу видеть стоимость, не открывая дополнительные отчеты или карточки номенклатуры. Давайте разберем, как реализовать этот процесс правильно, эффективно и с учетом требований производительности платформы 1С:Предприятие 8.3.
Для начала необходимо добавить новый реквизит в табличную часть (ТЧ) вашего документа. В качестве примера назовем его РозничнаяЦена. Тип данных для этого реквизита лучше установить как Число с соответствующей точностью (например, 15, 2), так как мы будем хранить в нем значение цены, полученное из РегистрСведений.ЦеныНоменклатуры.
После добавления реквизита перетащите его на форму документа в область соответствующей табличной части. Теперь, когда поле отображается, перейдем к логике автоматического заполнения.
Основная задача — чтобы при выборе товара в строке документа цена подтягивалась автоматически. Для этого необходимо использовать обработчик события ПриИзменении для колонки Номенклатура. Важно помнить, что выполнение запросов к базе данных должно происходить на сервере.
Рассмотрим пример реализации функции, которая получает цену из регистра:
&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
Если ТекущаяСтрока <> Неопределено Тогда
ТекущаяСтрока.РозничнаяЦена = ПолучитьРозничнуюЦенуНаСервере(ТекущаяСтрока.Номенклатура);
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПолучитьРозничнуюЦенуНаСервере(Номенклатура)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Номенклатура = &Номенклатура И ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних";
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Запрос.УстановитьПараметр("ВидЦены", Справочники.ВидыЦен.НайтиПоНаименованию("Розница"));
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Возврат Выборка.Цена;
КонецЕсли;
Возврат 0;
КонецФункции
Если вы хотите, чтобы цены заполнялись для уже существующих в документе товаров (например, при открытии документа), использовать вышеприведенный код в цикле — плохая практика, так как это приведет к резкому падению производительности («тормозам»). Вместо этого необходимо выполнить один групповой запрос.
Правильный алгоритм массового заполнения:
РегистрСведений.ЦеныНоменклатуры.СрезПоследних, передав весь список номенклатуры в условие В (&СписокНоменклатуры).При работе с ценами всегда учитывайте следующие важные моменты:
СрезПоследних. Всегда передавайте дату документа (или текущую дату), если требуется получить цену именно на определенный момент времени. Без параметра даты СрезПоследних вернет актуальную цену на текущую секунду, что может быть неверно для документов прошлого периода.ЦенообразованиеВызовСервера.ПолучитьЦену — использование типового функционала значительно надежнее.Применяя эти методы, вы сможете создать удобный и стабильный инструмент для работы с ценами, который будет корректно функционировать в условиях реальной эксплуатации системы.