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

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

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

Использование оператора В для перечисления значений

Самый простой и эффективный способ указать несколько конкретных значений в параметре виртуальной таблицы — это использование оператора В. Это позволяет перечислить нужные ссылки с помощью конструкции ЗНАЧЕНИЕ(). Рассмотрим на примере регистра бухгалтерии, когда нам нужно получить обороты одновременно по двум счетам: "Основное производство" и "Нематериальные активы".

Проанализируем правильный синтаксис запроса:


ВЫБРАТЬ
    ХозрасчетныйОбороты.Счет,
    ХозрасчетныйОбороты.СуммаОборот
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Обороты(
        ,
        ,
        ,
        Счет В (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновноеПроизводство), ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НематериальныеАктивы)),
        ,
        ,
        ,
    ) КАК ХозрасчетныйОбороты

В данном примере внутри скобок виртуальной таблицы мы использовали условие фильтрации. Обратите внимание, что список значений заключается в дополнительные круглые скобки. Это позволяет платформе сразу ограничить выборку на уровне обращения к СУБД.

Разбор логических ошибок: И или ИЛИ?

Часто начинающие разработчики путают логические операторы И и ИЛИ при попытке выбрать несколько значений. Рассмотрим ситуацию: если мы напишем Счет = Значение1 И Счет = Значение2, запрос всегда будет возвращать пустой результат. Выясним причину.

Поле в одной строке таблицы не может содержать два разных значения одновременно. Счет в проводке — это либо "Основное производство", либо "НМА". Он не может быть и тем, и другим сразу. Поэтому для объединения условий по одному полю всегда следует использовать либо оператор В, либо цепочку условий через ИЛИ.

Рассмотрим альтернативный вариант написания того же условия через ИЛИ:


РегистрБухгалтерии.Хозрасчетный.Обороты(
    ,
    ,
    ,
    Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновноеПроизводство) 
    ИЛИ Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НематериальныеАктивы),
    ,
    ,
    ,
)

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

Работа с иерархией счетов

В бухгалтерском учете крайне важно учитывать субсчета. Если мы укажем просто Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Товары), система выберет данные только по самому счету 41, но не по его субсчетам (41.01, 41.02 и т.д.), если они есть. Чтобы захватить всю структуру, используем оператор В ИЕРАРХИИ.

Рассмотрим пример:


Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Товары), ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ГотоваяПродукция))

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

Почему важно писать условия именно в параметрах, а не в ГДЕ?

Проанализируем производительность. В языке запросов 1С условия можно написать как в скобках виртуальной таблицы, так и в секции ГДЕ. Однако разница колоссальна:

  1. Параметры виртуальной таблицы: Платформа транслирует эти условия в SQL-запрос так, чтобы фильтрация происходила на этапе получения данных из индексов или итогов СУБД. Выбирается только нужный объем данных.
  2. Секция ГДЕ: Система сначала выполняет обращение к виртуальной таблице (которая может начать вычислять итоги по всем счетам регистра), и только потом, к полученному результату, применяет фильтр. На больших базах это гарантированно приводит к значительным задержкам и избыточному потреблению памяти.

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

Сложные логические выражения

Внутри параметров виртуальной таблицы можно использовать сложные комбинации условий. Допустим, нам нужны обороты по определенным счетам, но за исключением конкретной аналитики (Субконто).

Посмотрим на пример сложного условия:


(Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ЗатратыНаПроизводство))
 И НЕ Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОбщехозяйственныеРасходы))
 И Субконто1 = &ОпределеннаяНоменклатурнаяГруппа

Такой подход позволяет гибко настраивать фильтрацию прямо "на лету" внутри одного запроса, сохраняя при этом высокую скорость работы системы.

Использование пустых ссылок и предопределенных значений

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

Рассмотрим, как это выглядит в коде:

Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ПустаяСсылка)

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

Особенности для Системы компоновки данных (СКД)

Если вы работаете в контексте построения отчета на СКД, то жесткое прописание значений через ЗНАЧЕНИЕ() в тексте запроса может ограничить пользователя. Вместо этого в СКД принято использовать фигурные скобки — расширения языка запросов.

Разберем, как подготовить запрос для СКД:


РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, , {(Счет).* КАК Счет}, , , , )

В этом случае, если пользователь в настройках отчета выберет список счетов, СКД сама подставит их в параметры виртуальной таблицы в оптимальном виде. Однако, если задача стоит именно в "жестком" кодинге конкретных счетов, то методы, описанные выше (с оператором В), остаются приоритетными.

Передача больших списков через временные таблицы

Бывают ситуации, когда список счетов слишком велик (например, сотни позиций), и использование В (ЗНАЧЕНИЕ(...), ...) делает текст запроса нечитаемым или вызывает ошибки переполнения SQL-строки. В таких случаях мы рекомендуем использовать временные таблицы.

  1. Сначала выгружаем нужные счета во временную таблицу ВТ_НужныеСчета.
  2. Затем используем подзапрос в параметрах виртуальной таблицы.

Пример реализации:


РегистрБухгалтерии.Хозрасчетный.Обороты(
    ,
    ,
    ,
    Счет В (ВЫБРАТЬ Т.Ссылка ИЗ ВТ_НужныеСчета КАК Т),
    ,
    ,
    ,
)

Этот метод считается наиболее профессиональным при работе с динамическими и объемными списками фильтрации.

← На главную