Как получить данные по оборотам бухгалтерского регистра за каждый период, включая месяцы без движений, в 1С:Бухгалтерии 3.0?

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

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

Рассмотрим ситуацию, когда наш запрос по оборотам выводит данные только за январь, март, август, сентябрь, ноябрь и декабрь, потому что только в этих месяцах были проводки. Если нам нужно, чтобы в отчет попали все месяцы года, включая февраль, апрель, май и так далее, с нулевыми оборотами, стандартный запрос без дополнительных манипуляций не поможет. Попытки использовать ЕСТЬNULL(ХозрасчетныйОстаткиИОбороты.СуммаОборотДт, 0) или фильтрацию ГДЕ СуммаОборотДт = 0 также не дадут желаемого результата, поскольку платформа по умолчанию не возвращает строки для периодов, где движений не было вовсе.

Давайте выясним, почему так происходит, и какие существуют методы для решения этой задачи.

Особенности работы виртуальных таблиц регистров бухгалтерии

Прежде чем перейти к решениям, проанализируем поведение виртуальной таблицы РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты. Как было верно замечено в обсуждении, это особенность платформы 1С:Предприятие. Виртуальные таблицы регистров, по умолчанию, формируют записи только для тех периодов, по которым существуют фактические движения. Это сделано для оптимизации производительности и уменьшения объема данных. Соответственно, если в феврале не было никаких операций по счету, то февральская строка просто отсутствует в выборке из ОстаткиИОбороты. Именно поэтому фильтрация по `СуммаОборотДт = 0` не сработает – эта строка просто не будет существовать для фильтрации.

Параметр виртуальной таблицы МетодДополнения, который может принимать значения Движения или ДвиженияИГраницыПериода, регулирует включение в отчет периодов, не имеющих оборотов, но имеющих остатки (например, счет закрылся в прошлом месяце, но остаток еще есть). Однако он не решает проблему получения всех периодов, где не было вообще никаких движений (то есть даже нулевых остатков). Для нашей задачи требуется более универсальный подход.

Решение 1: Генерация последовательности периодов и левое соединение в запросе

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

Шаг 1: Создание временной таблицы с желаемыми периодами

Для начала нам потребуется получить таблицу, содержащую все месяцы в интересующем нас диапазоне дат. Мы можем сделать это несколькими способами:

  1. Использование регистра сведений "РегламентированныйПроизводственныйКалендарь" (или "ДанныеПроизводственногоКалендаря"). Этот регистр содержит даты на каждый день и идеально подходит для генерации списка периодов. Мы можем выбрать из него уникальные месяцы за нужный период, используя функцию НАЧАЛОПЕРИОДА().
  2. Программная генерация таблицы значений. Если вы работаете в коде 1С, вы можете программно создать таблицу значений с нужными датами и передать ее в запрос в качестве параметра.
  3. Генерация последовательности дат прямо в запросе. Существуют более сложные, но полностью внутризапросные способы генерации последовательности дат, обычно основанные на декартовом произведении небольшой вспомогательной таблицы с числами для "растягивания" диапазона дат.

Рассмотрим наиболее распространенный и удобный способ — с использованием РегламентированныйПроизводственныйКалендарь. Мы поместим результат в ВТ_Календарь.


ВЫБРАТЬ РАЗЛИЧНЫЕ
    НАЧАЛОПЕРИОДА(РегламентированныйПроизводственныйКалендарь.ДатаКалендаря, МЕСЯЦ) КАК МесяцПериода
ПОМЕСТИТЬ ВТ_Календарь
ИЗ
    РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
    РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &ДатаНачала И &ДатаОкончания
;

Здесь &ДатаНачала и &ДатаОкончания — это параметры, определяющие границы нашего отчетного периода. Важно, чтобы &ДатаОкончания включала последний день последнего месяца, который мы хотим видеть в отчете.

Шаг 2: Левое соединение с виртуальной таблицей ОстаткиИОбороты

После того как у нас есть временная таблица со всеми желаемыми периодами (ВТ_Календарь), нам необходимо соединить ее с результатом запроса к виртуальной таблице РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты. Ключевой момент здесь — использовать левое соединение (ЛЕВОЕ СОЕДИНЕНИЕ). Это гарантирует, что в результирующую выборку попадут все периоды из нашей сгенерированной таблицы дат, даже если для них нет соответствующих записей в ОстаткиИОбороты.

Для месяцев, в которых не было движений, поля из ХозрасчетныйОстаткиИОбороты будут иметь значение NULL. Чтобы представить их как нули, мы используем функцию ЕСТЬNULL().

Рассмотрим полный пример запроса:


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

В этом запросе мы используем следующие параметры:

Обратите внимание на то, что мы делаем соединение по ВТ_Календарь.МесяцПериода = ХозрасчетныйОстаткиИОбороты.Период. Оба эти поля должны быть приведены к началу месяца, что в нашем случае уже реализовано благодаря использованию параметра Месяц в виртуальной таблице и функции НАЧАЛОПЕРИОДА(..., МЕСЯЦ) в календаре.

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

Решение 2: Использование Системы Компоновки Данных (СКД)

Если вы строите отчеты с использованием Системы Компоновки Данных (СКД), задача значительно упрощается. СКД предоставляет встроенные механизмы для автоматического дополнения отсутствующих периодов.

Чтобы СКД автоматически дополнила отсутствующие периоды нулевыми значениями, выполните следующие шаги:

  1. Откройте настройки отчета в СКД (например, в пользовательском режиме или в конфигураторе).
  2. Перейдите на вкладку "Настройки" или "Выбранные поля".
  3. Найдите поле, которое отвечает за период (например, Период).
  4. В свойствах этого поля (обычно вызываются двойным щелчком по полю или кнопкой "Свойства") найдите параметр "Тип дополнения".
  5. Установите значение "Тип дополнения" в "Месяц" (или "День", "Неделя", "Квартал", "Год" — в зависимости от требуемой детализации).

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

Важные нюансы и дополнительные советы

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

← На главную