diamond АШ Tlg

Управление доступностью полей управляемой формы 1С 8.3 на примере типового механизма ЗУП 3.1

Расследование причины доступности или недоступности полей в формах документов

Разбор механизма доступности элементов управляемой формы на примере документа "Начисление зарплаты" в конфигурации ЗУП 3.1. Данный механизм примечателен тем, что в нём использованы вполне стандартные, но редко используемые возможности платформы 1С 8.3, поэтому обычный аналитик, знакомый с программированием, скорее всего вообще не сможет установить причину недоступности элемента формы, а неопытный программист потратит на выяснение много времени.

Итак, вот наш пациент, попробуем докопаться до причины недоступности полей "Основание" и/или "Место получения дохода":

Обычное начисление

Давайте посмотрим в конфигураторе, какие галочки стоят на по свойстве "Доступность":

Доступность имеется

Как видно, флажок доступности установлен и по идее ничто не должно мешать редактировать поле. Тем не менее это не так - поле остается недоступным. Логично будет предположить, что свойство "Доступность" устанавливается программно где-то при инициализации формы. Делаем поиск в тексте модуля формы по ключевым словам "Доступность", "НачисленияДокументОснование": ничего не находим. В этом месте можно предположить, что свойство устанавливается где-то в общем модуле, но глобальный поиск тоже ничего не даёт.

Какие ещё есть способы управления доступность? Вспоминайте! Правильно - условное оформление. Смотрим в конфигураторе:

Условное оформление

Наших исследумых полей в списке условно оформляемых полей нет. Вроде тупик? Ещё рано сдаваться, давайте откроем в отладчике форму и в самом конце обработчика события ПриСозданииНаСервере посмотрим как заполнена доступность нашего элемента в объекте "ЭтаФорма":

Доступно!

Доступность = Истина Да как так то?! Мы-то точно знаем что поле недоступно. Просмотр событий таблицы "ПриАктивацииСтроки", "ПриНачале Редактирования" и т.д. тоже никаких решений не дает. Ответ тут может быть только один: на форме применено условное оформление, только оно добавлено не в дизайнере формы, а программным способом (как реквизиты или элементы формы).

Для проверки этой гипотезы тут же в отладчике посмотрим свойство ЭтаФорма.УсловноеОформление.Элементы. Как видим, уже не три строки как было в дизайнере формы, а целая куча! А вот и попалось то что мы искали:

НЕ Доступно!

Теперь у нас реальность совпадает с кодом 1С. Некоторые из вас, кто хорошо помнит метаданные конфигурации, в этот момент могут вспомнить, что в табличной части "Начисления" у этого документа нет поля "ДоступноМестоПолученияДохода". Это ещё один ключевой момент, о котором почему-то многие забывают или не до конца разобрались. Дело в том, что реквизит "Объект" это не ДокументОбъект, а коллекция данных формы, и его можно дополнять полями прямо в самом реквизите, что и было сделано в ЗУП, но мы не догадались с самого начала там посмотреть (Объект - Начисления):

Колонка есть!

Далее уже просто требуется усидчивость: отладчиком по шагам отлавливаем и расписываем весь стек вызова. Если мы ещё раз вернемся в начало, то увидим что уже в самом начале "ПриСозданииНаСервере" было полностью заполнено свойство "УсловноеОформление". Значит копать надо начинать с обработчика "ПриЧтенииНаСервере". Для экономии времени привожу всю цепочку вызовов:

  • ПриЧтенииНаСервере
  • ПриПолученииДанныхНаСервере
  • ЗавершитьИнициализациюФормы
  • ДополнитьФорму
  • ЗарплатаКадрыРасширенный.ДокументыВыполненияНачисленийДополнитьФорму
  • ЗарплатаКадрыРасширенный.ВводНачисленийДополнитьФорму
  • ЗарплатаКадрыРасширенный.ВводНачисленийДобавитьЭлементыФормы
  • ЗарплатаКадрыРасширенный.ВводНачисленийУстановитьУсловноеОформление

В последней процедуре находим нужные строки:

ЭлементУсловногоОформления = Форма.УсловноеОформление.Элементы.Добавить();
ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
ЭлементОтбора = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ПутьКДанным + ".ДоступенВыборОснования");
ЭлементОтбора.ПравоеЗначение = Ложь;
ОформляемоеПоле = ЭлементУсловногоОформления.Поля.Элементы.Добавить(); 
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяТаблицы + ОписаниеТаблицыВидовРасчета.ИмяРеквизитаДокументОснование);

Домашнее задание:
а) Выяснить, где устанавливается значения реквизитов "ДоступенВыборОснования" и "ДоступноМестоПолученияДохода";
б) Как известно, событие "ПриЧтенииНаСервере" отрабатывает только при открытии существующего объекта, но на новых документах эти поля все равно недоступны. Найдите, как заполняется условное оформление в новых документах;
в) Ответьте на вопрос: в чём преимущество описанного типового подхода перед программной записью значения "Доступность"?