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