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