При разработке отчетов в 1С:Предприятие 8 на обычных формах одной из самых частых проблем начинающих программистов является некорректная работа с областями табличного документа. Типичная ситуация: вместо аккуратного списка документов программа выводит для каждой строки новую шапку, заголовок и названия колонок. Это происходит из-за нарушения логики цикла и неправильного порядка вызова методов вывода областей.
В этой статье мы подробно разберем, как структурировать код формирования отчета, чтобы заголовок выводился один раз, а строки реестра заполнялись динамически. Мы проанализируем распространенные ошибки и изучим профессиональные приемы оптимизации табличных документов.
Рассмотрим ситуацию: у нас есть макет с именем "Акт", который разделен на несколько именованных областей: Заголовок, Шапка (шапка таблицы с названиями колонок), Основа (строка с данными документа) и Подвал. Основная ошибка заключается в том, что разработчик помещает вызов методов Вывести(Шапка) или Вывести(Заголовок) внутрь цикла Пока Выборка.Следующий() Цикл. В результате 1С послушно отрисовывает весь комплект оформления для каждого найденного документа.
Давайте разберем правильный алгоритм формирования документа:
ТабличныйДокумент и получаем макет.Основа) и выводим только её.Прежде чем что-то выводить, нам нужно получить данные. Важно правильно настроить параметры периода и фильтры по организации и контрагенту. Проанализируем пример кода запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| РеализацияТоваровУслуг.Номер КАК Номер,
| РеализацияТоваровУслуг.Дата КАК Дата,
| РеализацияТоваровУслуг.Контрагент КАК Контрагент,
| РеализацияТоваровУслуг.Организация КАК Организация
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
| И РеализацияТоваровУслуг.Контрагент = &Контрагент
| И РеализацияТоваровУслуг.Организация = &Организация
|УПОРЯДОЧИТЬ ПО
| Дата,
| Номер";
Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(НачалоПериода));
Запрос.УстановитьПараметр("ДатаОкончания", КонецДня(КонецПериода));
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("Контрагент", Контрагент);
РезультатЗапроса = Запрос.Выполнить();
Важное примечание: Обратите внимание на использование РАЗРЕШЕННЫЕ. Это критически важно для систем с настроенными правами доступа (RLS), чтобы отчет не вызывал ошибку у пользователей с ограниченными правами. Также мы добавили УПОРЯДОЧИТЬ ПО, чтобы документы в реестре шли в хронологическом порядке.
Часто возникает вопрос: как вывести контрагента в заголовке, если мы еще не начали цикл обхода запроса? Рассмотрим ошибку: попытка обратиться к Выборка.Контрагент сразу после метода Выбрать() без вызова Следующий() приведет к тому, что значение будет пустым.
Правильнее всего брать данные для заголовка напрямую из реквизитов формы, так как именно их пользователь выбрал для фильтрации. Рассмотрим реализацию вывода верхней части отчета:
ТабДокумент = Новый ТабличныйДокумент;
Макет = ЭтотОбъект.ПолучитьМакет("Акт");
// Получаем области
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Основа");
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
// Заполняем параметры заголовка напрямую из формы
ОбластьЗаголовок.Параметры.Контрагент = Контрагент;
ОбластьЗаголовок.Параметры.Период = ПредставлениеПериода(НачалоПериода, КонецПериода);
// Выводим статичные части
ТабДокумент.Вывести(ОбластьЗаголовок);
ТабДокумент.Вывести(ОбластьШапка);
Теперь перейдем к основной части — выводу строк. Внутри цикла мы работаем только с областью строки (в нашем примере — Основа). Мы заполняем параметры каждой строки данными из выборки и выводим её в итоговый табличный документ.
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Заполняем параметры области данными из текущей строки выборки
ОбластьСтрока.Параметры.Заполнить(Выборка);
// Если нужно специфическое форматирование даты
ОбластьСтрока.Параметры.ДатаДокумента = Формат(Выборка.Дата, "ДФ=dd.MM.yyyy");
// Выводим только строку данных
ТабДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
// После цикла выводим подвал, если он предусмотрен
ТабДокумент.Вывести(ОбластьПодвал);
Чтобы отчет выглядел профессионально и был удобен в использовании, необходимо настроить свойства самого ТабличногоДокумента. Выясним, какие настройки наиболее полезны для реестров:
Истина, чтобы пользователь случайно не изменил данные в сформированном отчете.Истина, чтобы 1С автоматически подогнала ширину колонок под лист бумаги при печати.Проанализируем итоговый блок настроек:
ТабДокумент.ТолькоПросмотр = Истина;
ТабДокумент.ОтображатьСетку = Ложь;
ТабДокумент.АвтоМасштаб = Истина;
// Фиксируем первые 5 строк (заголовок + шапка)
ТабДокумент.ФиксацияСверху = 5;
ТабДокумент.Показать("Реестр документов реализации");
Хорошим тоном в программировании 1С считается проверка результата запроса на наличие данных. Если запрос не вернул ни одной записи, выводить пустую шапку с подвалом не имеет смысла. Перед началом формирования документа рекомендуется добавить проверку:
Если РезультатЗапроса.Пустой() Тогда
Предупреждение("За выбранный период данных не обнаружено!");
Возврат;
КонецЕсли;
Разберем совет опытных разработчиков: если у вас области Название, Реквезиты и Заголовок всегда выводятся вместе и содержат минимум параметров, их стоит объединить в одну большую область "ШапкаОтчета" непосредственно в конфигураторе. Это упрощает программный код, уменьшает количество вызовов метода Вывести() и снижает вероятность запутаться в логике построения документа.
Также не забывайте про возможность использования расшифровки. Если в макете в поле строки Основа для ячейки с номером документа указать в свойстве ПараметрРасшифровки имя Ссылка, то при двойном клике в сформированном отчете пользователь сможет сразу открыть соответствующий документ реализации.
Соблюдение этого структурного подхода позволит вам создавать надежные и понятные отчеты, которые легко поддерживать и модифицировать.