При работе с конфигурацией Зарплата и управление персоналом 3.1 разработчики часто сталкиваются с тем, что форма документа в режиме конфигуратора кардинально отличается от того, что видит пользователь. Типичный пример — документ ДанныеДляРасчетаЗарплаты. Попытки найти конкретное поле выбора сотрудника в конфигураторе и назначить ему стандартный обработчик ПриИзменении или ОбработкаВыбора часто заканчиваются неудачей: точка останова просто не срабатывает.
В этой статье мы разберем, почему это происходит, как устроена архитектура подобных форм-конструкторов и каким образом программно «отловить» выбор сотрудника в расширении.
Первое, что нам необходимо понять: форма документа ДанныеДляРасчетаЗарплаты является динамической. Ее состав, количество колонок и доступные поля зависят от выбранного Шаблона ввода данных. Это механизм-конструктор, который позволяет пользователям самостоятельно настраивать состав показателей для ввода.
Рассмотрим основные причины различий:
Элементы.Добавить().ДанныеСводно или ДанныеДетально.ДанныеДляРасчетаЗарплатыФормы и ДанныеДляРасчетаЗарплатыКлиент.Проанализируем структуру формы. Поскольку сотрудник выбирается внутри таблицы, нам нужно работать не с реквизитом формы, а с колонкой табличной части. В ЗУП 3.1 сотрудник в этом документе обычно отображается в одной из двух таблиц:
ДанныеСводно — если данные вводятся в целом за месяц.ДанныеДетально — если данные вводятся детально (по датам, видам работ и т.д.).Важно понимать, что даже если вы нашли элемент Сотрудник в конфигураторе, он может быть лишь заготовкой. В реальности на форме может отображаться программно созданный элемент с похожим именем.
Рассмотрим ситуацию, когда нам нужно запретить выбор определенного сотрудника или выполнить проверку условий при его выборе. Поскольку стандартная точка останова в модуле формы не срабатывает (так как выбор может обрабатываться системно), воспользуемся механизмом расширений.
Для начала нам нужно определить, какой именно обработчик события использовать. Рассмотрим пошаговый алгоритм решения задачи.
Разберем, как найти программно назначенные действия. В модуле формы в процедуре ПриСозданииНаСервере или в связанных общих модулях 1С часто использует метод УстановитьДействие. Нам нужно убедиться, какой обработчик назначен колонке сотрудника.
Проверим коллекцию ЭтаФорма.Элементы в отладке. Нас интересуют пути:
Элементы.ДанныеСводноСотрудникЭлементы.ДанныеДетальноСотрудникЕсли в основной конфигурации обработчик ОбработкаВыбора для поля не определен, 1С выполняет выбор системно. Чтобы вмешаться в этот процесс, нам нужно добавить свой обработчик в расширение. Рассмотрим пример добавления обработчика для таблицы ДанныеДетально.
В модуле формы расширения создадим процедуру-перехватчик:
&НаКлиенте
Процедура Расш1_ДанныеДетальноСотрудникОбработкаВыбораПосле(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
// Здесь мы уже имеем выбранного сотрудника
Если ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
// Выполняем нашу проверку
Если Не СотрудникСоответствуетУсловиям(ВыбранноеЗначение) Тогда
СтандартнаяОбработка = Ложь;
Сообщить("Выбор данного сотрудника запрещен по условиям компании!");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Так как поле создается динамически или его свойства меняются при смене шаблона, надежнее всего принудительно назначить обработчик в процедуре ПриОткрытии или ПриСозданииНаСервере (в зависимости от того, на каком этапе формируются элементы).
Проанализируем использование метода УстановитьДействие на клиенте:
&НаКлиенте
Процедура Расш1_ПриОткрытииПосле(Отказ)
// Находим элемент колонки сотрудника
ЭлементСотрудник = Элементы.Найти("ДанныеДетальноСотрудник");
Если ЭлементСотрудник <> Неопределено Тогда
// Назначаем обработчик события выбора
ЭлементСотрудник.УстановитьДействие("ОбработкаВыбора", "Расш1_ДанныеДетальноСотрудникОбработкаВыбора");
КонецЕсли;
КонецПроцедуры
Выясним причину, по которой точка останова может не срабатывать даже после настройки расширения. В документе ДанныеДляРасчетаЗарплаты существует переключатель режимов. Если вы добавили обработчик для таблицы ДанныеДетально, а пользователь в данный момент вводит данные в режиме Сводно, ваш код не будет вызван.
Поэтому необходимо проверить оба варианта таблиц:
ПриИзменении самого реквизита в строке таблицы, либо на ПередОкончаниемРедактирования.Если ваша задача — не просто проверить сотрудника после выбора, а ограничить сам список выбора (например, показывать только сотрудников конкретного подразделения), рассмотрим использование СвязиВыбора. В динамических формах это также делается программно.
Рассмотрим пример установки связи выбора через расширение в ПриСозданииНаСервере:
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
НоваяСвязь = Новый СвязьПараметраВыбора("Отбор.Подразделение", "Объект.Подразделение");
НовыеСвязи = Новый Массив;
НовыеСвязи.Добавить(НоваяСвязь);
// Применяем к динамическому элементу
Элементы.ДанныеДетальноСотрудник.СвязиПараметровВыбора = Новый ФиксированныйМассив(НовыеСвязи);
КонецПроцедуры
Важный момент: если вы используете расширение модуля формы, убедитесь, что вы расширяете именно те процедуры, которые отвечают за заполнение состава колонок. В типовой ЗУП 3.1 это часто происходит в модуле ДанныеДляРасчетаЗарплатыФормы. Иногда эффективнее перехватить процедуру в общем модуле, которая вызывается при изменении состава показателей шаблона.
Для успешной доработки документа ДанныеДляРасчетаЗарплаты в ЗУП 3.1 необходимо:
ДанныеСводно или ДанныеДетально) находится нужный вам элемент в конкретном режиме работы.&After (После) для метода ПриСозданииНаСервере или ПриОткрытии.Элементы и, если стандартные методы расширения не помогают, использовать УстановитьДействие для назначения своего обработчика события.Использование этих методов позволит вам корректно управлять поведением самых сложных динамических форм 1С, обеспечивая стабильную работу бизнес-логики в расширениях.