При разработке отчетов или обработок на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с мистической ситуацией: в схему компоновки данных (СКД) добавляется новое поле, оно прекрасно видно в консоли компоновки и в самом макете, но при инициализации объекта КомпоновщикНастроек в пользовательском режиме это поле упорно не появляется в списке доступных. Особенно остро эта проблема проявляется в комплексных конфигурациях, таких как 1С:ERP 2.5 или 1С:Комплексная автоматизация, в подсистемах печати этикеток и ценников.
В этой статье мы подробно разберем, почему КомпоновщикНастроекКомпоновкиДанных может "игнорировать" изменения в схеме, проанализируем влияние кэша и специфику БСП, а также рассмотрим практические способы решения этой проблемы.
Рассмотрим стандартную ситуацию: компоновщик настроек объявлен как реквизит обработки или отчета. В процессе разработки вы меняете макет СКД в конфигураторе, сохраняете, запускаете отладку, но количество доступных полей остается прежним. Выясним причину такого поведения. Платформа 1С оптимизирует работу с объектами, и если компоновщик настроек является частью метаданных объекта, он может инициализироваться старыми данными из внутреннего кэша сеанса или базы данных.
Решение: Одним из эффективных способов борьбы с этим является вынос компоновщика из реквизитов самого объекта (обработки) в реквизиты формы. Проанализируем, почему это помогает: при создании формы на сервере происходит "чистая" инициализация программных объектов, не привязанная к сериализованному состоянию объекта обработки, сохраненному в базе или кэше.
В ERP 2.5 подсистема печати этикеток и ценников работает через справочник Шаблоны этикеток и ценников. Когда мы вызываем стандартную обработку, система инициализирует компоновщик не просто по макету, а по сохраненным ранее настройкам шаблона. Если вы изменили макет в конфигураторе, но в справочнике уже есть созданный элемент, система при инициализации может использовать старую структуру, хранящуюся в реквизитах справочника.
Для исправления ситуации попробуем выполнить следующие действия:
ОбновлениеВспомогательныхДанных.epf. Она принудительно обновляет кэшируемые структуры метаданных.ПолучитьНастройки(). Часто после инициализации разработчики вызывают загрузку настроек, которая перетирает структуру доступных полей той, что была в момент сохранения настроек в файл или базу.В сложных обработках, таких как ПечатьЭтикетокИЦенников, схема компоновки часто модифицируется программно перед использованием. Посмотрим на типичный сценарий: процедура ПриПодготовкеСтруктурыДанныхНабора может жестко определять состав полей, которые разрешено выводить. Если вашего нового поля нет в списке разрешенных в коде модуля менеджера или формы, компоновщик его отсечет на этапе инициализации источника настроек.
Проанализируем пример обхода этой проблемы, предложенный в сообществе. Если штатные механизмы не позволяют добавить новое поле, можно использовать метод "подмены" уже существующего поля, которое не планируется использовать в текущем бизнес-процессе (например, поле PLU).
Для реализации такой подмены воспользуемся расширением или переопределением процедуры в модуле:
&Перед("ПриПодготовкеСтруктурыДанныхНабора")
Процедура Имя_ПриПодготовкеСтруктурыДанныхНабора(Режим, СхемаКомпоновкиДанных, ТекстЗапроса)
// Подменяем текст запроса, внедряя свою логику в существующее поле
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "КАК PLU,", "КАК PLU1,
| ВЫБОР КОГДА ИсходныеДанныеПоследнийЗапрос.Номенклатура.ИспользованиеХарактеристик = ЗНАЧЕНИЕ(Перечисление.ВариантыИспользованияХарактеристикНоменклатуры.НеИспользовать) ТОГДА
| ИсходныеДанныеПоследнийЗапрос.Номенклатура.Артикул + "" "" + ИсходныеДанныеПоследнийЗапрос.Номенклатура.НаименованиеПолное
| ИНАЧЕ
| ИсходныеДанныеПоследнийЗапрос.Характеристика.Артикул + "" "" + ИсходныеДанныеПоследнийЗапрос.Номенклатура.НаименованиеПолное + "" ("" + ИсходныеДанныеПоследнийЗапрос.Характеристика.НаименованиеПолное + "")""
| КОНЕЦ КАК PLU,");
КонецПроцедуры
В данном примере мы используем функцию СтрЗаменить, чтобы переопределить вычисляемое значение поля PLU. Это позволяет вывести нужную информацию в этикетку без изменения структуры компоновщика настроек, если он "отказывается" видеть новые поля.
Разберем еще один важный технический момент. Поле может присутствовать в запросе, но отсутствовать в доступных полях выбора, если на уровне настроек набора данных в СКД для этого поля установлены ограничения. Проверим следующие настройки в конструкторе схемы:
Если вы столкнулись с тем, что КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора.Элементы не содержит вашего поля после выполнения Инициализировать(), пройдем по шагам для выявления причины:
СхемаКомпоновки действительно присутствует нужное поле. Если его там нет — проблема в кэше метаданных сервера 1С. Требуется перезапуск службы или очистка папки snccntx.
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки);
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
ЗагрузитьНастройки().КомпоновщикНастроек прямо в коде процедуры и проинициализировать его той же схемой. Если в новом объекте поле появилось — значит, проблема в кэшировании реквизита объекта.Таким образом, мы выяснили, что проблема с "пропадающими" полями чаще всего кроется не в ошибках кода, а в многоуровневом кэшировании платформы 1С и специфических механизмах хранения настроек в библиотеке стандартных подсистем (БСП). Использование ОбновлениеВспомогательныхДанных.epf и внимательный анализ процедуры инициализации позволяют решить задачу в большинстве случаев.