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