В практике разработки на платформе 1С:Предприятие 8.3 (особенно в конфигурациях на обычных формах, таких как УТ 10.3 или УТ 2.1) часто возникает задача: при нажатии на ячейку в одном отчете (обработка расшифровки) должен открываться другой внешний отчет, в который уже переданы фильтры по выбранной номенклатуре, складу или типу цен. Рассмотрим, как правильно реализовать этот механизм через ПостроительОтчета и избежать распространенных ошибок при вызове экспортных процедур.
Разберем типичный сценарий. У нас есть программный код в обработчике расшифровки, который находит внешний отчет в справочнике, сохраняет его во временный файл и создает объект отчета. Однако при попытке сформировать отчет возникает ошибка: "Нехватка фактических параметров". Проанализируем код, с которым возникли трудности:
ОтчетАнализЦенКонтрагентов = ВнешниеОтчеты.Создать(ИмяФайла, Ложь);
// ... установка настроек ...
Форма = ОтчетАнализЦенКонтрагентов.ПолучитьФорму();
АнализЦенКонтрагентовДокументРезультат = Форма.ЭлементыФормы.Найти("ДокументРезультат");
Форма.СформироватьОтчет(АнализЦенКонтрагентовДокументРезультат); // Ошибка здесь!
Выясним причину ошибки и разберем правильный алгоритм работы с внешними отчетами по шагам.
Первым делом нам необходимо проверить саму процедуру СформироватьОтчет в модуле формы или объекта вызываемого отчета. Ошибка "Нехватка фактических параметров" прямо указывает на то, что в объявлении процедуры параметров больше, чем вы передаете при вызове.
Как выяснилось в ходе обсуждения, в целевом отчете процедура объявлена следующим образом:
Процедура СформироватьОтчет(ДокументРезультат, ПоказыватьЗаголовок, ТолькоЗаголовок = Ложь) Экспорт
Обратите внимание на второй параметр ПоказыватьЗаголовок. Он является обязательным, так как для него не указано значение по умолчанию (в отличие от третьего параметра). Следовательно, вызов должен выглядеть так:
// Передаем как минимум два параметра
Форма.СформироватьОтчет(АнализЦенКонтрагентовДокументРезультат, Истина);
При работе с ПостроительОтчета важно различать Параметры запроса и Отборы. Если в тексте запроса вашего отчета нет явного обращения к переменной через амперсанд (например, &Номенклатура), то использование метода Параметры.Вставить() не даст результата в плане фильтрации данных.
Рассмотрим, как правильно передать значение в Отбор, если вы хотите ограничить список выводимых данных:
// Пример установки отбора по Номенклатуре
НовыйОтбор = ОтчетАнализЦенКонтрагентов.ПостроительОтчета.Отбор;
Если НовыйОтбор.Найти("Номенклатура") = Неопределено Тогда
НовыйОтбор.Добавить("Номенклатура");
КонецЕсли;
НовыйОтбор["Номенклатура"].Использование = Истина;
НовыйОтбор["Номенклатура"].ВидСравнения = ВидСравнения.Равно;
НовыйОтбор["Номенклатура"].Значение = Расшифровка.Значение("Номенклатура");
Если же вы используете именно Параметры запроса, убедитесь, что в тексте запроса ПостроительОтчета.Текст эти параметры присутствуют. Установка выполняется стандартно:
ОтчетАнализЦенКонтрагентов.ПостроительОтчета.Параметры.Вставить("ТипЦен", НужныйТипЦен);
Проанализируем важный архитектурный момент: откуда вызывать формирование отчета? В 1С существует два подхода:
1. Вызов метода Формы: Вы используете этот метод, когда вам нужно, чтобы результат сразу отобразился в элементах управления открытой формы. Это удобно для пользователя, но требует наличия активной формы в памяти. Именно здесь часто возникают ошибки с параметрами, так как методы формы заточены под интерактивное взаимодействие.
2. Вызов метода Объекта: Если логика формирования вынесена в модуль объекта (что является правилом хорошего тона), лучше вызывать ОтчетОбъект.СформироватьОтчет(). Это позволяет сформировать данные даже без открытия окна, например, для фоновой печати или сохранения в файл.
Важно: Если вы открываете форму внешнего отчета программно, рекомендуется сначала заполнить настройки в объекте ОтчетАнализЦенКонтрагентов, а затем вызывать Форма.Открыть(). В типовых конфигурациях при открытии формы происходит автоматическое обновление настроек из объекта.
Объединим все исправления в единый работающий блок кода:
// 1. Создаем объект внешнего отчета
ОтчетОбъект = ВнешниеОтчеты.Создать(ИмяФайла, Ложь);
// 2. Устанавливаем настройки (даты, параметры, отборы)
ОтчетОбъект.ДатаОтчета = КонецДня(ТекущаяДата());
ОтчетОбъект.ПостроительОтчета.Параметры.Вставить("Номенклатура", Расшифровка.Значение("Номенклатура"));
ОтчетОбъект.ПостроительОтчета.Параметры.Вставить("ТипЦен", "Аптечная");
// 3. Получаем форму и инициализируем её элементы
Форма = ОтчетОбъект.ПолучитьФорму();
// 4. Находим табличный документ на форме для вывода
ТабДок = Форма.ЭлементыФормы.ДокументРезультат;
// 5. Вызываем формирование с соблюдением всех обязательных параметров процедуры
// Предположим, процедура в форме: СформироватьОтчет(ТабДок, ПоказатьЗаголовок)
Форма.СформироватьОтчет(ТабДок, Истина);
// 6. Открываем готовую форму пользователю
Форма.Открыть();
Таким образом, мы решили проблему нехватки параметров, разобравшись с сигнатурой метода, и обеспечили корректную передачу данных через ПостроительОтчета. Помните, что при работе с внешними отчетами всегда полезно заглядывать в модуль вызываемого отчета через конфигуратор, чтобы точно знать названия параметров и структуру экспортных процедур.