Как в отчете СКД настроить отбор по типу документа и рассчитать разницу между приходом и расходом

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

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

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

Способ 1. Использование оператора ССЫЛКА в тексте запроса

Это самый простой и прямолинейный способ, который подходит в тех случаях, когда список типов документов заранее известен и не будет меняться пользователем. Для реализации этого метода мы используем оператор ССЫЛКА. Рассмотрим пример правильного написания условия ГДЕ в конструкторе запроса.

Разберем типичную ситуацию: нам нужно отобрать документы типа ОприходованиеЗапасов и СписаниеЗапасов. Важно помнить, что один и тот же регистратор не может быть одновременно двумя разными документами, поэтому мы используем логическое ИЛИ.


ВЫБРАТЬ
    Запасы.Период,
    Запасы.Регистратор,
    Запасы.Номенклатура,
    Запасы.Количество
ИЗ
    РегистрНакопления.Запасы КАК Запасы
ГДЕ
    Запасы.Период МЕЖДУ &ДатаНачала И &ДатаОкончания
    И (Запасы.Регистратор ССЫЛКА Документ.ОприходованиеЗапасов 
       ИЛИ Запасы.Регистратор ССЫЛКА Документ.СписаниеЗапасов)

Важный нюанс: Обратите внимание на скобки в условии. Если их не поставить, приоритет оператора И нарушит логику, и отчет может работать некорректно. Мы объединяем условия по типам документов в одну логическую группу.

Почему не работает условие с оператором И?

Проанализируем ошибку, с которой часто сталкиваются начинающие разработчики. Если написать условие так:

ГДЕ Регистратор ССЫЛКА Документ.А И Регистратор ССЫЛКА Документ.Б

Система попытается найти запись, у которой поле Регистратор является одновременно и документом «А», и документом «Б». Поскольку это физически невозможно, запрос всегда будет возвращать пустой результат. Всегда используйте ИЛИ, когда перечисляете возможные типы для одного поля.

Способ 2. Гибкая фильтрация через ТИПЗНАЧЕНИЯ

Если мы хотим сделать отчет более универсальным, чтобы в будущем не переписывать запрос при добавлении новых документов, лучше использовать функцию ТИПЗНАЧЕНИЯ. Рассмотрим, как пробросить тип документа в настройки СКД, чтобы пользователь мог сам выбирать нужные фильтры.

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


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

Во-вторых, после добавления этого поля в схему компоновки данных, мы переходим на закладку Настройки. Теперь в списке доступных полей для отбора появится ТипРегистратора. Пользователь сможет нажать кнопку «Добавить отбор», выбрать это поле и в списке значений указать любые типы документов, которые его интересуют на данный момент.

Расчет разницы: Приход минус Расход

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

Выясним, как это реализовать прямо в тексте запроса с помощью конструкции ВЫБОР:


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

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

Продвинутый подход: Использование виртуальных таблиц

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

Посмотрим на преимущества этого метода:

  1. Производительность: Платформа 1С оптимизирует запросы к виртуальным таблицам на уровне СУБД.
  2. Готовые поля: Вам не нужно писать конструкцию ВЫБОР КОГДА. Виртуальная таблица уже содержит поля КоличествоПриход, КоличествоРасход и КоличествоОборот.
  3. Автоматический расчет: Поле КоличествоОборот уже вычисляется по формуле «Приход - Расход».

Пример запроса к виртуальной таблице с фильтрацией по регистратору:


ВЫБРАТЬ
    Запасы.Регистратор,
    Запасы.Номенклатура,
    Запасы.КоличествоПриход,
    Запасы.КоличествоРасход,
    Запасы.КоличествоОборот
ИЗ
    РегистрНакопления.Запасы.ОстаткиИОбороты(&ДатаНачала, &ДатаОкончания, Регистратор, , ) КАК Запасы
ГДЕ
    Запасы.Регистратор ССЫЛКА Документ.ОприходованиеЗапасов
    ИЛИ Запасы.Регистратор ССЫЛКА Документ.СписаниеЗапасов

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

Настройка ресурсов и оформления в СКД

Чтобы отчет выглядел профессионально, выполним финальные настройки в компоновщике:

Таким образом, сочетание правильной логики в запросе (использование ССЫЛКА или ТИПЗНАЧЕНИЯ) и грамотной настройки ресурсов позволяет создать мощный и гибкий инструмент для анализа движений по любым регистрам накопления в 1С.

← На главную