Внеконтекстный вызов методов объекта обработки (отчета) в управляемой форме

25.03.17

Разработка - Универсальные функции

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Пример.epf
.epf 12,19Kb ver:1.0
12
12 Скачать (1 SM) Купить за 1 850 руб.


Сразу хочется отметить, что речь пойдет о повторном использовании методов, которые фактически являются «статическими» в терминологии ООП, то есть не связанных с конкретным экземпляром объекта. Такие методы, не изменяя состояния (данных) самого объекта, выполняют некоторые действия или (и) возвращают результаты каких-то вычислений.

Как известно, платформа 1С-8.2/8.3 предоставляет возможность повторного использования кода путем размещения его в экспортных процедурах и функциях в следующих местах конфигурации:

  1. Модули объектов "Форма" и "УправляемаяФорма";
  2. Общие модули конфигурации;
  3. Модули менеджеров объектов;
  4. Модули объектов;

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


Модули объектов форм (по замечанию awk):

Этот вариант переиспользования не очень удобен по ряду причин:

- Объекты "Форма" или "УправляемаяФорма" отдельно создать можно только на стороне клиентов (метод ПолучитьФорму() не доступен на сервере). Поэтому на стороне сервера применение этого варианта переиспользования кода ограничено серверным контекстом управляемых форм.

- В силу узкой специализации объектов "Форма" или "УправляемаяФорма", призванных решать интерфейсные задачи.
На практике этот вариант переиспользования кода в основном используется для нестандартного начального заполнения данных формы до ее открытия или как один из возможных вариантов организации взаимодействия между между формами (в подчиненной форме через атрибут "ВладелецФормы" можно вызвать экспортный метод формы-владельца).


Общие модули конфигурации:

Этот вариант является самым простым с точки зрения использования на стороне клиента в управляемых формах, поскольку общие модули и их методы можно сделать непосредственно доступными для использования на клиенте:

&НаКлиенте
Процедура ОбработчикСобытия(Элемент…)
    
//…
    
ВычЗначение = ИмяОбщегоМодуля1.МетодФункция1(Пар1,Пар2,Пар3…);
    
//…
    
ИмяОбщегоМодуля2.МетодПроцедура2(Арг1,Арг2,Арг3…);
    
//…
КонецПроцедуры

Недостаток размещения кода в общих модулях заключается в уменьшении универсальности обработки (отчета).
Ее функционал «размазывается» по конфигурации. При переносе функционала в другое прикладное решение приходится помнить, что кроме самой обработки также требуется подтянуть «то, пятое, десятое».
А для универсальных обработок, используемых в качестве внешних, такая зависимость от общих модулей может оказаться вообще неприемлемой.


Модули менеджеров объектов:

Модуль менеджера объекта является естественным местом размещения кода общего назначения, не связанного с конкретным экземпляром объекта.

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

&НаСервереБезКонтекста
Функция ФормМетодФункция1(Пар1,Пар2,Пар3…)
     Возврат
Обработки[ИмяОбработки]. МетодФункция1 (Пар1,Пар2,Пар3…);
КонецФункции


&НаСервереБезКонтекста
Процедура ФормМетодПроцедура2(Арг1,Арг2,Арг3…)
    
Обработки[ИмяОбработки]. МетодПроцедура2(Арг1,Арг2,Арг3…);
КонецПроцедуры


//…

&НаКлиенте
Процедура ОбработчикСобытия(Элемент…)
    
//…
    
ВычЗначение = ФормМетодФункция1(Пар1,Пар2,Пар3…);
    
//…
    
ФормМетодПроцедура2(Арг1,Арг2,Арг3…);
    
//…
КонецПроцедуры

В принципе такой вариант размещения кода является приемлемым для обработки с точки зрения производительности и переносимости. Но здесь возникает затруднение, если предполагается использовать обработку (отчет) в качестве внешней обработки (внешнего отчета).

Дело в том, что у внешних обработок и отчетов нет менеджера объекта как такового.
А при сохранении встроенной обработки во внешнюю обработку модуль ее менеджера попросту теряется (кстати, без предупреждения).
В этом случае остается единственное место для размещения повторно используемого кода – модуль объекта обработки (отчета).


Модули объектов:

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

&НаСервере
Функция ФормМетодФункция1(Пар1,Пар2,Пар3…)
    
Обработка = РеквизитФормыВЗначение("Объект");
     Возврат
Обработка. МетодФункция1 (Пар1,Пар2,Пар3…);
КонецФункции


&НаСервере
Процедура ФормМетодПроцедура2(Арг1,Арг2,Арг3…)
    
Обработка = РеквизитФормыВЗначение("Объект");
    
Обработка. МетодПроцедура2(Арг1,Арг2,Арг3…);
КонецПроцедуры


//…

&НаКлиенте
Процедура ОбработчикСобытия(Элемент…)
    
//…
    
ВычЗначение = ФормМетодФункция1(Пар1,Пар2,Пар3…);
    
//…
    
ФормМетодПроцедура2(Арг1,Арг2,Арг3…);
    
//…
КонецПроцедуры

Серверные контекстные вызовы являются «затратными». Их использование оправдано, если в массовом порядке изменяются данные формы или когда для выполнения каких-то действий требуются данные всей формы или связанного с ней объекта.
Поэтому рекомендуется по возможности избегать использования серверных контекстных вызовов.


Что же делать, если метод объекта фактически является «статическим» и не использует данные самого объекта?

Например, пусть метод возвращает список значений меню, динамически зависящего только от значений переданных методу параметров. Ясно, что использование контекстного серверного вызова в этой ситуации явно неоправданно.

В работе //infostart.ru/public/236344/ при разработке управляемых форм обработки для решения этой проблемы был использован такой подход:

В специально предназначенном строковом реквизите обработки при инициализации модуля объекта сохраняется внутреннее строковое представление типа объекта обработки/отчета:

// установим внутреннее строковое представление типа значения объекта обработки
ЭтотОбъект.ОбработкаТип = ЗначениеВСтрокуВнутр(ТипЗнч(ЭтотОбъект));

Этот способ хорош тем, что "сразу" инициалициализирует нужный реквизит объекта обработки/отчета во всех формах, где объект обработки/отчета используется.

В принципе реквизит обработки можно заменить реквизитом самой формы.
Тогда описанное выше действие нужно будет выполнять в обработчике «ПриСозданииНаСервере»:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
Обработка = РеквизитФормыВЗначение("Объект");
    
// установим внутреннее строковое представление типа значения объекта обработки
    
ЭтаФорма.ОбработкаТип = ЗначениеВСтрокуВнутр(ТипЗнч(Обработка));

    
//…

    
ЗначениеВРеквизитФормы(Обработка, "Объект");
КонецПроцедуры

Значение этого реквизита в дальнейшем используется во вспомогательных внеконтекстных серверных методах формы для создания объекта обработки. Ну, а сам вызов методов объекта обработки на стороне клиента выглядит следующим образом:

&НаСервереБезКонтекста
Функция ФормМетодФункция1(ОбработкаТип,Пар1,Пар2,Пар3)
   
// создаем объект обработки по внутреннему строковому представлению его типа
    // для внеконтекстного выполнения экспортных методов
   
Обработка = Новый (ЗначениеИзСтрокиВнутр(ОбработкаТип));
    Возврат
Обработка. МетодФункция1 (Пар1,Пар2,Пар3…);
КонецФункции

&НаСервереБезКонтекста
Процедура ФормМетодПроцедура2(ОбработкаТип,Арг1,Арг2,Арг3…)
   
// создаем объект обработки по внутреннему строковому представлению его типа
    // для внеконтекстного выполнения экспортных методов
   
Обработка = Новый (ЗначениеИзСтрокиВнутр(ОбработкаТип));
   
Обработка. МетодПроцедура2(Арг1,Арг2,Арг3…);
КонецПроцедуры

В 

//…

&НаКлиенте
Процедура ОбработчикСобытия(Элемент…)
    
//…
    
ВычЗначение = ФормМетодФункция1(Объект.ОбработкаТип,Пар1,Пар2,Пар3…);
    
//…
    
ФормМетодПроцедура2(Объект.ОбработкаТип,Арг1,Арг2,Арг3…);
    
//…
КонецПроцедуры
В 

Таким образом, решается поставленная задача:
вызовы методов объекта осуществляется при внеконтекстных серверных вызовах со стороны клиента в управляемой форме. 

Кроме этого описанный выше подход более универсален, чем использование модуля менеджера объекта.
Так как при таком создании объекта в явном виде не используется информация о том, что за объект создается (объект обработки, отчета или чего другого), а также информация об имени метаданных объекта.


Применение:

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

Ограничения применения:

В случае внешних отчетов и обработок предлагаемый подход можно использовать только в том соединении с информационной базой, в котором был открыт файл обработки/отчета (был откомпилирован модуль объекта из файла).

При использовании в другом соединении (например, в фоновом задании или во внешнем соединении) у нас не получится создать объект внешней обработки/отчета по переданному внутреннему строковому представлению типа объекта обработки/отчета (смотрите первый пример ниже по тексту).
Поскольку в этом случае функция ЗначениеИзСтрокиВнут() вернет значение Тип(“Неопределено”вместо типа нужного нам объекта.

Например, может возникнуть вполне естественное желание запустить на выполнение обработку в фоновом задании.
Для этого потребуется экспортный метод некоего общего модуля, позволяющего выполнять произвольный код на стороне сервера.
Пусть это будет общий модуль «УТР_Сервер» и метод «ВыполнитьНаСервере» (реальный пример из конфигурации «Управление аптечной сетью»):

Процедура ВыполнитьНаСервере(Строка, ПереданноеЗначение=Неопределено) Экспорт
    Выполнить(
Строка);
КонецПроцедуры

Запустить обработку на выполнение в фоновом задании с передачей типа объекта обработки для его создания можно попытаться так:


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

   
стПараметры = Новый Структура("А",стАргументы);
   
стПараметры.Вставить("ОбработкаТип",ОбработкаТип);

   
КодВыполнения =
   
"П = ПереданноеЗначение;
    |// по переданному типу объекта обработки - НЕ РАБОТАЕТ !!!
    |Обработка = Новый(ЗначениеИзСтрокиВнутр(П.ОбработкаТип));
    |Обработка.МетодПроцедура2(П.А.Арг1,П.А.Арг2,П.А.Арг3);
    |"
;

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

   
ЕррорИнфо = "";
    Попытка
       
Задание = ФоновыеЗадания.Выполнить(
       
ИмяМетодаФЗ,ПараметрыФЗ,ОбработкаИмя+"_"+ФоновоеЗаданиеКлюч,"Выполнение обработки """+ОбработкаИмя+"""");
        Если
ТаймаутФЗ > 0 Тогда
           
Задание.ОжидатьЗавершения(ТаймаутФЗ);
        КонецЕсли;
       
ЗаданиеGUID = Задание.УникальныйИдентификатор;;
    Исключение
       
ЗаданиеGUID = Неопределено;
       
ЕррорИнфо = ОписаниеОшибки();
    КонецПопытки;

    Возврат
ЗаданиеGUID;
КонецФункции


Обход ограничений:

Что же делать, если очень хочется выполнить метод объекта внешней обработки/отчета именно в фоновом задании?
Тогда придется как-то передать фоновому заданию двоичные данные обработки (отчета) для создания ее (его) объекта.

Для этого есть три основных способа:

1) Передать через аргумент метода фонового задания навигационную ссылку на данные обработки/отчета в информационной базе
(для этого обработка должна быть сохранена в информационное базе,
например, в справочнике «ДополнительныеОтчетыИОбработки»):


&НаСервереБезКонтекста
Функция ПолучитьНавигационнуюСсылкуДопОбработки(ИмяОбработки)
   
УстановитьПривилегированныйРежим(Истина);
   
Запрос = Новый Запрос;
   
Запрос.Текст =
   
"ВЫБРАТЬ
    |   Т.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.ДополнительныеОтчетыИОбработки КАК Т
    |ГДЕ
    |   Т.ПометкаУдаления = ЛОЖЬ
    |   И Т.ИмяОбъекта = """
+ИмяОбработки+"""
    |   И Т.Вид = ЗНАЧЕНИЕ(Перечисление.ВидыДополнительныхОтчетовИОбработок.ДополнительнаяОбработка)
    |   И Т.Публикация = ЗНАЧЕНИЕ(Перечисление.ВариантыПубликацииДополнительныхОтчетовИОбработок.Используется)"
;
   
Выборка = Запрос.Выполнить().Выбрать();
    Пока
Выборка.Количество() = 0 Цикл
        Возврат
"";
    КонецЦикла;
   
Выборка.Следующий();
    Возврат
ПолучитьНавигационнуюСсылку(Выборка.Ссылка,"ХранилищеОбработки");
КонецФункции


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

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

   
КодВыполнения =
   
"П = ПереданноеЗначение;
    |// по навигационной ссылке двоичных данных обработки в ИБ
    |Обработка = ВнешниеОбработки.Создать(ВнешниеОбработки.Подключить(П.ОбработкаАдрес,,Ложь));
    |Обработка.МетодПроцедура2(П.А.Арг1,П.А.Арг2,П.А.Арг3);
    |"
;

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

   
ЕррорИнфо = "";
    Попытка
       
Задание = ФоновыеЗадания.Выполнить(
       
ИмяМетодаФЗ,ПараметрыФЗ,ОбработкаИмя+"_"+ФоновоеЗаданиеКлюч,"Выполнение обработки """+ОбработкаИмя+"""");
        Если
ТаймаутФЗ > 0 Тогда
           
Задание.ОжидатьЗавершения(ТаймаутФЗ);
        КонецЕсли;
       
ЗаданиеGUID = Задание.УникальныйИдентификатор;;
    Исключение
       
ЗаданиеGUID = Неопределено;
       
ЕррорИнфо = ОписаниеОшибки();
    КонецПопытки;

    Возврат
ЗаданиеGUID;
КонецФункции


2) Передать через аргумент метода фонового задания полный путь к файлу обработки/отчета
(полный путь можно получить из атрибута объекта “ИспользуемоеИмяФайла”,
этот путь должен быть доступен на стороне сервера):


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

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

   
КодВыполнения =
   
"П = ПереданноеЗначение;
    |// по пути к файлу обработки
    |Обработка = ВнешниеОбработки.Создать(П.ОбработкаПутьФайла,Ложь);
    |Обработка.МетодПроцедура2(П.А.Арг1,П.А.Арг2,П.А.Арг3);
    |"
;

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

   
ЕррорИнфо = "";
    Попытка
       
Задание = ФоновыеЗадания.Выполнить(
       
ИмяМетодаФЗ,ПараметрыФЗ,ОбработкаИмя+"_"+ФоновоеЗаданиеКлюч,"Выполнение обработки """+ОбработкаИмя+"""");
        Если
ТаймаутФЗ > 0 Тогда
           
Задание.ОжидатьЗавершения(ТаймаутФЗ);
        КонецЕсли;
       
ЗаданиеGUID = Задание.УникальныйИдентификатор;;
    Исключение
       
ЗаданиеGUID = Неопределено;
       
ЕррорИнфо = ОписаниеОшибки();
    КонецПопытки;

    Возврат
ЗаданиеGUID;
КонецФункции

В 

3) Передать через аргумент метода фонового задания сами двоичные данные файла обработки/отчета
(их можно получить конструктором по значению атрибута объекта “ИспользуемоеИмяФайла”):

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

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

   
КодВыполнения =
   
"П = ПереданноеЗначение;
    |// по двоичным данным обработки
    |ИмяФайла = ПолучитьИмяВременногоФайла("".epf"");
    |П.ОбработкаДанные.Записать(ИмяФайла);
    |Обработка = ВнешниеОбработки.Создать(ИмяФайла,Ложь);
    |Обработка.МетодПроцедура2(П.А.Арг1,П.А.Арг2,П.А.Арг3);
    |"
;

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

   
ЕррорИнфо = "";
    Попытка
       
Задание = ФоновыеЗадания.Выполнить(
       
ИмяМетодаФЗ,ПараметрыФЗ,ОбработкаИмя+"_"+ФоновоеЗаданиеКлюч,"Выполнение обработки """+ОбработкаИмя+"""");
        Если
ТаймаутФЗ > 0 Тогда
           
Задание.ОжидатьЗавершения(ТаймаутФЗ);
        КонецЕсли;
       
ЗаданиеGUID = Задание.УникальныйИдентификатор;;
    Исключение
       
ЗаданиеGUID = Неопределено;
       
ЕррорИнфо = ОписаниеОшибки();
    КонецПопытки;

    Возврат
ЗаданиеGUID;
КонецФункции

В 

Описание файлов поставки:

Пример.epf – демонстрационная обработка с примерами использования
(в том числе разные варианты выполнения в фоновом задании):

 Форма обработки с примером использования

серверный вызов управляемая форма фоновое задание

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

21.05.2024    21352    dimanich70    81    

146

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    4184    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    19783    atdonya    24    

58

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    5626    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    15189    YA_418728146    7    

169

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3700    57    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18655    173    sapervodichka    112    

135

Какой из интерфейсов в 1С является более прогрессивным и продвинутым: управляемый иди обычный


Оба интерфейса (обычный и управляемый) - взаимно дополняют друг-друга и каждый имеет свою область применения. (59.62%, 31 голосов)
59.62%
Управляемый интерфейс является очередной "вершиной технической мысли" - безоговорочная альтернатива обычному интерфейсу. (34.62%, 18 голосов)
34.62%
Управляемый интерфейс - "тупиковая ветвь эволюции", функционально никогда не приблизится обычному интерфейсу. (11.54%, 6 голосов)
11.54%

Отзывы
21. sanfoto 502 29.06.15 16:06 Сейчас в теме
Ндя прикольно разрабы платформы жгут.... ((((((
Дело в том, что у внешних обработок и отчетов нет менеджера объекта как такового.
А при сохранении встроенной обработки во внешнюю обработку модуль ее менеджера попросту теряется
(кстати, без предупреждения).


на днях случилось у меня это горе "при сохранении встроенной обработки во внешнюю обработку модуль ее менеджера попросту теряется"....

Работаем с "Хранилищем конфигурации", и тут другому программисту срочно понадобилась захваченная мною обработка для временной модификациив рабочей базе .... а мой код еще небыл доведен , ну я недолго думая сохранил в Файл как внешнюю обработку... отменил захват встроенной обработки.
Потом после работы "другого программиста" захватил обработку заново+загрузил свою сохраненую и прощай "мой модуль менеджера" (((((
27. temsan 14.02.17 10:23 Сейчас в теме
(18)
&НаСервереБезКонтекста
Функция Что_то_с_чем_то(Знач ОбъектОбработка, ТипОбработкиСтрока, Параметры)
Возврат ДанныеФормыВЗначение(ОбъектОбработка, Тип(ТипОбработкиСтрока)).НужнаяНамФункция(Параметры);
КонецФункции


По объему передаваемых данных этот метод занимает место между методом автора, и контекстным вызовом.
Еще плюс вашего метода - если использовать преобразования данных формы в объект и обратно, можно в принципе в модуле обработки оперировать реквизитами и табличными частями.
Взял себе на заметку, хороший способ уменьшить трафик, передавая в серверную функцию только один объект (а не всю форму и все ее данные).
24. yuraos 1003 02.02.17 10:15 Сейчас в теме
(23) Честно говоря в архитектуре платформы есть большой недостаток:
У прикладных объектов нет пользовательских исполняемых модулей,
аналогичных общим модулям конфигурации.

В дереве метаданных эти исполняемые модули могли бы размещаться в узлах "Модули",
подчиненных узлам метаданных прикладных объектов.

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

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

Свойство "глобальности" у таких модулей соответствует свойству "стационарности"
(в том смысле, которое оно существует в ООП).

Стационарный исполняемый модуль мыслится доступным через менеджер объектов прикладного типа.
Например: Справочники.ИмяСправочника.Модули.ИмяМодуля.ИмяМетода().

Не стационарные исполняемые модули мыслятся доступными в контексте объекта прикладного типа:
Например: ПеременнаяОбъект.Модули.ИмяМодуля.ИмяМетода()

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

"Клиентские" исполняемые модули прикладного объекта можно было бы включить в контекст управляемой формы
через два дополнительных свойства расширения формы объекта или формы списка объекта прикладного типа:
допустим: СтационарныеМодули и МодулиОбъекта.
Остальные комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. yuraos 1003 16.12.13 23:02 Сейчас в теме
Всем доброго времени суток!

В основе настоящей публикации, лежит изящный способ,
которым мне удалось исправить один недостаток в функционале
стандартных отчетов в УПП-1.2 еще под 1с-8.1.

Недостаток заключается в том, что внешний отчет нельзя открыть в новом окне.
И исправляется этот недостаток буквально одной строчкой кода:

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

Показать
2. bashinsky 135 17.12.13 09:40 Сейчас в теме
Надо будет попробовать.
3. Yashazz 4796 18.12.13 11:41 Сейчас в теме
Просто и изящно. Статья, предваряющая решение, ценнее, т.к. эти очевидные вроде бы вещи изложены ясно, внятно, просто, лаконично. Спасибо!
rusmil; temsan; rayastar; yuraos; +4 Ответить
5. yuraos 1003 18.12.13 16:57 Сейчас в теме
(3) Yashazz, (4) DAnry,
спасибо за высокую оценку моих скромных трудов.
удивительное рядом ... но оно замутнено
(плохой документацией)

--
к стати описанный способ создания объекта не ограничивается обработками и отчетами.
например, как легко проверить в табло формул,
следующий оператор создает объект справочника "Контрагенты":
Новый(Тип(''СправочникОбъект.Контрагенты''))

хотя на практике я использовал это только для обработок и отчетов.
6. Yashazz 4796 18.12.13 19:29 Сейчас в теме
(5) Ну-у-у, в Синтакс-помощнике для "Новый" это всё описано, и ниразу не фишка, а вот придумать так воспользоваться этим способом для решения проблемы внеконтекстного вызова - фишка. Правда, позволю себе ламерский вопрос - разве при внеконтекстном вызове доступны значения реквизитов формы? У меня в своё время это не получалось.
7. yuraos 1003 18.12.13 19:46 Сейчас в теме
(6) Yashazz, нет реквизиты (то есть данные) формы
во внеконтекстных методах формы не доступны.

все что нужно для выполнения метода объекта
приходится передавать через аргументы вспомогательного метода формы
+ еще внутреннее текстовое представление типа объекта для создания самого объекта.
---
это может быть несколько занудно,
зато какая ни есть - оптимизация клиент-сервеного взаимодействия.
:)
4. DAnry 9 18.12.13 16:31 Сейчас в теме
Очень интересно и познавательно. Благодарю за статью.
JinAir7460; +1 Ответить
8. vasiliy_b 284 20.12.13 14:43 Сейчас в теме
9. awk 744 20.12.13 23:07 Сейчас в теме
(0) Немного критики:

Сразу хочется отметить, что речь пойдет о повторном использовании методов,
которые фактически являются «статическими» в терминологии ООП,
то есть не связанных с конкретным экземпляром объекта.
Такие методы, не изменяя состояния (данных) самого объекта, выполняют
некоторые действия или (и) возвращают результаты каких-то вычислений.

Бред. Т.к.:
1. Статические методы вполне меняют данные (состояния), не объектов конечно, но классов.
2. При чем 1С и ООП? 1С это процедурный язык оперирующий объектами предметной области.

Как известно, платформа 1С-8.2 предоставляет возможность повторного
использования кода путем размещения его в экспортных процедурах и
функциях в следующих местах конфигурации:

Общие модули конфигурации;
Модули менеджеров объектов;
Модули объектов;

А если метод будет в форме, то его нельзя использовать повторно?

Этот вариант является самым простым с точки зрения использования на стороне клиента в управляемых формах,
поскольку общие модули и их методы можно сделать непосредственно доступными для использования на клиенте:

Что-то я не встречал особо директив компиляции в общих модулях. Наверное потому, что хорошим тоном является разделение модулей на серверные и клиентские.

Недостаток размещения кода в общих модулях заключается в уменьшении универсальности обработки (отчета).
Ее функционал «размазывается» по конфигурации. При переносе функционала в другое прикладное решение
приходится помнить, что кроме самой обработки также требуется подтянуть «то, пятое, десятое».
А для универсальных обработок, используемых в качестве внешних,
такая зависимость от общих модулей может оказаться вообще неприемлемой.


Чушь какая-то. Я ни разу не менял модулей (общих) при написании внешних обработок. Они либо пишутся под конкретную конфигурацию, либо используют уж очень общие модули типа: "СтроковыеФункцииКлиентСервер". А вообще есть правило: "Хочешь потерять данные - сделай их внешними".

Модуль объекта, Модуль менеджера - это модули оперирования данными. На клиенте данные только отображаются, потому и нет их на клиенте. Максимум, что 1С могло бы сделать, это их доступность с неявным вызовом сервера. А оно надо? Если надо - вызови явно.

Например, пусть метод возвращает список значений меню, динамически зависящего только от значений переданных
методу параметров. Ясно, что использование контекстного серверного вызова в этой ситуации явно неоправданно.
А вызов сервера оправдан?

Это легко решить передав таблицу состояний на клиента. А дальше не вызывая сервер:

Процедура ПриСозданииНаСервере...
...
НоваяСтрока = ТаблицаСостояний.Добавить();
НоваяСтрока.Значение = Значение1;
НоваяСтрока.Представление = Представление1;
НоваяСтрока.Состояние1 = Истина;
НоваяСтрока.Состояние2 = Ложь;

...
КонецПроцедуры

&НаКлиенте
Процедура Что_тоПриИзменении(Элемент)

Строки = ТаблицаСостояний.НайтиСтроки(Новый Структура("Состояние1",Истина));
...

КонецПроцедуры


Показать
Sam13; bulpi; +2 Ответить
10. yuraos 1003 20.12.13 23:34 Сейчас в теме
(9) о тут у нас, появился Белинский и это хорошо!!!

Всегда полезна хорошая критика ... если она умна, конструктивна и не предвзята.

Спасибо, awk, за высказанные мысли по обсуждаемой теме
и потраченное на это драгоценное время.

Постараюсь позже высказать свои ответные соображения.
11. yuraos 1003 22.12.13 18:24 Сейчас в теме
(10)(9) ну awk,
выкладываю обещанные ответные соображения
...
так сказать, как у тебя - развернуто по пунктам.
12. yuraos 1003 22.12.13 18:24 Сейчас в теме
(11)***
(10)(9)

Бред. Т.к.:
1. Статические методы вполне меняют данные (состояния), не объектов конечно, но классов.
2. При чем 1С и ООП? 1С это процедурный язык оперирующий объектами предметной области.


Интеллигентно не замечая слова "бред", спрашиваю себя К чему все это было сказано?
И думаю, что к чему угодно, но только не к теме публикации.

В начале статьи была использована аналогия с ООП, чтобы образно обрисовать область применения обсуждаемого
в статье материала (и не более того). А именно, что обсуждаемый способ вызова методов объекта имеет смысл
только для тех методов, которые не изменяют данные (или состояние объекта).
Так как при возврате потока исполнения обратно на клиент все эти изменения будут утеряны.

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


Скорее всего, это замечание связано с глухим неприятием ООП определенной частью сообщества 1С.
Это неприятие породило давнюю, малоконструктивную дискуссию между сторонниками и противниками ООП в 1С.

Мне не хотелось бы ввязываться в эту полемику, но скажу следующее:
Имеется одна (весьма похожая на 1С) программная среда - "Visual Basic for Applications" (VBA).
Она тоже оперирует с объектами своей предметной области (объектами приложений MS Office),
но там реализована полноценная поддержка классов и вроде бы это ничему не противоречит.
13. yuraos 1003 22.12.13 18:25 Сейчас в теме
(12)***
(10)(9)

А если метод будет в форме, то его нельзя использовать повторно?

Умное замечание!

Когда я писал статью, я был в раздумье: включить этот вариант переиспользования кода или нет.
Но в последний момент передумал, так этот способ не очень удобен по ряду причин:

- Объекты "Форма" или "УправляемаяФорма" отдельно создать можно только на стороне клиентов
(метод ПолучитьФорму() не доступен на сервере). Поэтому на стороне сервера применение этого
варианта переиспользования кода ограничено серверным контекстом управляемых форм.

- В силу узкой специализации объектов "Форма" или "УправляемаяФорма", призванных решать интерфейсные задачи.
На практике этот вариант переиспользования кода в основном используется для нестандартного начального
заполнения данных формы до ее открытия или как один из возможных вариантов организации взаимодействия между
между формами (в подчиненной форме через атрибут "ВладелецФормы" можно вызвать экспортный метод формы-владельца).

Впрочем, спасибо за замечание.
Наверное, стоило об этом упомянуть в публикации - что я и сделаю в скором времени.
14. yuraos 1003 22.12.13 18:25 Сейчас в теме
(13)***
(10)(9)

Что-то я не встречал особо директив компиляции в общих модулях. Наверное потому, что хорошим тоном является разделение модулей на
серверные и клиентские.

Поспорить с утверждением трудно. Но по смыслу это замечание слабо связано с комментируемым в статье местом.
15. yuraos 1003 22.12.13 18:26 Сейчас в теме
(14)***
(10)(9)

Чушь какая-то. Я ни разу не менял модулей (общих) при написании внешних обработок. Они либо пишутся под конкретную конфигурацию,
либо используют уж очень общие модули типа: "СтроковыеФункцииКлиентСервер". А вообще есть правило: "Хочешь потерять данные -
сделай их внешними".

Снова интеллигентно не замечая слова "чушь", хочу сказать,
что замечание тоже не сильно уместно, так как отражает лишь личный опыт его автора.
Из того, что ему ни разу не приходилось чего-то делать, еще не следует, что это не актуально, или что этого не делают другие.

Впрочем, мысль, высказанная в конце замечания – безусловно, ценная!
16. yuraos 1003 22.12.13 18:26 Сейчас в теме
(15)***
(10)(9)

Модуль объекта, Модуль менеджера - это модули оперирования данными. На клиенте данные только отображаются, потому и нет их на
клиенте. Максимум, что 1С могло бы сделать, это их доступность с неявным вызовом сервера. А оно надо? Если надо - вызови явно.

Давать названия вещам надо осторожно.
Проблема том, что названиям свойственно искажать внутреннюю сущность вещей. Неудачные названия порождают стереотипы и шаблоны.

С моей точки зрения Модуль объекта, Модуль менеджера - это просто контейнеры кода, каждый со своим контекстом и способом доступа.
Их использование не ограничено только "оперированием данными".
В обычном приложении они часто используются для решения чисто интерфейсных задач:
- запрос подтверждения действий;
- вывода состояния выполнения;
- вывода предупреждений и сообщений;

Я думаю было бы полезно расширить абстракцию, заложенную в понятие "ОбщийМодуль", и ввести в конфигурацию
сущности нового типа, скажем, "ИсполняемыйМодуль", аналогичные объектам Module из MS VBA.
"ОбщиеМодули" были бы частным случаем объектов "ИсполняемыйМодуль", находящимися примерно
в том же соотношении, что объекты "ОбщаяФорма" и просто "Форма".

Такие пользовательские модули можно было бы подчинять другим объектам метаданных,
локализуя тем самым специфическую функциональность в одном месте.

Подчиненные "ИсполняемыеМодули" могли бы помочь избежать потери функционала,
размещенного в модуле менеджера объекта, при сохранении отчетов и обработок
во внешних отчетах и обработках.

Доступ к подчиненным "ИсполняемымМодулям" на стороне клиентов управляемого приложения (и "вообще")
можно было бы, например, через новый атрибут "Модули" форм, объектов или менеджеров объектов:
// в контексте управляемой формы:
МодульСсылка = ЭтаФорма.Модули[ИмяМодуля]; 

// в контексте прикладного объекта:
МодульСсылка = ЭтотОбъект.Модули[ИмяМодуля]; 

// в контекстах, где доступны менеджеры обработок:
МодульСсылка = Обработки.БлокировкаСоединенийСИнформационнойБазой.Модули[ИмяМодуля];

Показать
17. yuraos 1003 22.12.13 18:28 Сейчас в теме
(16)
***
(10)(9)

А вызов сервера оправдан?
Это легко решить передав таблицу состояний на клиента. А дальше не вызывая сервер:
<...пример исполняемого кода...>

Идея в принципе интересная ... так сказать, всё заготовить на сервере на все случаи жизни в форме.
В принципе я так и поступаю в некоторых случаях.
Например, в работе http://infostart.ru/public/236344/ есть два, фиксированных, часто используемых контекстных меню.
Списки значений этих меню сохраняются в реквизитах формы при создании на сервере.

НО ПРЕДЛАГАЕМЫЙ ПОДХОД - НЕ ЯВЛЯЕТСЯ ПАНАЦЕЕЙ:
Допустим число состояний, используемых в форме, велико, и допустим, что
при использовании формы вероятность реализации конкретного состояния мала;

Очевидно, что в этой ситуации такие "заготовки" - пустая трата ресурсов, как на стороне сервера, так и на стороне клиента.
Так же предлагаемый подход не идеален с точки зрения поддержки и "читаемости" кода.

PS:
- Вообще внеконтекстные вызовы сервера не считаются чем-то плохим, чего следует избегать.
- В принципе даже бытует мнение (с которым я не очень согласен), что какое-то "лишнее" число
серверных контекстных вызовов - меньшее зло, если их оптимизация "слишком" запутывает "читаемость" кода.
...
надо полагать из-за последнего обстоятельства в "управляемых" типовых конфигурациях визуально наблюдаются дикие тормоза.
18. awk 744 22.12.13 22:44 Сейчас в теме
(12) Начнем с главного. Бред и чушь - это попытка окрасить выражения эмоциями. Что достаточно сложно сделать посредством эпистолярного жанра. Так что это выражение моего непонимания, а не попытка задеть. Приятно иметь дело с человеком который это понимает. Если задел извини.

ООП и 1С.

Аналогия просто неуместна, по природе ООП. ООП - наследник процедурного, модульного программирования. Это все равно, что сравнивать отца и сына, при этом ставя в пример отцу сына.

Поспорить с утверждением трудно. Но по смыслу это замечание слабо связано с комментируемым в статье местом.
Это связано с приведенным в статье примером. Там у метода есть директива компиляции, причем ключевое слово "экспорт", почему-то опущено.

Из того, что ему ни разу не приходилось чего-то делать, еще не следует, что это не актуально, или что этого не делают другие.
Да. Мне не приходилось менять общие модули ради внешней обработки. Делать разные версии, под разные конфигурации - приходилось.


В обычном приложении они часто используются для решения чисто интерфейсных задач:
То-то и оно, что в обычном. Я не предрекаю его смерть (вполне хорошее и проверенное решение), но тенденции таковы, что 1С все дальше уходит в сторону распределенных вычислений, с явным выделением кода по местам его действия. Тут редко прокатывает (если прокатывает вообще): "Все на клиента, а там разберемся" или "Дернем сервер пару раз - гигабитка ведь у нас".

Я думаю было бы полезно расширить абстракцию, заложенную в понятие "ОбщийМодуль", и ввести в конфигурацию
сущности нового типа, скажем, "ИсполняемыйМодуль", аналогичные объектам Module из MS VBA.
"ОбщиеМодули" были бы частным случаем объектов "ИсполняемыйМодуль", находящимися примерно
в том же соотношении, что объекты "ОбщаяФорма" и просто "Форма"....
Для начала, неплохо было бы в 1С реализовать пространства имен и метаданные модулей, а не как сейчас (цитата из синтакс-помощника); "Неопределено - т.к. Не предполагается работа из встроенного языка"


Допустим число состояний, используемых в форме, велико, и допустим, что
при использовании формы вероятность реализации конкретного состояния мала;
В классическом веб программировании - это решается возможностью формы вкладывать в формы и асинхронными вызовами (AJAX), к сожалению это проигнорировано 1С. Так что остается три варианта:

1. Использовать разные формы
2. Передавать все необходимые данные на клиента
3. Дергать сервер.


При этом надо учесть, что 1С рекомендует сервак по пустякам не дергать.


- Вообще внеконтекстные вызовы сервера не считаются чем-то плохим, чего следует избегать.
- В принципе даже бытует мнение (с которым я не очень согласен), что какое-то "лишнее" число
серверных контекстных вызовов - меньшее зло, если их оптимизация "слишком" запутывает "читаемость" кода.

Внеконтекстные вызовы сервера предназначены для уменьшения трафика при передачи данных от клиента на сервер. Только этим они отличаются от контекстных.

Пример 1: надо получить контрагента по документу основанию.

клиент сервер
1. форма выбора --> получение формы
2. При изменении <--
3. Получить контрагента --> ДокументОснование["Контрагент"]

В третьем шаге нет смысла тащить на сервер всю форму, со всеми реквизитами. Потому, целесообразно использовать НаСервереБезКонтекста.

В твоем варианте можно просто использовать:

Для методов модуля объекта:

&НаСервереБезКонтекста
Функция Что_то_с_чем_то(ОбъектОбработка, ТипОбработкиСтрока, Параметры)
Возврат ДанныеФормыВЗначение(ОбъектОбработка, Тип(ТипОбработкиСтрока)).НужнаяНамФункция(Параметры);
КонецФункции



Для методов модуля менеджера:

&НаСервереБезКонтекста
Функция Что_то_с_чем_то(Имя, Параметры)
Возврат Обработки[Имя].НужнаяНамФункция(Параметры);
КонецФункции
27. temsan 14.02.17 10:23 Сейчас в теме
(18)
&НаСервереБезКонтекста
Функция Что_то_с_чем_то(Знач ОбъектОбработка, ТипОбработкиСтрока, Параметры)
Возврат ДанныеФормыВЗначение(ОбъектОбработка, Тип(ТипОбработкиСтрока)).НужнаяНамФункция(Параметры);
КонецФункции


По объему передаваемых данных этот метод занимает место между методом автора, и контекстным вызовом.
Еще плюс вашего метода - если использовать преобразования данных формы в объект и обратно, можно в принципе в модуле обработки оперировать реквизитами и табличными частями.
Взял себе на заметку, хороший способ уменьшить трафик, передавая в серверную функцию только один объект (а не всю форму и все ее данные).
28. yuraos 1003 14.02.17 16:34 Сейчас в теме
(27) temsan,
под 8.3 не помню, наверное не пробывал,
а под 8.2 мне не удавалось передавать данные формы в функцию на сервере без контекста
ни в модуле формы, ни в серверный общий модуль с передачей на сервер.

Наверное из-за того, что передавал их по ссылке.

Платформа при этом выдавала мутную ошибку, что "нельзя изменять данные формы",
хотя я даже и не пытался переменной с данными формы что-либо присваивать.
29. temsan 15.02.17 11:17 Сейчас в теме
(28)
Платформа при этом выдавала мутную ошибку, что "нельзя изменять данные формы"

Для этого передаем параметр ОбъектОбработка по значению, но тогда не имеет смысл менять данные формы
Функция Что_то_с_чем_то(Знач ОбъектОбработка, ТипОбработкиСтрока, Параметры)


Оставим этот способ просто как вариант вызова методов модуля объекта, без контекстного вызова сервера.
19. lesenoklenok 35 24.01.14 13:54 Сейчас в теме
Спасибо за интересную статью
20. Styvi 6 03.10.14 17:28 Сейчас в теме
всем спасибо, читал с интересом и статью и комменты, особенно СТАТЬЮ... спасибо АВТОРУ...
21. sanfoto 502 29.06.15 16:06 Сейчас в теме
Ндя прикольно разрабы платформы жгут.... ((((((
Дело в том, что у внешних обработок и отчетов нет менеджера объекта как такового.
А при сохранении встроенной обработки во внешнюю обработку модуль ее менеджера попросту теряется
(кстати, без предупреждения).


на днях случилось у меня это горе "при сохранении встроенной обработки во внешнюю обработку модуль ее менеджера попросту теряется"....

Работаем с "Хранилищем конфигурации", и тут другому программисту срочно понадобилась захваченная мною обработка для временной модификациив рабочей базе .... а мой код еще небыл доведен , ну я недолго думая сохранил в Файл как внешнюю обработку... отменил захват встроенной обработки.
Потом после работы "другого программиста" захватил обработку заново+загрузил свою сохраненую и прощай "мой модуль менеджера" (((((
22. starik-2005 3091 01.02.17 16:31 Сейчас в теме
(21) а вот даже интересно было бы посмотреть код обращения к модулю менеджера внешней обработки )))
23. yuraos 1003 01.02.17 16:39 Сейчас в теме
(22) не в этой жизни и не на этой планете! ;)
24. yuraos 1003 02.02.17 10:15 Сейчас в теме
(23) Честно говоря в архитектуре платформы есть большой недостаток:
У прикладных объектов нет пользовательских исполняемых модулей,
аналогичных общим модулям конфигурации.

В дереве метаданных эти исполняемые модули могли бы размещаться в узлах "Модули",
подчиненных узлам метаданных прикладных объектов.

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

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

Свойство "глобальности" у таких модулей соответствует свойству "стационарности"
(в том смысле, которое оно существует в ООП).

Стационарный исполняемый модуль мыслится доступным через менеджер объектов прикладного типа.
Например: Справочники.ИмяСправочника.Модули.ИмяМодуля.ИмяМетода().

Не стационарные исполняемые модули мыслятся доступными в контексте объекта прикладного типа:
Например: ПеременнаяОбъект.Модули.ИмяМодуля.ИмяМетода()

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

"Клиентские" исполняемые модули прикладного объекта можно было бы включить в контекст управляемой формы
через два дополнительных свойства расширения формы объекта или формы списка объекта прикладного типа:
допустим: СтационарныеМодули и МодулиОбъекта.
25. yuraos 1003 02.02.17 10:18 Сейчас в теме
(24) По хорошему эти изменения нужно было вносить в архитектуру платформы с появлением управляемого приложения (платформа версии 8.2).
Но увы, что имеем - то имеем.
26. yuraos 1003 02.02.17 10:24 Сейчас в теме
(21) ну что ж, sanfoto, сохраняй на всякий случай всю свою конфу.
для отчетов - та же заподляна будет.
30. bulpi 217 28.03.17 18:55 Сейчас в теме
Познавательно, плюс поставил, но практически для меня полезности ноль. Выдумывать хитрые велосипеды, когда можно поступить, как обычно, не стоит. Потом тебя будет материть тот, кто будет поддерживать после тебя. И ты сам себя через полгода.
31. SlavaKron 08.11.18 14:23 Сейчас в теме
Мы ведь знаем имя нашей внешней обработки, не проще ли вместо
Обработка = Новый (ЗначениеИзСтрокиВнутр(ОбработкаТип))
использовать
Обработка = Новый ("ВнешняяОбработкаОбъект.МояВнешняяОбработка")

Тогда и не придется создавать лишний реквизит формы и передавать его на сервер.
32. yuraos 1003 08.11.18 17:24 Сейчас в теме
(31) Не всегда так можно обратиться к внешней обработке.
Для этого она в соединении с базой должна быть "правильно подключена".

Для обработки открываемой из внешнего файла, а не из справочника "Дополнительные бла-бла-бла",
это точно - не вариант.
33. SlavaKron 08.11.18 17:51 Сейчас в теме
(32) Почему вы так считаете? Я проверил оба варианта и в обоих работает.
34. yuraos 1003 08.11.18 20:06 Сейчас в теме
(33) Ладно, работает.
Но сути дела это тоже самое, только вместо самого типа объекта
в операторе Новый используется строковое имя типа.

Теперь пара ехидных вопроса:
1. Что будет если вашу обработку встроить в конфигурацию?
2. Что будет если ваш код перенести в обработку с другим именем
или даже еще лучше в отчет ??
35. PerlAmutor 155 05.08.21 19:19 Сейчас в теме
Пусть тут полежит:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    Обработка = РеквизитФормыВЗначение("Объект");
    ДобавляемыеРеквизиты = Новый Массив;
    РеквизитСлужебныеДанные1 = Новый РеквизитФормы("СлужебныеДанные1", Новый ОписаниеТипов("Неопределено"));
    РеквизитСлужебныеДанные2 = Новый РеквизитФормы("СлужебныеДанные2", Новый ОписаниеТипов("Неопределено"));
    ДобавляемыеРеквизиты.Добавить(РеквизитСлужебныеДанные1);
    ДобавляемыеРеквизиты.Добавить(РеквизитСлужебныеДанные2);
    ЭтотОбъект.ИзменитьРеквизиты(ДобавляемыеРеквизиты);

    // Метод 1
    Данные = Новый Структура("Обработка", Обработка);
    НовыйАдресХранилища = ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор);
    ЭтотОбъект.СлужебныеДанные1 = НовыйАдресХранилища;

    // Метод 2
    Типы = Новый Массив;
    Типы.Добавить(ТипЗнч(Обработка));
    ЭтотОбъект.СлужебныеДанные2 = Новый ОписаниеТипов(Типы);

КонецПроцедуры

#Область Метод1
&НаКлиенте
Процедура Команда1(Команда)
    Сообщить(ОбработатьДанныеМетод1("Метод1"));
КонецПроцедуры

&НаКлиенте
Функция ОбработатьДанныеМетод1(Данные)
    Возврат ОбработатьДанныеМетод1ВызовСервера(Данные, ЭтотОбъект.СлужебныеДанные1);
КонецФункции

&НаСервереБезКонтекста
Функция ОбработатьДанныеМетод1ВызовСервера(Данные, Знач АдресХранилища)

    Если ЭтоАдресВременногоХранилища(АдресХранилища) Тогда
        Обработка = ПолучитьИзВременногоХранилища(АдресХранилища).Обработка;
        Возврат Обработка.ОбработатьДанные(Данные);
    КонецЕсли;

КонецФункции
#КонецОбласти

#Область Метод2
&НаКлиенте
Процедура Команда2(Команда)
    Сообщить(ОбработатьДанныеМетод2("Метод2"));
КонецПроцедуры

&НаКлиенте
Функция ОбработатьДанныеМетод2(Данные)
    Возврат ОбработатьДанныеМетод2ВызовСервера(Данные, ЭтотОбъект.СлужебныеДанные2);
КонецФункции

&НаСервереБезКонтекста
Функция ОбработатьДанныеМетод2ВызовСервера(Данные, Знач ТипОбработка)

    Обработка = ТипОбработка.ПривестиЗначение();
    Возврат Обработка.ОбработатьДанные(Данные);

КонецФункции
#КонецОбласти
Показать
Оставьте свое сообщение