Рано или поздно перед каждым разработчиком и администратором систем на платформе 1С встает сложный выбор. Накопленные годами доработки в типовой конфигурации начинают существенно замедлять процесс обновления. Каждое очередное обновление превращается в многочасовое (а иногда и многодневное) сравнение и объединение конфигураций, где легко допустить ошибку и нарушить логику бизнес-процессов предприятия. С появлением и развитием механизма расширений в платформе «1С:Предприятие 8.3» возникла заманчивая идея: полностью очистить основную конфигурацию, вернуть её на строгую поддержку от вендора (повесить «замок»), а всю уникальную бизнес-логику и новые реквизиты вынести в расширения. Для пошаговой реализации этой задачи можно использовать методику обновления конфигурации с переносом доработок в расширение.
В этой статье мы подробно и по шагам разберем, насколько оправдан такой шаг, с какими скрытыми техническими угрозами вы можете столкнуться в процессе переноса доработок, как устроен механизм хранения данных расширений в СУБД и какие архитектурные шаблоны проектирования («Гибридный подход», программная модификация форм, использование директивы &ИзменениеИКонтроль) признаны лучшими практиками в сообществе 1С.
---
Прежде чем приступать к масштабному рефакторингу базы данных, давайте проанализируем, в чем заключается выгода для клиента и разработчика и какие сложности могут возникнуть на этом пути.
Главные преимущества использования расширений:
Основные сложности и подводные камни:
---
Выясним причину, почему перенос реквизитов в расширение «в один клик» — это крайне опасная затея. Рассмотрим, как именно платформа 1С организует хранение данных в СУБД (например, в MS SQL или PostgreSQL) для объектов, созданных внутри расширения.
Когда вы добавляете новый реквизит к существующему справочнику или документу непосредственно в основной конфигурации, платформа модифицирует физическую таблицу этого объекта в СУБД, создавая в ней новую колонку. Данные лежат в единой таблице, надежно защищенной механизмами СУБД и платформы.
Когда же вы добавляете собственный реквизит к заимствованному объекту через расширение конфигурации, логика работы платформы меняется:
_Reference150) в неизменном виде._Reference150_X1).JOIN) между основной и расширенной таблицами СУБД.В чем заключается главный риск?
Если администратор или разработчик по неосторожности удалит расширение из списка подключенных в режиме «1С:Предприятие», платформа воспримет это как команду на полное уничтожение структуры данных этого расширения. Все расширенные таблицы (с суффиксами _X1) будут безвозвратно удалены из СУБД вместе со всем их содержимым! Восстановить эти данные можно будет только из резервной копии СУБД, если она, конечно, существует и актуальна.
Более того, если вы решили перенести уже существующие реквизиты из основной конфигурации в расширение, простое их создание в расширении и удаление в конфигурации приведет к моментальной потере всей истории данных. Для безопасного переноса потребуется сложная многоэтапная процедура.
---
Если вы всё же твердо решили перенести данные добавленных ранее реквизитов из основной конфигурации в расширение, разберем этот процесс по шагам. Действовать нужно крайне аккуратно:
ДоговорыКонтрагентов) в расширение и создайте в нем новый реквизит с уникальным именем (например, Расш_СрокДействия). Обязательно укажите корректный тип данных.
Выборка = Справочники.ДоговорыКонтрагентов.Выбрать();
Пока Выборка.Следующий() Цикл
// Проверяем, заполнено ли старое значение реквизита в основной конфигурации
Если ЗначениеЗаполнено(Выборка.СтарыйСрокДействия) Тогда
ОбъектОбъект = Выборка.ПолучитьОбъект();
// Записываем данные в новый реквизит, созданный через расширение
ОбъектОбъект.Расш_СрокДействия = Выборка.СтарыйСрокДействия;
// Отключаем лишние проверки при записи, чтобы ускорить процесс
ОбъектОбъект.ОбменДанными.Загрузка = Истина;
ОбъектОбъект.Записать();
КонецЕсли;
КонецЦикла;
---
Чтобы избежать описанных выше рисков потери данных и не писать сложные обработки переноса, профессиональное сообщество разработчиков 1С выработало так называемый «Гибридный подход». Проанализируем эту стратегию подробнее.
Суть гибридного подхода заключается в четком разделении зон ответственности между основной конфигурацией и расширением:
Префикс_СрокДействия, Префикс_ДополнительныеСведения). Наличие уникальных префиксов гарантирует, что при автоматическом обновлении от фирмы «1С» ваши объекты никогда не пересекутся по именам с новыми типовыми объектами и не будут затерты.При таком подходе мы получаем лучшее из обоих миров: данные клиентов находятся в абсолютной безопасности в основной СУБД, а весь тяжелый программный код изолирован в расширении. Даже если расширение полностью отключить или удалить, структура данных не пострадает. После обратного подключения расширения вся логика мгновенно вернется в рабочее состояние.
Альтернативный вариант: Использование регистров сведений (РС)
Если вам категорически запрещено вносить хоть какие-то изменения в основную конфигурацию, а новые реквизиты создать необходимо, воспользуйтесь проверенным приемом. Вместо добавления реквизитов к объектам создайте в расширении новый независимый (или подчиненный) Регистр сведений. В качестве измерения укажите заимствованный объект (например, нужный справочник), а в качестве ресурса — ваше новое свойство. Чтение и запись данных в таком случае будут производиться через этот регистр, что убережет вас от изменения структуры таблиц самого справочника.
---
Еще одно важное правило качественной разработки расширений — это отказ от визуального заимствования форм в расширение без крайней необходимости. Если вы заимствуете форму визуально и интерактивно перетаскиваете на неё элементы, любое обновление типовой формы от «1С» может сломать интерфейс. Лучшая практика — изменять формы программно в модуле формы расширения.
Рассмотрим пример, как программно добавить кнопку и связать её с обработчиком события на заимствованной форме документа в расширении:
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Программное добавление команды формы
ИмяКоманды = "Расш1_ДополнительныйСервис";
НоваяКоманда = Команды.Добавить(ИмяКоманды);
НоваяКоманда.Действие = "Подключаемый_Расш1_ВыполнитьСервис";
НоваяКоманда.Заголовок = "Доп. сервис";
// Программное добавление кнопки на форму в группу "Командная панель"
НоваяКнопка = Элементы.Добавить("Расш1_КнопкаСервиса", Тип("КнопкаФормы"), Элементы.ФормаКоманднаяПанель);
НоваяКнопка.ИмяКоманды = ИмяКоманды;
НоваяКнопка.Заголовок = "Запустить сервис";
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_Расш1_ВыполнитьСервис(Команда)
// Описываем логику, которая должна выполниться по нажатию кнопки
ПоказатьПредупреждение(, "Дополнительный сервис успешно запущен!");
КонецПроцедуры
Используя этот метод, вы гарантируете, что даже при кардинальном изменении дизайна формы вендором ваша кнопка аккуратно встанет в стандартную командную панель формы без визуальных искажений.
---
Перейдем к разбору важнейшего инструмента для работы с кодом в расширениях — директиве &ИзменениеИКонтроль. В ранних версиях платформы разработчики часто использовали директиву &Вместо, полностью замещая типовой метод своим кодом. Однако это приводило к серьезной проблеме: если в новом релизе «1С» в оригинальный метод вносились исправления критических ошибок, расширение с директивой &Вместо полностью игнорировало эти обновления, продолжая выполнять старый код, сохраненный внутри расширения. Для контроля корректности таких процедур после выхода новых релизов подойдёт обработка для проверки методов расширений.
Директива &ИзменениеИКонтроль решает эту проблему. Принцип её работы строится на точечном изменении кода с помощью инструкций препроцессора:
#Вставка ... #КонецВставки.#Удаление ... #КонецУдаления.Посмотрим на практический пример использования директивы &ИзменениеИКонтроль:
&Вместо("РассчитатьСуммуДокумента")
&ИзменениеИКонтроль("РассчитатьСуммуДокумента")
Процедура Расш1_РассчитатьСуммуДокумента(СтрокаТабличнойЧасти)
// Оригинальный код расчета суммы
#Удаление
СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
#КонецУдаления
#Вставка
// Добавляем расчет с учетом нашей кастомной скидки
СкидкаПроцент = Расш1_ПолучитьСкидкуКлиента(СтрокаТабличнойЧасти.Ссылка.Контрагент);
ЧистаяСумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
СтрокаТабличнойЧасти.Сумма = ЧистаяСумма - (ЧистаяСумма * СкидкаПроцент / 100);
#КонецВставки
КонецПроцедуры
Критическое ограничение директивы:
Помните, что один и тот же метод основной конфигурации может быть расширен с помощью директивы &ИзменениеИКонтроль строго один раз во всей системе. Если у вас подключено несколько различных расширений, и в каждом из них сделана попытка контролировать один и тот же метод через &ИзменениеИКонтроль, платформа выдаст ошибку применимости еще на этапе запуска сеанса. В таких случаях необходимо объединять доработки в рамках одного расширения.
---
Согласно современным стандартам разработки фирмы «1С», при создании расширения крайне важно правильно выбрать его назначение. Это свойство задается в карточке параметров расширения и определяет порядок и приоритет выполнения кода платформой:
Соблюдение этой классификации гарантирует правильную очередность инициализации модулей и помогает избежать конфликтов компиляции при наличии в базе десятков расширений.
---
В процессе работы с расширениями разработчики часто сетуют на ограниченные возможности стандартного Конфигуратора 1С в плане сопоставления измененного кода с кодом основной конфигурации.
Для решения этой проблемы мы рекомендуем два основных пути:
&ИзменениеИКонтроль платформа автоматически вызовет внешнюю утилиту для наглядного слияния веток кода.---
Подводя итоги, можно с уверенностью сказать: перенос доработок в расширения — это отличная современная практика, которая действительно способна сэкономить множество рабочих часов при последующих обновлениях системы. Однако этот процесс требует глубокого понимания механизмов платформы.
Перед тем как начать проект миграции, сверьтесь с нашим чек-листом:
&Вместо везде, где требуется контроль оригинального алгоритма, внедрена директива &ИзменениеИКонтроль.