При разработке сложных прикладных решений на базе 1С:ERP или 1С:Комплексная автоматизация часто возникает необходимость встроить данные существующего отчета (например, «Остатки и доступность товаров») непосредственно в форму документа или справочника. Это позволяет пользователю видеть актуальную аналитику без лишних переключений между окнами. В данной статье мы подробно разберем, как решить эту задачу несколькими способами: от прямой работы со схемой компоновки данных до использования высокоуровневых функций БСП (Библиотеки стандартных подсистем).
Представим ситуацию: мы создаем новый документ НовыйДокумент. На его форме размещено поле РезультатОтчета с типом ТабличныйДокумент. Нам нужно, чтобы при определенных действиях пользователя (или при открытии) в этом поле отображался результат типового отчета с заранее определенными настройками. Например, это может быть актуально, если вам требуется вывести остатки товаров организаций с себестоимостью и датами последних закупок по конкретной номенклатуре или складу. При этом открывать форму самого отчета нельзя — все должно происходить «бесшовно».
Этот метод является классическим и наиболее гибким, так как он не зависит от программного интерфейса конкретного отчета. Мы фактически воспроизводим работу движка компоновки данных вручную. Для тех, кто хочет максимально сократить объем рутинного кода при такой реализации, рекомендуем обратить внимание на СКДБилдер: упрощаем программное создание СКД, который делает работу с объектной моделью более читаемой. Проанализируем последовательность шагов.
Рассмотрим пример кода, который реализует этот алгоритм на стороне сервера:
// Функция получает табличный документ на основе встроенного отчета
Функция СформироватьОтчетНаСервере(СсылкаНаОбъектДляФильтра) Экспорт
// 1. Получаем схему
СхемаКомпоновкиДанных = Отчеты.ОстаткиИДоступностьТоваров.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// 2. Получаем настройки (можно загрузить сохраненный вариант)
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
// 3. Установка параметров данных
ПараметрДата = Настройки.ПараметрыДанных.Элементы.Найти("Период");
Если ПараметрДата <> Неопределено Тогда
ПараметрДата.Значение = ТекущаяДата();
ПараметрДата.Использование = Истина;
КонецЕсли;
// 4. Установка отбора (например, по номенклатуре)
ЭлементОтбора = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номенклатура");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = СсылкаНаОбъектДляФильтра;
ЭлементОтбора.Использование = Истина;
// 5. Компоновка макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляРезультатаКомпоновки"));
// 6. Процессор компоновки и вывода
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ТабДок = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Возврат ТабДок;
КонецФункции
Важный момент: если мы хотим использовать не настройки по умолчанию, а конкретный «Вариант отчета», сохраненный пользователем, нам потребуется обратиться к хранилищу вариантов или использовать методы БСП для получения настроек по ссылке на вариант.
Если отчет спроектирован стандартно, у него есть встроенный метод СкомпоноватьРезультат(). Это более лаконичный путь, так как объект отчета уже содержит в себе КомпоновщикНастроек, и нам не нужно вручную создавать генераторы макета.
Проанализируем ситуацию: нам нужно создать объект отчета в памяти, программно «нажать» кнопку сформировать и забрать результат. Посмотрим на пример:
// Пример использования встроенного метода объекта
ОтчетОбъект = Отчеты.ОстаткиИДоступностьТоваров.Создать();
// Загружаем настройки варианта, если это необходимо
// ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(ПолученныеНастройки);
// Устанавливаем параметры через компоновщик настроек
ЗначениеПараметра = ОтчетОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Склад"));
Если ЗначениеПараметра <> Неопределено Тогда
ЗначениеПараметра.Значение = ВыбранныйСклад;
ЗначениеПараметра.Использование = Истина;
КонецЕсли;
ТабДок = Новый ТабличныйДокумент;
ОтчетОбъект.СкомпоноватьРезультат(ТабДок);
Этот метод хорош тем, что внутри СкомпоноватьРезультат может быть переопределена логика в модуле объекта отчета (процедура ПриКомпоновкеРезультата). Если мы будем использовать Способ 1, эта логика может не отработать, и данные будут некорректными. Это критично при создании инструментов для выявления расхождений, таких как сравнение товаров на складах и товаров организаций, где программные доработки запроса играют ключевую роль в поиске ошибок.
В конфигурациях 1С:ERP работа с отчетами сильно унифицирована. Выясним, как использовать штатные механизмы подсистемы «Варианты отчетов». Самый эффективный метод — использование общего модуля ОтчетыСервер.
Функция ОтчетыСервер.СформироватьОтчетДляВыводаВТабличныйДокумент() позволяет получить готовый результат, передав лишь описание отчета и настройки. Это избавляет программиста от написания десятков строк кода по инициализации процессоров компоновки. Более того, такой подход автоматически учитывает заголовки, подписи и другие элементы оформления, принятые в системе, что особенно важно, когда требуется сравнение товаров на складах организаций и себестоимости товаров с сохранением фирменного стиля отчетов 1С.
Рассмотрим, как это может выглядеть в коде:
// Пример вызова через БСП (ERP)
ПараметрыОтчета = ОтчетыСервер.ПараметрыОтчетаДляВыводаВТабличныйДокумент();
ПараметрыОтчета.ИмяОтчета = "ОстаткиИДоступностьТоваров";
ПараметрыОтчета.Вариант = СсылкаНаВариант; // СправочникСсылка.ВариантыОтчетов
ПараметрыОтчета.Настройки = ПользовательскиеНастройки;
Результат = ОтчетыСервер.СформироватьОтчетДляВыводаВТабличныйДокумент(ПараметрыОтчета);
// Результат.ТабличныйДокумент содержит готовый отчет
Разберем продвинутый сценарий: пользователь перемещается по списку товаров в документе, и в нижней части формы автоматически обновляется отчет по текущему товару. Подобный функционал уже реализован во многих расширениях, например, как Анализ позиций товаров в документе реализации, который мгновенно показывает историю движений.
Для реализации этого механизма выполним следующие шаги:
ПриАктивизацииСтроки для таблицы товаров.ПодключитьОбработчикОжидания.ТекущиеДанные.Номенклатура.ТабличныйДокумент.Иногда бизнес-задача требует не просто показать текущие остатки, а зафиксировать их в документе на момент его создания. Для этого сформированный ТабличныйДокумент необходимо сохранить в реквизит документа с типом ХранилищеЗначения.
Выясним причину, почему это важно: данные в регистрах меняются ежедневно. Если менеджеру нужно видеть ретроспективу, например, анализ списания запасов и продаж с себестоимостью без закрытия месяца на конкретную дату в прошлом, отчет покажет текущую ситуацию, а сохраненный «снимок» позволит увидеть данные, актуальные в момент оформления сделки. Сохранение снимка (snapshot) отчета решает эту проблему.
// Сохранение в объект
Объект.СнимокОтчета = Новый ХранилищеЗначения(ТабДок, Новый СжатиеДанных(9));
Мы проанализировали различные подходы к программному выводу отчетов в 1С. Для простых задач и внешних разработок отлично подходит прямая компоновка СКД. Для работы внутри типовых конфигураций (ERP, КА, УТ) правильнее использовать методы объекта или модули БСП, так как это гарантирует выполнение всех встроенных проверок и условий. Проектируйте интерфейсы так, чтобы информация была под рукой у пользователя, и используйте возможности платформы для автоматизации рутинных операций — от вывода простых остатков до реализации сложных инструментов, обеспечивающих поиск ошибок в учете при ордерной схеме.