ВнешниеОбработкиМенеджер

Типы · ExternalDataProcessorsManager

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

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

ВнешниеОбработкиМенеджер (ExternalDataProcessorsManager)

ВнешниеОбработкиМенеджер (ExternalDataProcessorsManager)

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

Методы:
Подключить (Connect)
ПолучитьФорму (GetForm)
Создать (Create)

Описание:

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

Доступность:

Сервер, толстый клиент, внешнее соединение.

См. также:
Глобальный контекст, свойство ВнешниеОбработки

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

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

Описание изменено в версии 8.3.22.

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

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

Своя EPF упаковок: compiled числовой макет, native проверка и реальный вывод88 →50

Из собственной вручную изготовленной и заранее одобренной EPF загружается один реальный instance, его native обычная форма меняет три количества, а native compiled4x4 макет выводит настоящий табличный документ. Проверяется Value всех9 числовых ячеек, не текстовая имитация. Здесь изготовлены только исходники и static tests; EPF и 1С не запускались.

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

Полный модуль ordinary формы собственной CF обработки ЗагрузчикУпаковок85, только thick ordinary8.5.1.1343 и exact own Base/один пользователь. Actual EPF authored/manually compiled только владельцем по указанной подготовке; никаких native операций автором.

Подготовка

  1. НИЧЕГО не выполняйте в production. Вручную подготовьте новый свой UUID-каталог C:\1C85_OwnEPFPackLab\5a4ff5ad-54e2-4aa6-aed5-fadf742c9aa5, свою новую пустую файловую Base внутри и CF УчебныеУпаковкиEPF85 только platform8.5.1.1343. Если каталог уже занят чужими/непонятными данными, не удаляйте и не переиспользуйте: подготовьте новый marker и согласованно исправьте все пути. CF основное приложение Обычное; бизнес-объектов, extension, подписок и фоновых/регламентных задач нет.

  2. В этой новой пустой CF вручную подготовьте ровно одного пользователя Упаковки85Ученик с собственной ролью, разрешающей учебное ordinary приложение, открытие своей обработки, чтение списка пользователей/metadata и разрешённую ручную загрузку своей EPF. Никаких прав из production не переносите. Запускайте Base через единственный File="C:\1C85_OwnEPFPackLab\5a4ff5ad-54e2-4aa6-aed5-fadf742c9aa5\Base"; без других connection частей; имя пользователя выбирается обычной собственной формой входа.

  3. Добавьте в CF ровно одну обработку ЗагрузчикУпаковок85, обычную ОсновнаяФорма. Реквизиты формы ОдобренныйSHA25685 Строка64 и Состояние85 Строка неограниченная; Состояние85 только просмотр. Кнопка ЗагрузитьТолькоСвоюEPF85 назначается одноимённому обработчику(Кнопка); main code целиком в модуль формы, ПриОткрытии() native событие. Supporting application code целиком в Модуль обычного приложения CF. BeforeStart только guard/Отказ, OnStart уже может открыть собственную loader форму.

  4. В Конфигураторе данной своей платформы: Файл → Новый → Внешняя обработка, Имя=МоиУпаковки85. Это НОВЫЙ собственный файл, не скачанная обработка. Ровно4 object реквизита: НазваниеОпыт85 Строка40, ПроверкаЗаполнения=ПоказыватьОшибку; КоличествоА85/КоличествоБ85/КоличествоВ85 Число(9,0), ДопустимыйЗнак=Любой, ПроверкаЗаполнения=НеПроверять, поскольку0 упаковок допустим. Object code ниже целиком в Модуль объекта; native callback ОбработкаПроверкиЗаполнения(Отказ,ПроверяемыеРеквизиты) не вызывайте самостоятельно.

  5. В этой EPF добавьте ровно одну обычную форму ОсновнаяФорма и назначьте основной. Через генератор формы выберите именно object реквизиты НазваниеОпыт85/КоличествоА85/КоличествоБ85/КоличествоВ85, не создавайте их одноимённые несвязанные form копии. Дополнительные form реквизиты Документ85 ТабличныйДокумент, Итог85 Число(12,0), Состояние85 Строка неограниченная; последние3 только просмотр. Поле табличного документа связано с Документ85. ВосстанавливатьЗначенияПриОткрытии=Нет, чтобы cached значения не заменили подготовленные3/2/4. Кнопка Пересчитать85 native действие(Кнопка); ordinary form supporting code целиком в модуль формы, ПриОткрытии() событие.

  6. Добавьте в EPF единственный макет РасчетУпаковок85 типа ТабличныйДокумент. Точная неперекрытая сетка4 строки ×4 колонки, без слияний/данных/форматирования внеR1C1:R4C4. Row1 текстовые заголовки Упаковка | Количество | ШтукВУпаковке | ВсегоШтук. R2C1 текст А85, R3C1 Б85, R4C1 В85. Все9 cells rows2–4 cols2–4 ДО сохранения/компиляции: СодержитЗначение=Да; ТипЗначения=Число(12,0); Заполнение=Параметр. В R2C2/C3/C4 Параметр соответственно КоличествоА/ШтукА/ВсегоА; R3 КоличествоБ/ШтукБ/ВсегоБ; R4 КоличествоВ/ШтукВ/ВсегоВ. В numeric свойство Значение cells R2C3/R3C3/R4C3 сохраните именно Число12/6/10, не Текст строки12/6/10; прочие numeric cells Значение0. Формат числа ЧГ=0;ЧДЦ=0 только для показа, он не создаёт numeric Value.

  7. Проверьте source ВСЕХ модулей этой своей EPF и CF, metadata и4x4 numeric cell свойства сами до загрузки. В Конфигураторе сохраните/скомпилируйте только свою EPF по C:\1C85_OwnEPFPackLab\5a4ff5ad-54e2-4aa6-aed5-fadf742c9aa5\МоиУпаковки85.epf. Вручную локальным способом получите SHA256 именно уже одобренной compilation и закрепите отдельно; его введите в loader ОдобренныйSHA25685. Не вычисляйте доверие копированием hash произвольной чужой EPF. Автор НЕ компилировал EPF, не запускал native файлы/hashing/1С/UI или изменял настройки.

  8. У approved artifact folder должен быть только собственный заранее разрешённый писатель, во время загрузки никто файл не меняет; не открывайте этот путь из shared/download folders. Hash beforeCreate обнаруживает отличие от закреплённой версии, но не является подписью и НЕ устраняет TOCTOU между Hash/Create. Если исключить другого писателя нельзя, exercise остановлен до исполнения внешнего кода. Ничего не снимайте в защите от опасных действий; SafeMode=True явно, третий protection параметр не передаётся и default не ослабляется.

#Если ТолстыйКлиентОбычноеПриложение Тогда

Перем МойЭкземпляр85, МояФорма85;

Процедура ПриОткрытии()
    ПроверитьСвойПустойСтенд();
    ПроверитьСвойПутьИПользователя85();
    МойЭкземпляр85 = Неопределено;
    МояФорма85 = Неопределено;
    ОдобренныйSHA25685 = "";
    Состояние85 = "Сначала вручную изготовьте и проверьте только свою EPF, затем введите SHA256 именно одобренной сборки. Имя файла/metadata после Create не доказывают доверие.";
КонецПроцедуры

Процедура ЗагрузитьТолькоСвоюEPF85(Кнопка)
    ПроверитьСвойПустойСтенд();
    ПроверитьСвойПутьИПользователя85();
    Если МойЭкземпляр85 <> Неопределено Или МояФорма85 <> Неопределено Тогда
        ВызватьИсключение "Один собственный instance на одну форму загрузчика; повторная загрузка не выполняется";
    КонецЕсли;
    Путь = "C:\1C85_OwnEPFPackLab\5a4ff5ad-54e2-4aa6-aed5-fadf742c9aa5\МоиУпаковки85.epf";
    Файл = Новый Файл(Путь);
    Если НРег(Файл.ПолноеИмя) <> НРег(Путь) Или Не Файл.Существует() Или Не Файл.ЭтоФайл() Тогда
        ВызватьИсключение "Должна существовать только своя заранее одобренная compiled EPF в exact UUID-root";
    КонецЕсли;
    Если Файл.Размер() <= 0 Или Файл.Размер() > 16777216 Тогда
        ВызватьИсключение "Допускается только своя небольшая непустая учебная EPF до16MiB";
    КонецЕсли;
    Ожидание = НРег(СокрЛП(ОдобренныйSHA25685));
    Если СтрДлина(Ожидание) <> 64 Тогда
        ВызватьИсключение "Нужен вручную закреплённый SHA256 одобренной собственной compilation, не hash случайного скачанного файла";
    КонецЕсли;
    Для Индекс = 1 По 64 Цикл
        Если СтрНайти("0123456789abcdef", Сред(Ожидание, Индекс, 1)) = 0 Тогда
            ВызватьИсключение "SHA256 должен состоять из64hex символов";
        КонецЕсли;
    КонецЦикла;
    Хеш = Новый ХешированиеДанных(ХешФункция.SHA256);
    Хеш.ДобавитьФайл(Путь);
    Если НРег(ПолучитьHexСтрокуИзДвоичныхДанных(Хеш.ХешСумма)) <> Ожидание Тогда
        ВызватьИсключение "Own EPF отличается от заранее одобренной сборки; до Create остановлено";
    КонецЕсли;
    МойМенеджер = ВнешниеОбработки;
    МойЭкземпляр85 = МойМенеджер.Создать(Путь, Истина);
    Описание = МойЭкземпляр85.Метаданные();
    Если Описание.Имя <> "МоиУпаковки85" Или Описание.Реквизиты.Количество() <> 4
        Или Описание.Формы.Количество() <> 1 Или Описание.Макеты.Количество() <> 1 Тогда
        ВызватьИсключение "После Create metadata не соответствует собственному упражнению; это диагностика, а не доказательство доверия к уже загруженному коду";
    КонецЕсли;
    Если НРег(МойЭкземпляр85.ИспользуемоеИмяФайла) <> НРег(Путь) Тогда
        ВызватьИсключение "Native UsedFileName не совпал с ожидаемым own artifact; не продолжаем упражнение";
    КонецЕсли;
    Макет = МойЭкземпляр85.ПолучитьМакет("РасчетУпаковок85");
    Если ТипЗнч(Макет) <> Тип("ТабличныйДокумент") Или Макет.ВысотаТаблицы <> 4 Или Макет.ШиринаТаблицы <> 4 Тогда
        ВызватьИсключение "Нужен настоящий compiled табличный макет4x4, не runtime подмена";
    КонецЕсли;
    МойЭкземпляр85.НазваниеОпыт85 = "Мой опыт упаковок85";
    МойЭкземпляр85.КоличествоА85 = 3;
    МойЭкземпляр85.КоличествоБ85 = 2;
    МойЭкземпляр85.КоличествоВ85 = 4;
    Если Не МойЭкземпляр85.ПроверитьЗаполнение() Тогда
        ВызватьИсключение "Native CheckFilling возвратил Ложь; own форма не открывается с неподготовленными данными";
    КонецЕсли;
    МояФорма85 = МойЭкземпляр85.ПолучитьФорму("ОсновнаяФорма", ЭтаФорма, "OwnPackForm_5a4ff5ad");
    Если МояФорма85 = Неопределено Тогда
        ВызватьИсключение "Native own instance форму не создал";
    КонецЕсли;
    МояФорма85.ПринятьСвойЭкземпляр85(МойЭкземпляр85);
    МояФорма85.Открыть();
    Состояние85 = "Открыта форма конкретного собственного instance в safeMode=True с default protection. Metadata и filename проверены только как принадлежность упражнению; начальный вывод должен получить настоящий числовой итог88.";
КонецПроцедуры

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвойПутьИПользователя85()
    Если ИмяПользователя() <> "Упаковки85Ученик" Тогда
        ВызватьИсключение "Только свой единственный учебный пользователь";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Если ТипЗнч(Пользователи) <> Тип("Массив") Или Пользователи.Количество() <> 1 Тогда
        ВызватьИсключение "Нужна своя CF ровно с одним вручную подготовленным пользователем";
    КонецЕсли;
    Если Пользователи[0].Имя <> "Упаковки85Ученик" Или Метаданные.Обработки.Количество() <> 1
        Или Метаданные.Обработки.Найти("ЗагрузчикУпаковок85") = Неопределено Тогда
        ВызватьИсключение "В CF должна быть только своя учебная обработка-загрузчик";
    КонецЕсли;
    Части = СтрРазделить(СтрокаСоединенияИнформационнойБазы(), ";");
    Если Части.Количество() <> 1 И Части.Количество() <> 2 Тогда
        ВызватьИсключение "Только единственный File для новой своей базы";
    КонецЕсли;
    Если Части.Количество() = 2 И СокрЛП(Части[1]) <> "" Тогда
        ВызватьИсключение "Дополнительные параметры connection здесь запрещены";
    КонецЕсли;
    Параметр = СокрЛП(Части[0]);
    Если НРег(Лев(Параметр, 5)) <> "file=" Тогда
        ВызватьИсключение "Рабочую/серверную базу нельзя использовать вместо own fixture";
    КонецЕсли;
    Путь = Сред(Параметр, 6);
    Если Лев(Путь, 1) = """" И Прав(Путь, 1) = """" Тогда
        Путь = Сред(Путь, 2, СтрДлина(Путь) - 2);
    КонецЕсли;
    Если НРег(Путь) <> НРег("C:\1C85_OwnEPFPackLab\5a4ff5ad-54e2-4aa6-aed5-fadf742c9aa5\Base") Тогда
        ВызватьИсключение "Нужен exact собственный UUID-путь Base без завершающего слеша";
    КонецЕсли;
КонецПроцедуры

#КонецЕсли
Свой EPF: объект, native CheckFilling callback и compiled numeric readback

Своя вручную создаваемая EPF МоиУпаковки85 → Модуль объекта, целиком.

Модуль объекта именно этой ВнешняяОбработка; global ЭтотОбъект native object context, thick ordinary; native callback2args без directcall.

#Если ТолстыйКлиентОбычноеПриложение Тогда

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

Функция СформироватьПроверенныйДокумент85() Экспорт
    Если Не ЭтотОбъект.ПроверитьЗаполнение() Тогда
        Возврат Неопределено;
    КонецЕсли;
    Макет = ЭтотОбъект.ПолучитьМакет("РасчетУпаковок85");
    Если ТипЗнч(Макет) <> Тип("ТабличныйДокумент") Или Макет.ВысотаТаблицы <> 4 Или Макет.ШиринаТаблицы <> 4 Тогда
        ВызватьИсключение "Compiled own макет обязан быть4x4";
    КонецЕсли;
    Метки = СтрРазделить("А85,Б85,В85", ",");
    Параметры = Новый Массив;
    Параметры.Добавить(СтрРазделить("КоличествоА,ШтукА,ВсегоА", ","));
    Параметры.Добавить(СтрРазделить("КоличествоБ,ШтукБ,ВсегоБ", ","));
    Параметры.Добавить(СтрРазделить("КоличествоВ,ШтукВ,ВсегоВ", ","));
    Шапка = СтрРазделить("Упаковка,Количество,ШтукВУпаковке,ВсегоШтук", ",");
    Для Колонка = 1 По 4 Цикл
        ЯчейкаШапки = Макет.Область(1, Колонка, 1, Колонка);
        Если ЯчейкаШапки.Заполнение <> ТипЗаполненияОбластиТабличногоДокумента.Текст Или ЯчейкаШапки.Текст <> Шапка[Колонка - 1] Тогда
            ВызватьИсключение "Compiled header отличается от собственного4x4 fixture";
        КонецЕсли;
    КонецЦикла;
    Для Строка = 2 По 4 Цикл
        ЯчейкаМетки = Макет.Область(Строка, 1, Строка, 1);
        Если ЯчейкаМетки.Заполнение <> ТипЗаполненияОбластиТабличногоДокумента.Текст Или ЯчейкаМетки.Текст <> Метки[Строка - 2] Тогда
            ВызватьИсключение "Compiled label собственной упаковки не совпал";
        КонецЕсли;
        Для Колонка = 2 По 4 Цикл
            Ячейка = Макет.Область(Строка, Колонка, Строка, Колонка);
            Если Ячейка.Заполнение <> ТипЗаполненияОбластиТабличногоДокумента.Параметр
                Или Ячейка.Параметр <> Параметры[Строка - 2][Колонка - 2] Тогда
                ВызватьИсключение "Нужна exact compiled numeric parameter cell, не текст/шаблон";
            КонецЕсли;
            ПрочитатьНастоящееЧисло85(Макет, Строка, Колонка);
        КонецЦикла;
    КонецЦикла;
    А = ПрочитатьНастоящееЧисло85(Макет, 2, 3);
    Б = ПрочитатьНастоящееЧисло85(Макет, 3, 3);
    В = ПрочитатьНастоящееЧисло85(Макет, 4, 3);
    Если А <> 12 Или Б <> 6 Или В <> 10 Тогда
        ВызватьИсключение "Compiled значения единиц должны быть настоящими числами12/6/10, не strings";
    КонецЕсли;
    Макет.Параметры.КоличествоА = ЭтотОбъект.КоличествоА85;
    Макет.Параметры.ШтукА = А;
    Макет.Параметры.ВсегоА = ЭтотОбъект.КоличествоА85 * А;
    Макет.Параметры.КоличествоБ = ЭтотОбъект.КоличествоБ85;
    Макет.Параметры.ШтукБ = Б;
    Макет.Параметры.ВсегоБ = ЭтотОбъект.КоличествоБ85 * Б;
    Макет.Параметры.КоличествоВ = ЭтотОбъект.КоличествоВ85;
    Макет.Параметры.ШтукВ = В;
    Макет.Параметры.ВсегоВ = ЭтотОбъект.КоличествоВ85 * В;
    Документ = Новый ТабличныйДокумент;
    Документ.Вывести(Макет);
    Если Документ.ВысотаТаблицы <> 4 Или Документ.ШиринаТаблицы <> 4 Тогда
        ВызватьИсключение "Нативный вывод собственного4x4 макета имеет неожиданную геометрию";
    КонецЕсли;
    Для Колонка = 1 По 4 Цикл
        Если Документ.Область(1, Колонка, 1, Колонка).Текст <> Шапка[Колонка - 1] Тогда
            ВызватьИсключение "Actual output header не совпал с собственным compiled header";
        КонецЕсли;
    КонецЦикла;
    Для Строка = 2 По 4 Цикл
        Если Документ.Область(Строка, 1, Строка, 1).Текст <> Метки[Строка - 2] Тогда
            ВызватьИсключение "Actual output label не совпал с собственной упаковкой";
        КонецЕсли;
    КонецЦикла;
    Количества = Новый Массив;
    Количества.Добавить(ЭтотОбъект.КоличествоА85);
    Количества.Добавить(ЭтотОбъект.КоличествоБ85);
    Количества.Добавить(ЭтотОбъект.КоличествоВ85);
    Единицы = Новый Массив;
    Единицы.Добавить(А);
    Единицы.Добавить(Б);
    Единицы.Добавить(В);
    Итог = 0;
    Для Строка = 2 По 4 Цикл
        Количество = ПрочитатьНастоящееЧисло85(Документ, Строка, 2);
        ВУпаковке = ПрочитатьНастоящееЧисло85(Документ, Строка, 3);
        Всего = ПрочитатьНастоящееЧисло85(Документ, Строка, 4);
        Если Количество <> Количества[Строка - 2] Или ВУпаковке <> Единицы[Строка - 2] Или Всего <> Количество * ВУпаковке Тогда
            ВызватьИсключение "Actual numeric output cell readback не совпал с own количествами/единицами/произведением";
        КонецЕсли;
        Итог = Итог + Всего;
    КонецЦикла;
    Возврат Новый Структура("Документ,Итог", Документ, Итог);
КонецФункции

Функция ПрочитатьНастоящееЧисло85(Документ, Строка, Колонка)
    Ячейка = Документ.Область(Строка, Колонка, Строка, Колонка);
    Если Не Ячейка.СодержитЗначение Тогда
        ВызватьИсключение "Compiled/output cell не содержит Value; не превращаем её текст в число";
    КонецЕсли;
    Типы = Ячейка.ТипЗначения.Типы();
    Если Типы.Количество() <> 1 Или Не Ячейка.ТипЗначения.СодержитТип(Тип("Число")) Тогда
        ВызватьИсключение "Compiled/output cell не разрешает числовой тип";
    КонецЕсли;
    Если ТипЗнч(Ячейка.Значение) <> Тип("Число") Тогда
        ВызватьИсключение "Native Value не является числом; не устанавливаем ContainsValue/ValueType после загрузки";
    КонецЕсли;
    Возврат Ячейка.Значение;
КонецФункции

#КонецЕсли
Своя EPF: обычная форма конкретного instance и commit только проверенного Doc

Своя EPF МоиУпаковки85 → ОсновнаяФорма обычная, связана с object реквизитами → модуль формы, целиком.

Ordinary форма именно native instance.GetForm; global ЭтотОбъект — связанный external object по native описанию; handler ПриОткрытии0 и Пересчитать85(Кнопка).

#Если ТолстыйКлиентОбычноеПриложение Тогда

Перем МойЭкземплярФормы85;

Процедура ПринятьСвойЭкземпляр85(Экземпляр) Экспорт
    Если МойЭкземплярФормы85 <> Неопределено Или Экземпляр <> ЭтотОбъект Тогда
        ВызватьИсключение "Ordinary форма должна принадлежать тому actual instance, который native GetForm вернул своему загрузчику";
    КонецЕсли;
    МойЭкземплярФормы85 = Экземпляр;
КонецПроцедуры

Процедура ПриОткрытии()
    Если МойЭкземплярФормы85 = Неопределено Тогда
        ВызватьИсключение "Открывайте только через собственный проверенный loader, не чужой EPF";
    КонецЕсли;
    ПринятьНовыйПроверенныйВывод85();
    Если Итог85 <> 88 Тогда
        ВызватьИсключение "Initial own количествам3/2/4 должны соответствовать actual numeric88";
    КонецЕсли;
КонецПроцедуры

Процедура Пересчитать85(Кнопка)
    ПринятьНовыйПроверенныйВывод85();
КонецПроцедуры

Процедура ПринятьНовыйПроверенныйВывод85()
    Кандидат = МойЭкземплярФормы85.СформироватьПроверенныйДокумент85();
    Если Кандидат = Неопределено Тогда
        Состояние85 = "Native ПроверитьЗаполнение вернул Ложь. Проверка поля/события остановила расчёт; предыдущий Документ85 и итог не заменены.";
        Возврат;
    КонецЕсли;
    Документ85 = Кандидат.Документ;
    Итог85 = Кандидат.Итог;
    Состояние85 = "Actual вывод проверен чтением9 числовых ячеек. Итог=" + Строка(Итог85)
        + ". Измените в самой форме только количества3/2/4 →1/3/2 и нажмите Пересчитать85; должен получиться настоящий50.";
КонецПроцедуры

#КонецЕсли
Своя CF: guards до старта, открытие loader только после главного окна

Своя пустая CF УчебныеУпаковкиEPF85 → Модуль обычного приложения, целиком.

Модуль обычного приложения, не объектный модуль; native global BeforeStart(Отказ) не показывает UI, native OnStart0 открывает свой loader после mainwindow.

#Если ТолстыйКлиентОбычноеПриложение Тогда

Процедура ПередНачаломРаботыСистемы(Отказ)
    Попытка
        ПроверитьСвойПустойСтенд();
        ПроверитьСвойПутьИПользователя85();
    Исключение
        Отказ = Истина;
    КонецПопытки;
КонецПроцедуры

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

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвойПутьИПользователя85()
    Если ИмяПользователя() <> "Упаковки85Ученик" Тогда
        ВызватьИсключение "Только свой единственный учебный пользователь";
    КонецЕсли;
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Если ТипЗнч(Пользователи) <> Тип("Массив") Или Пользователи.Количество() <> 1 Тогда
        ВызватьИсключение "Нужна своя CF ровно с одним вручную подготовленным пользователем";
    КонецЕсли;
    Если Пользователи[0].Имя <> "Упаковки85Ученик" Или Метаданные.Обработки.Количество() <> 1
        Или Метаданные.Обработки.Найти("ЗагрузчикУпаковок85") = Неопределено Тогда
        ВызватьИсключение "В CF должна быть только своя учебная обработка-загрузчик";
    КонецЕсли;
    Части = СтрРазделить(СтрокаСоединенияИнформационнойБазы(), ";");
    Если Части.Количество() <> 1 И Части.Количество() <> 2 Тогда
        ВызватьИсключение "Только единственный File для новой своей базы";
    КонецЕсли;
    Если Части.Количество() = 2 И СокрЛП(Части[1]) <> "" Тогда
        ВызватьИсключение "Дополнительные параметры connection здесь запрещены";
    КонецЕсли;
    Параметр = СокрЛП(Части[0]);
    Если НРег(Лев(Параметр, 5)) <> "file=" Тогда
        ВызватьИсключение "Рабочую/серверную базу нельзя использовать вместо own fixture";
    КонецЕсли;
    Путь = Сред(Параметр, 6);
    Если Лев(Путь, 1) = """" И Прав(Путь, 1) = """" Тогда
        Путь = Сред(Путь, 2, СтрДлина(Путь) - 2);
    КонецЕсли;
    Если НРег(Путь) <> НРег("C:\1C85_OwnEPFPackLab\5a4ff5ad-54e2-4aa6-aed5-fadf742c9aa5\Base") Тогда
        ВызватьИсключение "Нужен exact собственный UUID-путь Base без завершающего слеша";
    КонецЕсли;
КонецПроцедуры

#КонецЕсли

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

  1. Application BeforeStart проверяет только свою CF/версию/user/точный File-path, при отказе ставит Отказ=True без окон, Сообщить и статусных UI действий. Native OnStart() после создания главного окна открывает только обработку-загрузчик из своей CF; EPF не исполняется автоматически без ручного одобренного hash.

  2. Кнопка loader проверяет тот же own scope, отсутствие прошлого instance, точный заранее подготовленный file/size и64hex SHA. Actual file SHA сравнивается с заранее одобренным BEFORE native Create. После Create filename/metadata лишь проверяют ожидаемый вид упражнения, НЕ доказывают безопасность кода, который уже мог начать выполнение.

  3. МойМенеджер=ВнешниеОбработки — настоящий native ВнешниеОбработкиМенеджер. Создать(ownFile,Истина) возвращает настоящий ВнешняяОбработка; никакой fake ctor/unknown ИсходныйОбъект нет. Не используем manager Подключить или manager ПолучитьФорму. Имена/состав EPF и compiled4x4 проверяются как exercise contract; UsedFileName читается readonly.

  4. Loader задаёт actual object title и количества3/2/4, вызывает native ПроверитьЗаполнение(), затем actual instance.ПолучитьФорму("ОсновнаяФорма",ЭтаФорма,ownKey).Открыть(). Форма относится именно к этому конкретному instance, а не создаёт второй файл/объект; exported initializer принимает только тот same actual object, который с ней связан.

  5. В EPF object module global ЭтотОбъект действительно относится к этой внешней обработке. Native CheckFilling сам вызывает callback с2формалами. Название проверяется штатно, отрицательные количества отклоняет реальный callback; список проверяемых реквизитов не очищается для обхода обязательного названия. Native False возвращает Неопределено кандидата, предыдущий видимый Doc/итог сохраняется.

  6. GetTemplate извлекает настоящий compiled макет, проверяется4x4/header/labels/точные9 parameter mappings. Numeric Value12/6/10 берутся из compiled cell properties, а не случайного runtime макета. ContainsValue/ValueType/FillType после загрузки НЕ переустанавливаются для скрытого исправления; ошибочные numeric/layout дают честный refusal.

  7. Native FillType.Параметр описан как вывод значения параметра. Все9 parameter values задаются числами из actual object количеств и compiled units. Получается новый ТабличныйДокумент через native Вывести(Макет); runtime клеткам не подсовываются fake числа после вывода.

  8. Читаются реальные9 output cells: у каждой ContainsValue=True, ValueType содержит Число, ТипЗнч(Value)=Число. Количество/единицы/произведение сравниваются с3 actual rows. Суммируются actual cells R2C4/R3C4/R4C4:36+12+40=88. Только прошедший numeric readback кандидат становится видимым Документ85.

  9. В самой открытой instance форме вручную измените object количества на1/3/2, нажмите Пересчитать85. Это новый native compiled-template вывод: actual product cells12/18/20, итог50. Документ заменяется лишь после полной проверки; cached previous88 не выдаётся за новую50.

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

  1. Первое собственное открытие формы показывает3/2/4, units12/6/10, products36/12/40 и numeric итог88. Значение cells проверено нативным .Значение, не распознаванием видимого текста.

  2. Ручная смена1/3/2 обновляет видимый документ и actual product cells12/18/20, итог50. Ноль упаковок допустим; отрицательное количество native callback отказывает, не записывая ничего в DB.

  3. Очистите только НазваниеОпыт85 в своей форме и нажмите Пересчитать85: native ПроверитьЗаполнение() должен дать Ложь со штатным сообщением, прежние Doc/итог сохраняются. Верните название; отрицательный own qty вызывает настоящий callback refusal. Callback руками/тестовой прямой процедурой не вызывается.

  4. Для добровольного negative-layout опыта заново изготовьте независимый disposable собственный стенд с новым marker и отдельно одобренной собственной diagnostic EPF, где numeric cell создана как text либо с неверным параметром/units. Загрузка/расчёт обязаны честно отказать. Исходный approved file не копируйте для backup и не перезаписывайте автоматически; обычное упражнение вообще не требует новых копий/архивов.

  5. Без own SHA, с hash другой собственной сборки, с неправильным user/path/CF код останавливается до Create. При уже созданном instance кнопка повторной загрузки отказывает; закрытие формы не является разрешением автоматически создавать новый экземпляр/обходить protection.

  6. Никаких установок safeMode=False/protection отключено, COM, network, DBwrite или actual native compile исполнения автором. Manual runtime проверки выполняются только владельцем отдельного стенда.

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

Один реальный instance собственной EPF и его обычная форма выводят компилированный typed4x4 макет с проверенными actual numeric результатами88 и50; неправильные реквизиты/макет не подменяют предыдущий вывод.

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

  1. Hash заранее одобренного own artifact проверяется ДО Create. Metadata/filename после Create не доказывают, что loaded код был безопасен. SHA не подпись, не сертификат владения и не TOCTOU-proof; manual source review/own isolation обязательны.

  2. Native CheckFilling возвращает Bool и вызывает событие. Проверять только заполненность поля вручную вместо native method или напрямую вызывать callback — иной процесс. Нулевая упаковка разрешена, потому qty automatic filling check намеренно НеПроверять и собственный callback проверяет смысл числа.

  3. Raw FillType.Текст выводит текст, а Параметр — значение параметра. Поэтому все9 numeric cells compiled как parameter с ContainsValue и numeric type; числовой Формат не превращает string в Value. При неожиданном output type exercise остановлен, не исправлен тайно.

  4. ЭтотОбъект берётся в настоящем external object module/связанной ordinary форме. Его нельзя засчитать generic dot-access на неизвестном объекте другой обработки. Global manager служит source, форма получается native method именно от загруженного actual instance.

  5. EPF object/form и CF loader/app — разные модули и metadata contexts. Их нельзя вставить одним общим модулем в УТ/КА/УНФ. Только thick ordinary CF8.5.1.1343: managed/web/тонкий контекст здесь не обещан.

  6. ВнешниеОбработки.Создать безопасный режим явно Истина, protection третий аргумент не меняется. Не снимайте системный отказ/предупреждение опасного действия и не используйте скачанный EPF в качестве own источника.

  7. Изготовлены только lesson/test источники. Actual native файлы/hashing/EPF compilation/1С/UI/COM/network/DB/settings не выполнялись. Root и configuration sources read-only, frozen предыдущие партии сохранены, новых backups/archives нет.

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

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

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

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

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