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

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

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

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

Проблема жесткой адресации субконто

Рассмотрим ситуацию, с которой столкнулся автор темы. В коде использовалась прямая фильтрация по полю СубконтоДт1. Это работает до тех пор, пока нужная нам аналитика (например, Типы затрат) жестко закреплена за первым слотом в настройках счета. Однако, как только в структуре плана счетов происходят изменения или мы расширяем список анализируемых счетов, такой подход перестает работать.

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


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

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

Решение: Использование массива видов субконто

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

Как это работает: когда вы передаете массив, поля Субконто1, Субконто2 и Субконто3 в запросе начинают соответствовать не порядку в плане счетов, а порядку элементов в вашем массиве. Рассмотрим пошагово, как это реализовать.

Шаг 1. Формирование массива видов субконто

Сначала подготовим массив в коде на языке 1С. Порядок элементов в массиве критически важен.


МассивСубконто = Новый Массив;
// Добавляем виды субконто в нужном нам порядке
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ТипыЗатрат);
МассивСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.СтатьиЗатрат);

// Устанавливаем массив как параметр запроса
Запрос.УстановитьПараметр("ВидСубконто", МассивСубконто);

Теперь в запросе поле Субконто1 будет всегда содержать значение типа Типы затрат, а Субконто2 — Статьи затрат, независимо от того, как они настроены на счете в конфигураторе.

Шаг 2. Оптимизация текста запроса

Проанализируем, как теперь должен выглядеть текст запроса. Крайне важно накладывать условия не в секции ГДЕ, а непосредственно в параметрах виртуальной таблицы. Это позволяет серверу СУБД отсечь лишние записи на самом раннем этапе, что значительно ускоряет работу.


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

Важные технические нюансы

Рассмотрим несколько особенностей, которые помогут избежать ошибок при работе с большими объемами данных:

  1. Обработка пустых значений: Если на конкретном счете отсутствует один из видов субконто, указанных в массиве, соответствующее поле (например, Субконто2) вернет значение NULL. Проанализируем это при построении условий: если вы хотите видеть данные и по тем счетам, где аналитика не заполнена, используйте конструкцию ЕСТЬ NULL.
  2. Порядок в массиве: Если вы перепутаете порядок добавления в МассивСубконто, фильтры в запросе отработают некорректно. Всегда проверяйте соответствие индекса в массиве номеру поля в запросе.
  3. Производительность: Использование массива субконто заставляет систему строить временные таблицы и итоги в разрезе указанных измерений. Рекомендуем передавать в массив только те виды субконто, по которым реально планируется отбор или группировка.
  4. Использование Границы: Для корректного включения итогов за последнюю секунду периода всегда используйте объект Новый Граница(КонецПериода, ВидГраницы.Включая) при установке параметров НачалоПериода и КонецПериода.

Альтернативный способ: Обращение по имени (8.3)

В современных версиях платформы 8.3 при передаче массива видов субконто в запрос, можно использовать более читаемую конструкцию Субконто[ИмяВидаСубконто]. Однако классический метод с обращением через Субконто1, Субконто2 остается наиболее универсальным и быстрым с точки зрения написания кода "на лету".

Заключение

Мы выяснили, что использование массива субконто — это единственный верный способ написания универсального кода для работы с планом счетов в 1С. Это позволяет абстрагироваться от настроек конкретных счетов и обращаться к данным по их смысловому значению (виду аналитики).

Разберем краткий итог правильной последовательности действий:

  1. Создаем массив МассивСубконто.
  2. Добавляем в него ПланыВидовХарактеристик в строгом порядке.
  3. Передаем массив в параметр ВидСубконто виртуальной таблицы.
  4. В поле Условие виртуальной таблицы прописываем фильтры по Субконто1, Субконто2 и так далее, согласно индексам массива.

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

← На главную