При обновлении платформы 1С и конфигурации, а также изменении режима совместимости расширений, разработчики часто сталкиваются с неожиданными проблемами в работе ранее стабильных участков кода. Одна из таких ситуаций — невозможность доступа к предопределенным элементам справочников, особенно когда они используются в запросах или в прямом коде через расширения.
В этом материале мы рассмотрим конкретный случай, когда после обновления платформы с версии 8.3.16 на 8.3.19 и режима совместимости расширения с версии 8.3.14 на 8.3.16, код, обращающийся к предопределенным элементам справочника, перестал работать. Разберем, в чем причина такой ошибки и как ее устранить, а также обсудим особенности работы с предопределенными элементами в расширениях и запросах.
Исходная проблема, с которой мы столкнулись, выглядит следующим образом: после обновления платформы и режима совместимости расширения, следующая конструкция в запросе перестала работать:
| И КонтрагентыКонтактнаяИнформация.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АдресДоставкиКонтрагета)
Аналогично, не работало и прямое обращение к предопределенному элементу в коде:
Запрос.УстановитьПараметр("АдресДоставкиВид", Справочники.ВидыКонтактнойИнформации.АдресДоставкиКонтрагента);
Единственным рабочим способом обращения к элементу оказался поиск по наименованию:
Запрос.УстановитьПараметр("АдресДоставкиВид", Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Доставка"));
При этом после заимствования (добавления) справочника в расширение, прямой вызов Справочники.ВидыКонтактнойИнформации.АдресДоставкиКонтрагента начал работать, но обращение через функцию ЗНАЧЕНИЕ() в запросе по-прежнему вызывало ошибку. Возникала ошибка:
по причине:
{(7, 51)}: Неверные параметры "Справочник.ВидыКонтактнойИнформации.АдресДоставкиКонтрагета"
И КонтрагентыКонтактнаяИнформация.Вид = ЗНАЧЕНИЕ(<<?>>Справочник.ВидыКонтактнойИнформации.АдресДоставкиКонтрагета)
Внимательно изучив ошибку и проанализировав изменения в конфигурации, мы выяснили, что причина была удивительно простой, но неочевидной: изменение имени предопределенного элемента в базовой конфигурации.
В нашем случае, в конфигурации 1С:Управление нашей фирмой (УНФ) версии 1.6.22.75 реквизит назывался АдресДоставкиКонтрагета (без буквы "н"). В новой версии конфигурации это имя было исправлено поставщиком на АдресДоставкиКонтрагента. Соответственно, старый код, написанный под прежнюю версию конфигурации, стал невалидным, так как ссылался на несуществующий предопределенный элемент.
Это подчеркивает критическую важность тщательной проверки кода после обновлений, особенно когда используются жесткие ссылки на метаданные.
Решение проблемы заключается в приведении имен предопределенных элементов в нашем коде в соответствие с актуальными именами в обновленной базовой конфигурации. Рассмотрим шаги, которые необходимо предпринять:
АдресДоставкиКонтрагета на правильное АдресДоставкиКонтрагента в конструкции ЗНАЧЕНИЕ().Вот как будет выглядеть исправленный запрос:
| И КонтрагентыКонтактнаяИнформация.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АдресДоставкиКонтрагента)
Функция ЗНАЧЕНИЕ() в запросах очень строго проверяет существование указанного пути и имени. Даже малейшая опечатка, как в нашем случае, приведет к ошибке "Неверные параметры".
Пример исправленного кода:
Запрос.УстановитьПараметр("АдресДоставкиВид", Справочники.ВидыКонтактнойИнформации.АдресДоставкиКонтрагента);
В нашем случае прямой вызов Справочники.ВидыКонтактнойИнформации.АдресДоставкиКонтрагента начал работать после заимствования справочника в расширение, так как система метаданных в расширении получила актуальную информацию о существовании элемента с корректным именем. Однако если бы имя было указано неверно (как АдресДоставкиКонтрагета), то и прямой вызов не сработал бы.
Рассмотрим подробнее аспекты работы с предопределенными элементами и расширениями, чтобы предотвратить подобные ситуации в будущем и лучше понимать их поведение.
Как мы уже выяснили, одной из ключевых причин возникновения проблем с доступом к предопределенным элементам после обновления платформы или конфигурации может быть изменение имени самого предопределенного элемента поставщиком конфигурации. Это именно то, что произошло в нашем примере с УНФ. Разработчики конфигурации могут исправлять ошибки, улучшать читаемость или унифицировать наименования, что приводит к изменению программных имен предопределенных элементов.
Когда это происходит, весь ваш код, который ссылается на старое имя (будь то в запросах через ЗНАЧЕНИЕ() или в прямом коде), становится неработоспособным. Это требует обязательной актуализации ссылок в расширениях и любых доработках после каждого значительного обновления конфигурации.
Расширения значительно упрощают доработку типовых конфигураций, но имеют свои особенности при работе с предопределенными данными:
Справочники.ВидыКонтактнойИнформации.АдресДоставкиКонтрагента) считается самым надежным способом. В отличие от поиска по коду или наименованию, имя предопределенного элемента невозможно изменить пользователем в режиме 1С:Предприятие. Наименование же может быть изменено, что сделает поиск по наименованию ненадежным. Код также может быть изменен, если он не генерируется автоматически и не контролируется системой.Функция ЗНАЧЕНИЕ() является мощным инструментом в запросах 1С, предназначенным для обращения к предопределенным данным конфигурации. Разберем ее особенности:
ЗНАЧЕНИЕ() используется в запросах для получения ссылок на предопределенные данные, которые являются частью метаданных конфигурации. К таким данным относятся:
ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.ПоступлениеТоваров))ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка))ЗНАЧЕНИЕ() имеет строгий вид: <ТипПредопределенногоЗначения>.<ИмяОбъектаМетаданных>.<ИмяПредопределенногоЭлемента>. Например, Справочник.ВидыКонтактнойИнформации.АдресДоставкиКонтрагента.ЗНАЧЕНИЕ() в запросе выполняет очень строгую проверку существования указанного пути и имени предопределенного элемента. Если в имени есть хоть малейшая опечатка, или если элемент с таким именем больше не существует в метаданных (например, после обновления и изменения имени), запрос завершится ошибкой. Это отличает ее от, например, НайтиПоНаименованию() в коде, который может вернуть Неопределено или пустую ссылку, если элемент не найден, что может быть обработано программно без критической ошибки выполнения запроса.Режим совместимости расширения конфигурации — это важный параметр, который управляет возможностями, которые система предоставляет в расширении. Это свойство определяет, какие функциональные возможности платформы 1С могут быть использованы в данном расширении.
Помимо рассмотренных ситуаций, существуют и другие возможные проблемы с предопределенными элементами и их обновление:
Мы выяснили, что причиной "неработающей" конструкции ЗНАЧЕНИЕ() в запросе и прямого обращения к предопределенному элементу после обновления платформы и режима совместимости было изменение имени предопределенного элемента в базовой конфигурации. Это наглядно демонстрирует, как даже незначительная на первый взгляд правка со стороны поставщика конфигурации может привести к необходимости внесения изменений в расширения и доработанный код.
При работе с расширениями и предопределенными элементами всегда следует помнить о строгой проверке имен в запросах (особенно с ЗНАЧЕНИЕ()), надежности обращения по имени элемента, особенностях заимствования объектов и важности контроля режима совместимости. Тщательное тестирование после каждого обновления конфигурации и платформы является ключевым фактором для обеспечения стабильной работы ваших решений на 1С.