IE 2016

Методика упрощения поддержки конфигураций. Переопределение и вызов обработчиков событий для УФ 1С 8.2-8.3

Опубликовал pbazeliuk в раздел Администрирование - Оптимизация БД (HighLoad)

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

Этот метод появился на свет благодаря публикации http://infostart.ru/public/16980/ и внедрения конфигурации «Управление торговлей, редакция 11» в не российской торговой компании, из чего следует, что переписано и изменено было очень многое. С выходом каждого нового обновления, для внесения этих изменений, уходило все больше времени и на пике достигало уже до месяца и выливалось в огромные затраты. Так же при выявлении ошибок их нужно было исправлять оперативно и быстро, что со 100-150 одновременно работающими пользователями составляло огромную проблему. 


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

Что же для этого нужно? Рассматриваемый пример работает на конфигурации «Управление торговлей, редакция 11», для любой другой конфигурации адаптировать его не составит большого труда.

1. Нужно создать общий модуль МодульПереназначенияОбработчиков, вот такой он у меня: 

// Общая процедура перед переназначения обработчиков
//
// Параметры:
//  УправляемаяФорма – УправляемаяФорма – Управляемая форма.
//

Процедура ПереназначитьОбработчики(УправляемаяФорма) Экспорт
    Если
ТипЗнч(УправляемаяФорма) = Тип("УправляемаяФорма") Тогда
       
ОбщаяВнешняяОбработка = ПолучитьВнешнийОбъект("Библиотека внешних обработок");

       
ВнешняяОбработкаСерийныеНомера = ПолучитьВнешнийОбъект("Серийные номера");
       
ИмяВнешнейОбработкиСерийныеНомера = ПолучитьИмяВнешнегоОбъекта("Серийные номера");
       
ВнешняяОбработкаСерийныеНомера.ПодготовитьСерийныеНомераКРаботе(УправляемаяФорма, ОбщаяВнешняяОбработка, ИмяВнешнейОбработкиСерийныеНомера);

       
ОбщаяВнешняяОбработка.ПодменитьДействиеУправляемоеПриложение(УправляемаяФорма, "ПриЗакрытии", , "ВыполнитьОткатОбработчиков");

       
//Пример как можно изменить свойства управляемой формы
       
УправляемаяФорма.ПоведениеКлавишиEnter = ТипПоведенияКлавишиEnter.ПереходПоЭлементамФормы;
    КонецЕсли;
КонецПроцедуры


// Получаем внешнюю обработку или внешний отчет.
//
// Параметры:
//  ИмяВнешнегоОбъекта – Строка - имя внешнего объекта;
//  ЭтоОтчет – Булево – Ложь (Внешняя обработка), Истина (Внешний отчет).
//
// Возвращаемое значение:
//             – ВнешняяОбработка или ВнешнийОтчет
//

Функция ПолучитьВнешнийОбъект(ИмяВнешнегоОбъекта, ЭтоОтчет = Ложь) Экспорт
   
Ссылка          = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию(ИмяВнешнегоОбъекта);
    Если
Ссылка = Неопределено Тогда
        ВызватьИсключение
"Внешний объект с именем не найден: " + ИмяВнешнегоОбъекта;
    КонецЕсли;
   
ДвоичныеДанные  = Ссылка.ХранилищеОбработки.Получить();
   
АдресХранилища  = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
   
ИмяВнОбработки  = ?(ЭтоОтчет, ВнешниеОтчеты, ВнешниеОбработки).Подключить(АдресХранилища, , Ложь);
   
ОбработкаОбъект = ?(ЭтоОтчет, ВнешниеОтчеты, ВнешниеОбработки).Создать(ИмяВнОбработки);
    Возврат
ОбработкаОбъект;
КонецФункции


// Получаем имя внешней обработки или внешнего отчета.
//
// Параметры:
//  ИмяВнешнегоОбъекта – Строка - имя внешнего объекта;
//  ЭтоОтчет – Булево – Ложь (Внешняя обработка), Истина (Внешний отчет).
//
// Возвращаемое значение:
//             – Строка - Имя внешней обработки или отчета.
//

Функция ПолучитьИмяВнешнегоОбъекта(ИмяВнешнегоОбъекта, ЭтоОтчет = Ложь) Экспорт
   
Ссылка = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию(ИмяВнешнегоОбъекта);
    Если
Ссылка = Неопределено Тогда
        ВызватьИсключение
"Внешний объект с именем не найден: " + ИмяВнешнегоОбъекта;
    КонецЕсли;
   
ДвоичныеДанные  = Ссылка.ХранилищеОбработки.Получить();
   
АдресХранилища  = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
    Возврат ?(
ЭтоОтчет, ВнешниеОтчеты, ВнешниеОбработки).Подключить(АдресХранилища, , Ложь);
КонецФункции


// Получаем ссылку на элемент справочника ДополнительныеОтчетыИОбработки.
//
// Параметры:
//  ИмяВнешнегоОбъекта – Строка - имя внешнего объекта;
//
//
// Возвращаемое значение:
//             – СправочникСсылка.ДополнительныеОтчетыИОбработки - ссылка на элемент справочника ДополнительныеОтчетыИОбработки.
//

Функция ПолучитьСсылкуНаВнешнийОбъект(ИмяВнешнегоОбъекта) Экспорт
    Возврат
Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию(ИмяВнешнегоОбъекта);
КонецФункции

 

2. Далее, нужно загрузить общую внешнюю обработку в режиме предприятия. Код обработки:

// Функция добавляет элемент в коллекцию элементов формы и возращает его.
//
// Параметры:
//  ЭлементыФормы – ВсеЭлементыФормы – Содержит коллекцию всех элементов управляемой формы;
//  Параметры – Структура – параметры добавляемого элемента;
//  Родитель – ГруппаФормы, ТаблицаФормы, УправляемаяФорма – родитель добавляемого элемента.
//
// Возвращаемое значение:
//             – ДекорацияФормы, ГруппаФормы, КнопкаФормы, ТаблицаФормы, ПолеФормы – элемент управляемой формы.
//

Функция ДобавитьЭлементВКоллекциюЭлементовФормы(ЭлементыФормы, Параметры, Родитель = Неопределено) Экспорт

    Перем
ИмяЭлемента, ТипЭлемента;

    Если НЕ
ТипЗнч(Параметры) = Тип("Структура") Тогда
        ВызватьИсключение
"Параметры элемента формы не заданы!";
    КонецЕсли;

    Если НЕ
Параметры.Свойство("Имя", ИмяЭлемента) Тогда
        ВызватьИсключение
"Имя элемента формы не задано!";
    КонецЕсли;

    Если НЕ
Параметры.Свойство("ТипЭлемента", ТипЭлемента) Тогда
        ВызватьИсключение
"Тип элемента формы не задан!";
    КонецЕсли;

    Если НЕ
Родитель = Неопределено Тогда
        Если
ТипЗнч(Родитель) <> Тип("ГруппаФормы")
         И  
ТипЗнч(Родитель) <> Тип("ТаблицаФормы")
         И  
ТипЗнч(Родитель) <> Тип("УправляемаяФорма") Тогда
            ВызватьИсключение
"Родитель должен иметь один из перечисленных типов: ГруппаФормы; ТаблицаФормы; УправляемаяФорма.";
        КонецЕсли;
    КонецЕсли;

   
ЭлементФормы = ЭлементыФормы.Добавить(ИмяЭлемента, ТипЭлемента, Родитель);
   
ЗаполнитьЗначенияСвойств(ЭлементФормы, Параметры);
    Возврат
ЭлементФормы;

КонецФункции


// Функция добавляет команду в коллекцию команд формы и возращает его.
//
// Параметры:
//  Команды – КомандыФормы – Содержит коллекцию всех элементов управляемой формы;
//  Параметры – Структура – параметры добавляемой команды.
//
// Возвращаемое значение:
//             – КомандаФормы – команда управляемой формы.
//

Функция ДобавитьКомандуВКоллекциюКомандФормы(Команды, Параметры) Экспорт

    Перем
ИмяЭлемента;

    Если НЕ
ТипЗнч(Параметры) = Тип("Структура") Тогда
        ВызватьИсключение
"Параметры команды не заданы!";
    КонецЕсли;

    Если НЕ
Параметры.Свойство("Имя", ИмяЭлемента) Тогда
        ВызватьИсключение
"Имя команды не задано!";
    КонецЕсли;

   
Команда = Команды.Добавить(ИмяЭлемента);
   
ЗаполнитьЗначенияСвойств(Команда, Параметры);
    Возврат
Команда;

КонецФункции

Процедура
ПереместитьЭлементВКоллекциюЭлементовФормы(ЭлементыФормы, ИмяЭлемента, ИмяРодителя, МестоРасположения) Экспорт
   
ЭлементыФормы.Переместить(ЭлементыФормы.Найти(ИмяЭлемента), ЭлементыФормы.Найти(ИмяРодителя), ЭлементыФормы.Найти(МестоРасположения));
КонецПроцедуры


// Переопределяет обработчик события формы.
// Сохраняет штатный обработчик события внутри формы и устанавливает новый.
//
// Параметры:
//  Форма – УправляемаяФорма – Управляемая форма;
//  ИмяСобытияФормы – Строка – имя события;
//  ПолноеИмяЭлементаФормы – Строка – полное имя элемента формы;
//  НовоеДействие - Строка - имя процедуры обработчика;
//  ОбработкаИсключений – Булево – сообщать о наличии старого обработчика.
//

Процедура ПодменитьДействиеУправляемоеПриложение(Форма, ИмяСобытияФормы = "", ПолноеИмяЭлементаФормы = "", НовоеДействие, ОбработкаИсключений = Ложь) Экспорт

   
Объект = Форма;
   
ИмяЭлементаФормы = "";
    Если НЕ
ПустаяСтрока(ПолноеИмяЭлементаФормы) Тогда

       
МассивФрагментов = РазобратьСтрокуВМассивПоРазделителю(ПолноеИмяЭлементаФормы);
       
ИмяЭлементаФормы = МассивФрагментов[0];
       
Объект = Форма.Элементы.Найти(ИмяЭлементаФормы);
        Если
Объект = Неопределено Тогда
            ВызватьИсключение
"Элемент формы: " + ИмяЭлементаФормы + " не найден!";
        КонецЕсли;

        Если
МассивФрагментов.Количество() > 1 Тогда
           
ИмяЭлементаФормы = ИмяЭлементаФормы + МассивФрагментов[1];
            Если
ТипЗнч(Объект) = Тип("ТаблицаФормы") Тогда
               
Объект = Объект.Колонки[МассивФрагментов[1]].ЭлементУправления;
            ИначеЕсли
ТипЗнч(Объект) = Тип("КоманднаяПанель") Тогда
               
Объект = Объект.Кнопки[МассивФрагментов[1]];
            Иначе
                ВызватьИсключение
"Ошибка на этапе получения элемента формы. Тип значения(" + ТипЗнч(Объект) + ")";
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;

   
СтарыеОбработчики = "OldHandlers";
   
МассивРеквизитов = Форма.ПолучитьРеквизиты();
    Для Каждого
РеквизитФормы Из МассивРеквизитов Цикл
        Если
РеквизитФормы.Имя = СтарыеОбработчики Тогда
           
СтарыеОбработчики = Неопределено;
            Прервать;
        КонецЕсли;
    КонецЦикла;

    Если НЕ
СтарыеОбработчики = Неопределено Тогда
       
МассивНовыхРеквизитов = Новый Массив;
       
МассивНовыхРеквизитов.Добавить(Новый РеквизитФормы(СтарыеОбработчики, Новый ОписаниеТипов("СписокЗначений")));
       
Форма.ИзменитьРеквизиты(МассивНовыхРеквизитов);
    КонецЕсли;

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

    Если
ОбработкаИсключений И НЕ СтароеДействие = Неопределено Тогда
        ВызватьИсключение
"Конфликт обработчиков события """ + ИмяСобытияФормы + """ объекта """ + Строка(Объект) + """";
    КонецЕсли;

    Если
ТипЗнч(Объект) = Тип("КнопкаФормы") Тогда
       
Объект.ИмяКоманды = НовоеДействие;
    Иначе
       
Объект.УстановитьДействие(ИмяСобытияФормы, НовоеДействие);
    КонецЕсли;

   
OldHandlers = Форма.OldHandlers;
    Если НЕ
СтароеДействие = Неопределено И НЕ ПустаяСтрока(СтароеДействие) Тогда
       
OldHandlers.Добавить(ИмяЭлементаФормы + "." + ИмяСобытияФормы, СтароеДействие);
    КонецЕсли;
КонецПроцедуры


// Возвращает старый обработчик события формы.
//
// Параметры:
//  Форма – УправляемаяФорма – Управляемая форма;
//  ИмяСобытияФормы – Строка – имя события;
//  ПолноеИмяЭлементаФормы – Строка – полное имя элемента формы;
//  СтароеДействие - Строка - имя процедуры обработчика.
//

Процедура ОткатитьДействиеУправляемоеПриложение(ФормаИмяСобытияФормы = "", ПолноеИмяЭлементаФормы = "", СтароеДействие) Экспорт

   
Объект = Форма;
   
ИмяЭлементаФормы = "";
    Если НЕ
ПустаяСтрока(ПолноеИмяЭлементаФормы) Тогда

       
МассивФрагментов = РазобратьСтрокуВМассивПоРазделителю(ПолноеИмяЭлементаФормы);
       
ИмяЭлементаФормы = МассивФрагментов[0];
       
Объект = Форма.Элементы.Найти(ИмяЭлементаФормы);
        Если
Объект = Неопределено Тогда
            ВызватьИсключение
"Элемент формы: " + ИмяЭлементаФормы + " не найден!";
        КонецЕсли;

        Если
МассивФрагментов.Количество() > 1 Тогда
           
ИмяЭлементаФормы = ИмяЭлементаФормы + МассивФрагментов[1];
            Если
ТипЗнч(Объект) = Тип("ТаблицаФормы") Тогда
               
Объект = Объект.Колонки[МассивФрагментов[1]].ЭлементУправления;
            ИначеЕсли
ТипЗнч(Объект) = Тип("КоманднаяПанель") Тогда
               
Объект = Объект.Кнопки[МассивФрагментов[1]];
            Иначе
                ВызватьИсключение
"Ошибка на этапе получения элемента формы. Тип значения(" + ТипЗнч(Объект) + ")";
            КонецЕсли;
        КонецЕсли;

    КонецЕсли;

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


// Возвращает старые обработчики событий формы.
// Сохраняет штатный обработчик события внутри формы и устанавливает новый.
//
// Параметры:
//  Форма – УправляемаяФорма – Управляемая форма.
//

Процедура ВыполнитьОткатОбработчиков(Форма) Экспорт
    Для Каждого
Обработчик Из Форма.OldHandlers Цикл
       
Строка      = Обработчик.Значение;
       
ИндексТочки = Найти(Строка, ".");
       
ОткатитьДействиеУправляемоеПриложение(Форма, Прав(Строка, СтрДлина(Строка)-ИндексТочки), Лев(Строка, ИндексТочки-1), Обработчик.Представление);
    КонецЦикла;
КонецПроцедуры


// Функция разбивает строку разделителем.
//
// Параметры:
//  Строка - Строка - которую разбиваем;
//  Разделитель - Строка - символ-разделитель.
//
// Возвращаемое значение:
//             - Массив - содержащий фрагменты, на которые разбивает строку разделитель.
//

Функция РазобратьСтрокуВМассивПоРазделителю(Строка, Разделитель = ".") Экспорт
   
МассивСтрок = Новый Массив;
   
СтрокаЗамены = СтрЗаменить(Строка, Разделитель, Символы.ПС);
    Для
i=1 По СтрЧислоСтрок(СтрокаЗамены) Цикл МассивСтрок.Добавить(СтрПолучитьСтроку(СтрокаЗамены, i)); КонецЦикла;
    Возврат
МассивСтрок;
КонецФункции

 

На данном этапе, все уже готово для использования. Вот видео-пример использования механизма.

Статья в нашем блоге: www.avtomat.biz


UPDATE (24.03.2014): 
Изменена схема работы метода, проведена оптимизация и исправлены некоторые недочеты. Все это можно посмотреть в новом архиве к статье. Так же сама статья расширена.

 

ОТВЕТЫ НА ВОПРОСЫ:

  1. Для каких конфигураций подходит данный модуль?  механизм предназначен для работы с 1С Предприятие 8.2-8.3, основной режим запуска: "Управляемое приложение", так же конфигурация должна использовать "Библиотеку стандартных подсистем" (БСП), в противном случае нужно будет создать справочник "ДополнительныеОтчетыИОбработки" аналогичный как в БСП;
  2. Какие изменения нужно внести в конфигурацию?  нужно добавить в конфигурацию несколько общих модулей, а так же внести изменения в необходимую управляемую форму (УФ) в конце модуля и для подмены событий этой формы в обработчики ПриСозданииНаСервере() или ПриЧтенииНаСервере(). Реквизиты и табличные части документов можно добавлять, если вам нужно хранить учетные данные;
  3. Как влияет на "быстродействие" использование внешних обработок?  когда используется одна внешняя обработка ничего не заметно для конечного пользователя, когда парк обработок увеличивается скорость запуска формы увеличивается в среднем на ~0.3с с каждой новой обработкой. Не надо паниковать  проблема уже решена;
  4. Как можно вызвать старый обработчик события?  вызвать процедуру ВыполнитьДействиеПоУмолчанию() в которую передать имя события и массив параметров;
  5. Как методика упрощает обновление конфигурации?  после обновления достаточно перенести обработчики переопределения в обновленную конфигурацию и даже если появились новые штатные обработчики событий они будут работать верно в повальном количестве случаев. Управляемые формы не нужно изменять вручную - это все можно сделать с помощью этой методики програмно;
  6. Методика увеличивает время разработки?  да увеличивает время разработки. Если уже несколько форм переделано этим методом – тогда затраты времени ростут незначительно, а затраты на обновление конфигурации уменьшается очень существенно;
  7. Есть критическая ошибка, но пользователей нельзя отключать от базы, что делать? - достаточно внести измения во внешную обработку, изменить ее версию и подключить к базе. После этого, пользователи автоматически уже будут использовать исправленную версию обработки. А ночью обновить общий модуль, который связан с внешней обработкой для более комфортного использования конфигурации.

 

КЛЮЧЕВЫЕ ИЗМЕНЕНИЯ:

  1. У всех общих модулей снято свойство "Вызов сервера", теперь вызов из модуля формы выполняется вот так: &НаКлиенте -> &НаСервере -> ОбщийМодульСервер;
  2. Для сокращения запуска и вызова внешних обработчиков событий, код доработок дублируется в общих модулях. При запуске проверяется версия общего модуля с версией внешней обработки из справочника "ДополнительныеОтчетыИОбработки". Если версии совпадают УФ будет работать с контекстом общего модуля, если версии отличаются вызов процедур и функций будет осуществляется из внешнего объекта;
  3. Переработана работа с контекстом &НаКлиенте  код из форм внешнего объекта дублируется в общем клиентском модуле;
  4. Сам метод переопределения обработчиков событий оформлен так же как внешняя обработка, что добавляет некоторую дополнительную гибкость;
  5. Проверка на дополнительный вызов переназначения обработчиков. 

 

ТАК КАК ЖЕ ЭТО РАБОТАЕТ:

  1. Пользователь открывает документ происходит вызов ПриСозданииНаСервере() или ПриЧтенииНаСервере(). В одну или в обе процедуры мы добавляем наш вызов git_ПереопределениеОбработчиковСервер.ПереопределитьОбработчикиСобытий(ЭтаФорма). Как понять куда добавлять?  нужно посмотреть есть ли переопределение обработчиков в стандартной конфигурации (в УТ 11 оно есть), и добавить перед этим переопределением свой вызов;
  2. Далее идет переход в общий модуль "git_ПереопределениеОбработчиковСервер" в котором определяется первый ли это вызов (на случай, если добавили обработчики в ПриСозданииНаСервере() или ПриЧтенииНаСервере());
  3. Идет проверка версии модуля с версией внешней обработки, если версии одинаковые будет использоваться общий модуль git_ПереопределениеОбработчиковСервер, если версии различные будет использоваться внешняя обработка;
  4. Далее идет такая же проверка для каждой подключаемой внешней обработки (код можно посмотреть в файле .cf) и внутри каждой подключаемой обработки или общего модуля проверяется путь к механизму переопределения для вызова функций и процедур (общий модуль переопределения или модуль внешней обработки, служебные процедуры и функции обозначены комментарием // Только для внутреннего использования); 
  5. Ура! Форма пользовательского документа открылась, теперь так же необходимые функции запускаются из общего модуля (клиент, сервер) или из модуля\формы внешней обработки;
  6. Вызов обработчиков по умолчанию исполняеться с помощь вызова процедуры ВыполнитьДействиеПоУмолчанию();
  7. После закрытия формы все обработчики будут восстанавливаться для избежания проблем с кешированием форм.

Статья в нашем блоге (часть 2): www.avtomat.biz

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
cf+epf
.7z 36,30Kb
24.03.14
97
.7z 36,30Kb 97 Скачать

См. также

Лучшие комментарии

22. pbazelyuk 23.03.2014 03:13
(17) ivanov660, (20) zakov, вот часть 2 - avtomat.biz
+ 1 [ teflon; ]
# Ответить
5. alekseies 11.02.2013 10:06
Также жалко, что в управляемых формах нет секции инициализации или операторов основной программы. Тогда не пришлось бы вторгаться в штатную процедуру ПриСозданииНаСервере. Так же считаю что процедура обработки должна находиться в контексте формы, легче отслеживать изменения конфигурации ......
Ответили: (7)
+ 1 [ RomanRomans; ]
# Ответить
1. Поручик 10.02.2013 15:43
Пока не пробовал, но работа хорошая. Жалко, что в управляемых формах нет секции инициализации или операторов основной программы. Тогда не пришлось бы вторгаться в штатную процедуру ПриСозданииНаСервере.
+ 1 [ RomanRomans; ]
# Ответить

Комментарии

1. Поручик 10.02.2013 15:43
Пока не пробовал, но работа хорошая. Жалко, что в управляемых формах нет секции инициализации или операторов основной программы. Тогда не пришлось бы вторгаться в штатную процедуру ПриСозданииНаСервере.
+ 1 [ RomanRomans; ]
# Ответить
2. MarSeN (файл скачал) 10.02.2013 23:42
Доброе время суток.
Спасибо автору за статью - обязательно скачаю и попробую. Интересный подход в котором надо разобраться.
Плюс в копилку.
Как вариант решения описанной задачи 2 статьи:
http://infostart.ru/public/171514/?fruser=yes#users_raters
http://infostart.ru/public/170935/
Судя по описанию Ваш подход к переопределению обработчиков не требует вставки кода в модуль формы, надо посмотреть как реализовано. Я считал что процедура обработки должна находиться в контексте формы.
Буду признателен, если Вы в 2-х словах опишите механизм
Ответили: (3)
# Ответить
3. Baza 10.02.2013 23:51
(2) MarSeN, Добрый вечер, модуль формы требует изменения в процедуре "ПриСозданииНаСервере" и вставки ваших функций в конец модуля формы. Когда появиться возможность подписки на события формы, этих действий уже не потребуется.

Основной упор делается на то, что изменения в свои обработчики можно вносить без обновления конфигурации - просто обновляя внешнюю обработку, а так же сходство с подходом для 8.1, который описал в свое время tormozit. В видео это продемонстрировано.
Ответили: (6)
# Ответить
4. MarSeN (файл скачал) 10.02.2013 23:55
(3) Baza
Спасибо, получается что в принципе подходы у нас одинаковые ). Хранение кода в разных местах. Потребность диктует решения.
# Ответить
5. alekseies 11.02.2013 10:06
Также жалко, что в управляемых формах нет секции инициализации или операторов основной программы. Тогда не пришлось бы вторгаться в штатную процедуру ПриСозданииНаСервере. Так же считаю что процедура обработки должна находиться в контексте формы, легче отслеживать изменения конфигурации ......
Ответили: (7)
+ 1 [ RomanRomans; ]
# Ответить
6. plevakin 11.02.2013 15:01
(3) Baza, Когда появиться возможность подписки на события формы

А когда эта возможность появится?
Ответили: (8)
# Ответить
7. akomar 11.02.2013 15:06
(5) Зато очень легко вносить изменения в обоработку, на лету, без отключения пользователей от базы, что критично при большом количестве пользователей.
# Ответить
8. pbazelyuk 11.02.2013 16:02
(6) plevakin, в платформе 8.3.
# Ответить
9. tormozit 12.02.2013 10:35
Было бы неплохо указать ссылку и на основу, опубликованную на инфостарте http://infostart.ru/public/16980/ .
Ответили: (10) (15)
# Ответить
10. pbazelyuk 12.02.2013 22:38
(9) tormozit, изменил.
# Ответить
11. Азбука Морзе 13.02.2013 13:22
Отличная работа. Обязательно приму на вооружение.

п.с. В прошлой жизни так припекло с обновлением переделанной УТ11, что пришлось застрелится:)
# Ответить
12. fr.myha 14.02.2013 17:16
Интересный материал.
# Ответить
13. alekseies 15.02.2013 10:54
изменения можно вносить и в модуль формы, и также без отключения пользователей от базы, динамическое обновление, только изменения вносить программно .....
Ответили: (14)
# Ответить
14. pbazelyuk 15.02.2013 13:12
(13) alekseies, динамическое обновление в высоконагруженной базе в часто приводит к крашу базы, сама 1С не рекомендует его применять и еще что бы пользователь мог использовать обновления ему нужно перезапустить базу (для каждого сеанса конфигурация кешируеться). В данном методе все безопасно и перезагружать пользователю базу не нужно.
# Ответить
15. TODD22 18.02.2013 09:17
(9) Не открывается. Пишет что публикация не активна.
# Ответить
16. ivanov660 (файл скачал) 16.03.2013 09:33
Статья заинтересовала. Буду смотреть, надеюсь это поможет в нашей ситуации.
# Ответить
17. ivanov660 (файл скачал) 07.05.2013 15:56
Посмотрел, кое что понравилось и буду использовать что-то.
Вопрос: А как влияет на "быстродействие" использование внешних обработок? Я бы, к примеру, создал "Библиотека внешних обработок" как внутреннюю обработку.
Ответили: (18) (19) (22)
# Ответить
18. pbazelyuk 10.05.2013 09:38
(17) ivanov660, на быстродействие никак особо не влияет.
# Ответить
19. pbazelyuk 19.03.2014 15:14
(17) ivanov660, с ростом числа подключенных обработок начало влиять. К понедельнику выкачу новую статью с оптимизацией данного метода.
# Ответить
20. zakov 20.03.2014 13:27
Спасибо за статью, метод классный. Не пойму только как можно вызвать старый обработчик?
Ответили: (21) (22)
# Ответить
21. pbazelyuk 20.03.2014 23:04
(20) zakov, к понедельнику в продолжении статьи все опишу.
# Ответить
22. pbazelyuk 23.03.2014 03:13
(17) ivanov660, (20) zakov, вот часть 2 - avtomat.biz
+ 1 [ teflon; ]
# Ответить
23. Andry.Boris 25.03.2014 00:19
Спасибо за статью,
очень интересная реализация...
# Ответить
24. amon_ra 25.03.2014 14:25
Отлично. Пожалуй возьму себе на заметку. Огромное спасибо!
# Ответить
25. higs 26.03.2014 21:28
Присоединяюсь, интересный подход. И достаточно универсален. Спасибо!!
# Ответить
26. Alex_Japanese_Student 30.03.2014 07:11
Плюсую, сильная разработка, очень поможет
# Ответить
27. 0vrcr 03.03.2015 14:37
А не появилось варианта назначения нового обработчика на динамически созданный элемент? И чтобы сам обработчик был в глобальном модуле?

Например, создаем РегистрСведенийНаборЗаписей динамически на форме. Подключаем обработчик ПриИзменении. И чтобы этот обработчик хранился в общем модуле?
Ответили: (28)
# Ответить
28. pbazeliuk 03.03.2015 17:45
(27) 0vrcr, появилось что-то похожее, но все равно нужно добавить в форму процедуру\функцию перенаправления на общие модуля\внешние модуля
# Ответить
29. 0vrcr 05.03.2015 17:49
Ясно. Ну этот метод я знаю, сам использую. Жаль, спасибо! :)
# Ответить
30. CheBurator 05.03.2015 19:20
Было бы интересно почитать весьма про "внедрения конфигурации «Управление торговлей, редакция 11» в не российской торговой компании, из чего следует, что переписано и изменено было очень многое." - такие проекты не частые гости...
Ответили: (31) (32)
# Ответить
31. pbazeliuk 06.03.2015 03:59
(30) CheBurator, возможно, когда-то. На самом деле реализовано много, что-то более 7000 задач только на разработку, 3000 обращений на поддержку каждый месяц. А конца так и не видно...
# Ответить
32. pbazeliuk 06.03.2015 04:04
(30) CheBurator, самое, наверное, интересное - партионная себестоимость, которая полностью за месяц пересчитывается за 1-3 минуты, без перепроведения документов и использования последовательностей.
# Ответить
33. mikhailv (файл скачал) 02.04.2015 14:32
Видео из статьи не воспроизводится: ролик не найден. Почините, пожалуйста.
Ответили: (34)
# Ответить
34. pbazeliuk 03.04.2015 09:43
(33) mikhailv, добрый день, к сожалению, видео безвозвратно утеряно. Постараюсь на выходных обновить статью и снять новое видео.
# Ответить
35. Cyberhawk (файл скачал) 30.05.2016 18:23
Я правильно понимаю, что нет возможности размещать ЭУ (элементы управления - например, поле формы) в произвольном месте родителя (группы формы)?
Т.е. программно добавляемые ЭУ всегда размещаются в конце (справа или снизу).

//
Отбой, нашел метод Вставить() вместо Добавить()
Ответили: (36)
# Ответить
36. pbazeliuk 31.05.2016 09:46
(35) Cyberhawk, используйте процедуру ПереместитьЭлементВКоллекциюЭлементовФорм, если нужно изменить место расположения.
# Ответить
Внимание! За постинг в данном форуме $m не начисляются.
Внимание! Для написания сообщения необходимо авторизоваться
Текст сообщения*
Прикрепить файл