Смена типа реквизита через расширение: что разрешает платформа и как не потерять данные

· 11 мин

Содержание

Изменить тип реквизита в расширении 1С можно только у реквизита, который создан в самом расширении: открываете расширение в конфигураторе, меняете свойство «Тип» и обновляете конфигурацию базы данных. У реквизита основной конфигурации тип через расширение не меняется: заимствованный объект берёт тип из основной конфигурации. Там работает обходной путь — новый реквизит нужного типа в расширении плюс перенос данных.

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

Чей это реквизит: что расширение может и не может поменять

Первым делом определите происхождение реквизита. Откройте расширение в конфигураторе (Конфигурация → Расширения конфигурации, двойной щелчок по строке) и найдите объект в дереве.

  • 🟢 Собственный реквизит расширения. Добавлен в расширении к заимствованному справочнику или документу, либо принадлежит собственному объекту расширения. Его имя обычно начинается с префикса расширения, например Расш1_ДатаПоставки. Тип редактируется как у обычного реквизита.
  • 🔴 Реквизит основной конфигурации. Виден в расширении только потому, что заимствован объект или форма. Свойства такого реквизита в расширении не редактируются — они берутся из основной конфигурации.
  • 🟡 Реквизит основной конфигурации со снятой поддержкой. Если конфигурация снята с поддержки или в ней включена возможность изменений, тип можно поменять прямо в основной конфигурации. Но тогда это уже не работа с расширением, и при каждом обновлении типовой придётся сравнивать изменения вручную.
СитуацияГде менять типЧто будет с данными
Свой реквизит расширенияСвойство «Тип» в расширенииПлатформа преобразует значения при реструктуризации; что не преобразуется, станет пустым
Реквизит типовой, конфигурация на поддержкеНовый реквизит в расширенииСтарые данные остаются, переносите их обработкой
Реквизит типовой, поддержка снятаВ основной конфигурацииРеструктуризация основной таблицы, риски при обновлениях

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

Подготовка базы и расширения перед сменой типа

Смена типа — операция с данными. Ошибиться можно один раз, поэтому подготовка обязательна.

  1. Сделайте резервную копию. Для файловой базы — выгрузка в .dt через Администрирование → Выгрузить информационную базу в конфигураторе или копия каталога базы. Для клиент-серверной — бэкап средствами СУБД. Без копии тип не меняйте: обратного пути у неконвертированных значений нет.
  2. Сохраните расширение в файл. В списке расширений выделите нужное и выполните сохранение в файл .cfe. Это ваша точка отката для метаданных.
  3. Проверьте, сколько данных затронет смена. Простым запросом в консоли запросов посчитайте записи, где реквизит заполнен, и посмотрите примеры значений. Если вы меняете строку на число, сразу ищите строки, которые числом не являются: "12,5 кг", "б/н", пробелы.
  4. Найдите все места использования. В расширении: правый клик по реквизиту → Найти ссылки на объект. Ищите и по тексту модулей — запросы, где поле сравнивается или выводится, ссылки на него по имени в строках.
  5. Выберите окно для работ. Обновление структуры базы с данными расширения требует, чтобы пользователи не работали с изменяемыми таблицами. Предупредите людей заранее и делайте это вне рабочего времени.
Перед сменой типа реквизита
Выполнено: 0 / 6

Способ 1. Меняем тип собственного реквизита расширения

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

  1. Откройте конфигуратор, Конфигурация → Расширения конфигурации, откройте нужное расширение.
  2. В дереве найдите объект (справочник, документ) и в нём реквизит или реквизит табличной части.
  3. Откройте палитру свойств (Alt+Enter) и нажмите кнопку выбора у свойства «Тип».
  4. Выберите новый тип. Для строки задайте длину, для числа — длину и точность. Если нужен составной тип, поставьте флажок «Составной тип данных» и отметьте нужные типы.
  5. Проверьте связанные свойства: «Заполнять из данных заполнения», «Проверка заполнения», «Связи параметров выбора», «Параметры выбора». Они могут потерять смысл при новом типе.
  6. Выполните Конфигурация → Обновить конфигурацию базы данных (F7) для этого расширения.
  7. Платформа покажет окно реорганизации с перечнем изменений. Прочитайте его и только потом принимайте.

Что происходит со значениями при реструктуризации

При смене типа платформа пытается преобразовать хранимые значения:

  • 🔁 число → строка: обычно без потерь, 125 становится "125";
  • 🔁 строка → число: преобразуются только корректные числа, остальное становится нулём;
  • 🔁 строка большей длины → строка меньшей длины: хвост обрезается;
  • 🔁 простой тип → составной, который включает старый тип: значения сохраняются;
  • ❌ ссылка на один справочник → ссылка на другой: значения не переносятся, реквизит станет пустым.

Если хоть часть значений не преобразуется автоматически, не полагайтесь на реструктуризацию. Используйте схему с новым реквизитом и переносом данных — так старые значения останутся до тех пор, пока вы не проверите результат.

Способ 2. Тип реквизита основной конфигурации: новый реквизит в расширении

Нужно, например, хранить в справочнике «Номенклатура» срок годности числом дней, а в типовой это строка, либо нужна ссылка на свой справочник вместо строкового поля. Тип типового реквизита поменять нельзя, поэтому делаем замену.

  1. Заимствуйте объект. Правый клик по справочнику в основной конфигурации → Добавить в расширение.
  2. Добавьте реквизит. В заимствованном объекте создайте реквизит с нужным типом, например Расш1_СрокГодностиДней, тип «Число», длина 5, точность 0.
  3. Обновите базу. F7 для расширения. Новый реквизит появится пустым у всех элементов.
  4. Перенесите данные обработкой (код — в следующем разделе).
  5. Поменяйте формы. Заимствуйте форму объекта, добавьте элемент для нового реквизита, старый элемент скройте через свойство «Видимость» в расширении формы.
  6. Поменяйте код. Там, где типовой код читает старое поле, а вам нужно новое, используйте аннотации методов в модуле расширения: &После — чтобы дописать поведение, &Вместо — чтобы заменить метод целиком. Для запросов — своё поле в тексте запроса в вашем коде расширения.
  7. Поддерживайте синхронность, если старое поле всё ещё нужно типовым отчётам и обменам. Например, в обработчике ПередЗаписью объекта заполняйте старое строковое поле из нового числового.

Старый реквизит не удаляйте и не очищайте: он принадлежит типовой. Обмены, печатные формы и отчёты основной конфигурации продолжат с ним работать.

Перенос данных при изменении типа реквизита

Обработку переноса удобнее всего положить в само расширение: объект «Обработка» в расширении с одной командой или кодом в модуле формы на сервере. Ниже пример для переноса строкового срока годности в числовой реквизит расширения.

&НаСервереБезКонтекста
Функция ПеренестиСрокГодности()

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Номенклатура.Ссылка КАК Ссылка
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    Номенклатура.Расш1_СрокГодностиДней = 0";

    Выборка = Запрос.Выполнить().Выбрать();
    Перенесено = 0;
    Ошибки = Новый Массив;

    Пока Выборка.Следующий() Цикл
        Объект = Выборка.Ссылка.ПолучитьОбъект();
        СтрокаСрока = СокрЛП(Объект.СрокГодности);
        Если ПустаяСтрока(СтрокаСрока) Тогда
            Продолжить;
        КонецЕсли;
        Попытка
            Объект.Расш1_СрокГодностиДней = Число(СтрокаСрока);
        Исключение
            Ошибки.Добавить(Строка(Выборка.Ссылка) + ": " + СтрокаСрока);
            Продолжить;
        КонецПопытки;
        Объект.ОбменДанными.Загрузка = Истина;
        Объект.Записать();
        Перенесено = Перенесено + 1;
    КонецЦикла;

    Возврат СтрШаблон("Перенесено: %1, не распознано: %2",
        Формат(Перенесено, "ЧН=0; ЧГ=0"), Формат(Ошибки.Количество(), "ЧН=0; ЧГ=0"));

КонецФункции

Пояснения к коду:

  • СрокГодности в примере — условное имя исходного строкового реквизита. Подставьте имя своего поля.
  • ОбменДанными.Загрузка = Истина отключает проверки и подписки при записи. Это ускоряет перенос и не запускает лишнюю логику, но и не проверяет заполнение — поэтому проверку делайте отдельным запросом после переноса.
  • Массив Ошибки — список значений, которые не стали числом. Выведите его в сообщение или в табличный документ и разберите вручную.
  • Условие = 0 в запросе делает обработку повторяемой: запустили ещё раз — она возьмёт только необработанные элементы.

Перенос в больших базах

На сотнях тысяч объектов одна транзакция и одна выборка — плохая идея.

  • 📦 делите перенос на порции, например по 1000 объектов, через ВЫБРАТЬ ПЕРВЫЕ 1000 и повторный запуск;
  • ⏱ запускайте фоновым заданием, чтобы не держать клиент;
  • 🧾 для регистров сведений, где реквизит — ресурс, используйте наборы записей с отбором и записью с замещением, а не поэлементную перезапись объектов.

Перезапись документов с ОбменДанными.Загрузка = Истина не перепроводит их. Если от реквизита зависят движения, после переноса нужно перепровести документы за нужный период, иначе остатки и обороты останутся по старым данным.

Версии платформы и режим совместимости

Возможности расширений сильно зависят от версии платформы.

  • 🧩 Расширения конфигурации появились в платформе 8.3.6. Тогда они меняли формы и модули, но не структуру данных.
  • 🧩 Хранить свои данные — добавлять реквизиты и табличные части к заимствованным объектам, создавать свои справочники и документы — расширения научились в 8.3.11. На платформе с номером ниже 8.3.11 реквизитов в расширении нет, и менять тип нечего.
  • 🧩 У самого расширения есть свойство «Режим совместимости». Оно не может разрешать больше, чем режим совместимости основной конфигурации и сама платформа. Если в свойствах расширения недоступны нужные объекты, проверьте эти три значения.

Практическое правило: работайте на той же версии платформы, что и на рабочем сервере. Расширение, собранное в более новом конфигураторе, может не загрузиться в базу на старой платформе.

Ещё один момент — назначение расширения (свойство «Назначение»: исправление, адаптация, дополнение). Оно влияет на порядок применения нескольких расширений к одному объекту. Если два расширения добавляют реквизиты к одному справочнику, у каждого свой реквизит со своим префиксом, и конфликта по типу между ними нет.

Тестирование и контроль версий расширения

Где тестировать

Тип меняйте сначала на копии рабочей базы, а не в продуктиве. Порядок проверки:

  1. Загрузите копию .dt в отдельную тестовую базу.
  2. Примените изменённое расширение и обновите конфигурацию базы данных.
  3. Запустите перенос и сверьте количество записей: сколько было заполнено до, сколько после, сколько ушло в ошибки.
  4. Откройте формы объекта, создайте новый элемент, запишите существующий.
  5. Сформируйте отчёты, где участвует поле, и проверьте обмены, если реквизит в них выгружается.

Отладка

Ставьте точки останова в модулях расширения так же, как в основной конфигурации. Если метод перехвачен аннотацией &Вместо, проверьте, что после смены типа не осталось сравнений вида Если Объект.Расш1_Поле = "" Тогда для поля, которое стало числом — синтаксический контроль такую ошибку не поймает, она проявится только в работе.

Контроль версий

  • 🗂 Заполните свойство «Версия» расширения и меняйте его при каждом изменении структуры. Так по списку расширений видно, какая редакция стоит в базе.
  • 🗂 Расширение подключается к хранилищу конфигурации отдельно от основной конфигурации. Командная разработка идёт так же: захват объекта, правка типа, помещение.
  • 🗂 Если вы работаете в 1С:EDT, расширение — отдельный проект, и смена типа видна в истории Git как изменение файла метаданных реквизита.
  • 🗂 Храните .cfe каждой выпущенной версии. Откат метаданных без файла превращается в ручное восстановление.

Откат расширения на версию со старым типом снова запустит реструктуризацию. Значения, которые уже стали пустыми при первой смене типа, при откате не вернутся — вернуть их можно только из резервной копии базы.

Производительность после изменения типа реквизита

Тип поля влияет на размер таблиц и скорость запросов. Что учитывать:

Изменение типаВлияние на базуЧто сделать
Строка → строка неограниченной длиныПоле нельзя индексировать, по нему неудобно отбирать и сортировать в запросахОставьте фиксированную длину, если по полю ищут
Простой тип → составнойПлатформа хранит тип и значение в нескольких колонках, запросы с отбором по полю становятся тяжелееБерите составной тип только при реальной необходимости
Строка → ссылка на справочникОтбор по ссылке быстрее, при выводе нужно соединение со справочникомВключите индексирование, если по полю часто отбирают
Число большой длины → короткоеЭкономия места, риск переполненияПроверьте максимальные значения до смены

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

  • 🚀 включайте свойство «Индексировать» у реквизита расширения, если по нему строят отборы в списках и отчётах;
  • 🚀 не выводите поле расширения в динамический список без надобности;
  • 🚀 после массового переноса данных в клиент-серверной базе обновите статистику СУБД — регламентным заданием обслуживания или вручную в окно работ.

Ошибки при смене типа и что с ними делать

Диагностика: выберите симптом

Если после всех проверок данные расходятся с исходными, не пытайтесь «досинхронизировать» их второй обработкой поверх. Сравните выгрузку старых значений из резервной копии с текущими и переносите только расхождения — так вы не перезапишете то, что пользователи уже успели поправить вручную.