При разработке документов в платформе 1С 7.7 часто возникает задача динамического контроля ввода данных: необходимо разрешить или запретить пользователю редактировать определенную колонку табличной части (например, Цена) в зависимости от значения реквизита (например, флага ВидПитания.РучноеРедактированиеЦен).
Попытка решить эту задачу простым указанием процедуры в поле Формула колонки сталкивается с особенностью платформы: процедура формулы вызывается уже после того, как новое значение введено и фокус покидает ячейку. Использование операторов Возврат или процедуры СтатусВозврата(0) внутри пользовательской процедуры формулы не отменяет факт изменения данных ячейки. Разберем по шагам рабочие и проверенные способы решения этой задачи штатным функционалом 1С 7.7.
Проанализируем наиболее частую ситуацию, когда условие редактирования определяется реквизитом шапки документа (например, ВидПитания выбран в шапке). В этом случае нет необходимости отслеживать каждое нажатие клавиш в табличной части — достаточно централизованно управлять доступностью колонки на форме через свойство Доступность.
Разберем реализацию:
ПриОткрытии() модуля формы документа устанавливаем доступность колонки в соответствии со значением реквизита.ПриВыбореВидаПитания()) обновляем доступность колонки при каждом изменении значения пользователем.Посмотрим на пример кода:
Процедура ОбновитьДоступностьКолонок()
Если ПустоеЗначение(ВидПитания) = 0 Тогда
Форма.Цена.Доступность(ВидПитания.РучноеРедактированиеЦен);
Иначе
Форма.Цена.Доступность(0);
КонецЕсли;
КонецПроцедуры
Процедура ПриВыбореВидаПитания()
ОбновитьДоступностьКолонок();
КонецПроцедуры
Процедура ПриОткрытии()
ОбновитьДоступностьКолонок();
КонецПроцедуры
Если признак доступности зависит от реквизита самой строки табличной части, управление доступностью колонки можно привязать к предопределенной процедуре ПриВыбореСтроки(). Платформа 1С 7.7 вызывает это событие при каждом перемещении курсора по строкам табличной части документа.
Рассмотрим пример кода:
Процедура ПриВыбореСтроки()
Если ПустоеЗначение(ВидПитания) = 0 Тогда
Форма.Цена.Доступность(ВидПитания.РучноеРедактированиеЦен);
Иначе
Форма.Цена.Доступность(0);
КонецЕсли;
КонецПроцедуры
При таком подходе при переходе на строку колонка Цена будет мгновенно становиться доступной или недоступной для ввода данных.
Для запрета входа в режим редактирования строки можно использовать встроенное системное событие ПриНачалеРедактированияСтроки() в связке со СтатусВозврата(0). В отличие от пользовательских формул, эта процедура поддерживает системный отказ от редактирования.
Посмотрим на реализацию:
Процедура ПриНачалеРедактированияСтроки()
Если ВидПитания.РучноеРедактированиеЦен = 0 Тогда
Если Форма.АктивныйЭлемент = "Цена" Тогда
Предупреждение("Ручное редактирование цен для данного вида питания запрещено!");
СтатусВозврата(0);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важное ограничение: процедура ПриНачалеРедактированияСтроки() вызывается платформой 1С 7.7 ровно один раз — при начале редактирования строки. Если пользователь вошел в редактирование строки через колонку Количество, а затем перешел в колонку Цена с помощью мыши или клавиши Enter, событие не вызовется повторно. Поэтому для полной надежности рекомендуется комбинировать данный способ с восстановлением значения.
Если колонка открыта для редактирования, но введенное значение не должно быть принято при невыполнении условия, используем откат к предыдущему значению. Для этого запоминаем старое значение перед редактированием, а в формуле колонки возвращаем его на место и обновляем форму.
Разберем по шагам:
СтараяЦена).ПриВыбореСтроки() или ПриНачалеРедактированияСтроки() сохраняем текущее значение: СтараяЦена = Цена;.ПриРедактированииЦены().Цена с принудительной перерисовкой формы через Форма.Обновить(0).Посмотрим на пример кода:
Перем СтараяЦена;
Процедура ПриВыбореСтроки()
СтараяЦена = Цена;
КонецПроцедуры
Процедура ПриРедактированииЦены()
Если ВидПитания.РучноеРедактированиеЦен = 0 Тогда
Сообщить("Ручное изменение цены запрещено!", "!");
Цена = СтараяЦена;
Форма.Обновить(0);
Иначе
СтараяЦена = Цена;
КонецЕсли;
КонецПроцедуры
Такая связка гарантирует, что даже если пользователь обошел блокировку начала редактирования и изменил число в ячейке, после выхода из ячейки значение автоматически вернется к исходному.