Почему не изменяются значения в табличной части документа Установка цен номенклатуры и как это исправить

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При доработке типовых документов ценообразования (например, «Установка цен номенклатуры» в конфигурациях «Управление торговлей», «Комплексная автоматизация» или УПП) разработчики часто сталкиваются с ситуацией: в коде происходит обход строк табличной части, значение в добавленной колонке перезаписывается, но на форме документа ничего не меняется либо данные сразу сбрасываются. Разберем причины такого поведения платформы 1С и выясним, как правильно организовать программное заполнение колонок.

Посмотрим на типичный фрагмент кода, который пытается напрямую изменить строки табличной части объекта:


Табличка = ЭтотОбъект.Товары;
Для Каждого ТекущаяСтрока Из Табличка Цикл
    Если ТекущаяСтрока.ТипЦен = ВыбранныйТипЦены Тогда
        ТекущаяСтрока.ЦенаАкция = ТекущаяСтрока.Цена * (1 - ПроцентСкидки / 100);
    КонецЕсли;
КонецЦикла;

Точка останова в отладчике может показывать, что условие выполняется и свойство ячейки действительно получает новое число, однако в пользовательском интерфейсе изменений нет. Проанализируем архитектуру документа, чтобы понять, почему это происходит.

Архитектурные особенности документа Установка цен номенклатуры

В типовых конфигурациях табличное поле формы документа «Установка цен номенклатуры» привязано не к реальной табличной части Товары, а к служебному реквизиту формы — экранной Таблице Значений (часто именуемой ТаблицаЦен).

Рассмотрим, как устроена работа с данными в этом документе:

  1. Транспонирование структуры данных: В табличной части объекта Товары каждая строка содержит номенклатуру, один тип цены и значение этой цены. Если для одной позиции устанавливается 5 типов цен, в табличной части объекта сохраняется 5 отдельных строк.
  2. Формирование экранной матрицы: При открытии формы процедура модуля формы преобразует плоский список из ЭтотОбъект.Товары в удобную матрицу. В экранной таблице значений одна строка соответствует одной позиции номенклатуры, а типы цен динамически создаются в виде отдельных колонок.
  3. Синхронизация при записи: Пользователь редактирует именно экранную таблицу значений. Перед непосредственной записью документа вызывается типовая процедура, которая считывает экранную матрицу и перезаполняет реальную табличную часть Товары.

Таким образом, попытка изменить ЭтотОбъект.Товары напрямую из формы или внешней обработки не дает результата: интерфейс продолжает отображать данные из промежуточной экранной таблицы значений формы.

Способ 1. Заполнение экранной таблицы значений формы

Если расчет скидки или акции выполняется в контексте формы документа (например, по нажатию дополнительной кнопки или из вспомогательного диалога), обращаться необходимо к данным экранного табличного поля.

Разберем реализацию прямого изменения строк экранной таблицы значений:


// Получаем доступ к экранной таблице значений формы
ЭкраннаяТаблица = ЭлементыФормы.ТаблицаЦен.Значение;

Для Каждого СтрТаблицы Из ЭкраннаяТаблица Цикл
    // Проверяем наличие колонки и выполняем расчет
    Если ЭкраннаяТаблица.Колонки.Найти("ЦенаАкция") <> Неопределено Тогда
        СтрТаблицы.ЦенаАкция = СтрТаблицы.Цена * (1 - ПроцентСкидки / 100);
    КонецЕсли;
КонецЦикла;

// Обновляем визуальное отображение строк
ЭлементыФормы.ТаблицаЦен.ОбновитьСтроки();

Важный момент: если новая колонка была добавлена не только в метаданные табличной части, но и создается динамически при открытии формы, убедимся, что процедура формирования колонок формы (например, СформироватьКолонки() или ОбновитьКолонки()) корректно инициализирует добавленную колонку с нужным типом данных.

Способ 2. Заполнение табличной части объекта с последующей синхронизацией

Если обработка выполняется в модуле объекта или из внешнего алгоритма, где меняется именно табличная часть ЭтотОбъект.Товары, после завершения записи данных необходимо принудительно запустить процедуру перестроения экранной таблицы.

Посмотрим на алгоритм обновления:


// 1. Заполняем табличную часть объекта
Для Каждого СтрТовары Из ЭтотОбъект.Товары Цикл
    Если СтрТовары.ТипЦен = НужныйТипЦен Тогда
        СтрТовары.ЦенаАкция = СтрТовары.Цена * 0.9; // Пример скидки 10%
    КонецЕсли;
КонецЦикла;

// 2. Вызываем типовую процедуру модуля формы для синхронизации
// Имя процедуры зависит от релиза конфигурации (например, ЗаполнитьТаблицуЦен)
ЗаполнитьТаблицуЦен();

Также важно проверить типовую процедуру ПередЗаписью() в модуле формы. В ней должен присутствовать вызов переноса данных из экранной таблицы в табличную часть Товары, чтобы добавленные реквизиты не затирались стандартным алгоритмом выгрузки.

Рекомендации по доработке механизмов ценообразования

  1. Проверяйте состав реквизитов: При добавлении нового реквизита в табличную часть Товары убедитесь, что в процедурах выгрузки из экранной таблицы в объектную ТЧ прописано заполнение этого нового поля.
  2. Используйте типовой механизм изменения: Для массового пересчета цен безопаснее использовать штатную обработку документа «Изменить таблицу товаров», встроив дополнительное действие пересчета цен в ее структуру. Это исключит конфликты синхронизации интерфейса и базы данных.
← На главную