В процессе развития конфигураций 1С часто возникает необходимость пересмотреть структуру хранения данных. Типичный пример — переход от использования ссылки на справочник Пользователи к справочнику Физические лица в документах или табличных частях. Основная проблема здесь заключается в том, что при простом изменении типа в конфигураторе все ранее накопленные данные в базе данных будут безвозвратно потеряны, так как система не сможет автоматически сопоставить ссылки разных типов.
В этой статье мы подробно разберем, как выполнить такой переход профессионально, сохранив исторические данные и соблюдая стандарты разработки фирмы «1С».
Проанализируем самый надежный способ, который используется в типовых решениях. Вместо изменения типа существующего поля, мы создаем новое, а старое готовим к постепенному выводу из эксплуатации.
Ответственный с типом СправочникСсылка.Пользователи) и переименуем его в УдалитьОтветственный. Это визуально подскажет другим разработчикам, что поле устарело.Ответственный) и установим для него тип СправочникСсылка.ФизическиеЛица.Пользователи обычно есть штатный реквизит ФизическоеЛицо, который мы и будем использовать для сопоставления.Рассмотрим пример кода для такой миграции данных в документах:
Выборка = Документы.ПриемНаРаботу.Выбрать();
Пока Выборка.Следующий() Цикл
Объект = Выборка.ПолучитьОбъект();
// Проверяем, заполнено ли старое поле и не заполнено ли уже новое
Если ЗначениеЗаполнено(Объект.УдалитьОтветственный) И Не ЗначениеЗаполнено(Объект.Ответственный) Тогда
// Получаем ссылку на физлицо из карточки пользователя
ФизЛицоСсылка = Объект.УдалитьОтветственный.ФизическоеЛицо;
Если ЗначениеЗаполнено(ФизЛицоСсылка) Тогда
Объект.Ответственный = ФизЛицоСсылка;
Объект.ОбменДанными.Загрузка = Истина; // Чтобы не срабатывали проверки при записи
Объект.Записать();
КонецЕсли;
КонецЕсли;
КонецЦикла;
Разберем альтернативный вариант, который позволяет избежать создания нового поля, но требует нескольких этапов обновления базы данных. Этот метод «чище» с точки зрения имен метаданных, но сложнее в реализации при распределенных базах.
Сначала мы проанализируем ситуацию: нам нужно расширить тип, не удаляя старый. Для этого изменим тип реквизита на составной, добавив к СправочникСсылка.Пользователи новый тип СправочникСсылка.ФизическиеЛица. После этого запустим обработку, которая программно заменит в каждом документе ссылку на пользователя ссылкой на соответствующее физлицо. И только на финальном этапе, когда все данные сконвертированы, мы удалим тип Пользователи из состава реквизита, оставив только Физические лица.
Выясним причину возможных ошибок при переносе. Как было замечено в обсуждении, существует вероятность, что у пользователя не заполнено поле ФизическоеЛицо. Это часто встречается у системных учетных записей или сервисных пользователей для обмена.
Проанализируем, как с этим работать:
Пример программного ограничения типа на форме:
ЭтаФорма.Элементы.Ответственный.ОграничениеТипа = Новый ОписаниеТипов("СправочникСсылка.ФизическиеЛица");
Если вы работаете в современной конфигурации на базе Библиотеки Стандартных Подсистем (БСП), рассмотрим более продвинутый подход. Правильнее всего выполнять перенос данных через механизм обновления информационной базы.
Вместо ручного запуска обработок, создадим процедуру в модуле ОбновлениеИнформационнойБазы<ИмяКонфигурации>. Это обеспечит выполнение миграции в фоновом режиме при первом запуске системы после обновления. Это критически важно для крупных предприятий, где данные должны обновиться у всех пользователей одновременно и корректно передаться по каналам РИБ (распределенных информационных баз).
Внимание! Это один из самых опасных моментов. Если старый реквизит Пользователь участвовал в шаблонах ограничений доступа на уровне записей (RLS), то после замены типа права доступа могут «слететь». Система прав 1С обычно оперирует текущим пользователем сеанса. Если вы перешли на физические лица, вам придется переписать запросы в ролях, добавив соединение со справочником пользователей, чтобы сопоставить текущего пользователя с физлицом, указанным в документе.
Посмотрим на ситуацию со стороны базы данных SQL. На таблицах с миллионами записей создание нового реквизита и его заполнение — это тяжелая операция. Она приводит к значительному росту транзакционного лога. Рассмотрим рекомендации:
Удалить..., рекомендуется выполнить реиндексацию таблиц базы данных.Проанализируем последствия для окружения. Любая замена реквизита в метаданных — это «деструктивное» изменение. Это означает, что все внешние печатные формы, внешние отчеты и обработки, которые обращались к полю по старому имени или ожидали там тип Пользователь, перестанут работать. Перед тем как окончательно удалить старый реквизит, обязательно проведите глобальный поиск ссылок по всей конфигурации и обновите внешние файлы.
Используя подход с префиксом Удалить, вы даете себе и команде время на плавное исправление всех зависимых механизмов, сохраняя при этом работоспособность системы и целостность исторических данных.