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