Как правильно настроить запрос в 1С для вывода данных регистра накопления в несколько колонок?

Программист 1С v8.3 (Обычные формы) Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

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

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

Анализ исходного запроса и типичные ошибки

В исходном варианте запроса используется конструкция ВЫБОР КОГДА ... ТОГДА. Однако при её написании часто забывают о нескольких критически важных моментах, которые приводят к «пустым» результатам в отчете.

Рассмотрим пример логики, которая часто приводит к ошибкам:


ВЫБОР 
    КОГДА Поступление.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход) 
    И Поступление.Основание ССЫЛКА Документ.ПКОпроживание 
        ТОГДА Поступление.Сумма 
КОНЕЦ КАК Касса

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

Решение: Всегда добавляйте конструкцию ИНАЧЕ 0 внутри блока ВЫБОР. Это гарантирует, что в каждой строке будет числовое значение, даже если условие не подошло. Кроме того, рекомендуется оборачивать всё выражение в функцию ЕСТЬNULL, чтобы застраховаться от пустых значений при соединении таблиц.

Группировка данных — залог чистого отчета

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

Разберем, как это реализовать. В секции ВЫБРАТЬ мы должны применить функцию СУММА() ко всем числовым полям, а в конце запроса добавить секцию СГРУППИРОВАТЬ ПО, перечислив в ней все нечисловые поля (ФизЛицо, Контрагент и т.д.).

Посмотрим на пример правильной структуры запроса:


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

СГРУППИРОВАТЬ ПО
    Взаиморасчеты.ФизЛицо

Оптимизация: Виртуальные таблицы vs Физические таблицы

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

Для построения отчетов в 1С 8.3 рекомендуется использовать виртуальные таблицы, такие как .Обороты. Платформа рассчитывает их заранее, что значительно ускоряет выборку данных.

Посмотрим, как изменится наш запрос при использовании виртуальной таблицы:

  1. Данные будут выбираться из РегистрНакопления.ВзаиморасчетыПроживание.Обороты(&Начало, &Конец, , ).
  2. Фильтрация по датам происходит на уровне параметров виртуальной таблицы, а не в условии ГДЕ, что гораздо эффективнее.
  3. В виртуальной таблице оборотов уже есть готовые поля СуммаПриход и СуммаРасход, что упрощает логику разделения на оплату и начисление.

Проверка условий и типов данных

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

Использование ССЫЛКА позволяет серверу БД выполнять проверку типов более оптимально. Кроме того, это сокращает код и делает его более читаемым для других программистов.

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

Почему данные могут не отображаться в отчете?

Если запрос в консоли запросов возвращает правильные цифры, а в самом отчете колонки остаются пустыми, проблема кроется в выводе данных. Рассмотрим основные причины:

Итоги и рекомендации

Подводя итог, можно составить краткий чек-лист для создания надежного отчета с разделением по колонкам:

  1. Используйте СУММА() и СГРУППИРОВАТЬ ПО для объединения данных.
  2. Всегда пишите ИНАЧЕ 0 в конструкции ВЫБОР.
  3. Применяйте ССЫЛКА для проверки типа документа-регистратора или основания.
  4. Отдавайте предпочтение виртуальной таблице .Обороты для ускорения работы.
  5. Тщательно проверяйте имена параметров в макете — они должны строго совпадать с именами полей в результате запроса.

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

← На главную