Как в одном запросе получить сальдо и оборот с корреспондирующим счетом

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

При разработке отчетов и обработок в системе 1С:Предприятие 8 программисты часто сталкиваются с необходимостью объединить в одной выборке итоговые остатки по счету и детальные обороты в разрезе корреспондирующих счетов. Основная сложность заключается в архитектуре виртуальных таблиц регистра бухгалтерии. Рассмотрим подробнее, почему стандартная таблица ОстаткиИОбороты не всегда подходит для решения таких задач и как правильно спроектировать запрос.

Анализ проблемы и выбор виртуальной таблицы

Разберем ситуацию: нам необходимо получить сальдо по счету 19.03 и одновременно увидеть оборот в связке Дебет 19.03 — Кредит 68.02. Посмотрим на возможности виртуальных таблиц:

  1. Хозрасчетный.ОстаткиИОбороты: Идеальна для получения сальдо и общих оборотов, но она принципиально не содержит поля КорСчет. В ней хранятся уже агрегированные данные по счету без учета того, «откуда» пришли деньги или «куда» ушли.
  2. Хозрасчетный.Обороты: Содержит поле КорСчет, но не предоставляет данных об остатках (сальдо).

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

Решение №1: Использование объединения (UNION ALL) — Рекомендуемый метод

Профессиональная разработка в 1С предполагает использование оператора ОБЪЕДИНИТЬ ВСЕ вместо сложных соединений. Это позволяет избежать «раздувания» результата (картезианского произведения) и значительно повышает читаемость кода. Суть метода заключается в том, чтобы выбрать остатки в одной части запроса, а обороты — в другой, приведя их к общей структуре полей.

Рассмотрим пример построения такого запроса:


ВЫБРАТЬ
    ВТ_Данные.Счет КАК Счет,
    СУММА(ВТ_Данные.СальдоНач) КАК СальдоНач,
    СУММА(ВТ_Данные.ОборотСКорр) КАК ОборотСКорр
ИЗ
    (ВЫБРАТЬ
        Т_Остатки.Счет КАК Счет,
        Т_Остатки.СуммаОстатокДт КАК СальдоНач,
        0 КАК ОборотСКорр
    ИЗ
        РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, , , ) КАК Т_Остатки
    ГДЕ
        Т_Остатки.Счет = &Счет19
    
    ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
        Т_Обороты.Счет КАК Счет,
        0,
        Т_Обороты.СуммаОборотДт
    ИЗ
        РегистрБухгалтерии.Хозрасчетный.Обороты(&НачДата, &КонДата, , Счет = &Счет19, , КорСчет = &Счет68, , ) КАК Т_Обороты) КАК ВТ_Данные

СГРУППИРОВАТЬ ПО
    ВТ_Данные.Счет

Важный момент: Обратите внимание, что фильтрация по корреспондирующему счету 68.02 производится непосредственно в параметрах виртуальной таблицы Обороты. Это заставляет SQL-сервер выполнять отбор на этапе формирования временной таблицы в памяти, что существенно ускоряет выполнение запроса.

Решение №2: Использование временных таблиц и соединений

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

  1. Создаем временную таблицу ВТ_Остатки, куда помещаем сальдо из таблицы ОстаткиИОбороты.
  2. Создаем временную таблицу ВТ_Обороты, выбирая данные из таблицы Обороты с указанием конкретного КорСчета.
  3. Индексируем обе таблицы по полям связи (Счет, Субконто, Организация).
  4. Соединяем их в итоговом запросе.

Посмотрим на пример реализации связи:


ВЫБРАТЬ
    ЕСТЬNULL(ВТ_Остатки.Счет, ВТ_Обороты.Счет) КАК Счет,
    ЕСТЬNULL(ВТ_Остатки.СуммаКонечныйОстатокДт, 0) КАК Остаток,
    ЕСТЬNULL(ВТ_Обороты.СуммаОборотДт, 0) КАК ОборотСКоррСчетом
ИЗ
    ВТ_Остатки КАК ВТ_Остатки
        ПОЛНОЕ СОЕДИНЕНИЕ ВТ_Обороты КАК ВТ_Обороты
        ПО ВТ_Остатки.Счет = ВТ_Обороты.Счет
        И ВТ_Остатки.Субконто1 = ВТ_Обороты.Субконто1

При использовании соединений крайне важно использовать функцию ЕСТЬNULL. Если по счету есть остаток, но в выбранном периоде не было движений по конкретному корр. счету, запрос вернет NULL, что может привести к ошибкам в дальнейших вычислениях.

Оптимизация производительности

Проанализируем ситуацию с точки зрения нагрузки на систему. При работе с регистром бухгалтерии следует придерживаться следующих правил:

Подведение итогов

Мы выяснили, что наиболее устойчивым и производительным методом получения сальдо и оборотов с корр. счетом является использование объединения (UNION ALL). Этот подход исключает потерю данных при отсутствии оборотов и позволяет прозрачно управлять структурой результата. Если же вам необходимо использовать соединение (JOIN), обязательно используйте временные таблицы с предварительной индексацией и тщательную обработку пустых значений через ЕСТЬNULL.

← На главную