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

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

В процессе сопровождения и доработки типовых конфигураций 1С часто возникает задача полного перевода системы на поддержку с использованием расширений. Одна из типовых проблем — наличие объектов метаданных, измененных непосредственно в конфигурации. Рассмотрим частый случай: в типовое перечисление были добавлены новые значения, и теперь необходимо вынести эту доработку в расширение, чтобы "закрыть замочки" и упростить дальнейшие обновления.

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

Современный и простой способ: добавление значений в заимствованное перечисление

Начнем с наиболее предпочтительного и наименее трудозатратного метода. Начиная с версии платформы 1С:Предприятие 8.3.14, появилась замечательная возможность добавлять собственные значения в перечисления, заимствованные из основной конфигурации. Это кардинально упрощает нашу задачу.

Важные условия для применения этого способа:

  1. Версия платформы на сервере и клиенте должна быть не ниже 8.3.14.
  2. Режим совместимости основной конфигурации должен быть установлен в значение 8.3.14 или выше. Если режим совместимости более старый, эта функциональность будет недоступна.

Если эти условия выполняются, то процесс переноса доработки становится элементарным. Разберем его по шагам.

  1. Заимствуем перечисление в расширение. В дереве метаданных основной конфигурации (или используя Информер по метаданным для анализа свойств) находим наше перечисление, в которое ранее были добавлены значения. Нажимаем на него правой кнопкой мыши и выбираем команду "Добавить в расширение".
  2. Добавляем новые значения. Теперь в дереве метаданных нашего расширения появился этот объект со статусом "Заимствованный". Открываем его и на вкладке "Данные" добавляем те самые значения, которые ранее были внесены в основную конфигурацию. Сохраняем расширение.
  3. Удаляем значения из основной конфигурации. Возвращаемся в основную конфигурацию, снимаем ее с поддержки (если она на ней стояла), удаляем добавленные вручную значения из перечисления и возвращаем конфигурацию на полную поддержку. На этом этапе полезно выполнить анализ состава расширений на наличие ошибок.

В чем главное преимущество? Тип данных реквизитов в базе не меняется. Мы не создаем новый объект, а лишь дополняем существующий. Это означает, что не требуется никакой обработки по переносу и замене данных. Все ссылки в документах, регистрах и справочниках останутся корректными. После обновления конфигурации базы данных система будет видеть как типовые значения, так и ваши, добавленные через расширение.

Возможные сложности: новые значения не видны на формах

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

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

Как это исправить:

  1. Найдите процедуру или функцию, которая отвечает за формирование списка выбора. Часто это можно сделать через свойство поля формы "События" -> "ОбработкаПолученияДанныхВыбора". Это может быть обработчик в модуле формы или в модуле менеджера объекта.
  2. Создайте в расширении заимствованную форму и добавьте обработчик для нужного события с аннотацией &После или &Вместо.
  3. В своем обработчике дополните стандартный список выбора (СтандартнаяОбработка) вашими новыми значениями из перечисления.

Классический способ: создание нового перечисления и миграция данных

Этот способ следует использовать, если условия для современного подхода не выполняются (например, используется старая версия платформы или режим совместимости). Он полностью соответствует логике, предложенной на форуме, и является гораздо более трудоемким и рискованным.

Внимание! План, при котором вы просто заменяете измененную конфигурацию на типовую версию с сайта ИТС, приведет к безвозвратной потере данных! При удалении значений перечисления из конфигурации платформа удалит все записи, которые на них ссылались. Поэтому этап миграции данных является обязательным.

Разберем процесс по шагам.

  1. Создание аналога в расширении.

    В расширении создаем новое перечисление. Назовем его, например, моё_СтатусыЗаказов. В него необходимо скопировать все значения из исходного перечисления: и типовые, и добавленные вами. Важно, чтобы имена и синонимы совпадали для упрощения дальнейшей миграции.

  2. Анализ использования.

    Необходимо найти все места, где используется старое перечисление. Для этого используйте глобальный поиск по конфигурации или инструмент "Найти ссылки на объект". Нам нужно составить полный список документов, справочников, регистров (сведений и накопления), в реквизитах которых используется наше измененное перечисление.

  3. Написание обработки для миграции данных.

    Это самый ответственный этап. Нужно создать специальную обработку, которая пройдет по всем объектам из списка, найденного на предыдущем шаге, и для каждой записи заменит ссылку со старого значения перечисления на аналогичное значение из нового перечисления. Чтобы ускорить написание кода, можно использовать Консоль кода + ИИ-помощник (GigaChat).

    Ключевой момент при такой замене — использование режима ОбменДанными.Загрузка = Истина. Этот режим позволяет записывать объекты, отключая многие проверки целостности, бизнес-логику в обработчиках событий (ПередЗаписью, ПриЗаписи) и автоматическое проведение документов. Это необходимо для выполнения "технической" перезаписи данных без побочных эффектов.

    Посмотрим на примерный код для одного из объектов, например, документа "ЗаказКлиента".

    
    Процедура ПеренестиДанныеПоДокументам()
    
        // Создаем соответствие между старыми и новыми значениями
        СоответствиеЗначений = Новый Соответствие;
        Для Каждого Значение Из Метаданные.Перечисления.СтароеПеречисление.ЗначенияПеречисления Цикл
            Попытка
                СоответствиеЗначений.Вставить(
                    Перечисления.СтароеПеречисление[Значение.Имя], 
                    Перечисления.моё_НовоеПеречисление[Значение.Имя]
                );
            Исключение
                Сообщить("Не найдено соответствие для значения: " + Значение.Имя);
            КонецПопытки;
        КонецЦикла;
        
        // Выбираем все документы, которые нужно обработать
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |   ЗаказКлиента.Ссылка
            |ИЗ
            |   Документ.ЗаказКлиента КАК ЗаказКлиента
            |ГДЕ
            |   ЗаказКлиента.СтарыйРеквизитСтатус <> ЗНАЧЕНИЕ(Перечисление.ПустаяСсылка)";
    
        Результат = Запрос.Выполнить();
        Выборка = Результат.Выбрать();
    
        Пока Выборка.Следующий() Цикл
            Попытка
                ОбъектДокумент = Выборка.Ссылка.ПолучитьОбъект();
                
                // Получаем старое значение
                СтароеЗначение = ОбъектДокумент.СтарыйРеквизитСтатус;
                
                // Находим новое значение по соответствию
                НовоеЗначение = СоответствиеЗначений[СтароеЗначение];
                
                Если НовоеЗначение <> Неопределено Тогда
                    ОбъектДокумент.НовыйРеквизитСтатус = НовоеЗначение; // Предполагается, что вы временно добавили новый реквизит
                    
                    // Записываем объект в режиме обмена данными
                    ОбменДанными.Загрузка = Истина;
                    ОбъектДокумент.Записать(); // Используем нужный режим записи
                    ОбменДанными.Загрузка = Ложь;
                    
                Иначе
                    Сообщить("Не удалось найти новое значение для " + СтароеЗначение + " в документе " + Выборка.Ссылка);
                КонецЕсли;
                
            Исключение
                ОбменДанными.Загрузка = Ложь;
                Сообщить("Ошибка при обработке документа " + Выборка.Ссылка + ": " + ОписаниеОшибки());
            КонецПопытки;
        КонецЦикла;
    
    КонецПроцедуры
    

    Такую логику нужно будет повторить для каждого типа объекта, использующего перечисление. Чтобы не добавлять временные реквизиты, можно сразу изменять тип реквизита в расширении и выполнять миграцию, но это более сложный сценарий.

  4. Финальные действия.

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

Итоги и рекомендации

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

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

← На главную