Почему не выводится отчет и как правильно формировать данные по периодам в 1С

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

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

Разбор первой причины: Путаница в границах периода

Одной из самых частых ошибок является неправильная установка параметров &НачалоПериода и &КонецПериода. Проанализируем фрагмент кода, с которым возникли сложности:


Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ТекущаяДата())); 
Запрос.УстановитьПараметр("КонецПериода", ДобавитьМесяц(ТекущаяДата(), -6)); 

Здесь кроется критическая логическая ошибка. Функция НачалоМесяца(ТекущаяДата()) возвращает первое число текущего месяца (например, 01.10.2023). Функция ДобавитьМесяц(ТекущаяДата(), -6) возвращает дату на полгода назад (например, 01.04.2023). В языке запросов 1С оператор МЕЖДУ работает корректно только тогда, когда первое значение меньше второго. Если вы передадите в начало периода "октябрь", а в конец "апрель", запрос вернет пустой результат, так как в этом временном интервале нет ни одного дня.

Решение: Всегда следите за тем, чтобы НачалоПериода было хронологически раньше, чем КонецПериода.

Разбор второй причины: Несовпадение типов данных при сравнении

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


ОбластьМакета.Параметры.ТекущийМесяц = Формат(ТекущаяДата(),"ДФ='MMMM yyyy'");
// ... позже в цикле ...
Если ОбластьМакета.Параметры.ТекущийМесяц = НачалоМесяца(ТекущаяДата()) Тогда

Проанализируем ситуацию. В первом случае в параметр макета записывается Строка (например, "Октябрь 2023"). Во втором случае мы пытаемся сравнить эту строку с результатом функции НачалоМесяца(), которая возвращает тип Дата. В 1С строка никогда не будет равна дате, поэтому условие Если всегда будет ложным, и данные в макет не попадут.

Решение: Для логических проверок всегда используйте чистые типы Дата. Преобразовывайте их в строку с помощью функции Формат() только в самый последний момент — непосредственно при выводе в ячейку макета для пользователя.

Обработка значений NULL и группировка в запросе

Когда мы работаем с документами и их табличными частями, в результате запроса могут появиться значения NULL. Это происходит, если данные по ссылке отсутствуют или используются сложные соединения. Попытка применить функцию НачалоМесяца() к значению NULL в коде приведет к ошибке "Преобразование в тип Дата не может быть выполнено".

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


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

Использование функции НАЧАЛОПЕРИОДА внутри самого запроса позволяет нам сразу получать унифицированную дату начала месяца для каждой записи. Это значительно упрощает последующую обработку.

Как правильно выводить данные в макет

Выясним причину, по которой даже при наличии данных отчет может казаться пустым. Это часто связано с неправильным вызовом методов Вывести() и Присоединить().

Разберем алгоритм работы с областями:

  1. Сначала мы должны получить область из макета: Область = Макет.ПолучитьОбласть("Строка").
  2. Затем заполнить параметры в этой области: Область.Параметры.Тип = Результат.ТипДокумента.
  3. И только после заполнения параметров вывести область в табличный документ: ТабДок.Вывести(Область).

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

Оптимизация: Горизонтальный вывод (колонки по месяцам)

Если задача стоит вывести 6 месяцев в ряд (как колонки), использование ИначеЕсли для каждого месяца — плохая практика. Рассмотрим, как сделать это профессионально с помощью метода Присоединить():


// Выводим фиксированную левую часть (названия типов документов)
ТабДок.Вывести(ОбластьТипДокумента);

// В цикле присоединяем колонки месяцев справа
Для н = 0 По 5 Цикл
    ТекущийМесяцПериода = ДобавитьМесяц(НачалоМесяца(ДатаНачала), н);
    ОбластьМесяц = Макет.ПолучитьОбласть("КолонкаМесяц");
    ОбластьМесяц.Параметры.НазваниеМесяца = Формат(ТекущийМесяцПериода, "ДФ='MMMM yyyy'");
    ТабДок.Присоединить(ОбластьМесяц);
КонецЦикла;

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

Советы по отладке

Проанализируем ситуацию: код написан, ошибок нет, но данных все равно нет. Что делать?

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

← На главную