При разработке запросов в системе 1С:Предприятие часто возникает необходимость ограничить выборку данных из виртуальных таблиц (например, остатков или оборотов) конкретным набором значений. Стандартный подход с использованием внешних параметров, таких как Счет В (&СписокСчетов), удобен, но иногда требуется зафиксировать значения непосредственно в тексте запроса. Разберем подробно, как это сделать правильно, какие операторы использовать и каких логических ошибок следует избегать.
Самый простой и эффективный способ указать несколько конкретных значений в параметре виртуальной таблицы — это использование оператора В. Это позволяет перечислить нужные ссылки с помощью конструкции ЗНАЧЕНИЕ(). Рассмотрим на примере регистра бухгалтерии, когда нам нужно получить обороты одновременно по двум счетам: "Основное производство" и "Нематериальные активы".
Проанализируем правильный синтаксис запроса:
ВЫБРАТЬ
ХозрасчетныйОбороты.Счет,
ХозрасчетныйОбороты.СуммаОборот
ИЗ
РегистрБухгалтерии.Хозрасчетный.Обороты(
,
,
,
Счет В (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновноеПроизводство), ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НематериальныеАктивы)),
,
,
,
) КАК ХозрасчетныйОбороты
В данном примере внутри скобок виртуальной таблицы мы использовали условие фильтрации. Обратите внимание, что список значений заключается в дополнительные круглые скобки. Это позволяет платформе сразу ограничить выборку на уровне обращения к СУБД.
Часто начинающие разработчики путают логические операторы И и ИЛИ при попытке выбрать несколько значений. Рассмотрим ситуацию: если мы напишем Счет = Значение1 И Счет = Значение2, запрос всегда будет возвращать пустой результат. Выясним причину.
Поле в одной строке таблицы не может содержать два разных значения одновременно. Счет в проводке — это либо "Основное производство", либо "НМА". Он не может быть и тем, и другим сразу. Поэтому для объединения условий по одному полю всегда следует использовать либо оператор В, либо цепочку условий через ИЛИ.
Рассмотрим альтернативный вариант написания того же условия через ИЛИ:
РегистрБухгалтерии.Хозрасчетный.Обороты(
,
,
,
Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновноеПроизводство)
ИЛИ Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.НематериальныеАктивы),
,
,
,
)
Этот вариант абсолютно идентичен варианту с оператором В, но при большом количестве значений оператор В выглядит более лаконично и читаемо.
В бухгалтерском учете крайне важно учитывать субсчета. Если мы укажем просто Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Товары), система выберет данные только по самому счету 41, но не по его субсчетам (41.01, 41.02 и т.д.), если они есть. Чтобы захватить всю структуру, используем оператор В ИЕРАРХИИ.
Рассмотрим пример:
Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Товары), ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ГотоваяПродукция))
Такая конструкция в параметрах виртуальной таблицы автоматически соберет данные по всем дочерним счетам указанных групп. Это избавляет от необходимости вручную перечислять каждый субсчет, что особенно полезно при изменении плана счетов в будущем.
Проанализируем производительность. В языке запросов 1С условия можно написать как в скобках виртуальной таблицы, так и в секции ГДЕ. Однако разница колоссальна:
Важное правило: Всегда старайтесь максимально ограничить выборку (по периоду, счетам, измерениям) именно через параметры виртуальной таблицы.
Внутри параметров виртуальной таблицы можно использовать сложные комбинации условий. Допустим, нам нужны обороты по определенным счетам, но за исключением конкретной аналитики (Субконто).
Посмотрим на пример сложного условия:
(Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ЗатратыНаПроизводство))
И НЕ Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОбщехозяйственныеРасходы))
И Субконто1 = &ОпределеннаяНоменклатурнаяГруппа
Такой подход позволяет гибко настраивать фильтрацию прямо "на лету" внутри одного запроса, сохраняя при этом высокую скорость работы системы.
Иногда требуется отобрать записи, в которых значение какого-либо измерения или счета не заполнено. Для этого мы используем конструкцию ПустаяСсылка.
Рассмотрим, как это выглядит в коде:
Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ПустаяСсылка)
Это бывает полезно при поиске ошибок ведения учета или анализе некорректных проводок, сформированных программно.
Если вы работаете в контексте построения отчета на СКД, то жесткое прописание значений через ЗНАЧЕНИЕ() в тексте запроса может ограничить пользователя. Вместо этого в СКД принято использовать фигурные скобки — расширения языка запросов.
Разберем, как подготовить запрос для СКД:
РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, , {(Счет).* КАК Счет}, , , , )
В этом случае, если пользователь в настройках отчета выберет список счетов, СКД сама подставит их в параметры виртуальной таблицы в оптимальном виде. Однако, если задача стоит именно в "жестком" кодинге конкретных счетов, то методы, описанные выше (с оператором В), остаются приоритетными.
Бывают ситуации, когда список счетов слишком велик (например, сотни позиций), и использование В (ЗНАЧЕНИЕ(...), ...) делает текст запроса нечитаемым или вызывает ошибки переполнения SQL-строки. В таких случаях мы рекомендуем использовать временные таблицы.
ВТ_НужныеСчета.Пример реализации:
РегистрБухгалтерии.Хозрасчетный.Обороты(
,
,
,
Счет В (ВЫБРАТЬ Т.Ссылка ИЗ ВТ_НужныеСчета КАК Т),
,
,
,
)
Этот метод считается наиболее профессиональным при работе с динамическими и объемными списками фильтрации.