Введение
Рассмотрим ситуацию, когда в дорабатываемой конфигурации используется подсистема БСП - "Обновление версии ИБ". Эта подсистема позволяет при изменении версии основной конфигурации запускать обработчики обновления для перехода на новую версию. Например, в новой версии конфигурации изменилась структура регистра/справочника и т.п.. И после обновления базы необходимо произвести перенос из старых, ныне не используемых реквизитов, в новые. Это один из самых простых вариантов использования обработчиков обновления. На деле ситуации бывают сложнее и интереснее, но это не тема текущей статьи. Будем считать, что мы уже знакомы с этой подсистемой БСП, и нас интересует добавление собственных обработчиков обновления.
Стандартный метод
В документации БСП можно найти инструкцию - что делать, в случае если вам понадобилось добавление собственных обработчиков обновления. А именно, предлагается изменить имя основной конфигурации на собственное, и проставить собственную версию основной конфигурации. Далее необходимо создать подсистему (Добавить модуль ОбновлениеИнформационнойБазы<Постфикс>) - и дать ей недавно установленное имя основной конфигурации. И в рамках этой, вновь добавленной подсистемы и реализовывать собственные обработчики обновления. А типовую подсистему, которая прежде имела имя основной конфигурации, предлагается добавить в качестве требуемой (подчиненной, зависимой) к нашей. Таким образом мы будем изменять версию основной конфигурации, запуская процесс обновления на нашу версию, который потянул бы за собой и типовые обработчики обновления т.к. типовая подсистема объявлена требуемой.
Но такой подход не очень удобен по нескольким причинам:
1) При обновлении конфигурации требуется следить за тем, чтобы не затереть имя и версию основной конфигурации.
2) После обновления конфигурации изменится версия конфигурации поставщика, но версия основной конфигурации останется не тронутой (если мы соблюли 1 пункт). Поэтому что бы спровоцировать запуск обновления ИБ - потребуется дополнительно вручную изменить версию основной конфигурации.
3) Третья причина не совсем практическая, а больше про порядок. Если мы приняли решение дорабатывать конфигурацию используя расширение, то изменение имени и версии корня основной конфигурации кажется избыточным, когда у нас вся эта информация уже содержится в расширении (У расширения есть собственное имя, и версия)
Метод с использованием расширения
Поэтому когда мы используем расширение, то предлагается следующий подход:
Создаем подсистему (Добавить модуль ОбновлениеИнформационнойБазы<Постфикс>) - и даем ей имя расширения. И в рамках этой подсистемы реализовываем собственные обработчики обновления. А для того что бы эти обработчики исполнились, мы добавляем эту нашу подсистему в качестве требуемой для подсистемы связанной с основной конфигурацией. Такимо образом при выполнении обновления ИБ у нас запустится процесс обновления основной конфигурации, которая потащит за собой по цепочке и наши обработчики. Но пока что остается не решенным вопрос с запуском самого процесса обновления. Ведь изменение версии расширения не повлечет за собой запуск обновления ИБ. Каждый раз запускать сеанс с параметром "ЗапуститьОбновлениеИнформационнойБазы"?
Для решения этой проблемы мы добавим в служебную функцию БСП, определяющую потребность в запуске обновления, условие, проверяющее изменение версии расширения.
 

 
Для большего понимания попытаемся отобразить на схеме одновременно все варианты:
1) Отсутствие собственных обработчиков обновления
2) Метод предлагаемый документацией БСП
3) Метод с использованием расширения
 

Технические детали
 
Всего потребовалось расширить три модуля:
1) Служебный модуль подсистемы "Обновление ИБ" для добавления условия при смене версии расширения
2) Переопределяемый модуль для добавления подсистемы расширения
3) Модуль подсистемы основной конфигурации для добавления нашей подсистемы в качестве требуемой для основной
 

 
Тексты модулей:
 
 ОбновлениеИнсформационнойБазыРАСШ
 
 
#Область ПрограммныйИнтерфейс
#Область ДляВызоваИзДругихПодсистем
// СтандартныеПодсистемы.ОбновлениеВерсииИБ
////////////////////////////////////////////////////////////////////////////////
// Сведения о библиотеке (или конфигурации).
// Заполняет основные сведения о библиотеке или основной конфигурации.
// Библиотека, имя которой имя совпадает с именем конфигурации в метаданных, определяется как основная конфигурация.
// 
// Параметры:
//  Описание - Структура:
//
//   * Имя                 - Строка - имя библиотеки, например, "СтандартныеПодсистемы".
//   * Версия              - Строка - версия в формате из 4-х цифр, например, "2.1.3.1".
//
//   * ИдентификаторИнтернетПоддержки - Строка - уникальное имя программы в сервисах Интернет-поддержки.
//   * ТребуемыеПодсистемы - Массив - имена других библиотек (Строка), от которых зависит данная библиотека.
//                                    Обработчики обновления таких библиотек должны быть вызваны ранее
//                                    обработчиков обновления данной библиотеки.
//                                    При циклических зависимостях или, напротив, отсутствии каких-либо зависимостей,
//                                    порядок вызова обработчиков обновления определяется порядком добавления модулей
//                                    в процедуре ПриДобавленииПодсистем общего модуля
//                                    ПодсистемыКонфигурацииПереопределяемый.
//   * РежимВыполненияОтложенныхОбработчиков - Строка - "Последовательно" - отложенные обработчики обновления выполняются
//                                    последовательно в интервале от номера версии информационной базы до номера
//                                    версии конфигурации включительно или "Параллельно" - отложенный обработчик после
//                                    обработки первой порции данных передает управление следующему обработчику, а после
//                                    выполнения последнего обработчика цикл повторяется заново.
//   * ЗаполнятьДанныеНовыхПодсистемПриПереходеСДругойПрограммы - Булево - если установить Истина, то при переходе с
//                                    другой программы будут автоматически выполнены обработчики начального заполнения
//                                    новых подсистем. При описании обработчика обновления можно при необходимости
//                                    отключить его выполнение, указав свойство НеВыполнятьПриПереходеСДругойПрограммы.
//
Процедура ПриДобавленииПодсистемы(Описание) Экспорт
	
	Расширение = расшОбщегоНазначенияПовтИсп.ТекущееРасширение();
	
	Описание.Имя    = Расширение.Имя;
	Описание.Версия = Расширение.Версия;
	
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Обработчики обновления информационной базы.
// Добавляет в список процедуры-обработчики обновления данных ИБ
// для всех поддерживаемых версий библиотеки или конфигурации.
// Вызывается перед началом обновления данных ИБ для построения плана обновления.
//
// Параметры:
//  Обработчики - см. ОбновлениеИнформационнойБазы.НоваяТаблицаОбработчиковОбновления
//
// Пример:
//  Для добавления своей процедуры-обработчика в список:
//  Обработчик = Обработчики.Добавить();
//  Обработчик.Версия              = "1.1.0.0";
//  Обработчик.Процедура           = "ОбновлениеИБ.ПерейтиНаВерсию_1_1_0_0";
//  Обработчик.РежимВыполнения     = "Оперативно";
//
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
	// Добавляем наши обработчики
КонецПроцедуры
// См. ОбновлениеИнформационнойБазыПереопределяемый.ПередОбновлениемИнформационнойБазы.
Процедура ПередОбновлениемИнформационнойБазы() Экспорт
	
КонецПроцедуры
// Вызывается после завершения обновления данных ИБ.
// В зависимости от тех или иных условий можно отключить штатное открытие формы
// с описанием изменений в новой версии программы при первом входе в нее (после обновления),
// а также выполнить другие действия.
//
// Не рекомендуется выполнять в данной процедуре какую-либо обработку данных.
// Такие процедуры следует оформлять штатными обработчиками обновления, выполняемыми на каждую версию "*".
// 
// Параметры:
//   ПредыдущаяВерсия     - Строка - версия до обновления. "0.0.0.0" для "пустой" ИБ.
//   ТекущаяВерсия        - Строка - версия после обновления. Как правило, соответствует Метаданные.Версия.
//   ВыполненныеОбработчики - ДеревоЗначений:
//     * НачальноеЗаполнение - Булево - если Истина, то обработчик должен срабатывать при запуске на "пустой" базе.
//     * Версия              - Строка - например, "2.1.3.39". Номер версии конфигурации, при переходе
//                                      на которую должна быть выполнена процедура-обработчик обновления.
//                                      Если указана пустая строка, то это обработчик только для начального заполнения
//                                      (должно быть указано свойство НачальноеЗаполнение).
//     * Процедура           - Строка - полное имя процедуры-обработчика обновления/начального заполнения. 
//                                      Например, "ОбновлениеИнформационнойБазыУПП.ЗаполнитьНовыйРеквизит"
//                                      Обязательно должна быть экспортной.
//     * РежимВыполнения     - Строка - режим выполнения обработчика обновления. Допустимые значения:
//                                      Монопольно, Отложенно, Оперативно. Если значение не заполнено, обработчик
//                                      считается монопольным.
//     * ОбщиеДанные         - Булево - если Истина, то обработчик должен срабатывать до
//                                      выполнения любых обработчиков, использующих разделенные данные.
//                                      Допустимо указывать только для обработчиков с режимом выполнения Монопольно и Оперативно.
//                                      Если указать значение Истина для обработчика с режимом
//                                      выполнения Отложенно, будет выдано исключение.
//     * УправлениеОбработчиками - Булево - если Истина, то обработчик должен иметь параметр типа Структура, в котором
//                                          есть свойство РазделенныеОбработчики - таблица значений со структурой,
//                                          возвращаемой этой функцией.
//                                      При этом колонка Версия игнорируется. В случае необходимости выполнения
//                                      разделенного обработчика в данную таблицу необходимо добавить строку с
//                                      описанием процедуры обработчика.
//                                      Имеет смысл только для обязательных (Версия = *) обработчиков обновления 
//                                      с установленным флагом ОбщиеДанные.
//     * Комментарий         - Строка - описание действий, выполняемых обработчиком обновления.
//     * Идентификатор       - УникальныйИдентификатор - необходимо заполнять для обработчиков отложенного обновления,
//                                                 для остальных заполнение не требуется. Требуется для идентификации
//                                                 обработчика в случае его переименования.
//     
//     * БлокируемыеОбъекты  - Строка - необходимо заполнять для обработчиков отложенного обновления,
//                                      для остальных заполнение не требуется. Полные имена объектов через запятую, 
//                                      которые следует блокировать от изменения до завершения процедуры обработки данных.
//                                      Если заполнено, то также требуется заполнить и свойство ПроцедураПроверки.
//     * ПроцедураПроверки   - Строка - необходимо заполнять для обработчиков отложенного обновления,
//                                      для остальных заполнение не требуется. Имя функции, которая для переданного объекта 
//                                      определяет, завершена ли для него процедура обработки данных. 
//                                      Если переданный объект обработан, то следует вернуть значение Истина. 
//                                      Вызывается из процедуры ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан.
//                                      Параметры, передаваемые в функцию:
//                                         Параметры - см. ОбновлениеИнформационнойБазы.МетаданныеИОтборПоДанным.
//     * ПроцедураЗаполненияДанныхОбновления - Строка - указывается процедура, которая регистрирует данные,
//                                      подлежащие обновлению данным обработчиком.
//     * ЗапускатьТолькоВГлавномУзле  - Булево - только для обработчиков отложенного обновления с режимом выполнения Параллельно.
//                                      Указать Истина, если обработчик обновления должен выполняться только в главном
//                                      узле РИБ.
//     * ЗапускатьИВПодчиненномУзлеРИБСФильтрами - Булево - только для обработчиков отложенного обновления с режимом
//                                      выполнения Параллельно.
//                                      Указать Истина, если обработчик обновления должен также выполняться в
//                                      подчиненном узле РИБ с фильтрами.
//     * ЧитаемыеОбъекты              - Строка - объекты, которые обработчик обновления будет читать при обработке данных.
//     * ИзменяемыеОбъекты            - Строка - объекты, которые обработчик обновления будет изменять при обработке данных.
//     * ПриоритетыВыполнения         - ТаблицаЗначений - таблица приоритетов выполнения между отложенными обработчиками,
//                                      изменяющими или читающими одни и те же данные. Подробнее см. в комментарии
//                                      к функции ОбновлениеИнформационнойБазы.ПриоритетыВыполненияОбработчика.
//     * ВыполнятьВГруппеОбязательных - Булево - следует указывать, если обработчик требуется
//                                      выполнять в одной группе с обработчиками на версии "*".
//                                      При этом возможно менять порядок выполнения обработчика
//                                      относительно других путем изменения приоритета.
//     * Приоритет           - Число  - для внутреннего использования.
//     * МонопольныйРежим    - Неопределено
//                           - Булево - если указано Неопределено, то обработчик 
//                                      должен безусловно выполняться в монопольном режиме.
//                                      Для обработчиков перехода на конкретную версию (версия <> *):
//                                        Ложь   - обработчик не требует монопольного режима для выполнения.
//                                        Истина - обработчик требует монопольного режима для выполнения.
//                                      Для обязательных обработчиков обновления (Версия = "*"):
//                                        Ложь   - обработчик не требует монопольного режима.
//                                        Истина - обработчик может требовать монопольного режима для выполнения.
//                                                 В такие обработчики передается параметр типа структура
//                                                 со свойством МонопольныйРежим (типа Булево).
//                                                 При запуске обработчика в монопольном режиме передается
//                                                 значение Истина. В этом случае обработчик должен выполнить
//                                                 требуемые действия по обновлению. Изменение параметра
//                                                 в теле обработчика игнорируется.
//                                                 При запуске обработчика в немонопольном режиме передается
//                                                 значение Ложь. В этом случае обработчик не должен вносить никакие
//                                                 изменения в ИБ.
//                                                 Если в результате анализа выясняется, что обработчику требуется
//                                                 изменить данные ИБ, следует установить значение параметра в Истина
//                                                 и прекратить выполнение обработчика.
//                                                 В этом случае оперативное (немонопольное) обновление ИБ будет
//                                                 отменено и будет выдана ошибка с требованием выполнить обновление в
//                                                 монопольном режиме.
//   ВыводитьОписаниеОбновлений - Булево - если установить Ложь, то не будет открыта форма
//                                с описанием изменений в новой версии программы. По умолчанию Истина.
//   МонопольныйРежим           - Булево - признак того, что обновление выполнилось в монопольном режиме.
//
Процедура ПослеОбновленияИнформационнойБазы(Знач ПредыдущаяВерсия, Знач ТекущаяВерсия,
		Знач ВыполненныеОбработчики, ВыводитьОписаниеОбновлений, Знач МонопольныйРежим) Экспорт
		
КонецПроцедуры
// См. ОбновлениеИнформационнойБазыПереопределяемый.ПриПодготовкеМакетаОписанияОбновлений.
Процедура ПриПодготовкеМакетаОписанияОбновлений(Знач Макет) Экспорт
	
КонецПроцедуры
#КонецОбласти
#КонецОбласти 
 
 
 
 
 ОбновлениеИнформационнойБазыСлужебныйПовтИсп
 
 
&Вместо("НеобходимоОбновлениеИнформационнойБазы")
Функция расшНеобходимоОбновлениеИнформационнойБазы()
	
	Результат = ПродолжитьВызов();
	
	Расширение = расшОбщегоНазначенияПовтИсп.ТекущееРасширение();
	Если ОбновлениеИнформационнойБазыСлужебный.НеобходимоВыполнитьОбновление(
		Расширение.Версия, ОбновлениеИнформационнойБазыСлужебный.ВерсияИБ(Расширение.Имя)) Тогда
		Результат = Истина;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции
 
 
 
 
 ОбновлениеИнформационнойБазыУП
 
 
&После("ПриДобавленииПодсистемы")
Процедура расшПриДобавленииПодсистемы(Описание)
	Расширение = расшОбщегоНазначенияПовтИсп.ТекущееРасширение();
	Описание.ТребуемыеПодсистемы.Добавить(Расширение.Имя);
КонецПроцедуры
 
 
 
 
 ПодсистемыКонфигурацииПереопределяемый
 
 
&После("ПриДобавленииПодсистем")
Процедура расшПриДобавленииПодсистем(МодулиПодсистем)
	МодулиПодсистем.Добавить("ОбновлениеИнсформационнойБазыРАСШ");
КонецПроцедуры
 
 
 
 
 расшОбщегоНазначенияПовтИсп
 
 
Функция ТекущееРасширение() Экспорт
	
	Отбор = Новый Структура("Имя", "Расширение");
	
	УстановитьПривилегированныйРежим(Истина);
	НайденныеРасширения = РасширенияКонфигурации.Получить(Отбор);
	УстановитьПривилегированныйРежим(Ложь);
	
	Расширение = НайденныеРасширения[0];
	Возврат Расширение;
	
КонецФункции
 
 
 
 
Модуль ОбновлениеИнформационнойБазыУП является модулем подсистемы с именем основной конфигурации, то есть именно эта подсистема, описанная в данном модуле, является "основной".
Итог
Мы рассмотрели подход при котором без изменения корня основной конфигурации мы можем создавать свои обработчики обновления, которые сможем запускать изменяя версию расширения в конфигураторе. Стоит отметить, что и стандартный подход из документации к БСП и рассмотренный нами, обладают одним большим минусом - что бы выполнились наши обработчики, в любом случае требуется и выполнение типовых обработчиков, что может занимать значительное время. К сожалению подсистема БСП "Обновление ИБ" поддерживает только одну "основную" подсистему, связанную с основной конфигурацией по имени. Поэтому мы и выбираем между подходами - сделать "основной" нашу подсистема, а типовую зависимой. Или типовую оставить основной, а нашу добавить в её зависимости.
 
	- Платформа: 1С:Предприятие 8.3 (8.3.25.1546)
- Конфигурация: 1С:ERP Управление предприятием 2 (2.5.21.104)