Как правильно перенести изменения из измененной типовой конфигурации 1С в расширения и стоит ли это делать?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Рано или поздно перед каждым разработчиком и администратором систем на платформе 1С встает сложный выбор. Накопленные годами доработки в типовой конфигурации начинают существенно замедлять процесс обновления. Каждое очередное обновление превращается в многочасовое (а иногда и многодневное) сравнение и объединение конфигураций, где легко допустить ошибку и нарушить логику бизнес-процессов предприятия. С появлением и развитием механизма расширений в платформе «1С:Предприятие 8.3» возникла заманчивая идея: полностью очистить основную конфигурацию, вернуть её на строгую поддержку от вендора (повесить «замок»), а всю уникальную бизнес-логику и новые реквизиты вынести в расширения. Для пошаговой реализации этой задачи можно использовать методику обновления конфигурации с переносом доработок в расширение.

В этой статье мы подробно и по шагам разберем, насколько оправдан такой шаг, с какими скрытыми техническими угрозами вы можете столкнуться в процессе переноса доработок, как устроен механизм хранения данных расширений в СУБД и какие архитектурные шаблоны проектирования («Гибридный подход», программная модификация форм, использование директивы &ИзменениеИКонтроль) признаны лучшими практиками в сообществе 1С.

---

Зачем переходить на расширения: взвешиваем «за» и «против»

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

Главные преимущества использования расширений:

  1. Существенное упрощение и удешевление обновлений. Основная конфигурация остается полностью типовой. Это позволяет выполнять обновление в полуавтоматическом режиме за считанные минуты. Пользователи или штатные администраторы могут обновлять систему самостоятельно (хотя это и требует определенного контроля).
  2. Тиражируемость доработок. Выделив определенный функционал в изолированное расширение, мы можем легко переносить его между базами разных клиентов, если они используют аналогичные типовые конфигурации.
  3. Безопасность основной конфигурации. Все доработки локализованы в отдельном контейнере. Если функционал расширения больше не нужен или работает некорректно, его можно временно отключить одной галочкой в свойствах расширения, не затрагивая ядро системы.

Основные сложности и подводные камни:

  1. Контроль применимости кода. При обновлении типовой конфигурации структура её методов, процедур и функций может кардинально измениться. Если ваше расширение жестко завязано на измененные типовые процедуры, платформа откажется применять расширение при запуске базы данных. Придется оперативно адаптировать код расширения под новый релиз.
  2. Отсутствие простых инструментов сравнения в старых версиях платформы. Сравнить основную конфигурацию с расширением стандартными средствами Конфигуратора напрямую бывает затруднительно. Нам приходится использовать современные инструменты разработки или внешние программы сравнения.
  3. Риск безвозвратной потери данных. Это наиболее критичный аспект, который мы подробно рассмотрим далее. При неправильном проектировании структуры данных в расширении любая техническая ошибка или неосторожное действие администратора могут привести к полной потере информации, накопленной пользователями.

---

Технические нюансы: физическая структура СУБД и риски потери данных

Выясним причину, почему перенос реквизитов в расширение «в один клик» — это крайне опасная затея. Рассмотрим, как именно платформа 1С организует хранение данных в СУБД (например, в MS SQL или PostgreSQL) для объектов, созданных внутри расширения.

Когда вы добавляете новый реквизит к существующему справочнику или документу непосредственно в основной конфигурации, платформа модифицирует физическую таблицу этого объекта в СУБД, создавая в ней новую колонку. Данные лежат в единой таблице, надежно защищенной механизмами СУБД и платформы.

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

В чем заключается главный риск?

Если администратор или разработчик по неосторожности удалит расширение из списка подключенных в режиме «1С:Предприятие», платформа воспримет это как команду на полное уничтожение структуры данных этого расширения. Все расширенные таблицы (с суффиксами _X1) будут безвозвратно удалены из СУБД вместе со всем их содержимым! Восстановить эти данные можно будет только из резервной копии СУБД, если она, конечно, существует и актуальна.

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

---

Пошаговый алгоритм миграции существующих реквизитов

Если вы всё же твердо решили перенести данные добавленных ранее реквизитов из основной конфигурации в расширение, разберем этот процесс по шагам. Действовать нужно крайне аккуратно:

  1. Создайте резервную копию базы данных. Это обязательный шаг перед проведением любых низкоуровневых операций с метаданными. При обслуживании нескольких баз для этой операции применяется автоматическое архивирование информационных баз 1С.
  2. Создайте аналогичные реквизиты в расширении. Заимствуйте необходимый объект (например, справочник ДоговорыКонтрагентов) в расширение и создайте в нем новый реквизит с уникальным именем (например, Расш_СрокДействия). Обязательно укажите корректный тип данных.
  3. Напишите обработку для переноса данных. Нам необходимо скопировать информацию из старого реквизита основной конфигурации в новый реквизит расширения. Напишем и выполним код, который обойдет все элементы справочника и перенесет значения. Для больших баз данных желательно использовать регламентные задания или пакетную обработку во избежание переполнения транзакционного лога СУБД. Посмотрим на пример кода такой обработки:

Выборка = Справочники.ДоговорыКонтрагентов.Выбрать();
Пока Выборка.Следующий() Цикл
    // Проверяем, заполнено ли старое значение реквизита в основной конфигурации
    Если ЗначениеЗаполнено(Выборка.СтарыйСрокДействия) Тогда
        ОбъектОбъект = Выборка.ПолучитьОбъект();
        // Записываем данные в новый реквизит, созданный через расширение
        ОбъектОбъект.Расш_СрокДействия = Выборка.СтарыйСрокДействия;
        
        // Отключаем лишние проверки при записи, чтобы ускорить процесс
        ОбъектОбъект.ОбменДанными.Загрузка = Истина;
        ОбъектОбъект.Записать();
    КонецЕсли;
КонецЦикла;
  1. Перенесите ссылки в связанных объектах. Если старый реквизит использовался в движениях регистров, формулах расчетов или других объектах метаданных, вам потребуется переписать эти механизмы в расширении на работу с новым реквизитом, после чего перепровести документы или перезаписать движения программно.
  2. Удалите старый реквизит из основной конфигурации. Только после того, как вы убедились, что все данные полностью перенесены в таблицы расширения и успешно считываются системой, вы можете удалить старый реквизит из основной конфигурации и поставить ее на замок.

---

Гибридный подход как лучшая практика разработки

Чтобы избежать описанных выше рисков потери данных и не писать сложные обработки переноса, профессиональное сообщество разработчиков 1С выработало так называемый «Гибридный подход». Проанализируем эту стратегию подробнее.

Суть гибридного подхода заключается в четком разделении зон ответственности между основной конфигурацией и расширением:

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

Альтернативный вариант: Использование регистров сведений (РС)

Если вам категорически запрещено вносить хоть какие-то изменения в основную конфигурацию, а новые реквизиты создать необходимо, воспользуйтесь проверенным приемом. Вместо добавления реквизитов к объектам создайте в расширении новый независимый (или подчиненный) Регистр сведений. В качестве измерения укажите заимствованный объект (например, нужный справочник), а в качестве ресурса — ваше новое свойство. Чтение и запись данных в таком случае будут производиться через этот регистр, что убережет вас от изменения структуры таблиц самого справочника.

---

Программное изменение форм

Еще одно важное правило качественной разработки расширений — это отказ от визуального заимствования форм в расширение без крайней необходимости. Если вы заимствуете форму визуально и интерактивно перетаскиваете на неё элементы, любое обновление типовой формы от «1С» может сломать интерфейс. Лучшая практика — изменять формы программно в модуле формы расширения.

Рассмотрим пример, как программно добавить кнопку и связать её с обработчиком события на заимствованной форме документа в расширении:


&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    // Программное добавление команды формы
    ИмяКоманды = "Расш1_ДополнительныйСервис";
    НоваяКоманда = Команды.Добавить(ИмяКоманды);
    НоваяКоманда.Действие = "Подключаемый_Расш1_ВыполнитьСервис";
    НоваяКоманда.Заголовок = "Доп. сервис";
    
    // Программное добавление кнопки на форму в группу "Командная панель"
    НоваяКнопка = Элементы.Добавить("Расш1_КнопкаСервиса", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель);
    НоваяКнопка.ИмяКоманды = ИмяКоманды;
    НоваяКнопка.Заголовок = "Запустить сервис";
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_Расш1_ВыполнитьСервис(Команда)
    // Описываем логику, которая должна выполниться по нажатию кнопки
    ПоказатьПредупреждение(, "Дополнительный сервис успешно запущен!");
КонецПроцедуры

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

---

Механизм директивы &ИзменениеИКонтроль

Перейдем к разбору важнейшего инструмента для работы с кодом в расширениях — директиве &ИзменениеИКонтроль. В ранних версиях платформы разработчики часто использовали директиву &Вместо, полностью замещая типовой метод своим кодом. Однако это приводило к серьезной проблеме: если в новом релизе «1С» в оригинальный метод вносились исправления критических ошибок, расширение с директивой &Вместо полностью игнорировало эти обновления, продолжая выполнять старый код, сохраненный внутри расширения. Для контроля корректности таких процедур после выхода новых релизов подойдёт обработка для проверки методов расширений.

Директива &ИзменениеИКонтроль решает эту проблему. Принцип её работы строится на точечном изменении кода с помощью инструкций препроцессора:

Посмотрим на практический пример использования директивы &ИзменениеИКонтроль:


&Вместо("РассчитатьСуммуДокумента")
&ИзменениеИКонтроль("РассчитатьСуммуДокумента")
Процедура Расш1_РассчитатьСуммуДокумента(СтрокаТабличнойЧасти)
    
    // Оригинальный код расчета суммы
    #Удаление
    СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
    #КонецУдаления
    
    #Вставка
    // Добавляем расчет с учетом нашей кастомной скидки
    СкидкаПроцент = Расш1_ПолучитьСкидкуКлиента(СтрокаТабличнойЧасти.Ссылка.Контрагент);
    ЧистаяСумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
    СтрокаТабличнойЧасти.Сумма = ЧистаяСумма - (ЧистаяСумма * СкидкаПроцент / 100);
    #КонецВставки
    
КонецПроцедуры

Критическое ограничение директивы:

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

---

Классификация расширений по назначению

Согласно современным стандартам разработки фирмы «1С», при создании расширения крайне важно правильно выбрать его назначение. Это свойство задается в карточке параметров расширения и определяет порядок и приоритет выполнения кода платформой:

  1. Исправление (Patch). Используется в первую очередь для оперативного закрытия багов и уязвимостей в коде конфигурации (аналогично патчам, которые выпускает сама фирма «1С»). Расширения с этим назначением компилируются платформой первыми.
  2. Адаптация. Это основное назначение для доработки бизнес-логики под нужды конкретной организации. Сюда следует относить большинство ваших кастомных модулей, изменяющих проведение документов, расчеты или интерфейсы.
  3. Дополнение. Используется для создания абсолютно нового, независимого функционала, который расширяет возможности программы, но напрямую не ломает и не изменяет существующие механизмы типового решения.

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

---

Инструменты сравнения модулей и современная разработка

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

Для решения этой проблемы мы рекомендуем два основных пути:

---

Резюме и чек-лист успешной миграции

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

Перед тем как начать проект миграции, сверьтесь с нашим чек-листом:

← На главную