При разработке внешних обработок для массового обновления данных разработчики иногда сталкиваются с ситуацией, когда нужное поле видно на форме элемента справочника, однако в структуре самого объекта метаданных этот реквизит отсутствует. Попытка открыть формы для тысяч элементов или найти реквизит в объекте справочника приводит к ошибкам. Разберем архитектурные особенности управляемых форм 1С и выясним, как правильно реализовать массовую обработку таких данных.
Проанализируем базовую концепцию управляемого интерфейса 1С:Предприятие 8.3:
ПолучитьФорму или ОткрытьФорму для 7 000 элементов в цикле неизбежно приведет к утечкам оперативной памяти, зависанию клиентского сеанса и аварийному завершению работы программы.Если реквизит формы не связан напрямую с реквизитом объекта, значит, форма выступает лишь инструментом отображения или ввода. Сами данные либо динамически считываются из других таблиц базы данных, либо передаются в прикладные механизмы перед записью объекта.
Прежде чем писать код внешней обработки, откроем конфигуратор и проанализируем модуль формы справочника:
ПриСозданииНаСервере, ПриЧтенииНаСервере или ПослеЗагрузкиДанныхИзНастроек. Выясним, откуда считывается значение: из регистра сведений, табличной части дополнительных реквизитов или внешнего источника.ПередЗаписьюНаСервере, ПриЗаписиНаСервере и ОбработкаПроверкиЗаполненияНаСервере. Посмотрим, куда передается значение реквизита формы перед фиксацией изменений.Рассмотрим типовые сценарии и способы их программной реализации во внешней обработке.
Если поле является дополнительным сведением (механизм БСП), оно хранится в независимом регистре сведений ДополнительныеСведения. Для его изменения не требуется перезаписывать сам элемент справочника. Разберем пример пакетной записи через менеджер записи:
Для Каждого СсылкаЭлемента Из МассивСсылок Цикл
МенеджерЗаписи = РегистрыСведений.ДополнительныеСведения.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = СсылкаЭлемента;
МенеджерЗаписи.Свойство = НужноеСвойство; // ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
МенеджерЗаписи.Значение = НовоеЗначение;
МенеджерЗаписи.Записать(Истина);
КонецЦикла;
Если реквизит выведен через механизм дополнительных реквизитов БСП, физически он расположен в табличной части объекта ДополнительныеРеквизиты. Посмотрим, как программно найти или добавить строку в табличную часть объекта справочника:
Для Каждого СсылкаЭлемента Из МассивСсылок Цикл
ОбъектСправочника = СсылкаЭлемента.ПолучитьОбъект();
НайденнаяСтрока = ОбъектСправочника.ДополнительныеРеквизиты.Найти(НужноеСвойство, "Свойство");
Если НайденнаяСтрока = Неопределено Тогда
НайденнаяСтрока = ОбъектСправочника.ДополнительныеРеквизиты.Добавить();
НайденнаяСтрока.Свойство = НужноеСвойство;
КонецЕсли;
НайденнаяСтрока.Значение = НовоеЗначение;
ОбъектСправочника.Записать();
КонецЦикла;
Если реквизит формы отображает срез последних цен, штрихкод, статус или ответственное лицо, запись необходимо выполнять напрямую в соответствующий регистр сведений:
НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Номенклатура.Установить(СсылкаНоменклатура);
НаборЗаписей.Отбор.ВидЦены.Установить(НужныйВидЦены);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Период = ТекущаяДатаСеанса();
НоваяЗапись.Номенклатура = СсылкаНоменклатура;
НоваяЗапись.ВидЦены = НужныйВидЦены;
НоваяЗапись.Цена = НоваяЦена;
НаборЗаписей.Записать();
В некоторых конфигурациях реквизит формы служит для передачи управляющих флагов в модуль объекта перед записью. В модуле формы значение помещается в структуру ДополнительныеСвойства объекта справочника. Во внешней обработке мы можем передать эти параметры напрямую без участия формы:
Для Каждого СсылкаЭлемента Из МассивСсылок Цикл
ОбъектСправочника = СсылкаЭлемента.ПолучитьОбъект();
ОбъектСправочника.ДополнительныеСвойства.Вставить("ИмяСлужебногоПараметра", ЗначениеПараметра);
ОбъектСправочника.Записать();
КонецЦикла;
Если конфигурация разработана на базе Библиотеки стандартных подсистем (БСП), для массовой корректировки 7 000 элементов не обязательно писать внешнюю обработку с нуля. Типовая обработка ГрупповоеИзменениеРеквизитов позволяет: