К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как получить константу в запросе 1С

Как получить значение константы в запросе 1С: через таблицу Константы, параметр запроса и встроенный язык. Примеры кода, ошибки и проверка результата.

Константа в 1С — это объект конфигурации для хранения одного значения, которое изменяется редко: наименование организации, валюта учёта, функциональные опции, настройки обмена. Разработчику регулярно требуется подставить значение константы в запрос — чтобы отфильтровать данные, вывести настройку в отчёт или использовать её в вычислении.

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

Обращение к таблице Константы прямо в запросе

Язык запросов 1С предоставляет таблицу Константы, поля которой — это константы конфигурации. Самый простой вариант выглядит так:

ВЫБРАТЬ

Константы.ВалютаУчета КАК ВалютаУчета,

Константы.НаименованиеОрганизации КАК НаименованиеОрганизации

ИЗ

Константы КАК Константы

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

Таблицу Константы можно соединять с другими таблицами. Например, чтобы вывести товары с ценой в валюте учёта, таблицу констант соединяют без условия (или с условием ИСТИНА), поскольку в ней всегда одна строка:

ВЫБРАТЬ

Товары.Номенклатура КАК Номенклатура,

Товары.Цена КАК Цена,

Константы.ВалютаУчета КАК Валюта

ИЗ

Справочник.Номенклатура КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ Константы КАК Константы

ПО (ИСТИНА)

Признак корректного результата: запрос возвращает одну строку при выборке только из Константы, а при соединении значение константы повторяется в каждой строке результата. Если строка пустая или значение NULL — проверьте, что константа с таким именем существует в конфигурации и заполнена.

Получение константы кодом и передача параметром

Второй способ — прочитать значение средствами встроенного языка и передать его в запрос как параметр. Это предпочтительный вариант для отборов и вычислений:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Продажи.Номенклатура КАК Номенклатура,

| Продажи.Сумма КАК Сумма

|ГДЕ

| Продажи.Валюта = &ВалютаУчета";

Запрос.УстановитьПараметр("ВалютаУчета", Константы.ВалютаУчета.Получить());

Результат = Запрос.Выполнить();

Метод Получить() возвращает текущее значение константы. Если константа не заполнена, вернётся значение по умолчанию для её типа: пустая строка, ноль, пустая ссылка или Ложь — учитывайте это в условиях отбора.

Параметр выигрывает у таблицы Константы по производительности, когда запрос выполняется многократно в цикле или используется в условии ГДЕ по индексированному полю: оптимизатор СУБД работает с конкретным значением, а не с подзапросом к таблице констант. Также параметр обязателен, если запрос строится динамически и имя константы заранее неизвестно.

Чтение через менеджер значения и составные типы

Для констант составного типа (например, константа может хранить ссылку на разные справочники) иногда требуется более тонкая работа — через менеджер значения константы:

МенеджерЗначения = Константы.ОсновнаяОрганизация.СоздатьМенеджерЗначения();

МенеджерЗначения.Прочитать();

ЗначениеКонстанты = МенеджерЗначения.Значение;

Менеджер значения нужен в основном для записи константы и для проверки заполненности, но им можно и читать. Для простого получения значения достаточно Получить() — менеджер избыточен.

Отдельный случай — константы типа ХранилищеЗначения. В запросе их получить бессмысленно: таблица Константы вернёт объект хранилища, с которым язык запросов не работает. Такие константы читают только кодом:

Настройки = Константы.НастройкиОбмена.Получить().Получить();

// первый Получить() — хранилище значения, второй — извлечённый объект

Константы в СКД и динамических списках

В схеме компоновки данных оба подхода доступны, но с нюансами. В наборе данных-запросе можно использовать таблицу Константы так же, как в обычном запросе. Однако чаще значение константы передают параметром, чтобы конечный пользователь мог переопределить его в настройках отчёта:

ВЫБРАТЬ

Продажи.Номенклатура КАК Номенклатура,

Продажи.Сумма КАК Сумма

ГДЕ

Продажи.Валюта = &ВалютаУчета

Чтобы параметр заполнялся автоматически, в модуле отчёта используют обработчик ПриКомпоновкеРезультата и устанавливают значение параметра через КомпоновщикНастроек. Либо в параметрах СКД указывают выражение на встроенном языке — для параметра доступно выражение Константы.ВалютаУчета.Получить(), если включить «Выражение» в настройках параметра.

В динамических списках обращение к таблице Константы в произвольном запросе работает, но замедляет открытие списка при большом объёме данных, если константа участвует в соединении. Практичнее передавать значение параметром при создании формы списка.

Сравнение вариантов

Таблица Константы в запросе

Подходит для отчётов и печатных форм, где нужно вывести несколько настроек. Ограничение: лишнее обращение к таблице при массовых вызовах, нельзя использовать для ХранилищаЗначения.

Параметр запроса

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

Менеджер значения

Нужен для записи константы и контроля заполненности. Для простого чтения избыточен — используйте Получить().

Функциональные опции и константы-периодики

Функциональные опции, хранящиеся в константах, читаются точно так же — через Константы.ИмяОпции.Получить() или таблицу Константы. Проверять их в запросе имеет смысл, когда от отключённой опции зависит состав выборки, но чаще такую проверку выполняют кодом через ПолучитьФункциональнуюОпцию() и просто не выполняют лишний запрос.

Если настройка должна меняться во времени (например, курс или ставка по периодам), константа не подходит — используйте периодический регистр сведений. Попытка хранить историю в константе приведёт к потере прежних значений при каждом изменении. В запросе периодический регистр читают через виртуальную таблицу СрезПоследних.

Маршрут решения

Как выбрать действие

Нужно вывести одну-две константы в отчёт или печатную формуИспользуйте таблицу Константы в тексте запроса
Константа участвует в отборе ГДЕ или запрос выполняется в циклеПолучите значение кодом и передайте параметром
Константа имеет тип ХранилищеЗначенияЧитайте только кодом через двойной Получить(), в запрос её не включайте
Нужна история изменения настройкиЗамените константу периодическим регистром сведений и читайте СрезПоследних

Частые ошибки и проверка результата

Самая распространённая ошибка — опечатка в имени константы в тексте запроса. Запрос не компилируется на этапе написания, и ошибка «Поле не найдено» всплывёт только при выполнении. Проверяйте имя по конфигуратору или используйте конструктор запроса, который подставляет корректные имена.

Вторая типичная ситуация — константа не заполнена, и отбор по параметру с пустым значением не возвращает данных. Перед установкой параметра проверяйте заполненность и обрабатывайте пустое значение явно, например условием ИЛИ &ВалютаУчета = ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка) — если пустая константа должна означать «без отбора».

Третья ошибка — попытка соединить таблицу Константы по условию на равенство с полем другой таблицы в надежде «отфильтровать». Таблица Константы не содержит ключей; соединять её нужно без условия или по ИСТИНА, а фильтрацию выполнять в секции ГДЕ.

Типичные ошибки
01
Опечатка в имени константы — ошибка «Поле не найдено» проявится только при выполнении запроса, а не при написании кода
02
Отбор по незаполненной константе — параметр с пустым значением отфильтрует все строки, и запрос вернёт пустой результат
03
Соединение с таблицей Константы по условию равенства — при ложном условии получите NULL вместо значения константы
04
Чтение константы типа ХранилищеЗначения через запрос — язык запросов не умеет извлекать содержимое хранилища

Итоговая проверка проста: выполните запрос в консоли запросов, убедитесь, что возвращается одна строка с ожидаемым значением, и сверьте его с фактическим значением константы в режиме предприятия. Для параметризованного запроса выведите значение параметра в журнал или сообщение перед выполнением.

Итог

Что важно запомнить

Константу в запросе получают через таблицу Константы (всегда одна строка) или через параметр, установленный кодом Константы.Имя.Получить(). Для отборов и циклов предпочтителен параметр, для вывода настроек в отчёт — таблица Константы. ХранилищеЗначения читается только кодом, а для истории изменений вместо константы используют периодический регистр сведений.

Частые вопросы

Можно ли получить константу в запросе, не зная её имени заранее?

Нет, в тексте запроса имя поля таблицы Константы должно быть задано явно. Если имя известно только во время выполнения, получайте значение кодом через Константы[ИмяКонстанты].Получить() и передавайте параметром.

Почему запрос к таблице Константы возвращает NULL?

Чаще всего из-за соединения с условием, которое оказалось ложным, — при ЛЕВОМ СОЕДИНЕНИИ поля констант становятся NULL. Соединяйте таблицу Константы без условия или по ИСТИНА. Также проверьте, что константа вообще заполнена в базе.

Как получить константу в запросе на управляемой форме?

Точно так же: либо таблицей Константы в тексте запроса, либо параметром. Для динамического списка на форме значение параметра устанавливают в обработчике ПриСозданииНаСервере через Свойства списка.

Что вернёт Константы.Имя.Получить(), если константа не заполнена?

Значение по умолчанию для типа константы: пустая строка для строки, 0 для числа, Ложь для булево, пустая ссылка для ссылочных типов. Ошибки не будет, но отбор по такому значению может вернуть пустой результат.

Можно ли изменить константу запросом?

Нет, язык запросов 1С предназначен только для чтения данных. Запись константы выполняется кодом: Константы.Имя.Установить(НовоеЗначение) или через менеджер значения с последующим вызовом Записать().

Что быстрее: таблица Константы или параметр?

Для одиночного запроса разница незаметна. При массовом выполнении в цикле параметр эффективнее, так как значение читается из базы один раз, а не при каждом обращении к таблице Константы внутри запроса.