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