При переходе на новые релизы платформы «1С:Предприятие 8» (например, линейку 8.3.13 и выше) разработчики иногда сталкиваются с ситуацией, когда при программном создании менеджера записи регистра сведений перестает выполняться или отлаживаться событие ОбработкаЗаполнения. Особенно остро проблема заявляет о себе, когда в этом событии инициализируется стандартный реквизит Период для периодических регистров, и при попытке записи система выдает ошибку «Значение поля Период не может быть пустым».
В этой статье мы подробно разберем, почему возникает эта проблема, как устроена архитектура событий регистров сведений в 1С, и как правильно инициализировать данные при программной работе с менеджером записи.
Для того чтобы понять причину «отказа» события, давайте проанализируем структуру объектов конфигурации 1С. Главное заблуждение многих начинающих разработчиков кроется в предположении, что объект РегистрСведенийМенеджерЗаписи обладает тем же жизненным циклом и набором событий, что и стандартные ссылочные документы или справочники.
Рассмотрим ключевые особенности работы этих объектов:
РегистрСведенийМенеджерЗаписи не имеет собственного модуля объекта. Следовательно, у него физически не может быть собственного обработчика события ОбработкаЗаполнения.ОбработкаЗаполнения определено исключительно для объекта типа РегистрСведенийНаборЗаписей и описывается в Модуле набора записей соответствующего регистра сведений.СоздатьМенеджерЗаписи() платформа выполняет только инициализацию «пустой» заготовки в памяти. Автоматического вызова события заполнения при этом не происходит. Это стандартное поведение платформы во всех версиях (начиная с 8.1, 8.2 и заканчивая актуальными релизами 8.3).Если в вашем коде заполнение ключевых полей (таких как Период) было завязано исключительно на обработчик заполнения, то при программном создании записи без дополнительных инструкций этот код просто проигнорируется, что неизбежно приведет к ошибке при записи.
Если логика заполнения реквизитов регистра сведений сложная и ее необходимо сохранить именно в модуле набора записей в обработчике ОбработкаЗаполнения, мы обязаны вызвать этот механизм программно.
Для этого у объекта РегистрСведенийМенеджерЗаписи существует специальный метод Заполнить(). Давайте рассмотрим пример его использования:
// Шаг 1. Создаем менеджер записи программно
МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
// Шаг 2. Подготовим данные для заполнения (это могут быть любые типы данных заполнения)
ДанныеЗаполнения = Новый Структура;
ДанныеЗаполнения.Вставить("Период", ТекущаяДата());
ДанныеЗаполнения.Вставить("Валюта", Справочники.Валюты.НайтиПоКоду("810"));
// Шаг 3. Явно вызываем метод Заполнить
// Это действие заставит платформу обратиться к модулю набора записей и выполнить событие ОбработкаЗаполнения
МенеджерЗаписи.Заполнить(ДанныеЗаполнения);
// Шаг 4. Записываем данные в базу
МенеджерЗаписи.Записать(Истина);
При вызове метода Заполнить() платформа под капотом создаст виртуальный набор записей, вызовет обработчик из модуля набора и перенесет результат обратно в свойства менеджера записи. В этот момент отладчик успешно зайдет в процедуру ОбработкаЗаполнения в модуле набора записей.
Если логика заполнения проста или уникальна для конкретного участка кода, использовать событие ОбработкаЗаполнения не обязательно. Более того, с точки зрения производительности и читаемости кода, правильнее напрямую присваивать значения свойствам менеджера записи.
Проанализируем классический пример прямого заполнения:
// Создаем менеджер записи
МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
// Заполняем ключевые измерения напрямую
МенеджерЗаписи.Период = ТекущаяДата();
МенеджерЗаписи.Номенклатура = СсылкаНаТовар;
МенеджерЗаписи.ТипЦен = СсылкаНаТипЦен;
// Заполняем ресурсы
МенеджерЗаписи.Цена = 1500;
// Записываем данные
МенеджерЗаписи.Записать(Истина);
Этот способ работает быстрее, так как исключает лишние системные вызовы событий модуля набора записей, и полностью прозрачен для отладки.
Автор темы также упомянул проблему: «даже отладчик не заходит, на новой платформе перестала работать отладка на сервере». Действительно, в релизах линейки 8.3.13 (включая 8.3.13.1644) разработчики часто сталкивались со сбоями в работе механизма отладки.
Если вы уверены, что код выполняется, но точка останова в процедурах на сервере игнорируется, выполните следующие действия по настройке окружения:
-debug. Проверить это можно в реестре Windows (ветка службы 1C:Enterprise 8.3 Server Agent) или в конфигурационном файле в Linux.Использование правильной методики работы с программными объектами 1С в сочетании с верно настроенным сервером отладки позволит вам быстро локализовать и устранить любые подобные затруднения.