Разработка в экосистеме 1С постоянно эволюционирует, и появление расширений конфигурации значительно упростило жизнь разработчикам и администраторам систем. Возможность внедрить доработки без изменения основной конфигурации выглядит крайне заманчиво. Однако, когда дело доходит до добавления новых реквизитов, справочников или регистров непосредственно в расширение, мы сталкиваемся с серьезной дилеммой. Где безопаснее хранить новые данные — в основной конфигурации или в расширении? Какие подводные камни ожидают нас при работе с распределенными информационными базами (РИБ) и обновлении платформы? Давайте подробно разберем эти вопросы, проанализируем физическую структуру хранения данных в СУБД и выясним, как избежать критических ошибок.
Для того чтобы понять, насколько безопасно хранить данные в расширениях, проанализируем, как платформа 1С взаимодействует с базой данных на уровне СУБД (MS SQL, PostgreSQL и др.). Существует опасное заблуждение: якобы при удалении или изменении реквизита в расширении данные «чудесным образом» сохраняются в таблицах и никуда не исчезают.
Выясним истинную картину происходящего:
РеализацияТоваровУслуг) через механизм расширения, платформа не трогает физическую таблицу этого документа в СУБД (например, _Document549). Вместо этого создается специальная вспомогательная таблица расширения (например, _Document549X1), которая связывается с основной таблицей по уникальному идентификатору ссылки (Ref)._Document549X1, если в расширении больше нет кастомных полей для этого объекта. Накопленные данные в этот момент уничтожаются навсегда._FldXXXXX), которые не связаны с текущими метаданными, но мешают последующей установке новых версий расширения, вызывая ошибки SDBL (системы баз данных 1С).Рассмотрим подробнее причины, по которым многие опытные разработчики оценивают вероятность потери данных в расширениях при регулярных обновлениях как крайне высокую. Выделим основные факторы риска:
Проанализируем ситуацию с обновлением конфигурации и расширений в распределенных базах. Существует мнение, что расширения обновляются в РИБ гораздо «прозрачнее», чем основная конфигурация. Выясним, так ли это на самом деле, и разберем технические особенности этого процесса:
"Данные принимаются от узла с другим набором расширений, меняющих структуру данных. Необходимо произвести перенос расширений конфигурации в узел". Если версии расширений в главном и подчиненном узлах разойдутся хотя бы на один реквизит, обмен данными полностью заблокируется. Администратору придется вручную выравнивать версии расширений конфигуратором, что сводит на нет все преимущества автоматического обмена.ИспользоватьРасширенияКонфигурации, что в ряде случаев требует внесения изменений в саму основную конфигурацию и снятия ее с полной поддержки.Если вы пришли к выводу, что хранить важные бизнес-данные в расширении слишком рискованно, и приняли решение перенести накопленные метаданные в основную конфигурацию, выполнять эту процедуру нужно крайне аккуратно. Простое удаление реквизита из расширения и создание его в основной конфигурации приведет к безвозвратной потере информации.
Разберем по шагам безопасный алгоритм миграции данных:
Откройте основную конфигурацию и создайте в ней новые реквизиты (или объекты метаданных), которые полностью соответствуют по типу данных и назначению тем реквизитам, которые сейчас находятся в расширении. Важно задать им понятные имена, отличные от имен в расширении, чтобы избежать конфликтов имен при компиляции (например, если в расширении реквизит назывался ДопИнформация_Расш, в основной конфигурации назовите его ДопИнформация).
Обновите конфигурацию базы данных (нажмите клавишу F7). На данном этапе у вас в базе будут сосуществовать два реквизита: старый в расширении (с данными) и новый в основной конфигурации (пока еще пустой).
Напишите и запустите обработку, которая программно перепишет данные из полей расширения в поля основной конфигурации. Рассмотрим пример кода для переноса данных реквизита справочника Контрагенты:
Выборка = Справочники.Контрагенты.Выбрать();
ПроведеноОбъектов = 0;
НачатьТранзакцию();
Попытка
Пока Выборка.Следующий() Цикл
ОбъектКонтрагент = Выборка.ПолучитьОбъект();
// Проверяем, заполнен ли реквизит в расширении
Если ЗначениеЗаполнено(ОбъектКонтрагент.ДопИнформация_Расш) Тогда
// Копируем значение в новый реквизит основной конфигурации
ОбъектКонтрагент.ДопИнформация = ОбъектКонтрагент.ДопИнформация_Расш;
// Записываем объект, отключая лишние проверки при необходимости
ОбъектКонтрагент.ОбменДанными.Загрузка = Истина;
ОбъектКонтрагент.Записать();
ПроведеноОбъектов = ПроведеноОбъектов + 1;
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
Сообщить("Успешно перенесено объектов: " + ПроведеноОбъектов);
Исключение
ОтменитьТранзакцию();
Сообщить("Ошибка при переносе данных: " + ОписаниеОшибки());
КонецПопытки;
Использование свойства ОбменДанными.Загрузка = Истина крайне важно, так как это позволяет обойти прикладные проверки при записи объекта и существенно ускорить процесс выполнения обработки.
Убедитесь, что все данные успешно скопированы. Для этого можно воспользоваться консолью запросов или написать простую сверку. Напишем пример запроса для контроля:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Ссылка,
| Контрагенты.ДопИнформация_Расш КАК ИзРасширения,
| Контрагенты.ДопИнформация КАК ИзКонфигурации
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.ДопИнформация_Расш <> Контрагенты.ДопИнформация";
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Сообщить("Внимание! Обнаружены расхождения в данных!");
Иначе
Сообщить("Проверка пройдена успешно. Данные идентичны.");
КонецЕсли;
Только после того, как вы полностью убедились в идентичности перенесенных данных, можно зайти в конфигуратор расширения, удалить старый вспомогательный реквизит ДопИнформация_Расш и обновить конфигурацию базы данных. На этом процесс безопасной миграции успешно завершен.
Подводя итог, сформулируем основные правила успешной и безопасной архитектурной работы с метаданными и расширениями в 1С: