Почему не выводится печатная форма при открытии ОбщейФормы.ПечатьДокументов в БП 3.0.142.56 и выше?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

При работе с конфигурацией 1С:Бухгалтерия Предприятия 3.0, особенно после обновления до версий 3.0.142.56 и более поздних, пользователи и разработчики часто сталкиваются с проблемами при попытке вывода печатных форм. Эти сложности возникают, как правило, при использовании внешних печатных форм или собственных обработок, которые открывают общую форму печати документов (ОбщаяФорма.ПечатьДокументов). Изменения в базовой функциональности подсистемы БСП (Библиотека Стандартных Подсистем), касающиеся механизмов формирования и вывода печатных форм, требуют адаптации существующего кода. Рассмотрим эту проблему подробнее и разберем пути её решения.

Анализируем начальную проблему: ошибка «ОбъектыНазначения - Неопределено» и «ИдентификаторЗадания»

Изначально, разработчики часто использовали прямой вызов формы печати, передавая ей параметры. Вот пример кода, который мог использоваться для открытия формы печати:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ПараметрыПечати = Новый Структура;
    ПараметрыИсточника = Новый Структура("ИдентификаторКоманды, ОбъектыНазначения");
    ПараметрыИсточника.ИдентификаторКоманды = Параметры.ИдентификаторКоманды;
    ПараметрыИсточника.ОбъектыНазначения = Параметры.ОбъектыНазначения;
    ПараметрыОткрытия = Новый Структура("ИсточникДанных, ПараметрыИсточника, ПараметрыПечати");
    ПараметрыОткрытия.ИсточникДанных = Параметры.ДополнительнаяОбработкаСсылка;
    ПараметрыОткрытия.ПараметрыИсточника = ПараметрыИсточника;
    ПараметрыОткрытия.ПараметрыПечати = ПараметрыПечати;
    ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия);
    Закрыть;
КонецПроцедуры

В ранних версиях БП 3.0 такой подход мог работать, но с обновлениями, особенно до версии 3.0.142.56, возникали проблемы. В частности, мы могли наблюдать, что Параметры.ОбъектыНазначения оказывался Неопределено, что блокировало дальнейшую работу. Это происходило потому, что платформа начала ожидать, что параметры будут переданы в другой структуре или подготовлены заранее.

Дальнейшее развитие проблемы привело к другой распространенной ошибке, связанной с асинхронным выполнением операций. Мы могли видеть ошибку:

Поле объекта не обнаружено (ИдентификаторЗадания)

которая возникала в общем модуле ДлительныеОперацииКлиент, строка 55:


{ОбщийМодуль.ДлительныеОперацииКлиент.Модуль(55)}:РасширенныеПараметры.Вставить("ИдентификаторЗадания", ДлительнаяОперация.ИдентификаторЗадания);

Эта ошибка указывала на то, что объект ДлительнаяОперация, возвращаемый функцией УправлениеПечатьюВызовСервера.НачатьФормированиеПечатныхФорм, не содержал ожидаемого поля ИдентификаторЗадания. Это свидетельствует о том, что структура объекта, описывающего длительную операцию, изменилась в новых версиях БСП, и старый код, который полагался на определенную структуру, перестал работать. В новых версиях 1С:ЗУП 3.1 и УТ 11.5 такой код мог функционировать корректно, что подтверждает версию о различиях в версиях БСП, используемых в разных конфигурациях.

Для понимания контекста, вот код, который приводил к этой ошибке:


#Область ОбработчикиСобытийФормы
&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Если ЭтоОтладка Тогда
        Возврат;
    КонецЕсли;

    ПараметрыИсточника = Новый Структура;
    ПараметрыИсточника.Вставить("ИдентификаторКоманды", Параметры.ИдентификаторКоманды);
    ПараметрыИсточника.Вставить("ОбъектыНазначения", Параметры.ОбъектыНазначения);

    ПараметрыОткрытия = УправлениеПечатьюСлужебныйКлиент.ПараметрыОткрытияФормыПечати;
    ПараметрыОткрытия.Вставить("ИсточникДанных", Параметры.ДополнительнаяОбработкаСсылка);
    ПараметрыОткрытия.Вставить("ПараметрыИсточника", ПараметрыИсточника);
    ПараметрыОткрытия.Вставить("ПараметрКоманды", Параметры.ОбъектыНазначения);
    ПараметрыОткрытия.УникальныйИдентификаторХранилища = ЭтаФорма.УникальныйИдентификатор;

    ДлительнаяОперация = УправлениеПечатьюВызовСервера.НачатьФормированиеПечатныхФорм(ПараметрыОткрытия);
    ПараметрыОткрытия.ВладелецФормы = ЭтаФорма;

    ОповещениеОЗавершении = Новый ОписаниеОповещения("ВыполнитьОткрытиеПечатнойФормыФормированияПечатныхФорм", ЭтотОбъект, ПараметрыОткрытия);
    ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОповещениеОЗавершении, УправлениеПечатьюСлужебныйКлиент.ПараметрыОжидания(ЭтаФорма));
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьОткрытиеПечатнойФормыФормированияПечатныхФорм(РезультатФоновойОперации, ПараметрыОткрытия) Экспорт
    Если Не РезультатФоновойОперации = Неопределено Тогда
        Если РезультатФоновойОперации.Статус = "Ошибка" Тогда
            ПоказатьПредупреждение(, РезультатФоновойОперации.КраткоеПредставлениеОшибки);
        Иначе
            СтруктураРезультата = ПолучитьИзВременногоХранилища(РезультатФоновойОперации.АдресРезультата);
            ПараметрыОткрытия.Вставить("ОбъектыПечати", СтруктураРезультата.ОбъектыПечати);
            ПараметрыОткрытия.Вставить("ПараметрыВывода", СтруктураРезультата.ПараметрыВывода);
            ПараметрыОткрытия.Вставить("КоллекцияПечатныхФорм", СтруктураРезультата.КоллекцияПечатныхФорм);

            ВладелецФормы = ПараметрыОткрытия.ВладелецФормы;
            ПараметрыОткрытия.Удалить("ВладелецФормы");
            ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия, ВладелецФормы, Строка(Новый УникальныйИдентификатор));
        КонецЕсли;
    КонецЕсли;
    Закрыть;
КонецПроцедуры
#КонецОбласти

В данном коде мы видим попытку использовать функции УправлениеПечатьюВызовСервера.НачатьФормированиеПечатныхФорм() и ДлительныеОперацииКлиент.ОжидатьЗавершение(), что является корректным подходом для асинхронных операций в БСП. Однако, ошибка ИдентификаторЗадания указывает на несовместимость версии БСП или неправильную обработку возвращаемого значения.

Альтернативный способ печати (не через ОткрытьФорму)

Прежде чем перейти к основному решению с ОткрытьФорму, рассмотрим кратко альтернативный способ, который позволяет вывести печатную форму без непосредственного открытия ОбщаяФорма.ПечатьДокументов, а сразу передать коллекцию печатных форм для печати. Этот метод подходит, если вам не нужна интерактивная работа с формой печати (выбор экземпляров, отправка по почте и т.д.), а требуется просто отобразить или распечатать документ:


&НаКлиенте
Процедура Печать(Команда)
    ТабДок = ПечатьНаСервере(); // Вызываем серверную функцию для получения ТабличногоДокумента

    // Создаем новую коллекцию печатных форм
    КоллекцияПечатныхФорм = УправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм("СчетДоговор");
    
    // Присваиваем полученный ТабличныйДокумент первому элементу коллекции
    КоллекцияПечатныхФорм[0].ТабличныйДокумент = ТабДок;
    КоллекцияПечатныхФорм[0].Экземпляров = 1; // Устанавливаем количество экземпляров
    КоллекцияПечатныхФорм[0].СинонимМакета = НСтр("ru = 'Товарный чек'"); // Задаем синоним макета

    // Открываем форму предварительного просмотра или печати
    УправлениеПечатьюКлиент.ПечатьДокументов(КоллекцияПечатныхФорм, Неопределено, ЭтаФорма);
КонецПроцедуры

&НаСервере
Функция ПечатьНаСервере()

    // Подготавливаем коллекцию для одной печатной формы на сервере
    ВременнаяКоллекцияДляОднойПечатнойФормы = УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм("СчетДоговор");
    СтруктураПараметровПечати = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода;

    // Предполагается, что у вашего объекта есть метод Печать,
    // который заполняет ВременнаяКоллекцияДляОднойПечатнойФормы
    // Док.ВыгрузитьЗначения - это массив со ссылками на документы, которые нужно напечатать
    // Например, если печатаем один документ, то это может быть Массив со ссылкой на Объект (например, документ СписаниеМатериаловИзЭксплуатации)
    // РеквизитФормыВЗначение("Объект").Печать(
    //     Новый Массив(Объект.Ссылка),
    //     ВременнаяКоллекцияДляОднойПечатнойФормы,
    //     Новый СписокЗначений(),
    //     СтруктураПараметровПечати
    // );
    
    // Пример вызова вашего собственного метода печати на сервере
    // Допустим, у вас есть своя функция на сервере, которая возвращает ТабличныйДокумент
    ТабличныйДокумент = Новый ТабличныйДокумент;
    // ... логика формирования ТабличногоДокумента ...
    // Например, можно вызвать метод печати из общего модуля или вашей обработки
    // УправлениеПечатью.ВыполнитьКомандуПечати(ВременнаяКоллекцияДляОднойПечатнойФормы, ИдентификаторКоманды, ОбъектыПечати, ПараметрыВывода);
    
    // Если ВременнаяКоллекцияДляОднойПечатнойФормы была заполнена
    Если ВременнаяКоллекцияДляОднойПечатнойФормы.Количество Тогда
        Возврат ВременнаяКоллекцияДляОднойПечатнойФормы[0].ТабличныйДокумент;
    Иначе
        Возврат Новый ТабличныйДокумент; // Возвращаем пустой ТабличныйДокумент, если ничего не сформировалось
    КонецЕсли;
КонецФункции

Этот метод через УправлениеПечатьюКлиент.ПечатьДокументов() удобен для простого вывода, но не решает задачу открытия именно формы со всеми её интерактивными возможностями.

Решение проблемы с ОткрытьФорму("ОбщаяФорма.ПечатьДокументов") для БП 3.0.142.56

Для того чтобы корректно открыть ОбщаяФорма.ПечатьДокументов в версиях БП 3.0.142.56 и выше, необходимо учитывать изменения в механизме формирования печатных форм и передачи параметров. Нам потребуется заранее сформировать коллекцию печатных форм на сервере и затем передать её в форму.

Шаг 1: Получение ссылки на внешнюю печатную форму и подготовка параметров

Сначала нам нужно получить ссылку на нашу внешнюю печатную форму (ВПФ) и подготовить структуру ПараметрыОткрытия.


&НаКлиенте
Процедура ПечатьТТН(Команда)
    // 1. Получение Внешней печатной формы (ВПФ)
    // Мы создаем функцию НайтиВПФ, которая вернет ссылку на вашу внешнюю печатную форму
    ВПФ = НайтиВПФ("Печать ТТН"); 

    // Проверяем, что ВПФ найдена
    Если ВПФ = Неопределено Тогда
        ПоказатьПредупреждение(, "Внешняя печатная форма 'Печать ТТН' не найдена.");
        Возврат;
    КонецЕсли;

    // 2. Подготовка структуры ПараметрыОткрытия
    ПараметрыОткрытия = Новый Структура("ИсточникДанных, ПараметрыИсточника, КоллекцияПечатныхФорм");
    ПараметрыОткрытия.ИсточникДанных = ВПФ;

    // 3. Подготовка структуры ПараметрыИсточника
    // ИдентификаторКоманды - это имя команды печати в вашей ВПФ
    // ОбъектыНазначения - это массив ссылок на объекты, для которых выполняется печать
    ПараметрыОткрытия.ПараметрыИсточника = Новый Структура("ИдентификаторКоманды, ОбъектыНазначения");
    ИдентификаторКомандыПечати1 = "ПечатьТТН3"; // Пример идентификатора команды
    ПараметрыОткрытия.ПараметрыИсточника.ИдентификаторКоманды = ИдентификаторКомандыПечати1;
    
    // Предполагаем, что ОбъектыНазначения уже заполнен и содержит ссылки на документы
    // Например: ОбъектыНазначения = Новый Массив(); ОбъектыНазначения.Добавить(Объект.Ссылка);
    ПараметрыОткрытия.ПараметрыИсточника.ОбъектыНазначения = ОбъектыНазначения; 

    // 4. Формирование КоллекцииПечатныхФорм на сервере
    СформироватьПечатныеФормы(ПараметрыОткрытия);

    // 5. Открытие формы печати
    ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия);
КонецПроцедуры

Шаг 2: Вспомогательные функции для поиска ВПФ и формирования печатных форм

Эти функции будут выполняться на сервере и помогут нам подготовить данные.


&НаСервереБезКонтекста
Функция НайтиВПФ(НаименованиеВПФ)
    // Функция для поиска внешней печатной формы по наименованию
    // Возвращает ссылку на элемент справочника "ДополнительныеОтчетыИОбработки"
    Возврат Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию(НаименованиеВПФ);
КонецФункции

&НаСервере
Процедура СформироватьПечатныеФормы(ПараметрыОткрытия)
    Результат = Неопределено;
    ОбъектыПечати = Новый СписокЗначений;
    ПараметрыВывода = Неопределено;

    // Вызываем стандартный механизм печати по внешнему источнику
    // Это инициирует формирование печатных форм на сервере
    УправлениеПечатью.ПечатьПоВнешнемуИсточнику(
        ПараметрыОткрытия.ИсточникДанных,
        ПараметрыОткрытия.ПараметрыИсточника,
        Результат, // Сюда будет помещена коллекция сформированных печатных форм
        ОбъектыПечати, // Сюда будут помещены ссылки на объекты печати
        ПараметрыВывода // Сюда будут помещены параметры вывода
    );

    // Результат, который возвращает УправлениеПечатью.ПечатьПоВнешнемуИсточнику,
    // обычно представляет собой таблицу значений.
    // Нам нужно преобразовать её в массив для передачи в форму печати.
    // Общегоназначения.ТаблицаЗначенийВМассив - это функция из общего модуля БСП.
    ПараметрыОткрытия.КоллекцияПечатныхФорм = Общегоназначения.ТаблицаЗначенийВМассив(Результат);
КонецПроцедуры

Данный подход, показанный в сообщениях, помогает адаптировать печатные формы под конфигурации, использующие обновленную БСП, например, КА 2.5.

Переход на новый асинхронный механизм печати в БП 3.0.142.56 и выше

Самое комплексное решение для актуальных релизов БП 3.0, которое учитывает все особенности асинхронного формирования и специфику передачи параметров, представлено в виде сравнения "БЫЛО" и "СТАЛО". Оно демонстрирует полный переход к современному механизму печати.

Было (старый подход)

Вот как мог выглядеть код, который работал в более старых версиях, но затем столкнулся с проблемами:


&НаКлиенте
Процедура Печать(КомандыПечати) экспорт;
    РеквизитыОбработки = Новый Структура;
    РеквизитыОбработки.Вставить("ОтветЗаПроверку", Объект.ОтветЗаПроверку);
    РеквизитыОбработки.Вставить("НДС", Объект.НДС);

    // Добавление дополнительных реквизитов в ОбъектыНазначения
    // Это не всегда корректно, так как ОбъектыНазначения должен содержать ссылки на документы
    // или другие объекты ИБ, а не произвольные структуры с реквизитами обработки.
    Параметры.ОбъектыНазначения.Вставить(0, РеквизитыОбработки); 
    
    КлючУникальности = Строка (Новый УникальныйИдентификатор);
    ПараметрыИсточника = Новый Структура;
    ПараметрыИсточника.Вставить("ИдентификаторКоманды", Параметры.ИдентификаторКоманды);
    ПараметрыИсточника.Вставить("ОбъектыНазначения", Параметры.ОбъектыНазначения);

    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("ИсточникДанных", Параметры.ДополнительнаяОбработкаСсылка);
    ПараметрыОткрытия.Вставить("ПараметрыИсточника", ПараметрыИсточника);

    Закрыть; // Раннее закрытие формы может быть проблемой
    ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия, ЭтаФорма, КлючУникальности);
КонецПроцедуры

Основные недостатки этого кода: прямое добавление произвольной структуры в ОбъектыНазначения (которое должно содержать ссылки) и отсутствие асинхронного формирования печатных форм, что является критичным для новых версий БСП.

Стало (новый, рекомендованный подход)

Для того чтобы код работал в актуальных релизах, мы должны перейти к асинхронному формированию печатных форм и использовать стандартные вспомогательные функции БСП. Разберем шаги нового подхода.

  1. Подготовка ПараметровИсточника и ПараметровОткрытия: Мы начинаем с подготовки всех необходимых параметров, включая реквизиты обработки, идентификатор команды и объекты назначения. Важно использовать УправлениеПечатьюСлужебныйКлиент.ПараметрыОткрытияФормыПечати для инициализации структуры ПараметрыОткрытия, так как она возвращает предопределенную структуру со всеми необходимыми полями.
  2. Асинхронное формирование печатных форм: Ключевое изменение — использование УправлениеПечатьюВызовСервера.НачатьФормированиеПечатныхФорм(). Эта функция запускает процесс формирования печатных форм на сервере в фоновом режиме. Она возвращает структуру, которая описывает длительную операцию.
  3. Обработка результата: Вместо прямого ожидания завершения операции (как это было с ДлительныеОперацииКлиент.ОжидатьЗавершение, которое приводило к ошибке ИдентификаторЗадания), мы можем имитировать синхронное получение результата, если процесс формирования не является на самом деле длительной операцией или мы хотим его принудительно завершить. После завершения формирования (или сразу после вызова НачатьФормированиеПечатныхФорм, если печать очень быстрая или серверная функция возвращает уже готовый результат), мы получаем результат из временного хранилища.
  4. Открытие ОбщаяФорма.ПечатьДокументов: Полученные данные, включая коллекцию печатных форм, параметры вывода и офисные документы, корректно передаются в ОткрытьФорму("ОбщаяФорма.ПечатьДокументов"). Особое внимание следует уделить обработке ОфисныеДокументы, если они присутствуют в печатной форме, так как их тоже нужно поместить во временное хранилище.

Вот полный пример адаптированного кода:


&НаКлиенте
Процедура ПечатьКнопка(Команда)
    // 1. Подготовка дополнительных реквизитов обработки
    РеквизитыОбработки = Новый Структура;
    РеквизитыОбработки.Вставить("ОтветЗаПроверку", Объект.ОтветЗаПроверку);
    РеквизитыОбработки.Вставить("НДС", Объект.НДС);

    // Добавление реквизитов в Параметры.ОбъектыНазначения.
    // Если Параметры.ОбъектыНазначения - это Массив, то можно добавить структуру.
    // Если ОбъектыНазначения должны содержать только ссылки, этот шаг может потребовать доработки.
    // В данном примере предполагается, что Параметры.ОбъектыНазначения может содержать и структуры
    // или это делается для того, чтобы эти реквизиты были доступны в серверной процедуре формирования.
    Если ТипЗнч(Параметры.ОбъектыНазначения) = Тип("Массив") И Параметры.ОбъектыНазначения.Количество() > 0 Тогда
        // Заменяем первый элемент, если это объект. Иначе добавляем.
        // Более правильный подход - передавать РеквизитыОбработки отдельным параметром
        // или использовать ПараметрыИсточника для их хранения.
        Если ТипЗнч(Параметры.ОбъектыНазначения[0]) = Тип("Структура") Тогда
            // Если первый элемент уже структура, то дополняем ее
            Для Каждого КлючЗначение Из РеквизитыОбработки Цикл
                Параметры.ОбъектыНазначения[0].Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
            КонецЦикла;
        Иначе
            // Добавляем как первый элемент, если там не структура
            Параметры.ОбъектыНазначения.Вставить(0, РеквизитыОбработки);
        КонецЕсли;
    Иначе
        Параметры.ОбъектыНазначения = Новый Массив();
        Параметры.ОбъектыНазначения.Добавить(РеквизитыОбработки);
    КонецЕсли;
    
    КлючУникальности = Строка (Новый УникальныйИдентификатор);
    СтандартнаяОбработка = Ложь; // Отменяем стандартную обработку, если это обработчик команды

    // 2. Подготовка ПараметровИсточника
    ПараметрыИсточника = Новый Структура;
    ПараметрыИсточника.Вставить("ИдентификаторКоманды", Параметры.ИдентификаторКоманды);
    ПараметрыИсточника.Вставить("ОбъектыНазначения", Параметры.ОбъектыНазначения);

    // 3. Инициализация ПараметровОткрытия с помощью вспомогательной функции БСП
    ПараметрыОткрытия = УправлениеПечатьюСлужебныйКлиент.ПараметрыОткрытияФормыПечати;
    ПараметрыОткрытия.Вставить("ИсточникДанных", Параметры.ДополнительнаяОбработкаСсылка);
    ПараметрыОткрытия.Вставить("ПараметрыИсточника", ПараметрыИсточника);
    ПараметрыОткрытия.Вставить("ПараметрКоманды", Параметры.ОбъектыНазначения); // Дублирование, возможно, избыточно
    ПараметрыОткрытия.УникальныйИдентификаторХранилища = ЭтаФорма.УникальныйИдентификатор;

    // 4. Асинхронное формирование печатных форм на сервере
    // Эта функция запускает фоновое задание или непосредственно формирует формы,
    // если операция не требует длительного выполнения.
    СформированныеПечатныеФормы = УправлениеПечатьюВызовСервера.НачатьФормированиеПечатныхФорм(ПараметрыОткрытия);

    // 5. Имитация результата фоновой операции для немедленной обработки на клиенте.
    // Это обходной путь, если мы не хотим использовать ДлительныеОперацииКлиент.ОжидатьЗавершение,
    // либо если НачатьФормированиеПечатныхФорм уже вернула готовый результат.
    РезультатФоновойОперации = Новый Структура;
    РезультатФоновойОперации.Вставить("Статус", "Выполнено");
    РезультатФоновойОперации.Вставить("КраткоеПредставлениеОшибки", "");
    РезультатФоновойОперации.Вставить("ПодробноеПредставлениеОшибки", "");
    РезультатФоновойОперации.Вставить("Сообщения", Новый ФиксированныйМассив(Новый Массив));
    // Помещаем результат формирования во временное хранилище и получаем его адрес
    РезультатФоновойОперации.Вставить("АдресРезультата", ПоместитьВоВременноеХранилище(СформированныеПечатныеФормы, ПараметрыОткрытия.УникальныйИдентификаторХранилища));

    // Передаем текущую форму как владельца
    ПараметрыОткрытия.ВладелецФормы = ЭтаФорма; // Важно для корректного отображения формы печати

    // 6. Вызов процедуры обработки результата и открытия формы печати
    ВыполнитьКомандуПечатиПослеФормированияПечатныхФорм(РезультатФоновойОперации, ПараметрыОткрытия);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьКомандуПечатиПослеФормированияПечатныхФорм(РезультатФоновойОперации, ПараметрыОткрытия) Экспорт
    Если РезультатФоновойОперации <> Неопределено Тогда
        Если РезультатФоновойОперации.Статус = "Ошибка" Тогда
            ВызватьИсключение РезультатФоновойОперации.КраткоеПредставлениеОшибки;
        КонецЕсли;

        // Получаем детальную структуру результата формирования из временного хранилища
        СтруктураРезультата = ПолучитьИзВременногоХранилища(РезультатФоновойОперации.АдресРезультата);

        // Заполнение параметров открытия формы печати из полученной структуры результата
        // Здесь важно убедиться, что все ожидаемые поля присутствуют в СтруктураРезультата
        ПараметрыОткрытия.Вставить("ОбъектыПечати", СтруктураРезультата.ОбъектыПечати);
        ПараметрыОткрытия.Вставить("ПараметрыВывода", СтруктураРезультата.ПараметрыВывода);
        ПараметрыОткрытия.Вставить("ПараметрыПечати", СтруктураРезультата.ПараметрыПечати); // Новое поле
        
        КоллекцияПечатныхФорм = СтруктураРезультата.КоллекцияПечатныхФорм;
        ОфисныеДокументы = СтруктураРезультата.ОфисныеДокументы;

        // Обработка офисных документов (например, Word, Excel), которые могли быть сформированы.
        // Их также необходимо поместить во временное хранилище для доступа клиентом.
        Для Каждого ПечатнаяФорма Из КоллекцияПечатныхФорм Цикл
            ОфисныеДокументыНовыеАдреса = Новый Соответствие;
            Если ЗначениеЗаполнено(ПечатнаяФорма.ОфисныеДокументы) Тогда
                Для Каждого ОфисныйДокумент Из ПечатнаяФорма.ОфисныеДокументы Цикл
                    // ОфисныеДокументы[ОфисныйДокумент.Ключ] - это сам двоичный файл документа
                    ОфисныеДокументыНовыеАдреса.Вставить(ПоместитьВоВременноеХранилище(ОфисныеДокументы[ОфисныйДокумент.Ключ], ПараметрыОткрытия.УникальныйИдентификаторХранилища), ОфисныйДокумент.Значение);
                КонецЦикла;
                ПечатнаяФорма.ОфисныеДокументы = ОфисныеДокументыНовыеАдреса;
            КонецЕсли;
        КонецЦикла;

        ПараметрыОткрытия.Вставить("КоллекцияПечатныхФорм", КоллекцияПечатныхФорм);
        
        СообщенияЗадания = Новый Массив(РезультатФоновойОперации.Сообщения);
        ОбщегоНазначенияКлиентСервер.ДополнитьМассив(СообщенияЗадания, СтруктураРезультата.Сообщения);
        ПараметрыОткрытия.Вставить("Сообщения", СообщенияЗадания);

        ВладелецФормы = ПараметрыОткрытия.ВладелецФормы;
        ПараметрыОткрытия.Удалить("ВладелецФормы"); // Владелец формы не передается в саму форму, а используется при ее открытии

        // Открытие ОбщаяФорма.ПечатьДокументов
        ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия, ВладелецФормы, Строка(Новый УникальныйИдентификатор));
    КонецЕсли;
    Закрыть(); // Закрываем текущую форму после открытия формы печати
КонецПроцедуры

Дополнительные вызовы и эволюция проблемы в БП 3.0.148.41

Важно отметить, что механизм печати в 1С:Предприятии 3.0 постоянно развивается. Даже если представленное выше решение (из раздела "Стало") работает в БП 3.0.142.56, оно может вызвать новые проблемы в более поздних релизах. Например, после обновления до БП 3.0.148.41 мы можем столкнуться с новой ошибкой:

Поле объекта не обнаружено (ОбъектыПечати)


{ВнешняяОбработка.РеализацияТоваровУслуг_СчетНаОплатуПокупателю_СчетЗаказ.Форма.Форма.Форма(322)}:ПараметрыОткрытия.Вставить("ОбъектыПечати", СтруктураРезультата.ОбъектыПечати);

Эта ошибка говорит о том, что в структуре СтруктураРезультата, полученной из временного хранилища после выполнения НачатьФормированиеПечатныхФорм, больше нет поля ОбъектыПечати. Это означает, что разработчики 1С могли изменить структуру возвращаемых данных или перенести информацию об объектах печати в другое поле или вложенную структуру (например, внутри КоллекцияПечатныхФорм). Для решения этой новой проблемы потребуется дальнейшая адаптация кода, изучение актуальной структуры, возвращаемой функциями БСП, или использование более высокоуровневых общих модулей для печати, которые абстрагируются от внутренних изменений.

Рекомендации по адаптации и отладке

  1. Актуализация Внешних Печатных Форм (ВПФ): Если вы используете ВПФ, всегда убеждайтесь, что они актуализированы и совместимы с текущей версией вашей конфигурации. После каждого серьезного обновления типовой конфигурации рекомендуется проверять и обновлять ВПФ.
  2. Использование Отладчика: При возникновении ошибок типа "Поле объекта не обнаружено" незаменимым инструментом является отладчик. Установите точку останова непосредственно перед строкой, где возникает ошибка, и проанализируйте содержимое объекта (в данном случае СтруктураРезультата). Вы сможете увидеть, какие поля в ней присутствуют и как изменилась её структура.
  3. Изучение документации и БСП: Всегда полезно изучать изменения в БСП и документацию от 1С по работе с механизмами печати. Это позволит быть в курсе последних изменений и применять наиболее актуальные подходы.
  4. Применение стандартных функций БСП: Старайтесь максимально использовать стандартные функции и модули БСП для работы с печатью (УправлениеПечатью, УправлениеПечатьюКлиент, УправлениеПечатьюСлужебныйКлиент, УправлениеПечатьюВызовСервера), так как они будут обновляться вместе с конфигурацией и поддерживать обратную совместимость или предоставлять четкие пути миграции.

Таким образом, проблема вывода печатных форм в обновленных версиях 1С:Бухгалтерии Предприятия 3.0 решается путем адаптации кода к асинхронному механизму формирования и правильной передаче параметров в ОбщаяФорма.ПечатьДокументов, с использованием актуальных функций БСП и постоянным вниманием к изменениям в структуре возвращаемых данных.

← На главную