ПараметрыПолученияАрхиваФайлов.Режим

Свойства · Mode

Тип: РежимПолученияАрхиваФайлов. Определяет, помещать ли все файлы в архив перед получением. Значение по умолчанию: ПолучатьАрхивВсегда.

Полное описание, параметры и ограничения

ПараметрыПолученияАрхиваФайлов.Режим (GetFilesArchiveParameters.Mode)

ПараметрыПолученияАрхиваФайлов (GetFilesArchiveParameters)

Режим (Mode)

Доступен, начиная с версии 8.3.15.

Использование:
Чтение и запись.
Описание:
Тип: РежимПолученияАрхиваФайлов.
Определяет, помещать ли все файлы в архив перед получением.
Значение по умолчанию: ПолучатьАрхивВсегда.
Доступность:

Тонкий клиент, веб-клиент, мобильный клиент, толстый клиент, мобильное приложение (клиент).

Использование в версии:

Доступен, начиная с версии 8.3.15.

Методическая информация

Практические примеры

Выгрузка учебных счетов: один ZIP и два обычных JSON, исходники 2500

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

Где и как запускать

Windows 8.5.1.1343; собственная новая File CF; тонкий клиент Taxi. MAIN управляемой формы: server-create2, client transfer/callback2; серверный общий модуль получает только UUID и фиксированные скалярные источники.

Подготовка

  1. Это будущий самостоятельный ручной опыт, а не выполненная здесь выгрузка. На Windows 8.5.1.1343 создайте новую собственную файловую базу C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\IB. Запускайте только тонким клиентом с интерфейсом Такси, одним своим сеансом. Не используйте рабочую базу, сетевой каталог, расширения, фоновые задания или чужие файлы.

  2. Конфигурация УчебнаяВыгрузкаСчетов85: ОсновнойРежимЗапуска=УправляемоеПриложение, совместимость НеИспользовать, язык Русский. Создайте только форму Счета85, общую команду ВыгрузитьСчета85, подсистему УчебныеСчета85, общий модуль УчебныйАрхивСервер85 и роль УчебнаяПолная85. Документы, справочники, регистры и сервисы здесь не нужны. Никаких исходных данных в базе не записывается.

  3. Создайте одного пользователя УченикАрхива85 с собственной полной ролью, включая Администрирование: ПолучитьПользователей требует именно этих прав. Это ручная подготовка новой базы, не изменение чужих учетных записей или доказательство прав по имени роли.

  4. Вручную создайте только для этого нового стенда папку C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output и три пустые подпапки Always, Raw, Extract. Все каталоги должны быть обычными собственными локальными каталогами без переадресаций/ссылок и других процессов, изменяющих файлы. Не используйте Downloads или Temp. В них не должно быть никаких существующих файлов; код проверит пустоту, но не создаст, не удалит и не перезапишет их.

  5. Общие → Общие формы → Добавить: управляемая форма Счета85. КоличествоИсточников85/Фаза85 — Число 1.0; СуммаИсточников85/РазмерИсточников85 — Число 9.0; Состояние85 — Строка 500; Готово85/Занят85/Остановка85/Завершено85 — Булево. Основного реквизита-объекта, параметров, таблиц и команд формы нет. Перенесите на форму пять полей с именами одноименных реквизитов: количество, сумма, размер, фаза, состояние. ПутьКДанным — одноименный реквизит, ТолькоПросмотр=Истина. Флаги оставьте служебными.

  6. Вставьте полный FORM в Общие → Общие формы → Счета85 → Модуль. В свойствах формы свяжите ПриСозданииНаСервере с одноименной процедурой (Отказ, СтандартнаяОбработка). Переменные источников/параметров/журнала объявлены &НаКлиенте. ПутьКДанным проверяется только сервером формы; клиент не читает вымышленное Значение элемента.

  7. Общие → Общие модули → УчебныйАрхивСервер85: Сервер=Да, Вызов сервера=Да; оба клиентских флага, Внешнее соединение, Глобальный и Привилегированный=Нет, повторное использование возвращаемых значений НеИспользовать. Вставьте COMMON целиком. Он из фиксированных собственных Base64 создает 33/33/34 байта и помещает их во временное хранилище с фактическим UUID формы, а не с новым случайным UUID. Серверу не передаются форма, команда или оповещение.

  8. Общие → Общие команды → Добавить: ВыгрузитьСчета85, без параметра, ИзменяетДанные=Нет, группа Панель действий → Сервис. Вставьте COMMAND целиком; точная предопределенная точка входа ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды), &НаКлиенте. Команда не пишет информационную базу, но ее выполнение означает ваше отдельное явное согласие создать только указанные учебные файлы.

  9. Общие → Подсистемы: УчебныеСчета85, ВключатьВКомандныйИнтерфейс=Да, Подсистема с одной командой=Нет; в Состав включите ВыгрузитьСчета85. В редакторе подсистемы Прочее → Командный интерфейс → Панель действий → Сервис включите общую видимость команды и видимость роли УчебнаяПолная85. В модуль управляемого приложения вставьте APPLICATION целиком.

  10. Обновите только собственную учебную CF и запустите тонким клиентом. Настоящий запуск0 создаст и откроет уникальную форму: 3 источника, сумма 2500, размер 100 байт, фаза 0. Открыть — процедура; отдельно читается Открыта(). Никакие файлы еще не выгружаются. Если вы не согласны создавать учебные результаты, не выполняйте команду.

  11. Проверьте все три пустые папки и выполните свою команду ВыгрузитьСчета85 один раз. Фаза 1 читает defaults конструктора, задает always.zip/ПолучатьАрхивВсегда и передает один A500. Даже один файл при Always должен стать архивом Always\always.zip. После настоящего callback архив читается актуальным ЧтениеФайлаАрхива, проверяется единственная собственная запись и извлекается в свой пустой Extract. Это не средство безопасной обработки чужого ZIP: не подменяйте созданный файл и не запускайте параллельные изменения.

  12. После подтвержденной первой фазы private routine запускает фазу 2: конструктор с именем when-required.zip и режимом ПолучатьАрхивПриНеобходимости, два источника B750/C1250. Именно в тонком клиенте native режим не архивирует: ожидаются Raw\invoice-b.json и Raw\invoice-c.json, никакого when-required.zip. Условия веб-клиента без расширения отличаются; данный урок не запускайте в веб-клиенте.

  13. Callback ПослеПолучения85 имеет два параметра: настоящий массив ОписаниеПереданногоФайла и дополнительные параметры собственного уведомления. Мы записываем реальные Имя/ПолноеИмя, но не угадываем, сколько описаний вернет упаковка и как они сопоставлены ZIP. Итог проверяется независимо по своим заранее отсутствовавшим путям, размеру и полным байтам, а все три серверных источника снова сверяются: 2×250=500, 3×250=750, 5×250=1250, всего 2500 и 100 байт.

  14. Это вариант Без диалога. Native здесь не объявляет Неопределено как отмену: неизвестное завершение не является ни отменой, ни успехом. После ошибки остается STOP и возможный частичный вывод. Не повторяйте запрос, не удаляйте файлы и не обещайте откат. Чтение архива закрывается одной попыткой; при неудачном закрытии сохраняются исходная и дополнительная диагностики, состояние ресурса неизвестно. При отсутствии callback Busy остается незавершенным; расследуйте только свой стенд вручную.

  15. Временное хранилище связано с настоящим UUID формы и живет по native правилам, а не между сеансами. Закрытие формы/сеанса во время выгрузки не является проверенным способом отмены. Для нового опыта нужен новый отдельно подготовленный собственный стенд/пустые каталоги, а не автоматическая очистка или сброс STOP.

  16. Здесь выполнено только авторство и статические проверки исходников. Компиляция 1С, GUI, доставка callback, упаковка, извлечение, файловые чтения/создание и отображение чисел не запускались. Ожидаемый результат — будущая ручная проверка, не заявление об успешном runtime.

&НаКлиенте
Перем Источники85, СнимокИсточников85, ПараметрыАрхива85, ЖурналЗавершений85;

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Отказ = Истина;
    Попытка
        УчебныйАрхивСервер85.ПроверитьСтенд85();
        КоличествоИсточников85 = 3;
        СуммаИсточников85 = 2500;
        РазмерИсточников85 = 100;
        Фаза85 = 0;
        Готово85 = Истина;
        Занят85 = Ложь;
        Остановка85 = Ложь;
        Завершено85 = Ложь;
        Состояние85 = "Готово: по команде будут созданы только собственные учебные файлы";
        ПроверитьСвязи85();
        Отказ = Ложь;
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаСервере
Процедура ПроверитьСвязи85()
    УчебныйАрхивСервер85.ПроверитьСтенд85();
    Имена = Новый Массив;
    Имена.Добавить("КоличествоИсточников85");
    Имена.Добавить("СуммаИсточников85");
    Имена.Добавить("РазмерИсточников85");
    Имена.Добавить("Фаза85");
    Имена.Добавить("Состояние85");
    Для Каждого ИмяПоля Из Имена Цикл
        Поле = ЭтаФорма.Элементы.Найти(ИмяПоля);
        Если Поле = Неопределено Или ТипЗнч(Поле) <> Тип("ПолеФормы") Тогда
            ВызватьИсключение "Не найдены свои readonly поля формы";
        КонецЕсли;
        Если Поле.ПутьКДанным <> ИмяПоля Или Не Поле.ТолькоПросмотр Тогда
            ВызватьИсключение "Неверные связи или редактируемые поля собственных счетов";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьГотовность85() Экспорт
    Если Готово85 <> Истина Или Остановка85 <> Ложь Или Не ЭтаФорма.Открыта()
        Или ЭтаФорма.ВладелецФормы <> Неопределено
        Или КоличествоИсточников85 <> 3 Или СуммаИсточников85 <> 2500 Или РазмерИсточников85 <> 100 Тогда
        ВызватьИсключение "Нужна собственная открытая форма с неизмененным итогом 2500 и 100 байт";
    КонецЕсли;
    ПроверитьСвязи85();
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьПустойКаталог85(Путь)
    Если Путь <> "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Always"
        И Путь <> "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Raw"
        И Путь <> "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Extract" Тогда
        ВызватьИсключение "Разрешены только три собственных каталога учебного UUID-стенда";
    КонецЕсли;
    Каталог = Новый Файл(Путь);
    Если Не Каталог.Существует() Тогда
        ВызватьИсключение "Вручную подготовьте новый собственный пустой каталог";
    КонецЕсли;
    Если Не Каталог.ЭтоКаталог() Или НайтиФайлы(Путь, "*", Ложь).Количество() <> 0 Тогда
        ВызватьИсключение "Каталог должен быть пустым: ничего не перезаписываем и не удаляем";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура НачатьВыгрузку85() Экспорт
    Попытка
        ПроверитьГотовность85();
        Если Занят85 <> Ложь Или Завершено85 <> Ложь Или Фаза85 <> 0
            Или Источники85 <> Неопределено Или СнимокИсточников85 <> Неопределено Тогда
            ВызватьИсключение "Один собственный сеанс допускает только один полный опыт";
        КонецЕсли;
        ПроверитьПустойКаталог85("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Always");
        ПроверитьПустойКаталог85("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Raw");
        ПроверитьПустойКаталог85("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Extract");
        Если ТипЗнч(ЭтаФорма.УникальныйИдентификатор) <> Тип("УникальныйИдентификатор") Тогда
            ВызватьИсключение "Форма должна иметь свой настоящий UUID";
        КонецЕсли;
        Источники85 = УчебныйАрхивСервер85.СоздатьИсточники85(ЭтаФорма.УникальныйИдентификатор);
        СнимокИсточников85 = Источники85;
        ЖурналЗавершений85 = Новый Массив;
        ПроверитьПолныйИсточник85();
        НачатьФазу85(1);
    Исключение
        Остановить85();
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьПолныйИсточник85()
    ПроверитьГотовность85();
    Если ТипЗнч(Источники85) <> Тип("ФиксированныйМассив")
        Или ТипЗнч(СнимокИсточников85) <> Тип("ФиксированныйМассив")
        Или Источники85.Количество() <> 3 Или СнимокИсточников85.Количество() <> 3 Тогда
        ВызватьИсключение "Потерян полный фиксированный источник";
    КонецЕсли;
    Для Номер = 0 По 2 Цикл
        Источник = Источники85[Номер];
        Снимок = СнимокИсточников85[Номер];
        Если ТипЗнч(Источник) <> Тип("ФиксированнаяСтруктура") Или Источник.Количество() <> 7
            Или ТипЗнч(Снимок) <> Тип("ФиксированнаяСтруктура") Или Снимок.Количество() <> 7 Тогда
            ВызватьИсключение "Не совпала структура собственного снимка";
        КонецЕсли;
        Для Каждого ПолеСнимка Из Снимок Цикл
            Если Не Источник.Свойство(ПолеСнимка.Ключ, ЗначениеПоля)
                Или ТипЗнч(ЗначениеПоля) <> ТипЗнч(ПолеСнимка.Значение)
                Или ЗначениеПоля <> ПолеСнимка.Значение Тогда
                ВызватьИсключение "Изменено одно из семи полей источника";
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    УчебныйАрхивСервер85.ПроверитьИсточники85(Источники85);
КонецПроцедуры

&НаКлиенте
Процедура НачатьФазу85(Фаза)
    ПроверитьПолныйИсточник85();
    Если Занят85 <> Ложь Или (Фаза <> 1 И Фаза <> 2) Или Фаза85 <> Фаза - 1 Тогда
        ВызватьИсключение "Нарушена последовательность двух собственных выгрузок";
    КонецЕсли;
    Файлы = Новый Массив;
    Если Фаза = 1 Тогда
        ПараметрыАрхива85 = Новый ПараметрыПолученияАрхиваФайлов();
        Если ТипЗнч(ПараметрыАрхива85) <> Тип("ПараметрыПолученияАрхиваФайлов")
            Или ПараметрыАрхива85.ИмяАрхива <> ""
            Или ПараметрыАрхива85.Режим <> РежимПолученияАрхиваФайлов.ПолучатьАрхивВсегда Тогда
            ВызватьИсключение "Не подтверждены документированные значения конструктора по умолчанию";
        КонецЕсли;
        ПараметрыАрхива85.ИмяАрхива = "always.zip";
        ПараметрыАрхива85.Режим = РежимПолученияАрхиваФайлов.ПолучатьАрхивВсегда;
        КаталогФазы = "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Always";
        Первый = 0;
        Последний = 0;
    Иначе
        ПараметрыАрхива85 = Новый ПараметрыПолученияАрхиваФайлов("when-required.zip", РежимПолученияАрхиваФайлов.ПолучатьАрхивПриНеобходимости);
        Если ТипЗнч(ПараметрыАрхива85) <> Тип("ПараметрыПолученияАрхиваФайлов")
            Или ПараметрыАрхива85.ИмяАрхива <> "when-required.zip"
            Или ПараметрыАрхива85.Режим <> РежимПолученияАрхиваФайлов.ПолучатьАрхивПриНеобходимости Тогда
            ВызватьИсключение "Не подтверждены имя и режим второго конструктора";
        КонецЕсли;
        КаталогФазы = "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Raw";
        Первый = 1;
        Последний = 2;
    КонецЕсли;
    ПроверитьПустойКаталог85(КаталогФазы);
    Для Номер = Первый По Последний Цикл
        Источник = Источники85[Номер];
        ОписаниеФайла = Новый ОписаниеПередаваемогоФайла(Источник.Имя, Источник.Адрес);
        Если ТипЗнч(ОписаниеФайла) <> Тип("ОписаниеПередаваемогоФайла")
            Или ОписаниеФайла.Имя <> Источник.Имя Или ОписаниеФайла.Хранение <> Источник.Адрес Тогда
            ВызватьИсключение "Перепутаны клиентское имя и серверное хранение";
        КонецЕсли;
        Файлы.Добавить(ОписаниеФайла);
    КонецЦикла;
    Если Файлы.Количество() <> Фаза Тогда
        ВызватьИсключение "В первой фазе нужен один JSON, во второй — два";
    КонецЕсли;
    Если Фаза = 1 И (ПараметрыАрхива85.ИмяАрхива <> "always.zip"
        Или ПараметрыАрхива85.Режим <> РежимПолученияАрхиваФайлов.ПолучатьАрхивВсегда) Тогда
        ВызватьИсключение "Изменена явная политика единственного ZIP";
    КонецЕсли;
    Фаза85 = Фаза;
    Занят85 = Истина;
    Состояние85 = "Ожидаем реальное завершение фазы " + Строка(Фаза);
    ДополнительныеПараметры = Новый ФиксированнаяСтруктура("Форма,Фаза", ЭтаФорма.УникальныйИдентификатор, Фаза);
    Оповещение = Новый ОписаниеОповещения("ПослеПолучения85", ЭтаФорма, ДополнительныеПараметры);
    Если ТипЗнч(Оповещение.Модуль) <> Тип("ФормаКлиентскогоПриложения") Или Оповещение.Модуль <> ЭтаФорма Тогда
        ВызватьИсключение "Уведомление должно вернуться в свою управляемую форму";
    КонецЕсли;
    НачатьПолучениеФайловССервера(Оповещение, Файлы, КаталогФазы, ПараметрыАрхива85);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПолучения85(ПолученныеФайлы, ДополнительныеПараметры) Экспорт
    Попытка
        ПроверитьПолныйИсточник85();
        Если Занят85 <> Истина Или (Фаза85 <> 1 И Фаза85 <> 2)
            Или ТипЗнч(ДополнительныеПараметры) <> Тип("ФиксированнаяСтруктура")
            Или ДополнительныеПараметры.Количество() <> 2
            Или Не ДополнительныеПараметры.Свойство("Форма", ИдентификаторФормы)
            Или Не ДополнительныеПараметры.Свойство("Фаза", ЗавершеннаяФаза)
            Или ТипЗнч(ИдентификаторФормы) <> Тип("УникальныйИдентификатор")
            Или ИдентификаторФормы <> ЭтаФорма.УникальныйИдентификатор
            Или ТипЗнч(ЗавершеннаяФаза) <> Тип("Число") Или ЗавершеннаяФаза <> Фаза85 Тогда
            ВызватьИсключение "Неизвестное, повторное или чужое завершение выгрузки";
        КонецЕсли;
        Если ТипЗнч(ПолученныеФайлы) <> Тип("Массив") Тогда
            ВызватьИсключение "Здесь нет диалога: неопределенный результат не объявляем отменой или успехом";
        КонецЕсли;
        Наблюдение = Новый Массив;
        Для Каждого ПереданныйФайл Из ПолученныеФайлы Цикл
            Если ТипЗнч(ПереданныйФайл) <> Тип("ОписаниеПереданногоФайла") Тогда
                ВызватьИсключение "Неизвестное описание фактически полученного файла";
            КонецЕсли;
            Если ТипЗнч(ПереданныйФайл.Имя) <> Тип("Строка") Или ТипЗнч(ПереданныйФайл.ПолноеИмя) <> Тип("Строка") Тогда
                ВызватьИсключение "Ожидаются фактические строковые имена без догадки о соответствии архиву";
            КонецЕсли;
            Наблюдение.Добавить(Новый ФиксированнаяСтруктура("Имя,ПолноеИмя", ПереданныйФайл.Имя, ПереданныйФайл.ПолноеИмя));
        КонецЦикла;
        ЖурналЗавершений85.Добавить(Новый ФиксированнаяСтруктура("Фаза,Описания", Фаза85, Новый ФиксированныйМассив(Наблюдение)));
        Если Фаза85 = 1 Тогда
            ПроверитьАрхив85();
        Иначе
            ПроверитьФайл85("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Raw\invoice-b.json", Источники85[1]);
            ПроверитьФайл85("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Raw\invoice-c.json", Источники85[2]);
            Если НайтиФайлы("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Raw", "*", Ложь).Количество() <> 2 Тогда
                ВызватьИсключение "В тонком клиенте WhenRequired должен дать ровно два обычных JSON, без ZIP";
            КонецЕсли;
        КонецЕсли;
        ПроверитьПолныйИсточник85();
        Занят85 = Ложь;
        Если Фаза85 = 1 Тогда
            НачатьФазу85(2);
        Иначе
            Если ЖурналЗавершений85.Количество() <> 2 Тогда
                ВызватьИсключение "Нужны два настоящих завершения";
            КонецЕсли;
            Завершено85 = Истина;
            Состояние85 = "Проверено: ZIP A500, обычные B750/C1250; три источника 2500/100 байт не изменены";
        КонецЕсли;
    Исключение
        Остановить85();
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьФайл85(Путь, Источник)
    Если Путь <> "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Extract\invoice-a.json"
        И Путь <> "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Raw\invoice-b.json"
        И Путь <> "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Raw\invoice-c.json" Тогда
        ВызватьИсключение "Нельзя читать произвольные файлы";
    КонецЕсли;
    ФайлРезультата = Новый Файл(Путь);
    Если Не ФайлРезультата.Существует() Тогда
        ВызватьИсключение "Нет заранее запланированного собственного результата";
    КонецЕсли;
    Если Не ФайлРезультата.ЭтоФайл() Тогда
        ВызватьИсключение "Ожидался собственный файл, а не каталог";
    КонецЕсли;
    ДанныеФайла = Новый ДвоичныеДанные(Путь);
    Если ДанныеФайла.Размер() <> Источник.Размер
        Или СтрЗаменить(СтрЗаменить(Base64Строка(ДанныеФайла), Символы.ВК, ""), Символы.ПС, "") <> Источник.Base64 Тогда
        ВызватьИсключение "Полные байты результата не совпали со своим исходным JSON";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьАрхив85()
    ПутьАрхива = "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Always\always.zip";
    ФайлАрхива = Новый Файл(ПутьАрхива);
    Если Не ФайлАрхива.Существует() Тогда
        ВызватьИсключение "Собственный ZIP для единственного A500 отсутствует";
    КонецЕсли;
    Если Не ФайлАрхива.ЭтоФайл()
        Или НайтиФайлы("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Always", "*", Ложь).Количество() <> 1 Тогда
        ВызватьИсключение "В своем Always должен находиться только созданный always.zip";
    КонецЕсли;
    ПроверитьПустойКаталог85("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Extract");
    ЧтениеАрхива = Неопределено;
    ЗакрытиеНачато = Ложь;
    Попытка
        ЧтениеАрхива = Новый ЧтениеФайлаАрхива(ПутьАрхива);
        Если ТипЗнч(ЧтениеАрхива) <> Тип("ЧтениеФайлаАрхива") Тогда
            ВызватьИсключение "Не получен собственный актуальный reader";
        КонецЕсли;
        ЭлементыАрхива = ЧтениеАрхива.Элементы;
        Если ТипЗнч(ЭлементыАрхива) <> Тип("ЭлементыФайлаАрхива") Или ЭлементыАрхива.Количество() <> 1 Тогда
            ВызватьИсключение "Собственный архив должен содержать один исходный счет";
        КонецЕсли;
        Для Каждого ЭлементАрхива Из ЭлементыАрхива Цикл
            Если ТипЗнч(ЭлементАрхива) <> Тип("ЭлементФайлаАрхива")
                Или ЭлементАрхива.ИсходноеИмя <> "invoice-a.json"
                Или ЭлементАрхива.РазмерНесжатого <> 33 Или ЭлементАрхива.Зашифрован Тогда
                ВызватьИсключение "Архив не соответствует собственному A500: извлечение запрещено";
            КонецЕсли;
            ЧтениеАрхива.Извлечь(ЭлементАрхива, "C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Extract");
        КонецЦикла;
        ЗакрытиеНачато = Истина;
        ЧтениеАрхива.Закрыть();
    Исключение
        ИсходнаяОшибка = ОписаниеОшибки();
        ОшибкаЗакрытия = "";
        Если ЧтениеАрхива <> Неопределено И Не ЗакрытиеНачато Тогда
            ЗакрытиеНачато = Истина;
            Попытка
                ЧтениеАрхива.Закрыть();
            Исключение
                ОшибкаЗакрытия = ОписаниеОшибки();
            КонецПопытки;
        КонецЕсли;
        ВызватьИсключение "Ошибка проверки собственного архива: " + ИсходнаяОшибка + "; дополнительная ошибка закрытия: " + ОшибкаЗакрытия;
    КонецПопытки;
    ПроверитьФайл85("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Extract\invoice-a.json", Источники85[0]);
    Если НайтиФайлы("C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\Output\Extract", "*", Ложь).Количество() <> 1 Тогда
        ВызватьИсключение "Не подтвержден единственный собственный извлеченный JSON";
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура Остановить85()
    Остановка85 = Истина;
    Состояние85 = "СТОП: результат может быть частичным; не повторять, не удалять и не подтверждать успех";
КонецПроцедуры
Полный серверный модуль: собственные JSON и повторное чтение всех исходных байтов

Своя CF → Общие → Общие модули → УчебныйАрхивСервер85 → Модуль целиком

Сервер/Вызов сервераДа; оба клиентских флагаНет, без привилегий/повторного использования. Производит собственные literal payload и native временное хранилище своей формы; DB-записей нет.

Процедура ПроверитьСтенд85() Экспорт
    Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnArchiveInvoiceExport5_661b6cb7-dd72-47ce-a19e-f0d347714047\IB"";" Или Метаданные.ОсновнойРежимЗапуска <> РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Или Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда
        ВызватьИсключение "Откройте только новую собственную файловую учебную базу 8.5.1.1343";
    КонецЕсли;
    Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если Пользователь = Неопределено Или ПользователиИнформационнойБазы.ПолучитьПользователей().Количество() <> 1 Тогда
        ВызватьИсключение "Нужен один собственный пользователь с административными правами учебной базы";
    КонецЕсли;
    Если Пользователь.Имя <> "УченикАрхива85" Тогда
        ВызватьИсключение "Это не пользователь собственного учебного стенда";
    КонецЕсли;
КонецПроцедуры

Функция План85() Экспорт
    ПроверитьСтенд85();
    План = Новый Массив;
    План.Добавить(Новый ФиксированнаяСтруктура("Имя,Количество,Цена,Сумма,Размер,Base64", "invoice-a.json", 2, 250, 500, 33, "eyJxdHkiOjIsInByaWNlIjoyNTAsInRvdGFsIjo1MDB9"));
    План.Добавить(Новый ФиксированнаяСтруктура("Имя,Количество,Цена,Сумма,Размер,Base64", "invoice-b.json", 3, 250, 750, 33, "eyJxdHkiOjMsInByaWNlIjoyNTAsInRvdGFsIjo3NTB9"));
    План.Добавить(Новый ФиксированнаяСтруктура("Имя,Количество,Цена,Сумма,Размер,Base64", "invoice-c.json", 5, 250, 1250, 34, "eyJxdHkiOjUsInByaWNlIjoyNTAsInRvdGFsIjoxMjUwfQ=="));
    Возврат Новый ФиксированныйМассив(План);
КонецФункции

Функция СоздатьИсточники85(ИдентификаторФормы) Экспорт
    ПроверитьСтенд85();
    Если ТипЗнч(ИдентификаторФормы) <> Тип("УникальныйИдентификатор") Тогда
        ВызватьИсключение "Нужен фактический UUID уже созданной собственной формы";
    КонецЕсли;
    Источники = Новый Массив;
    Для Каждого ПланСчета Из План85() Цикл
        Данные = Base64Значение(ПланСчета.Base64);
        Если ТипЗнч(Данные) <> Тип("ДвоичныеДанные") Или Данные.Размер() <> ПланСчета.Размер Тогда
            ВызватьИсключение "Не подтвержден собственный двоичный JSON";
        КонецЕсли;
        Адрес = ПоместитьВоВременноеХранилище(Данные, ИдентификаторФормы);
        Если ТипЗнч(Адрес) <> Тип("Строка") Или Адрес = "" Или Не ЭтоАдресВременногоХранилища(Адрес) Тогда
            ВызватьИсключение "Не получен реальный адрес временного хранилища";
        КонецЕсли;
        Источники.Добавить(Новый ФиксированнаяСтруктура("Имя,Количество,Цена,Сумма,Размер,Base64,Адрес", ПланСчета.Имя, ПланСчета.Количество, ПланСчета.Цена, ПланСчета.Сумма, ПланСчета.Размер, ПланСчета.Base64, Адрес));
    КонецЦикла;
    Результат = Новый ФиксированныйМассив(Источники);
    ПроверитьИсточники85(Результат);
    Возврат Результат;
КонецФункции

Процедура ПроверитьИсточники85(Источники) Экспорт
    ПроверитьСтенд85();
    Если ТипЗнч(Источники) <> Тип("ФиксированныйМассив") Или Источники.Количество() <> 3 Тогда
        ВызватьИсключение "Нужны все три собственных источника";
    КонецЕсли;
    План = План85();
    Номер = 0;
    Итого = 0;
    Байт = 0;
    Для Каждого Источник Из Источники Цикл
        Если ТипЗнч(Источник) <> Тип("ФиксированнаяСтруктура") Или Источник.Количество() <> 7 Тогда
            ВызватьИсключение "Нужны семь неизменяемых полей каждого исходного счета";
        КонецЕсли;
        Для Каждого ПолеПлана Из План[Номер] Цикл
            Если Не Источник.Свойство(ПолеПлана.Ключ, ЗначениеПоля)
                Или ТипЗнч(ЗначениеПоля) <> ТипЗнч(ПолеПлана.Значение)
                Или ЗначениеПоля <> ПолеПлана.Значение Тогда
                ВызватьИсключение "Изменен полный собственный источник";
            КонецЕсли;
        КонецЦикла;
        Если Не Источник.Свойство("Адрес", Адрес) Или ТипЗнч(Адрес) <> Тип("Строка")
            Или Адрес = "" Или Не ЭтоАдресВременногоХранилища(Адрес) Тогда
            ВызватьИсключение "Неверный адрес исходного JSON";
        КонецЕсли;
        Данные = ПолучитьИзВременногоХранилища(Адрес);
        Если ТипЗнч(Данные) <> Тип("ДвоичныеДанные") Или Данные.Размер() <> Источник.Размер
            Или СтрЗаменить(СтрЗаменить(Base64Строка(Данные), Символы.ВК, ""), Символы.ПС, "") <> Источник.Base64
            Или Источник.Сумма <> Источник.Количество * Источник.Цена Тогда
            ВызватьИсключение "Изменены байты, размер или независимый расчет исходного счета";
        КонецЕсли;
        Итого = Итого + Источник.Сумма;
        Байт = Байт + Данные.Размер();
        Номер = Номер + 1;
    КонецЦикла;
    Если Итого <> 2500 Или Байт <> 100 Или Номер <> 3 Тогда
        ВызватьИсключение "Все исходники должны оставаться 2500 и 100 байт";
    КонецЕсли;
КонецПроцедуры
Полный модуль приложения: открытие собственной формы без автоматической выгрузки

Своя CF → Модуль управляемого приложения целиком

Тонкий клиент Windows; настоящий запуск0 и собственный клиентский reference формы. Открытие не запускает файловый опыт.

Перем СвояФормаАрхива85, ГотовоПриложение85, ОстановкаПриложение85;

Процедура ПриНачалеРаботыСистемы()
    #Если Не ТонкийКлиент Тогда
        ВызватьИсключение "Учебный опыт разрешен только в тонком клиенте Windows";
    #КонецЕсли
    Если ГотовоПриложение85 <> Неопределено Или ОстановкаПриложение85 <> Неопределено Тогда
        ВызватьИсключение "Повторный запуск не сбрасывает состояние STOP";
    КонецЕсли;
    ГотовоПриложение85 = Ложь;
    ОстановкаПриложение85 = Ложь;
    Попытка
        УчебныйАрхивСервер85.ПроверитьСтенд85();
        Кандидат = ПолучитьФорму("ОбщаяФорма.Счета85", , , Истина);
        Если Кандидат = Неопределено Или ТипЗнч(Кандидат) <> Тип("ФормаКлиентскогоПриложения") Тогда
            ВызватьИсключение "Не создана собственная управляемая форма";
        КонецЕсли;
        Если Кандидат.ВладелецФормы <> Неопределено Или Кандидат.Открыта() Тогда
            ВызватьИсключение "Нужна новая самостоятельная форма";
        КонецЕсли;
        Кандидат.Открыть();
        Если Не Кандидат.Открыта() Тогда
            ВызватьИсключение "Открытие своей формы не подтверждено";
        КонецЕсли;
        Кандидат.ПроверитьГотовность85();
        СвояФормаАрхива85 = Кандидат;
        ГотовоПриложение85 = Истина;
    Исключение
        ОстановкаПриложение85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры

Функция ПолучитьСвоюФормуАрхива85() Экспорт
    Если ГотовоПриложение85 <> Истина Или ОстановкаПриложение85 <> Ложь
        Или ТипЗнч(СвояФормаАрхива85) <> Тип("ФормаКлиентскогоПриложения") Тогда
        ВызватьИсключение "Собственная форма не готова или приложение остановлено";
    КонецЕсли;
    Если Не СвояФормаАрхива85.Открыта() Или СвояФормаАрхива85.ВладелецФормы <> Неопределено Тогда
        ОстановкаПриложение85 = Истина;
        ВызватьИсключение "Своя форма закрыта или изменен владелец";
    КонецЕсли;
    Возврат СвояФормаАрхива85;
КонецФункции
Полный модуль своей общей команды: отдельное согласие начать учебную выгрузку

Своя CF → Общие → Общие команды → ВыгрузитьСчета85 → Модуль целиком

Тонкий клиент, настоящая ОбработкаКоманды2. Вызов экспортного старта своей формы; callback руками не вызывается.

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

Разбор по шагам

  1. Подготовьте новую собственную файловую CF, тонкий клиент, форму, общую команду и три пустые папки.

  2. Настоящий запуск открывает readonly форму; только ваше отдельное выполнение команды начинает файловый опыт.

  3. Первый конструктор и Always упаковывают один JSON A500; реальный callback подтверждает результат, reader проверяет/извлекает его.

  4. Второй конструктор и WhenRequired в тонком клиенте возвращают B750/C1250 обычными файлами; число файлов не превращает режим в Always.

  5. Сравните полные байты собственных результатов и все семь полей каждого неизменяемого источника; одна ошибка оставляет STOP без повторов и удаления.

Как проверить результат

  1. Исходники: три ASCII UTF-8 JSON без BOM, 33+33+34=100 байт; суммы 500+750+1250=2500.

  2. Always\always.zip содержит только invoice-a.json; Extract\invoice-a.json совпадает полными байтами с A500.

  3. Raw содержит ровно invoice-b.json и invoice-c.json, совпадающие с B750/C1250, без when-required.zip.

  4. Все три исходных серверных payload и адреса неизменны до/после; GUI/компиляция/доставка файлов проверяются вами вручную только в своем стенде.

Ожидаемый результат

Один последовательный опыт показывает реальное различие режимов получения файлов и не принимает непроверенный частичный результат за успех.

На что обратить внимание

  1. ПолучатьАрхивПриНеобходимости архивирует только веб-клиент без расширения работы с файлами; в тонком клиенте здесь два обычных JSON.

  2. ИмяАрхива/Режим изменяемы, UUID формы/поля переданных описаний/содержимое архива только читаются. Нет ручного конструктора для callback результата.

  3. Контракт callback не доказывает соответствие описаний архивному файлу. Не проверяем догадку о количестве/именах массива; отдельно читаем собственные известные результаты.

  4. Find/Get коллекции архива имеют противоречивые 0-аргументные прототипы: они не используются и не засчитываются. Обход — настоящий foreach/Количество.

  5. Извлекается только созданный этим опытом собственный архив при отсутствии других изменяющих его процессов. Проверка одного ИсходноеИмя не делает урок защитой от произвольного чужого архива.

  6. Неизвестное завершение, отсутствие callback, исключение, изменение источника или закрытие ресурса не дают гарантии отката/атомарности/отсутствия частичных файлов. STOP остается, автоматического удаления нет.

  7. События запуска0, создания формы2, команды2 и завершения2 доставляет платформа. Самодельных вызовов этих событий, реальных файловых операций или runtime-доказательств здесь нет.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.