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