Как правильно изменить тип реквизита со строки на справочник без потери данных в 1С

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

В практике разработки на платформе 1С:Предприятие часто возникает задача изменения структуры данных в уже работающей базе. Типичный пример: изначально реквизит (например, КБК в платежном поручении) был создан как обычная Строка, но со временем пользователи начали просить возможность выбора из справочника для минимизации ошибок ввода. Простое изменение типа в конфигураторе приводит к полной очистке этого поля во всех существующих документах при обновлении конфигурации базы данных. Разберем подробно, как выполнить эту задачу профессионально, сохранив все данные и обеспечив комфортную работу пользователей.

Почему происходит потеря данных при смене типа

Прежде чем переходить к решениям, проанализируем причину проблемы. База данных 1С хранит значения разных типов в разных форматах. Когда мы меняем Строка на СправочникСсылка, платформа физически не может автоматически сопоставить текстовое значение (например, "18210101011011000110") с уникальным идентификатором (GUID) элемента справочника, так как этого элемента еще просто не существует. В итоге старая колонка в таблице SQL удаляется или очищается, и создается новая, пустая. Чтобы этого избежать, нам нужно создать «мостик» для переноса данных.

Вариант 1. Использование составного типа данных

Этот способ считается наиболее простым и быстрым для начинающего разработчика. Основная идея заключается в том, чтобы временно разрешить реквизиту хранить и старые строки, и новые ссылки. Рассмотрим по шагам:

  1. Расширение типа реквизита. В конфигураторе находим нужный реквизит (в нашем примере — КБК в документе ПлатежноеПоручение). В палитре свойств открываем выбор типа и добавляем к текущему типу Строка тип СправочникСсылка.КБК. Теперь реквизит стал составным.
  2. Обновление конфигурации. При таком подходе данные в существующих документах сохранятся, так как тип Строка по-прежнему поддерживается.
  3. Программная миграция. Нам необходимо создать обработку, которая переберет все документы, прочитает строковое значение, найдет или создаст соответствующий элемент в справочнике и запишет ссылку обратно в это же поле. Проанализируем пример кода для такой обработки:

// Пример миграции данных для составного типа
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ПлатежноеПоручение.Ссылка КАК Ссылка,
    |	ПлатежноеПоручение.КБК КАК КБК_Текст
    |ИЗ
    |	Документ.ПлатежноеПоручение КАК ПлатежноеПоручение
    |ГДЕ
    |	ТИПЗНАЧЕНИЯ(ПлатежноеПоручение.КБК) = ТИП(СТРОКА)
    |	И ПлатежноеПоручение.КБК <> """"";

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    // Ищем элемент в справочнике по наименованию (или коду)
    СсылкаНаКБК = Справочники.КБК.НайтиПоНаименованию(Выборка.КБК_Текст, Истина);
    
    // Если не нашли — создаем новый
    Если СсылкаНаКБК.Пустая() Тогда
        НовыйОбъект = Справочники.КБК.СоздатьЭлемент();
        НовыйОбъект.Наименование = Выборка.КБК_Текст;
        // Заполняем другие важные реквизиты, если нужно
        НовыйОбъект.Записать();
        СсылкаНаКБК = НовыйОбъект.Ссылка;
    КонецЕсли;
    
    // Записываем ссылку в документ
    ОбъектДок = Выборка.Ссылка.ПолучитьОбъект();
    ОбъектДок.КБК = СсылкаНаКБК;
    // Используем ОбменДанными.Загрузка = Истина, чтобы избежать лишних проверок и движений
    ОбъектДок.ОбменДанными.Загрузка = Истина;
    ОбъектДок.Записать();
КонецЦикла;
  1. Завершение перехода. После того как все документы обновлены и в поле КБК теперь везде хранятся ссылки, можно снова зайти в конфигуратор и убрать тип Строка из состава типов реквизита. Платформа поймет, что данные теперь соответствуют единственному оставшемуся типу, и сохранит их.

Вариант 2. Создание нового реквизита и переименование старого

Этот метод более надежен и соответствует стандартам разработки крупных систем (например, в типовых конфигурациях от 1С). Разберем этот алгоритм:

  1. Маркировка старого поля. Переименуем текущий реквизит КБК в УдалитьКБК. Это даст понять другим разработчикам и самой системе, что поле устарело.
  2. Создание нового поля. Создадим новый реквизит КБК с типом СправочникСсылка.КБК.
  3. Перенос данных. Аналогично предыдущему способу, пишем обработку, которая берет данные из УдалитьКБК, находит/создает элемент справочника и записывает его в новый реквизит КБК.
  4. Работа с формами. На формах документов заменяем поле ввода, связанное с УдалитьКБК, на новое поле, связанное с КБК.

Преимущества этого метода: мы не рискуем целостностью данных в момент изменения типа, так как создаем совершенно новую физическую колонку в таблице БД. Старые данные остаются доступны для сверки в любой момент до окончательного удаления реквизита УдалитьКБК.

Вариант 3. Использование истории выбора и списков без смены типа

Иногда пользователю не нужен полноценный справочник как объект учета, а нужна лишь помощь при вводе. Если КБК — это просто строка, которую неохота вводить дважды, выясним причину: возможно, достаточно настроить интерфейсные механизмы.

Рассмотрим возможности платформы для типа Строка:

Пример программного формирования списка выбора без смены типа реквизита:


&НаКлиенте
Процедура КБКАвтоПодбор(Элемент, Текст, ДанныеВыбора, Параметры, Ожидание, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ДанныеВыбора = ПолучитьСписокКБКПоСтроке(Текст);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьСписокКБКПоСтроке(Знач Текст)
    Список = Новый СписокЗначений;
    // Выбираем уникальные КБК из уже существующих документов
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 10
        |	ПлатежноеПоручение.КБК КАК КБК
        |ИЗ
        |	Документ.ПлатежноеПоручение КАК ПлатежноеПоручение
        |ГДЕ
        |	ПлатежноеПоручение.КБК ПОДОБНО &Текст";
    Запрос.УстановитьПараметр("Текст", Текст + "%");
    
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Список.Добавить(Выборка.КБК);
    КонецЦикла;
    
    Возврат Список;
КонецФункции

Профессиональный подход: Обработчики обновления БСП

Если вы работаете в конфигурации, где используется Библиотека стандартных подсистем (БСП), «правильный» путь выглядит иначе. Мы не запускаем ручные обработки. Вместо этого:

  1. Мы регистрируем процедуру миграции данных в модуле ОбновлениеИнформационнойБазы<ИмяВашейКонфигурации>.
  2. В этой процедуре мы используем возможности БСП для группового изменения объектов.
  3. Система сама запустит этот код при первом входе пользователя после обновления конфигурации. Это гарантирует, что данные будут перенесены у всех клиентов в распределенной базе данных (РИБ).

Важные нюансы при работе с КБК

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

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

← На главную