При доработке типовых документов ценообразования (например, «Установка цен номенклатуры» в конфигурациях «Управление торговлей», «Комплексная автоматизация» или УПП) разработчики часто сталкиваются с ситуацией: в коде происходит обход строк табличной части, значение в добавленной колонке перезаписывается, но на форме документа ничего не меняется либо данные сразу сбрасываются. Разберем причины такого поведения платформы 1С и выясним, как правильно организовать программное заполнение колонок.
Посмотрим на типичный фрагмент кода, который пытается напрямую изменить строки табличной части объекта:
Табличка = ЭтотОбъект.Товары;
Для Каждого ТекущаяСтрока Из Табличка Цикл
Если ТекущаяСтрока.ТипЦен = ВыбранныйТипЦены Тогда
ТекущаяСтрока.ЦенаАкция = ТекущаяСтрока.Цена * (1 - ПроцентСкидки / 100);
КонецЕсли;
КонецЦикла;
Точка останова в отладчике может показывать, что условие выполняется и свойство ячейки действительно получает новое число, однако в пользовательском интерфейсе изменений нет. Проанализируем архитектуру документа, чтобы понять, почему это происходит.
В типовых конфигурациях табличное поле формы документа «Установка цен номенклатуры» привязано не к реальной табличной части Товары, а к служебному реквизиту формы — экранной Таблице Значений (часто именуемой ТаблицаЦен).
Рассмотрим, как устроена работа с данными в этом документе:
Товары каждая строка содержит номенклатуру, один тип цены и значение этой цены. Если для одной позиции устанавливается 5 типов цен, в табличной части объекта сохраняется 5 отдельных строк.ЭтотОбъект.Товары в удобную матрицу. В экранной таблице значений одна строка соответствует одной позиции номенклатуры, а типы цен динамически создаются в виде отдельных колонок.Товары.Таким образом, попытка изменить ЭтотОбъект.Товары напрямую из формы или внешней обработки не дает результата: интерфейс продолжает отображать данные из промежуточной экранной таблицы значений формы.
Если расчет скидки или акции выполняется в контексте формы документа (например, по нажатию дополнительной кнопки или из вспомогательного диалога), обращаться необходимо к данным экранного табличного поля.
Разберем реализацию прямого изменения строк экранной таблицы значений:
// Получаем доступ к экранной таблице значений формы
ЭкраннаяТаблица = ЭлементыФормы.ТаблицаЦен.Значение;
Для Каждого СтрТаблицы Из ЭкраннаяТаблица Цикл
// Проверяем наличие колонки и выполняем расчет
Если ЭкраннаяТаблица.Колонки.Найти("ЦенаАкция") <> Неопределено Тогда
СтрТаблицы.ЦенаАкция = СтрТаблицы.Цена * (1 - ПроцентСкидки / 100);
КонецЕсли;
КонецЦикла;
// Обновляем визуальное отображение строк
ЭлементыФормы.ТаблицаЦен.ОбновитьСтроки();
Важный момент: если новая колонка была добавлена не только в метаданные табличной части, но и создается динамически при открытии формы, убедимся, что процедура формирования колонок формы (например, СформироватьКолонки() или ОбновитьКолонки()) корректно инициализирует добавленную колонку с нужным типом данных.
Если обработка выполняется в модуле объекта или из внешнего алгоритма, где меняется именно табличная часть ЭтотОбъект.Товары, после завершения записи данных необходимо принудительно запустить процедуру перестроения экранной таблицы.
Посмотрим на алгоритм обновления:
// 1. Заполняем табличную часть объекта
Для Каждого СтрТовары Из ЭтотОбъект.Товары Цикл
Если СтрТовары.ТипЦен = НужныйТипЦен Тогда
СтрТовары.ЦенаАкция = СтрТовары.Цена * 0.9; // Пример скидки 10%
КонецЕсли;
КонецЦикла;
// 2. Вызываем типовую процедуру модуля формы для синхронизации
// Имя процедуры зависит от релиза конфигурации (например, ЗаполнитьТаблицуЦен)
ЗаполнитьТаблицуЦен();
Также важно проверить типовую процедуру ПередЗаписью() в модуле формы. В ней должен присутствовать вызов переноса данных из экранной таблицы в табличную часть Товары, чтобы добавленные реквизиты не затирались стандартным алгоритмом выгрузки.
Товары убедитесь, что в процедурах выгрузки из экранной таблицы в объектную ТЧ прописано заполнение этого нового поля.