Как добавить отбор по контрагенту в обработку выгрузки документов в XML

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

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

Модификация текста запроса для добавления отбора

Для начала проанализируем исходный код запроса. В нем уже присутствуют условия по периоду и организации. Чтобы добавить фильтр по контрагенту, нам необходимо расширить секцию ГДЕ. Важно помнить, что в языке запросов 1С условия соединяются логическим оператором И (AND) или ИЛИ (OR).

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


ТекстЗапроса = "ВЫБРАТЬ
               |    РеализацияТоваровУслуг.Ссылка КАК Ссылка,
               |    РеализацияТоваровУслуг.Номер КАК Номер,
               |    РеализацияТоваровУслуг.Дата КАК Дата,
               |    РеализацияТоваровУслуг.Контрагент КАК Контрагент
               |ИЗ
               |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
               |ГДЕ
               |    РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНач И &ДатаКонец
               |    И РеализацияТоваровУслуг.Организация = &Организация
               |    И РеализацияТоваровУслуг.Контрагент = &Контрагент";

В этом примере мы добавили строку И РеализацияТоваровУслуг.Контрагент = &Контрагент. Обратите внимание на использование амперсанда (&) перед именем переменной — это указывает системе, что Контрагент является параметром, значение которого будет передано позже.

Установка параметров запроса

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


Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ДатаНач", ПериодВыгрузки.ДатаНачала);
Запрос.УстановитьПараметр("ДатаКонец", ПериодВыгрузки.ДатаОкончания);
Запрос.УстановитьПараметр("Организация", РекОрганизация);
// Устанавливаем наш новый параметр
Запрос.УстановитьПараметр("Контрагент", РекКонтрагент);

Здесь РекКонтрагент — это имя реквизита на вашей форме, в котором пользователь выбирает нужного партнера. Выясним причину часто возникающих ошибок: если вы забудете установить параметр, программа выдаст исключение "Параметр не установлен".

Анализ и исправление типичных синтаксических ошибок

При редактировании текста запроса программисты часто сталкиваются с ошибками компиляции, такими как "Ожидается ключевое слово 'КонецФункции'" или "Обнаружено логическое завершение исходного текста модуля". Посмотрим на типичную ошибку из практики:

И РеализацияТоваровУслуг.Контрагент = &Контрагент"; Запрос.УстановитьПараметр...

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

Реализация условия "Если не выбран, то выгружать всех"

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

Способ 1. Универсальное условие в самом запросе.

Этот метод позволяет не менять структуру кода, а лишь дополнить текст запроса логической проверкой на заполненность параметра.


Запрос.Текст = "ВЫБРАТЬ ...
               |ГДЕ
               |    РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНач И &ДатаКонец
               |    И РеализацияТоваровУслуг.Организация = &Организация
               |    И (&ОтборПоКонтрагентуУстановлен = ЛОЖЬ 
               |        ИЛИ РеализацияТоваровУслуг.Контрагент = &Контрагент)";

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

Способ 2. Использование оператора В ИЕРАРХИИ.

Если в параметр &Контрагент передать пустую ссылку того же типа, а в запросе использовать В ИЕРАРХИИ, это может сработать некорректно в зависимости от настроек базы. Однако использование В ИЕРАРХИИ полезно, если вы хотите выбрать документы по всем дочерним компаниям холдинга, указав только головного контрагента.

Оптимизация выгрузки в XML

Рассмотрим процесс записи данных. Использование объекта ЗаписьXML является наиболее производительным способом формирования файлов, так как данные пишутся последовательно, не перегружая оперативную память. Проанализируем фрагмент кода для выгрузки шапки и табличной части документа:


Результат = Запрос.Выполнить().Выбрать();
ЗаписьXML.ЗаписатьНачалоЭлемента("СписокДокументов");

Пока Результат.Следующий() Цикл
    ЗаписьXML.ЗаписатьНачалоЭлемента("Реализация");
    ЗаписьXML.ЗаписатьАтрибут("Номер", Строка(Результат.Номер));
    ЗаписьXML.ЗаписатьАтрибут("Дата", Строка(Результат.Дата));
    ЗаписьXML.ЗаписатьАтрибут("Контрагент", Строка(Результат.Контрагент));
    
    // Выгрузка табличной части Товары
    ВыборкаТовары = Результат.Товары.Выбрать();
    Пока ВыборкаТовары.Следующий() Цикл
        ЗаписьXML.ЗаписатьНачалоЭлемента("СтрокаТовара");
        ЗаписьXML.ЗаписатьАтрибут("Номенклатура", Строка(ВыборкаТовары.Номенклатура));
        ЗаписьXML.ЗаписатьАтрибут("Количество", Строка(ВыборкаТовары.Количество));
        ЗаписьXML.ЗаписатьКонецЭлемента();
    КонецЦикла;
    
    ЗаписьXML.ЗаписатьКонецЭлемента(); // Конец реализации
КонецЦикла;

ЗаписьXML.ЗаписатьКонецЭлемента(); // Конец СпискаДокументов

Важный совет: При получении данных через точку (например, РеализацияТоваровУслуг.Контрагент.ИНН), если поле Контрагент не заполнено, запрос вернет значение NULL. Чтобы избежать ошибок при записи в XML, используйте функцию ЕСТЬNULL(РеализацияТоваровУслуг.Контрагент.ИНН, "") прямо в тексте запроса. Это гарантирует, что в файл запишется пустая строка вместо неопределенного значения.

Таким образом, мы разобрали не только механизм добавления простого фильтра, но и научились делать отборы гибкими, обрабатывать вложенные таблицы и корректно формировать структуру XML-файла. Применение этих методов позволит вам создавать надежные механизмы обмена данными между различными конфигурациями 1С.

← На главную