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