Предназначен для управления внешними обработками и позволяет получать значения типа ВнешняяОбработка при помощи метода Создать. Доступ к объекту осуществляется через свойство глобального контекста ВнешниеОбработки.
Полное описание, параметры и ограничения
ВнешниеОбработкиМенеджер (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 операций автором.
Подготовка
НИЧЕГО не выполняйте в production. Вручную подготовьте новый свой UUID-каталог C:\1C85_OwnEPFPackLab\5a4ff5ad-54e2-4aa6-aed5-fadf742c9aa5, свою новую пустую файловую Base внутри и CF УчебныеУпаковкиEPF85 только platform8.5.1.1343. Если каталог уже занят чужими/непонятными данными, не удаляйте и не переиспользуйте: подготовьте новый marker и согласованно исправьте все пути. CF основное приложение Обычное; бизнес-объектов, extension, подписок и фоновых/регламентных задач нет.
В этой новой пустой CF вручную подготовьте ровно одного пользователя Упаковки85Ученик с собственной ролью, разрешающей учебное ordinary приложение, открытие своей обработки, чтение списка пользователей/metadata и разрешённую ручную загрузку своей EPF. Никаких прав из production не переносите. Запускайте Base через единственный File="C:\1C85_OwnEPFPackLab\5a4ff5ad-54e2-4aa6-aed5-fadf742c9aa5\Base"; без других connection частей; имя пользователя выбирается обычной собственной формой входа.
Добавьте в CF ровно одну обработку ЗагрузчикУпаковок85, обычную ОсновнаяФорма. Реквизиты формы ОдобренныйSHA25685 Строка64 и Состояние85 Строка неограниченная; Состояние85 только просмотр. Кнопка ЗагрузитьТолькоСвоюEPF85 назначается одноимённому обработчику(Кнопка); main code целиком в модуль формы, ПриОткрытии() native событие. Supporting application code целиком в Модуль обычного приложения CF. BeforeStart только guard/Отказ, OnStart уже может открыть собственную loader форму.
В Конфигураторе данной своей платформы: Файл → Новый → Внешняя обработка, Имя=МоиУпаковки85. Это НОВЫЙ собственный файл, не скачанная обработка. Ровно4 object реквизита: НазваниеОпыт85 Строка40, ПроверкаЗаполнения=ПоказыватьОшибку; КоличествоА85/КоличествоБ85/КоличествоВ85 Число(9,0), ДопустимыйЗнак=Любой, ПроверкаЗаполнения=НеПроверять, поскольку0 упаковок допустим. Object code ниже целиком в Модуль объекта; native callback ОбработкаПроверкиЗаполнения(Отказ,ПроверяемыеРеквизиты) не вызывайте самостоятельно.
В этой 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 целиком в модуль формы, ПриОткрытии() событие.
Добавьте в 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.
Проверьте 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 или изменял настройки.
У 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 без завершающего слеша";
КонецЕсли;
КонецПроцедуры
#КонецЕслиРазбор по шагам
Application BeforeStart проверяет только свою CF/версию/user/точный File-path, при отказе ставит Отказ=True без окон, Сообщить и статусных UI действий. Native OnStart() после создания главного окна открывает только обработку-загрузчик из своей CF; EPF не исполняется автоматически без ручного одобренного hash.
Кнопка loader проверяет тот же own scope, отсутствие прошлого instance, точный заранее подготовленный file/size и64hex SHA. Actual file SHA сравнивается с заранее одобренным BEFORE native Create. После Create filename/metadata лишь проверяют ожидаемый вид упражнения, НЕ доказывают безопасность кода, который уже мог начать выполнение.
МойМенеджер=ВнешниеОбработки — настоящий native ВнешниеОбработкиМенеджер. Создать(ownFile,Истина) возвращает настоящий ВнешняяОбработка; никакой fake ctor/unknown ИсходныйОбъект нет. Не используем manager Подключить или manager ПолучитьФорму. Имена/состав EPF и compiled4x4 проверяются как exercise contract; UsedFileName читается readonly.
Loader задаёт actual object title и количества3/2/4, вызывает native ПроверитьЗаполнение(), затем actual instance.ПолучитьФорму("ОсновнаяФорма",ЭтаФорма,ownKey).Открыть(). Форма относится именно к этому конкретному instance, а не создаёт второй файл/объект; exported initializer принимает только тот same actual object, который с ней связан.
В EPF object module global ЭтотОбъект действительно относится к этой внешней обработке. Native CheckFilling сам вызывает callback с2формалами. Название проверяется штатно, отрицательные количества отклоняет реальный callback; список проверяемых реквизитов не очищается для обхода обязательного названия. Native False возвращает Неопределено кандидата, предыдущий видимый Doc/итог сохраняется.
GetTemplate извлекает настоящий compiled макет, проверяется4x4/header/labels/точные9 parameter mappings. Numeric Value12/6/10 берутся из compiled cell properties, а не случайного runtime макета. ContainsValue/ValueType/FillType после загрузки НЕ переустанавливаются для скрытого исправления; ошибочные numeric/layout дают честный refusal.
Native FillType.Параметр описан как вывод значения параметра. Все9 parameter values задаются числами из actual object количеств и compiled units. Получается новый ТабличныйДокумент через native Вывести(Макет); runtime клеткам не подсовываются fake числа после вывода.
Читаются реальные9 output cells: у каждой ContainsValue=True, ValueType содержит Число, ТипЗнч(Value)=Число. Количество/единицы/произведение сравниваются с3 actual rows. Суммируются actual cells R2C4/R3C4/R4C4:36+12+40=88. Только прошедший numeric readback кандидат становится видимым Документ85.
В самой открытой instance форме вручную измените object количества на1/3/2, нажмите Пересчитать85. Это новый native compiled-template вывод: actual product cells12/18/20, итог50. Документ заменяется лишь после полной проверки; cached previous88 не выдаётся за новую50.
Как проверить результат
Первое собственное открытие формы показывает3/2/4, units12/6/10, products36/12/40 и numeric итог88. Значение cells проверено нативным .Значение, не распознаванием видимого текста.
Ручная смена1/3/2 обновляет видимый документ и actual product cells12/18/20, итог50. Ноль упаковок допустим; отрицательное количество native callback отказывает, не записывая ничего в DB.
Очистите только НазваниеОпыт85 в своей форме и нажмите Пересчитать85: native ПроверитьЗаполнение() должен дать Ложь со штатным сообщением, прежние Doc/итог сохраняются. Верните название; отрицательный own qty вызывает настоящий callback refusal. Callback руками/тестовой прямой процедурой не вызывается.
Для добровольного negative-layout опыта заново изготовьте независимый disposable собственный стенд с новым marker и отдельно одобренной собственной diagnostic EPF, где numeric cell создана как text либо с неверным параметром/units. Загрузка/расчёт обязаны честно отказать. Исходный approved file не копируйте для backup и не перезаписывайте автоматически; обычное упражнение вообще не требует новых копий/архивов.
Без own SHA, с hash другой собственной сборки, с неправильным user/path/CF код останавливается до Create. При уже созданном instance кнопка повторной загрузки отказывает; закрытие формы не является разрешением автоматически создавать новый экземпляр/обходить protection.
Никаких установок safeMode=False/protection отключено, COM, network, DBwrite или actual native compile исполнения автором. Manual runtime проверки выполняются только владельцем отдельного стенда.
Ожидаемый результат
Один реальный instance собственной EPF и его обычная форма выводят компилированный typed4x4 макет с проверенными actual numeric результатами88 и50; неправильные реквизиты/макет не подменяют предыдущий вывод.
На что обратить внимание
Hash заранее одобренного own artifact проверяется ДО Create. Metadata/filename после Create не доказывают, что loaded код был безопасен. SHA не подпись, не сертификат владения и не TOCTOU-proof; manual source review/own isolation обязательны.
Native CheckFilling возвращает Bool и вызывает событие. Проверять только заполненность поля вручную вместо native method или напрямую вызывать callback — иной процесс. Нулевая упаковка разрешена, потому qty automatic filling check намеренно НеПроверять и собственный callback проверяет смысл числа.
Raw FillType.Текст выводит текст, а Параметр — значение параметра. Поэтому все9 numeric cells compiled как parameter с ContainsValue и numeric type; числовой Формат не превращает string в Value. При неожиданном output type exercise остановлен, не исправлен тайно.
ЭтотОбъект берётся в настоящем external object module/связанной ordinary форме. Его нельзя засчитать generic dot-access на неизвестном объекте другой обработки. Global manager служит source, форма получается native method именно от загруженного actual instance.
EPF object/form и CF loader/app — разные модули и metadata contexts. Их нельзя вставить одним общим модулем в УТ/КА/УНФ. Только thick ordinary CF8.5.1.1343: managed/web/тонкий контекст здесь не обещан.
ВнешниеОбработки.Создать безопасный режим явно Истина, protection третий аргумент не меняется. Не снимайте системный отказ/предупреждение опасного действия и не используйте скачанный EPF в качестве own источника.
Изготовлены только lesson/test источники. Actual native файлы/hashing/EPF compilation/1С/UI/COM/network/DB/settings не выполнялись. Root и configuration sources read-only, frozen предыдущие партии сохранены, новых backups/archives нет.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.