Как запретить изменение цены в табличной части, если документ создан программно?

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

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

В данной статье мы проанализируем ситуацию, когда в документе присутствует флаг АвтоматическоеСозданиеДокумента, и разберем по шагам, как правильно заблокировать изменение цены, не нарушая работу типовых механизмов пересчета.

Анализ проблемы: почему стандартные обработчики не всегда помогают?

Рассмотрим типичную ошибку начинающего разработчика. Пытаясь вставить условие только в процедуру ТоварыЦенаПриИзменении, мы сталкиваемся с тем, что цена может измениться «в обход» этого события. Например, при выборе или смене номенклатуры срабатывает типовой механизм, который автоматически подставляет цену из прайс-листа или соглашения. В этом случае событие изменения цены пользователем не генерируется, но данные в строке перезаписываются.

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

Способ 1. Блокировка колонки на уровне интерфейса

Самый надежный способ предотвратить изменение данных пользователем — сделать колонку недоступной для редактирования еще в момент открытия формы. Выясним, как это реализовать в зависимости от типа форм.

Для обычных форм (как в примере автора) мы можем использовать процедуру ПриОткрытии или ПередОткрытием. Разберем пример кода:


Процедура ПриОткрытии()
    // Проверяем флаг программного создания
    Если ЭтотОбъект.АвтоматическоеСозданиеДокумента Тогда
        // Устанавливаем запрет изменения для конкретной колонки
        ЭлементыФормы.Товары.Колонки.Цена.ТолькоПросмотр = Истина;
    КонецЕсли;
КонецПроцедуры

Этот метод хорош тем, что пользователь сразу видит: поле «Цена» заблокировано (оно обычно выделяется серым фоном). Однако это не защитит от программного изменения цены внутри самой формы при смене номенклатуры.

Способ 2. Управление логикой в обработчике «ПриИзменении» номенклатуры

Проанализируем ситуацию, описанную в сообщении №11 форума. Когда пользователь меняет номенклатуру в строке, типовая конфигурация обычно вызывает цепочку процедур для поиска актуальной цены. Чтобы сохранить «старую» цену, нам нужно вмешаться в этот процесс.

Рассмотрим пример реализации в процедуре ТоварыНоменклатураПриИзменении:


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

Таким образом, даже если типовой код найдет новую цену в справочнике, мы принудительно вернем то значение, которое было в строке изначально.

Способ 3. Использование события «ПриНачалеРедактирования»

Если мы хотим запретить редактирование цены «на лету» без полной блокировки колонки (например, если в некоторых строках редактирование все же разрешено), можно воспользоваться событием табличной части ПриНачалеРедактирования.

Посмотрим на пример логики:


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

Способ 4. Реализация для Управляемых форм (Условное оформление)

Если ваша конфигурация использует управляемые формы (например, УТ 11, ERP 2.x), то наиболее современным и правильным методом будет использование Условного оформления. Это позволяет избежать написания лишнего кода в обработчиках событий.

Разберем последовательность действий:

  1. Перейдем на вкладку «Условное оформление» в редакторе формы.
  2. Добавим новое правило.
  3. В «Оформлении» установим флаг ТолькоПросмотр = Истина.
  4. В «Условии» укажем: Объект.АвтоматическоеСозданиеДокумента Равно Истина.
  5. В «Оформляемых полях» выберем поле ТоварыЦена.

Платформа 1С будет автоматически управлять доступностью поля на уровне интерфейса, основываясь на значении вашего реквизита. Это наиболее «чистый» метод, который не ломает типовой функционал и легко поддерживается при обновлениях.

Важные рекомендации по обеспечению целостности данных

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

Используем процедуру ПередЗаписью в модуле документа для финального контроля:


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

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

← На главную