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

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

При получении остатков или оборотов из регистра бухгалтерии разработчики часто сталкиваются с задачей: выбрать данные не по одному конкретному счету, а по списку счетов или по группам субсчетов (например, отобрать счета 21, 43 и группу субсчетов счета 10: 10.01–10.09). Проанализируем, как правильно составить такой запрос, как передать параметры и как оптимизировать производительность выборки.

Способ 1. Использование оператора В ИЕРАРХИИ и передача массива счетов в параметры

Разберем классический и наиболее гибкий способ. Чтобы выбрать счета вместе со всеми их подчиненными субсчетами (например, счет 10 со всеми его субсчетами от 10.01 до 10.09), в языке запросов 1С используется конструкция В ИЕРАРХИИ. В нее можно передавать как одиночное значение, так и коллекцию значений (массив или список значений).

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

Посмотрим на пример формирования массива счетов и текста запроса:


// Формируем список счетов для отбора
СписокСчетов = Новый Массив;
СписокСчетов.Добавить(ПланыСчетов.Хозрасчетный.ПолуфабрикатыСобственногоПроизводства); // Счет 21
СписокСчетов.Добавить(ПланыСчетов.Хозрасчетный.Материалы); // Счет 10 (будут выбраны все субсчета)
СписокСчетов.Добавить(ПланыСчетов.Хозрасчетный.ГотоваяПродукция); // Счет 43

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

Запрос.УстановитьПараметр("Период", ТекущаяДата());
Запрос.УстановитьПараметр("СписокСчетов", СписокСчетов);

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    // Обработка полученных данных
КонецЦикла;

Способ 2. Прямое указание предопределенных счетов через литерал ЗНАЧЕНИЕ

Рассмотрим ситуацию, когда список счетов строго фиксирован и не зависит от выбора пользователя в пользовательском интерфейсе. В этом случае нет необходимости создавать коллекцию в коде встроенного языка и вызывать метод УстановитьПараметр. Можно указать предопределенные счета непосредственно в тексте запроса с помощью функции ЗНАЧЕНИЕ.

Посмотрим, как выглядит текст такого запроса:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ХозрасчетныйОстатки.Счет КАК Счет,
    |	ХозрасчетныйОстатки.Субконто1 КАК Субконто1,
    |	ХозрасчетныйОстатки.КоличествоОстаток КАК КоличествоОстаток
    |ИЗ
    |	РегистрБухгалтерии.Хозрасчетный.Остатки(
    |			&Период,
    |			Счет В ИЕРАРХИИ (
    |				ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ПолуфабрикатыСобственногоПроизводства),
    |				ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Материалы),
    |				ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ГотоваяПродукция)
    |			),
    |			,
    |			КоличествоОстаток > 0) КАК ХозрасчетныйОстатки";

Запрос.УстановитьПараметр("Период", ТекущаяДата());
РезультатЗапроса = Запрос.Выполнить();

Важные особенности и правила оптимизации

Выясним ключевые нюансы, на которые необходимо обращать внимание при работе с запросами к регистру бухгалтерии:

  1. Параметры виртуальной таблицы против секции ГДЕ: Наложение условий на счета и остатки в параметрах виртуальной таблицы (2-й и 4-й параметры соответственно) заставляет СУБД фильтровать записи на этапе расчета итогов. Если перенести отбор в секцию ГДЕ, платформа сначала рассчитает остатки по всей таблице регистра и лишь затем отфильтрует результат, что приведет к существенному падению производительности.
  2. Разница между В и В ИЕРАРХИИ: Конструкция Счет В (&СписокСчетов) производит точное сопоставление. Если передать счет 10, субсчета 10.01 или 10.02 в выборку не попадут. Для захвата всех вложенных субсчетов обязательно используйте Счет В ИЕРАРХИИ (&СписокСчетов).
  3. Передача пустого массива: Если в параметр &СписокСчетов передать пустой массив или пустой список значений, условие вернет ложь (1 = 0), и запрос вернет пустую таблицу. Перед выполнением запроса проверяйте заполненность коллекции.
  4. Порядок и состав видов субконто: Поле Субконто1 обращается к первому субконто счета. Если у счетов 10, 21 и 43 порядок видов субконто различается, поле Субконто1 вернет разные типы значений. Для жесткой фиксации состава субконто передавайте необходимый массив видов субконто в 3-й параметр виртуальной таблицы (Субконто).
← На главную