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

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

При работе с запросами в 1С, особенно с виртуальными таблицами регистров бухгалтерии, программисты часто сталкиваются с задачей: необходимо вывести данные по конкретному счету, если он выбран пользователем, или по всем счетам сразу, если параметр оставлен пустым. В системе компоновки данных (СКД) это решается автоматически с помощью фигурных скобок, но в обычном программном запросе или при работе через Web-сервисы требуется особый подход. Рассмотрим подробнее, как правильно реализовать такой отбор несколькими способами.

Проблема использования простых условий

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

Метод 1: Динамическое формирование текста запроса

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

Рассмотрим пример кода, где условие подставляется динамически:


Если ЗначениеЗаполнено(ВыбранныйСчет) Тогда
    УсловиеСчета = "Счет В ИЕРАРХИИ(&Счет)";
    Запрос.УстановитьПараметр("Счет", ВыбранныйСчет);
Иначе
    // Если счет не выбран, передаем "ИСТИНА", чтобы условие не ограничивало выборку
    УсловиеСчета = "ИСТИНА";
КонецЕсли;

Запрос.Текст = 
    "ВЫБРАТЬ
    |   ХозрасчетныйОстаткиИОбороты.Счет КАК Счет,
    |   ХозрасчетныйОстаткиИОбороты.СуммаОборотДт КАК СуммаДт
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&Начало, &Конец, , , " + УсловиеСчета + ", , ) КАК ХозрасчетныйОстаткиИОбороты";

В данном примере мы используем переменную УсловиеСчета. Если пользователь выбрал счет, мы применяем оператор В ИЕРАРХИИ, который позволяет захватить не только сам счет, но и все его субсчета. Если же счет не выбран, мы подставляем ИСТИНА (или просто пустую строку, если синтаксис позволяет), и виртуальная таблица возвращает данные по всем счетам. Это наиболее эффективный метод с точки зрения СУБД.

Метод 2: Использование логического флага в запросе

Если вы не хотите динамически менять текст запроса (например, запрос очень большой и сложный), можно использовать логическое условие «ИЛИ». Для этого в запрос передается дополнительный параметр-флаг, который сигнализирует о том, заполнен ли счет.

Проанализируем пример такого запроса:


Запрос.Текст = 
    "ВЫБРАТЬ
    |   ХозрасчетныйОстаткиИОбороты.Счет КАК Счет,
    |   ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстаток КАК Остаток
    |ИЗ
    |   РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(
    |       &Начало, 
    |       &Конец, , , 
    |       (&ВсеСчета ИЛИ Счет В ИЕРАРХИИ (&Счет)), , 
    |   ) КАК ХозрасчетныйОстаткиИОбороты";

Запрос.УстановитьПараметр("Счет", ВыбранныйСчет);
Запрос.УстановитьПараметр("ВсеСчета", НЕ ЗначениеЗаполнено(ВыбранныйСчет));

Как это работает? Если ВыбранныйСчет пуст, параметр &ВсеСчета принимает значение ИСТИНА. В логике запроса выражение (ИСТИНА ИЛИ Счет В ИЕРАРХИИ (&Счет)) всегда будет давать ИСТИНА для любой строки, и фильтрация по счету фактически отключится. Если же счет выбран, &ВсеСчета будет ЛОЖЬ, и сработает вторая часть условия.

Важный момент: использование оператора ИЛИ в условиях запроса может замедлить выполнение на очень больших объемах данных, так как оптимизатор СУБД не всегда может эффективно использовать индексы в таких случаях. Для большинства типовых задач этот метод вполне приемлем.

Метод 3: Особенности работы через Web-сервисы (интеграция)

При передаче данных между базами (например, из БП 3.0 в УПП), как упоминалось в обсуждении, возникают сложности с типами данных. Если вы передаете параметр через Web-сервис, он может прийти как Строка (GUID или Код счета) или Неопределено.

Рассмотрим рекомендации для таких случаев:

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

Посмотрим на пример обработки параметра в Web-сервисе:


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

Важность использования «В ИЕРАРХИИ»

В бухгалтерском учете структура счетов иерархична. Если мы укажем Счет = &Счет и выберем счет 41 «Товары», мы не получим данные по субсчетам 41.01, 41.02 и так далее. Выясним причину: в проводках (движениях регистра) всегда указывается конечный субсчет. Поэтому для получения корректных итогов по группе счетов использование оператора В ИЕРАРХИИ является обязательным условием. Если вы хотите разрешить выбор только конкретного списка счетов, передавайте в параметр Массив и используйте оператор В (&МассивСчетов).

Итоги и рекомендации

Мы проанализировали основные способы работы с необязательными фильтрами. Подведем итоги:

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

← На главную