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

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

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

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

Задача «получить реквизит формы в запросе» возникает у разработчика 1С в двух типовых ситуациях. Первая — нужно передать значение реквизита формы (например, выбранную организацию или дату) в запрос как параметр, чтобы отфильтровать данные. Вторая — нужно получить значение реквизита объекта, редактируемого на форме (например, контрагента из документа), и использовать его при построении запроса. В обоих случаях ключевой механизм — это свойство Параметры объекта Запрос и метод УстановитьПараметр().

Важно понимать базовый принцип: запрос в 1С не «видит» форму и её реквизиты напрямую. Текст запроса работает только с данными информационной базы и с параметрами, которые разработчик явно передал перед выполнением. Поэтому правильная схема всегда одна: прочитать значение реквизита формы в коде модуля формы, затем передать его в запрос через Запрос.УстановитьПараметр("ИмяПараметра", Значение), а в тексте запроса обратиться к нему через амперсанд — &ИмяПараметра.

Ниже разобраны рабочие примеры для обычных и управляемых форм, передача реквизитов объекта и табличных частей, получение значений из динамического списка, а также типичные ошибки, из-за которых запрос возвращает пустой результат или падает с ошибкой.

Как устроена передача значений из формы в запрос

Объект Запрос выполняется в контексте данных, а не интерфейса. У него нет доступа к реквизитам формы, элементам управления и свойствам объекта, открытого на редактирование. Единственный канал связи — коллекция параметров, которую разработчик заполняет до вызова Выполнить().

Типовой шаблон выглядит так: в модуле формы вы объявляете запрос, задаёте текст с параметрами через символ &, затем для каждого параметра вызываете УстановитьПараметр(), передавая туда значение реквизита формы. Порядок установки параметров не важен, но все параметры, встречающиеся в тексте, должны быть установлены до выполнения — иначе платформа выдаст ошибку «Параметр не найден».

&НаКлиенте

Процедура СформироватьОтчет(Команда)

СформироватьОтчетНаСервере();

КонецПроцедуры

&НаСервере

Процедура СформироватьОтчетНаСервере()

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

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

"ВЫБРАТЬ

| РеализацияТоваровУслуг.Ссылка КАК Документ,

| РеализацияТоваровУслуг.СуммаДокумента КАК Сумма

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.Организация = &Организация

| И РеализацияТоваровУслуг.Дата МЕЖДУ &НачалоПериода И &КонецПериода";

Запрос.УстановитьПараметр("Организация", Организация);

Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);

Запрос.УстановитьПараметр("КонецПериода", КонецДня(КонецПериода));

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

// дальнейшая обработка результата

КонецПроцедуры

Здесь Организация, НачалоПериода и КонецПериода — реквизиты формы, созданные в конфигураторе или программно. В серверной процедуре они доступны напрямую по имени, поэтому передача в запрос занимает одну строку на параметр.

Передача реквизита формы как параметра: пошагово

Разберём последовательность действий от создания реквизита до проверки результата. Этот порядок одинаков для управляемых форм в любой типовой конфигурации.

Порядок действий
  1. 1
    Создайте реквизит формы нужного типа (например, ДокументСсылка, СправочникСсылка, Дата) в редакторе формы или программно через ИзменитьРеквизиты().
  2. 2
    В модуле формы создайте серверную процедуру и объявите объект Запрос с текстом, где в условиях используются параметры вида &ИмяПараметра.
  3. 3
    Перед выполнением вызовите Запрос.УстановитьПараметр() для каждого параметра, передав значение реквизита формы.
  4. 4
    Выполните запрос и обработайте результат: Выгрузить() в таблицу значений или обойти выборку через Выбрать().
  5. 5
    Проверьте результат на тестовых данных: убедитесь, что отбор сработал и типы параметров совпадают с типами полей в условии.

Если реквизит формы имеет составной тип (например, «Произвольный» или список значений), перед передачей его нужно привести к конкретному типу, который ожидает запрос. Для списка значений запрос поддерживает проверку В (&СписокЗначений) — платформа автоматически развернёт список в набор значений.

Обратите внимание на даты: если реквизит формы — дата без времени, а в запросе сравнение идёт с полем типа «Дата и время», верхнюю границу периода передавайте через КонецДня(), иначе документы за последний день периода «потеряются» из-за сравнения с полуночью.

Получение реквизита объекта, редактируемого на форме

Частый сценарий: на форме открыт документ, и нужно в запросе использовать его реквизит — контрагента, склад, договор. В управляемой форме основной реквизит объекта обычно называется Объект, и его поля доступны через точку: Объект.Контрагент, Объект.Ссылка.

&НаСервере

Функция ПолучитьЗадолженностьКонтрагента()

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

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

"ВЫБРАТЬ

| РасчетыСКонтрагентамиОстатки.СуммаОстаток КАК Долг

|ИЗ

| РегистрНакопления.РасчетыСКонтрагентами.Остатки(, Контрагент = &Контрагент) КАК РасчетыСКонтрагентамиОстатки";

Запрос.УстановитьПараметр("Контрагент", Объект.Контрагент);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Возврат Выборка.Долг;

Иначе

Возврат 0;

КонецЕсли;

КонецФункции

В обычных формах (толстый клиент, обычное приложение) доступ к реквизитам объекта идёт через ДокументОбъект.Контрагент или напрямую по имени реквизита, если форма связана с объектом. Логика передачи в запрос та же.

Передача табличной части и списка значений в запрос

Реквизит формы типа «ТаблицаЗначений» или табличная часть объекта передаётся в запрос целиком — это удобно для соединения с данными базы. Таблица передаётся как параметр и подключается в тексте запроса через конструкцию ПОМЕСТИТЬ.

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

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

"ВЫБРАТЬ

| ТаблицаТоваров.Номенклатура КАК Номенклатура,

| ТаблицаТоваров.Количество КАК Количество

|ПОМЕСТИТЬ ВТ_Товары

|ИЗ

| &ТаблицаТоваров КАК ТаблицаТоваров

|;

|ВЫБРАТЬ

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

| ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

|ИЗ

| ВТ_Товары КАК ВТ_Товары

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

| ПО ВТ_Товары.Номенклатура = Остатки.Номенклатура";

Запрос.УстановитьПараметр("ТаблицаТоваров", Объект.Товары.Выгрузить());

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

Список значений для отбора по нескольким элементам передаётся напрямую: Запрос.УстановитьПараметр("Склады", СписокСкладов), а в тексте — условие Склад В (&Склады). Массив также допустим в качестве значения параметра.

Реквизиты формы и динамический список

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Список.Параметры.УстановитьЗначениеПараметра("ТекущаяОрганизация", Организация);

КонецПроцедуры

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

Способы передать значение в запрос

УстановитьПараметр()

Универсальный способ для программно создаваемого объекта Запрос. Работает с любыми типами, включая таблицы значений и списки.

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

Для произвольных запросов динамических списков на форме. Значение задаётся через Список.Параметры.УстановитьЗначениеПараметра().

Параметры СКД

Для отчётов на компоновке данных: параметры объявляются в схеме и заполняются в настройках или программно через КомпоновщикНастроек.

Типичные ошибки и как их диагностировать

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

Типичные ошибки
01
Обращение к реквизиту формы прямо в тексте запроса (ГДЕ Организация = Организация без амперсанда) — запрос воспримет это как поле таблицы и выдаст ошибку «Поле не найдено».
02
Параметр объявлен в тексте, но не установлен через УстановитьПараметр() — ошибка «Параметр не найден» при выполнении.
03
Несовпадение типов: в параметр передана строка, а поле в базе — ссылка на справочник. Запрос выполнится, но вернёт пустой результат без сообщения об ошибке.
04
Передача даты без учёта времени: верхняя граница периода без КонецДня() отсекает документы за последний день.
05
Обращение к реквизиту формы в клиентской процедуре при создании запроса — объект Запрос недоступен на клиенте, запрос нужно формировать и выполнять на сервере.

Для диагностики пустого результата полезно временно вывести значения параметров через Сообщить() перед выполнением и проверить, что в реквизитах формы действительно лежат ожидаемые значения, а не пустые ссылки. Часто причина в том, что реквизит не заполнен пользователем или очищен при открытии формы.

Контрольные точки

Как проверить результат

Все параметры из текста запроса установлены
Норма

Запрос выполняется без ошибок

Тревожный признак

Ошибка «Параметр &Имя не найден»

Тип параметра совпадает с типом поля
Норма

Отбор срабатывает, записи находятся

Тревожный признак

Пустой результат без ошибок

Значение реквизита формы перед выполнением
Норма

В реквизите заполненное значение ожидаемого типа

Тревожный признак

Пустая ссылка или Неопределено

Ограничения и альтернативные подходы

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

Альтернативы прямому запросу: для простого чтения одного реквизита по ссылке быстрее и проще обратиться через точку (Объект.Контрагент.ИНН) — платформа сама сформирует обращение к базе. Для отчётов с настраиваемыми отборами уместнее СКД, где параметры связываются с реквизитами формы через настройки компоновки, а не вручную.

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

Как выбрать подход

Нужно отфильтровать данные по значению реквизита формыПрограммный запрос с УстановитьПараметр() в серверной процедуре
Отбор должен менять список на формеПараметры динамического списка или отбор компоновки данных
Нужно прочитать один реквизит связанного объектаОбращение через точку без запроса
Пользователь сам настраивает отборы и группировкиОтчёт на СКД с параметрами вместо ручного запроса

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

Можно ли обратиться к реквизиту формы прямо в тексте запроса?

Нет. Текст запроса выполняется в контексте базы данных и не знает о существовании формы. Любое значение из формы нужно сначала прочитать в коде модуля и передать через параметр с символом & в тексте запроса.

Почему запрос с параметром возвращает пустой результат без ошибки?

Чаще всего тип параметра не совпадает с типом поля (например, строка вместо ссылки) или значение параметра пустое — незаполненный реквизит формы. Проверьте значение перед выполнением и убедитесь, что типы совпадают.

Как передать в запрос несколько значений из реквизита-списка?

Передайте список значений или массив как обычный параметр и используйте в тексте оператор В: «ГДЕ Склад В (&Склады)». Платформа автоматически развернёт коллекцию в набор условий.

Можно ли выполнить запрос в клиентской процедуре формы?

Нет, объект Запрос доступен только на сервере. Из клиентского обработчика вызовите серверную процедуру — реквизиты формы будут доступны в ней через контекст формы, если она объявлена как &НаСервере с контекстом.

Как передать в запрос табличную часть документа с формы?

Вызовите Объект.Товары.Выгрузить() и передайте полученную таблицу значений параметром. В тексте запроса примите её через «ИЗ &ТаблицаТоваров» с помещением во временную таблицу, затем соединяйте с данными базы.

Чем отличается параметр динамического списка от параметра запроса?

По сути это тот же механизм, но для динамического списка значение задаётся через Список.Параметры.УстановитьЗначениеПараметра(), а не через УстановитьПараметр(), поскольку объект запроса списка скрыт внутри компоновки данных.

Итог

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

Реквизит формы попадает в запрос только через параметр: читаем значение в серверной процедуре, устанавливаем через УстановитьПараметр(), используем в тексте через &Имя. Следите за типами, заполненностью значений и границами периодов — это три главные причины пустых результатов.