НачатьОткрытие, НачатьПолучениеВложений и НачатьЗакрытие соединены полноценными экспортными обработчиками. Свой поток живёт до подтверждения закрытия.
Где и как запускать
Полный модуль собственной управляемой формы внешней обработки, толстый клиент Windows 8.5.1.1343.
Подготовка
Создайте отдельную собственную конфигурацию УчебнаяКонфигурацияСинтаксиса и внешнюю обработку с управляемой формой. Команда Выполнить связана с процедурой Выполнить, кнопка вызывает эту команду.
Вставьте полный модуль одного урока на уровне модуля формы, не внутрь существующего обработчика. Серверная функция создаёт собственную таблицу Книга / 3 / 250 / 750 и возвращает настоящие PDF-байты.
Используйте толстый клиент Windows платформы 8.5.1.1343. Серверу необходима возможность экспортировать табличный документ в PDF. Веб-клиент и его расширения этим уроком не проверяются.
Окна имеют префикс guide-owned; закрывайте вручную только эти окна. Показать передаётся пустое имя файла, поэтому рабочий файл для автосохранения не назначается.
Во время асинхронной операции не закрывайте форму и не запускайте второй экземпляр операции. Ждать означает ожидание завершения обещания, а не получение готового документа без ожидания.
Только урок печати требует строковый реквизит формы Подтверждение. Печать разрешается отдельной фразой и обязательным диалогом, в котором пользователь сам выбирает собственное тестовое устройство или отменяет.
При подготовке пособия эти окна и печать в 1С не запускались: проверки структуры не являются доказательством внешнего вида или физического вывода.
Перем Занято;
Перем СобственноеСостояние;
&НаСервереБезКонтекста
Функция СоздатьСобственныеБайтыPDF()
Таблица = Новый ТабличныйДокумент;
Таблица.КодЯзыка = "ru";
Таблица.Область(1, 1).Текст = "СОБСТВЕННЫЙ УЧЕБНЫЙ ОБРАЗЕЦ";
Таблица.Область(2, 1).Текст = "Книга";
Таблица.Область(2, 2).Текст = "3";
Таблица.Область(2, 3).Текст = "250";
Таблица.Область(2, 4).Текст = "750";
Таблица.Область(1, 1, 2, 4).ЦветФона = Новый Цвет(255, 255, 210);
Таблица.Область(, 1, , 1).ШиринаКолонки = 45;
Поток = Новый ПотокВПамяти;
Попытка
Таблица.Записать(Поток, ТипФайлаТабличногоДокумента.PDF);
Данные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
Исключение
Поток.Закрыть();
ВызватьИсключение;
КонецПопытки;
Возврат Данные;
КонецФункции
&НаКлиенте
Функция ОповещениеPDF(Имя, Состояние)
Возврат Новый ОписаниеОповещения(Имя, ЭтотОбъект, Состояние, "ОшибкаPDF", ЭтотОбъект);
КонецФункции
&НаКлиенте
Процедура Выполнить(Команда)
Если Занято = Истина Тогда
ВызватьИсключение "Собственная цепочка уже запущена";
КонецЕсли;
Данные = СоздатьСобственныеБайтыPDF();
Состояние = Новый Структура("Маркер,Поток,Чтение", "guide-owned-reader", Данные.ОткрытьПотокДляЧтения(), Новый ЧтениеPDF);
СобственноеСостояние = Состояние;
Занято = Истина;
Попытка
Состояние.Чтение.НачатьОткрытие(ОповещениеPDF("ПослеОткрытияPDF", Состояние), Состояние.Поток);
Исключение
Сообщить("Запуск не подтверждён: " + ОписаниеОшибки());
Сообщить("Не повторяйте запуск: закройте только собственную учебную форму");
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПослеОткрытияPDF(Состояние) Экспорт
Если Состояние <> СобственноеСостояние Или Состояние.Маркер <> "guide-owned-reader" Тогда
ВызватьИсключение "Неизвестное состояние читателя";
КонецЕсли;
Попытка
Состояние.Чтение.НачатьПолучениеВложений(ОповещениеPDF("ПослеВложенийPDF", Состояние));
Исключение
Сообщить("Следующий шаг не подтверждён: " + ОписаниеОшибки());
Сообщить("Не повторяйте запуск: закройте только собственную учебную форму");
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПослеВложенийPDF(Вложения, Состояние) Экспорт
Если Состояние <> СобственноеСостояние Или Состояние.Маркер <> "guide-owned-reader" Тогда
ВызватьИсключение "Неизвестное состояние читателя";
КонецЕсли;
Сообщить(ТипЗнч(Вложения) = Тип("КоллекцияВложенийPDF"));
Сообщить(Вложения.Количество() = 0);
Попытка
Состояние.Чтение.НачатьЗакрытие(ОповещениеPDF("ПослеЗакрытияPDF", Состояние));
Исключение
Сообщить("Закрытие не подтверждено: " + ОписаниеОшибки());
Сообщить("Не повторяйте запуск: закройте только собственную учебную форму");
КонецПопытки;
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗакрытияPDF(Состояние) Экспорт
Если Состояние <> СобственноеСостояние Или Состояние.Маркер <> "guide-owned-reader" Тогда
ВызватьИсключение "Неизвестное состояние читателя";
КонецЕсли;
Состояние.Поток.Закрыть();
СобственноеСостояние = Неопределено;
Занято = Ложь;
Сообщить("Собственная цепочка PDF завершена и поток закрыт");
КонецПроцедуры
&НаКлиенте
Процедура ОшибкаPDF(ИнформацияОбОшибке, Состояние, СтандартнаяОбработка) Экспорт
Если Состояние <> СобственноеСостояние Или Состояние.Маркер <> "guide-owned-reader" Тогда
ВызватьИсключение "Неизвестное состояние ошибки";
КонецЕсли;
СтандартнаяОбработка = Ложь;
Сообщить("Ошибка собственного PDF: " + ИнформацияОбОшибке.Описание);
Попытка
Состояние.Чтение.Закрыть();
Состояние.Поток.Закрыть();
Исключение
Сообщить("Освобождение не подтверждено: " + ОписаниеОшибки());
Сообщить("Не повторяйте запуск: закройте только собственную учебную форму");
Возврат;
КонецПопытки;
СобственноеСостояние = Неопределено;
Занято = Ложь;
КонецПроцедурыРазбор по шагам
Создать собственный поток и читатель. Сохранить состояние в переменной формы, запретить повторный запуск.
Открытие завершает обработчик с одним аргументом Состояние. Только после него запускается получение вложений.
Получение передаёт два аргумента: Вложения и Состояние. Следующим шагом запросить закрытие читателя.
Закрытие передаёт только Состояние. После подтверждения закрыть свой поток и снять занятость.
Обработчик ошибки имеет три аргумента. Ошибка начала следующего шага или освобождения оставляет защиту от повторного запуска: пользователь закрывает только учебную форму.
Как проверить результат
Две проверки в ПослеВложенийPDF дают Истина, затем появляется сообщение о завершении цепочки и закрытии собственного потока.
До последнего callback повторный запуск запрещён. При неподтверждённом начале/закрытии успех не объявляется и флаг занятости не снимается.
Ожидаемый результат
Полный callback-модуль без выдуманного параметра Результат у открытия и закрытия.
На что обратить внимание
Не закрывайте поток сразу после НачатьОткрытие: операция ещё может работать. Не вызывайте все три Начать подряд без ожидания callback.
Если начало шага выбросило исключение, код не предполагает, что асинхронная операция точно не началась: состояние сохраняется, повтор запрещается.
Не закрывайте рабочие окна, формы или чужие потоки при учебной ошибке.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.