При разработке отчетов и обработок в платформе 1С 7.7 начинающие программисты нередко сталкиваются с ситуацией: синтаксис запроса написан без ошибок, объект печатной формы инициализирован, метод выполнения запроса отрабатывает успешно, однако на экран выводится пустая таблица (или только ее шапка). Проанализируем исходный код, выясним причину такого поведения платформы и разберем правильные варианты реализации вывода данных.
Рассмотрим фрагмент кода, вызвавший проблему:
Перем Запрос, ТекстЗапроса, Таб;
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(Сформировать)
|Ссылка = Справочник.Контрагенты.ТекущийЭлемент;
|Код = Справочник.Контрагенты.Код;
|Родитель = Справочник.Контрагенты.Родитель;
|ОсновнойДоговор = Справочник.Контрагенты.ОсновнойДоговор;
|ОсновнойСчет = Справочник.Контрагенты.ОсновнойСчет;
|АдресПроживания = Справочник.Контрагенты.ТСЖ_АдресПроживания;
|Квартиросъемщик = Справочник.Контрагенты.ТСЖ_Квартиросъемщик;
|КолВоПроживающих = Справочник.Контрагенты.ТСЖ_КолВоПроживающих;
|Характеристика = Справочник.Контрагенты.ТСЖ_Характеристика;
|ДействуетС = Справочник.Контрагенты.ТСЖ_ДействуетС;
|ДействуетПо = Справочник.Контрагенты.ТСЖ_ДействуетПо;
|"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Сформировать");
Таб.ВывестиСекцию("Заголовок");
Состояние("Заполнение выходной таблицы...");
Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0);
Таб.ТолькоПросмотр(1);
Таб.Показать("Сформировать", "");
Здесь допущены сразу две критические ошибки:
Группировка) запрос не формирует иерархическое дерево или список строк для последовательного обхода.Таб.ВывестиСекцию("Заголовок");. Сами строки данных даже не считываются из объекта Запрос, а секция строк таблицы ни разу не отправляется на вывод.Разберем по шагам, как исправить алгоритм с использованием объекта Запрос.
Для корректного формирования выборки необходимо добавить в текст запроса группировку по ключевому полю (например, по ссылке на элемент справочника). Дополнительно можно использовать модификаторы, такие как без групп, чтобы папки справочника не попадали в итоговый отчет.
После успешного выполнения запроса необходимо организовать цикл с помощью метода Группировка() объекта Запрос и внутри цикла вызывать метод ВывестиСекцию() для строки макета.
Посмотрим на исправленный пример кода:
Перем Запрос, ТекстЗапроса, Таб;
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(Сформировать)
|Ссылка = Справочник.Контрагенты.ТекущийЭлемент;
|Код = Справочник.Контрагенты.Код;
|Родитель = Справочник.Контрагенты.Родитель;
|ОсновнойДоговор = Справочник.Контрагенты.ОсновнойДоговор;
|ОсновнойСчет = Справочник.Контрагенты.ОсновнойСчет;
|АдресПроживания = Справочник.Контрагенты.ТСЖ_АдресПроживания;
|Квартиросъемщик = Справочник.Контрагенты.ТСЖ_Квартиросъемщик;
|КолВоПроживающих = Справочник.Контрагенты.ТСЖ_КолВоПроживающих;
|Характеристика = Справочник.Контрагенты.ТСЖ_Характеристика;
|ДействуетС = Справочник.Контрагенты.ТСЖ_ДействуетС;
|ДействуетПо = Справочник.Контрагенты.ТСЖ_ДействуетПо;
|Группировка Ссылка без групп;
|"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Предупреждение("Ошибка выполнения запроса!");
Возврат;
КонецЕсли;
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Сформировать");
// Выводим шапку отчета
Таб.ВывестиСекцию("Заголовок");
Таб.ВывестиСекцию("ШапкаТаблицы");
Состояние("Заполнение выходной таблицы...");
// Обходим полученные результаты запроса
Пока Запрос.Группировка("Ссылка") = 1 Цикл
// В секции макета "Строка" ячейки должны иметь тип "Выражение"
// и обращаться к полям запроса: Запрос.Код, Запрос.АдресПроживания и т.д.
Таб.ВывестиСекцию("Строка");
КонецЦикла;
Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0);
Таб.ТолькоПросмотр(1);
Таб.Показать("Сформировать", "");
Важные нюансы настройки макета печатной формы:
Строка обязательно нужно переключить свойство содержимого на Выражение. Если оставить тип Текст, платформа выведет текстовые имена переменных вместо значений.Запрос.Код, Запрос.Ссылка.Наименование, Запрос.АдресПроживания.Период с ... по ...; значения будут получены на текущую системную дату (или ТА).Рассмотрим альтернативное решение. В 1С 7.7 для простых отчетов по справочникам использовать объект Запрос не обязательно. Более того, встроенный запрос к справочникам часто работает медленнее, так как создает временные таблицы на диске, что ощутимо на больших базах формата DBF.
Для последовательного обхода справочника платформа предоставляет быстрый механизм прямой выборки методами ВыбратьЭлементы() и ПолучитьЭлемент().
Посмотрим на пример реализации прямой выборки:
Перем Спр, Таб;
Спр = СоздатьОбъект("Справочник.Контрагенты");
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Сформировать");
Таб.ВывестиСекцию("Заголовок");
Таб.ВывестиСекцию("ШапкаТаблицы");
Состояние("Выборка данных справочника...");
// Инициализируем выборку всех элементов
Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
// Пропускаем группы (папки), если нужны только конечные элементы
Если Спр.ЭтоГруппа() = 1 Тогда
Продолжить;
КонецЕсли;
// В ячейках секции "Строка" можно напрямую писать: Спр.Код, Спр.Наименование и т.д.
Таб.ВывестиСекцию("Строка");
КонецЦикла;
Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0);
Таб.ТолькоПросмотр(1);
Таб.Показать("Сформировать", "");
Преимущества данного подхода:
Спр.Код, Спр.ТСЖ_АдресПроживания, Спр.ТСЖ_Квартиросъемщик.Спр.ИспользоватьРодителя(НужнаяПапка) для вывода конкретной группы контрагентов.Если нет уверенности в правильном оформлении макета или кода циклов, разберем еще один проверенный способ: воспользоваться встроенным Конструктором печати в Конфигураторе 1С 7.7. Для этого откройте форму списка или редактирования целевого справочника, перейдите в меню конструкторов и выберите формирование процедуры печати. Конструктор автоматически создаст и настроит макет, расставит секции, заполнит тип ячеек «Выражение» и напишет программный код выборки без ошибок.