Как в СКД вывести остатки на начало и конец периода по реквизиту регистратора

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

При разработке отчетов на Системе Компоновки Данных (СКД) программисты часто сталкиваются с ситуацией, когда необходимо получить остатки в разрезе аналитики, которая отсутствует в измерениях регистра накопления, но присутствует в качестве реквизита в документах-регистраторах. Типичный пример из практики 1С:УНФ — необходимость увидеть движение денежных средств и остатки по конкретным проектам, при этом поле Проект заполнено в документах, но не является измерением регистра ДенежныеСредства.

Стандартные виртуальные таблицы Остатки и ОстаткиИОбороты в 1С работают исключительно с измерениями регистра. Если мы попытаемся вытащить реквизит регистратора через точку в этих таблицах, мы получим корректные обороты, но остатки будут рассчитаны неверно (либо будут пустыми), так как система не «хранит» итоги в разрезе произвольных реквизитов документов. Рассмотрим подробнее, как решить эту задачу несколькими способами.

Метод 1. Расчет остатков через физическую таблицу регистра

Проанализируем ситуацию: так как готовых итогов по проектам нет, нам придется рассчитать их самостоятельно, обратившись к основной физической таблице регистра накопления. Идея заключается в том, чтобы просуммировать все движения «с начала времен» до даты начала отчета (для получения начального остатка) и до даты окончания отчета (для конечного остатка).

Разберем по шагам логику построения запроса в СКД:

  1. Выбираем данные из физической таблицы регистра (например, РегистрНакопления.ДенежныеСредства).
  2. Обязательно соединяемся с таблицей регистратора, чтобы получить доступ к реквизиту Проект.
  3. Используем конструкцию ВЫБОР КОГДА для определения знака суммы в зависимости от вида движения.
  4. Группируем данные по проекту.

Пример структуры запроса для вычисления остатков:


ВЫБРАТЬ
    Т.Регистратор.Проект КАК Проект,
    СУММА(ВЫБОР
            КОГДА Т.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
                ТОГДА Т.Сумма
            ИНАЧЕ -Т.Сумма
        КОНЕЦ) КАК СуммаКонечныйОстаток,
    0 КАК СуммаНачальныйОстаток
ИЗ
    РегистрНакопления.ДенежныеСредства КАК Т
ГДЕ
    Т.Период <= &КонецПериода
ГРУППИРОВАТЬ ПО
    Т.Регистратор.Проект

Важный нюанс: расчет остатков «с начала времен» может существенно замедлить работу отчета на больших базах данных. Чтобы оптимизировать процесс, рекомендуется сначала отобрать только те записи, которые попадают в интересующий нас период по оборотам, и объединить их с результатами расчета остатков.

Метод 2. Использование ролей полей в СКД

Для того чтобы СКД поняла, что наши вычисленные поля являются именно остатками, и правильно агрегировала их в группировках и итогах, необходимо настроить Роли на вкладке «Наборы данных».

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

  1. Для поля СуммаНачальныйОстаток в колонке «Роль» открываем редактор и указываем тип Начальный остаток. В поле «Группа» пишем имя (например, «Сумма»), а в поле «Счет/Аналитика» указываем наш Проект.
  2. Для поля СуммаКонечныйОстаток указываем тип Конечный остаток с той же группой и аналитикой.
  3. Для поля Период обязательно указываем роль «Период», чтобы система знала временную последовательность движений.

В этом случае СКД применит свои внутренние алгоритмы для корректного вывода итогов по периодам и группировкам.

Метод 3. Использование функции ВычислитьВыражение

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

Посмотрим на пример выражения для вычисляемого поля:


ВычислитьВыражение("Сумма(СуммаОборот)", "Период", "Группировка", "Первая", "Текущая")

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

Метод 4. Архитектурное решение (изменение конфигурации)

Если отчет по остаткам в разрезе проектов требуется пользователям на регулярной основе и данных в базе много, выполнение расчетов «на лету» по физической таблице станет узким местом системы. Проанализируем более профессиональный подход:

Добавление измерения в регистр. Самым правильным с точки зрения производительности и методики 1С решением будет добавление поля Проект в состав измерений регистра накопления ДенежныеСредства. В этом случае:

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

Обработка пустых значений

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


ВЫБРАТЬ
    ЕСТЬNULL(Т.Регистратор.Проект, ЗНАЧЕНИЕ(Справочник.Проекты.ПустаяСсылка)) КАК Проект,
    ...

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

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

← На главную