Почему в запросе расширения 1С возникает ошибка «Неверные параметры» при использовании ЗНАЧЕНИЕ() и как ее исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Каждый разработчик 1С рано или поздно сталкивается с ситуацией, когда один и тот же запрос успешно выполняется в консоли запросов в режиме «1С:Предприятие», но при попытке сохранить его в конфигураторе внутри расширения система выдает ошибку «Неверные параметры». Особенно часто это происходит при попытке обратиться к предопределенным элементам справочников, документов или планов видов характеристик через стандартную конструкцию ЗНАЧЕНИЕ().

В этой статье мы подробно разберем, почему возникает данная ошибка, проанализируем внутренние механизмы платформы «1С:Предприятие 8» при работе с расширениями и рассмотрим три эффективных способа решения этой проблемы с примерами кода.

Выясняем причину: почему Конфигуратор ругается, а в режиме Предприятия все работает?

Давайте проанализируем ситуацию. Предположим, мы пишем запрос к табличной части контактной информации контрагентов в расширении конфигурации. Нам необходимо отфильтровать данные по определенному типу и виду контактной информации. Мы пишем следующий запрос:


ВЫБРАТЬ
    КонтрагентыКонтактнаяИнформация.Представление КАК Представление,
    КонтрагентыКонтактнаяИнформация.Ссылка КАК Ссылка
ИЗ
    Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
ГДЕ
    КонтрагентыКонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес)
    И КонтрагентыКонтактнаяИнформация.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ФактАдресКонтрагента)

При попытке открыть этот запрос в Конструкторе запросов или при синтаксической проверке модуля в расширении мы получаем ошибку компиляции на строке с проверкой вида контактной информации. Платформа сообщает о неверных параметрах в функции ЗНАЧЕНИЕ().

Чтобы понять, почему так происходит, рассмотрим механику работы платформы:

  1. Локальная проверка в Конфигураторе: Синтаксический контроль кода и конструктор запросов в расширении работают исключительно в рамках тех метаданных, которые добавлены (заимствованы) в само расширение. Если справочник ВидыКонтактнойИнформации заимствован в расширение, но его конкретный предопределенный элемент (например, ФактАдресКонтрагента) не был перенесен в структуру расширения, конфигуратор считает, что такого элемента не существует. Именно поэтому возникает ошибка «Неверные параметры».
  2. Компиляция метаданных в режиме Предприятия: При запуске клиентского сеанса происходит динамическое слияние метаданных основной конфигурации и подключенных расширений. Поскольку в физической базе данных (в основной конфигурации) этот предопределенный элемент реально существует, в режиме «1С:Предприятие» запрос отрабатывает абсолютно корректно и без ошибок.

Теперь, когда мы понимаем физику процесса, давайте разберем три основных способа обхода и решения этой проблемы.

Способ 1. Использование параметров запроса (универсальный и безопасный путь)

Наиболее гибкой и безопасной практикой в разработке 1С считается отказ от жесткого кодирования предопределенных значений через ЗНАЧЕНИЕ() в текстах запросов внутри расширений. Вместо этого мы можем передавать предопределенные элементы в качестве параметров запроса.

Рассмотрим, как будет выглядеть наш запрос в этом случае:


ВЫБРАТЬ
    КонтрагентыКонтактнаяИнформация.Представление КАК Представление,
    КонтрагентыКонтактнаяИнформация.Ссылка КАК Ссылка
ИЗ
    Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
ГДЕ
    КонтрагентыКонтактнаяИнформация.Тип = &ТипАдрес
    И КонтрагентыКонтактнаяИнформация.Вид = &ВидАдреса

Теперь нам необходимо правильно передать эти параметры в коде на встроенном языке. Для получения ссылки на предопределенный элемент базы данных мы можем использовать несколько подходов в зависимости от контекста выполнения кода.

Вариант А. Прямое обращение через менеджер справочника (на сервере):


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ..."; // Наш текст запроса с параметрами
Запрос.УстановитьПараметр("ТипАдрес", Перечисления.ТипыКонтактнойИнформации.Адрес);
Запрос.УстановитьПараметр("ВидАдреса", Справочники.ВидыКонтактнойИнформации.ФактАдресКонтрагента);

Вариант Б. Использование функции ПредопределенноеЗначение (универсально):

Если код должен работать в контексте, где прямое обращение к менеджерам объектов может быть ограничено (например, на клиенте), мы можем использовать системную функцию ПредопределенноеЗначение():


ВидАдреса = ПредопределенноеЗначение("Справочник.ВидыКонтактнойИнформации.ФактАдресКонтрагента");
Запрос.УстановитьПараметр("ВидАдреса", ВидАдреса);

Вариант В. Использование функций БСП (для конфигураций на базе Библиотеки стандартных подсистем):

Если мы разрабатываем решение в конфигурации, использующей БСП (например, УТ, ERP, БП, ЗУП), настоятельно рекомендуется использовать безопасный метод общего модуля БСП:


ВидАдреса = ОбщегоНазначения.ПредопределенныйЭлемент("Справочник.ВидыКонтактнойИнформации.ФактАдресКонтрагента");
Запрос.УстановитьПараметр("ВидАдреса", ВидАдреса);

Этот метод хорош тем, что если по какой-то причине предопределенный элемент отсутствует в базе данных (например, база повреждена или элемент был переименован), функция вернет Неопределено и программа продолжит работу, избегая аварийного завершения сеанса с критической ошибкой.

Способ 2. Заимствование предопределенного элемента в расширение

Начиная с версии платформы 8.3.12, разработчики получили штатную возможность заимствовать не только сами объекты метаданных, но и их предопределенные элементы. Это позволяет сохранить использование конструкции ЗНАЧЕНИЕ() непосредственно в тексте запроса.

Разберем по шагам, как заимствовать предопределенный элемент в расширение:

  1. В дереве конфигурации расширения найдите заимствованный справочник (в нашем примере это ВидыКонтактнойИнформации).
  2. Нажмите по объекту правой кнопкой мыши и выберите пункт «Открыть предопределенные данные».
  3. В открывшемся окне предопределенных элементов нажмите правой кнопкой мыши на нужный элемент (например, ФактАдресКонтрагента) и выберите команду «Добавить в расширение» (также это можно сделать через командную панель окна).
  4. После этого элемент появится в списке предопределенных данных вашего расширения.

Важный нюанс: При заимствовании предопределенного элемента платформа автоматически активирует механизм проверки свойства «Предопределенные». Это означает, что при запуске системы платформа будет жестко проверять полное соответствие данного предопределенного элемента (его имени, кода и наименования) в основной конфигурации и в расширении. Если при последующем обновлении основной конфигурации разработчики вендора изменят или удалят этот предопределенный элемент, расширение просто откажется подключаться, и пользователи не смогут войти в базу до тех пор, пока администратор не исправит расширение.

Способ 3. Использование поля ИмяПредопределенныхДанных в запросе

Существует еще один изящный способ, который позволяет обойтись без заимствования предопределенных элементов и без передачи параметров в запрос. Начиная с версии платформы 8.3.3, у всех таблиц объектов, поддерживающих предопределенные данные (справочники, планы видов характеристик, планы счетов), появилось скрытое системное поле ИмяПредопределенныхДанных.

Это строковое поле, которое хранит имя предопределенного элемента в конфигураторе. Мы можем написать условие фильтрации прямо по этому полю, используя обычное сравнение со строкой:


ВЫБРАТЬ
    КонтрагентыКонтактнаяИнформация.Представление КАК Представление,
    КонтрагентыКонтактнаяИнформация.Ссылка КАК Ссылка
ИЗ
    Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
ГДЕ
    КонтрагентыКонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес)
    И КонтрагентыКонтактнаяИнформация.Вид.ИмяПредопределенныхДанных = "ФактАдресКонтрагента"

Проанализируем преимущества данного подхода:

Развитие механизмов расширений в новых версиях платформы (8.3.21+)

Технологии не стоят на месте, и начиная с версии платформы 8.3.21, возможности по работе с предопределенными данными в расширениях были значительно расширены. Теперь разработчики могут не только заимствовать существующие элементы основной конфигурации, но и создавать собственные новые предопределенные элементы для заимствованных справочников и планов видов характеристик прямо внутри расширения.

Ранее для добавления нового предопределенного значения разработчикам приходилось снимать основную конфигурацию с поддержки и вносить изменения непосредственно в нее. Теперь же эту задачу можно полностью решить локально внутри расширения, сохранив типовую конфигурацию в неизменном виде.

Резюме и рекомендации

Мы рассмотрели три способа решения проблемы с ошибкой «Неверные параметры» в запросах расширений. Какой же способ выбрать?

  1. Если вы стремитесь к максимальной безопасности при будущих обновлениях конфигурации и используете БСП, рекомендуем использовать Способ 1 (Параметры запроса с получением значения через функции БСП).
  2. Если вам важно написать быстрый и простой запрос без изменения программного кода на встроенном языке, используйте Способ 3 (Фильтрация по полю ИмяПредопределенныхДанных).
  3. Если вы используете платформу версии 8.3.12 и выше, и вам крайне важно использовать именно типизированное сравнение через ЗНАЧЕНИЕ(), воспользуйтесь Способом 2 (Заимствование предопределенного элемента), но помните о рисках при последующих обновлениях конфигурации поставщика.
← На главную