Смена типа значения, реквизита и ссылки в 1С 8.3

· 9 мин

Содержание

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

Тип значения меняют функциями Число(), Строка(), Дата(). Тип реквизита — в Конфигураторе, с последующим обновлением структуры базы данных. Тип ссылки в поле пользователь может сменить сам, только если реквизит объявлен составным; иначе это работа разработчика.

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

Что именно нужно изменить?

Что в 1С называют типом

За словом «тип» в 1С стоят разные сущности, и от того, какая имеется в виду, зависит способ.

🔹 Примитивные типы — Строка, Число, Дата, Булево. Это базовые значения без привязки к объектам конфигурации.

🔹 Ссылочные типы — ссылки на объекты базы: СправочникСсылка.Контрагенты, ДокументСсылка.РеализацияТоваровУслуг, ПеречислениеСсылка.СтатусыЗаказов. Такое значение указывает на конкретный элемент базы.

🔹 Составной тип — поле, которое принимает несколько типов сразу. Например, реквизит «Получатель» может хранить и контрагента, и физлицо.

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

Преобразование типа значения в коде

Самый простой случай — привести значение к другому типу прямо во встроенном языке. Для этого есть функции-конструкторы.

Количество = Число("15");         // строка → число 15
Текст      = Строка(Количество);  // число → строка "15"
ДатаДок    = Дата("20240110");    // строка "ГГГГММДД" → дата 10.01.2024

Если нужно получить число в виде строки без разделителя групп разрядов, используйте форматирование:

Текст = Формат(Количество, "ЧГ=0");  // "15", а не "1 500" для тысяч

Чтобы узнать текущий тип значения, применяйте ТипЗнч(), а сравнивать его удобно с результатом функции Тип():

Если ТипЗнч(Контрагент) = Тип("СправочникСсылка.Контрагенты") Тогда
    // значение действительно ссылка на контрагента
КонецЕсли;

Функции преобразования не «чинят» некорректные данные. Число("пусто") вызовет ошибку Преобразование значения к типу Число не может быть выполнено. Проверяйте вход заранее или оборачивайте вызов в попытку.

Когда источник данных ненадёжен (ввод пользователя, выгрузка из внешнего файла), безопаснее перехватывать ошибку и подставлять значение по умолчанию:

Попытка
    Количество = Число(СтрокаВвода);
Исключение
    Количество = 0;  // не удалось распознать число
КонецПопытки;

Этот способ меняет тип значения в памяти на время выполнения кода. На структуру базы он не влияет — поле останется того типа, каким объявлено в метаданных.

Как сменить тип реквизита через Конфигуратор

Если нужно, чтобы реквизит справочника или документа навсегда стал другого типа, правка идёт в Конфигураторе.

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

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

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

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

  • Если старый и новый тип совместимы (например, увеличили длину строки или разрядность числа), значения сохраняются.
  • Если типы несовместимы (строку меняете на ссылку, число на дату), поле очищается — платформа подставит значение по умолчанию. Строка «15» при смене на тип Число не превратится в 15, поле просто обнулится.

Ориентир, какие изменения обычно проходят без потери данных, а какие нет:

Изменение типаДанные
Строка → строка большей длиныСохраняются
Число → число с большей разрядностью или точностьюСохраняются
Строка ↔ число, дата ↔ любой другой типОчищаются
Ссылка на один объект → ссылка на другой объектОчищаются
Добавление типа к существующему (переход к составному)Сохраняются

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

Перед обновлением структуры базы
Выполнено: 0 / 4

Как изменить тип ссылки в поле документа

Теперь про сторону пользователя. В поле документа можно выбрать объект другого типа, только если реквизит объявлен составным типом. Признак простой: при вводе значения платформа предлагает сначала выбрать, из какого списка подбирать (контрагенты, физлица и т. д.), а затем сам объект.

Если такого выбора нет и поле жёстко привязано к одному справочнику, пользователь сменить тип не сможет — поле принимает только значения этого справочника. Чтобы оно принимало несколько типов, реквизит придётся делать составным в Конфигураторе.

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

Отдельная задача — массово заменить ссылки в уже заполненных документах (например, поменять контрагента на другого в сотнях строк). Для этого в типовых конфигурациях на БСП есть Групповое изменение реквизитов. Открыть его можно так:

  1. Включите команду «Все функции»: Главное меню → Сервис → Параметры, отметьте флажок Отображать команду "Все функции".
  2. Откройте Главное меню → Все функции → Стандартные → Групповое изменение реквизитов.
  3. Выберите объекты, отметьте реквизит и задайте новое значение.

Групповое изменение меняет значение реквизита, но в пределах уже объявленного типа. Сделать из реквизита-строки реквизит-ссылку оно не может — это снова работа в Конфигураторе.

Перенос данных на объект другого типа через обработку

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

Выборка = Справочники.Контрагенты.Выбрать();
Пока Выборка.Следующий() Цикл
    Новый = Справочники.Партнеры.СоздатьЭлемент();
    Новый.Наименование = Выборка.Наименование;
    Новый.ИНН          = Выборка.ИНН;
    Новый.Записать();
КонецЦикла;

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

Порядок переноса обычно такой:

  • 🔸 создать новые объекты и сохранить соответствие «старый → новый»;
  • 🔸 перепривязать все ссылки на старые объекты к новым;
  • 🔸 убедиться, что старые объекты больше нигде не используются (поиск ссылок по объекту);
  • 🔸 только после этого пометить старые объекты на удаление.

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

Для документов перенос сложнее, чем для справочников: кроме реквизитов шапки нужно переносить строки табличных частей. Их читают во вложенном цикле и добавляют в новый документ методом Добавить():

НоваяСтрока = НовыйДокумент.Товары.Добавить();
НоваяСтрока.Номенклатура = СтрокаИсточника.Номенклатура;
НоваяСтрока.Количество   = СтрокаИсточника.Количество;

Если документ формирует движения по регистрам, после записи его нужно провести — иначе остатки и итоги не пересчитаются.

Составной тип: когда поле принимает несколько типов

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

При работе с таким полем в коде всегда проверяйте тип перед обращением к реквизитам объекта:

Если ТипЗнч(Получатель) = Тип("СправочникСсылка.Контрагенты") Тогда
    ИНН = Получатель.ИНН;
ИначеЕсли ТипЗнч(Получатель) = Тип("СправочникСсылка.ФизическиеЛица") Тогда
    ИНН = Получатель.ИНН;
КонецЕсли;

Без такой проверки обращение к несуществующему для данного типа реквизиту приведёт к ошибке выполнения.

Ограничения, о которых стоит помнить:

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

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

Частые ошибки при смене типа

Ошибки здесь делятся на две группы: потеря данных при реструктуризации и ошибки выполнения в коде.

СимптомПричинаЧто делать
Поле обнулилось после обновления базыСтарый и новый тип несовместимы, реструктуризация очистила значенияВосстановить из копии; переносить данные обработкой, а не сменой типа «в лоб»
Преобразование значения к типу ... не может быть выполненоВ Число()/Дата() передали некорректную строкуПроверять вход, обрабатывать пустые и ошибочные значения
Поле объекта не обнаружено при работе с составным полемОбращение к реквизиту без проверки типаДобавить Если ТипЗнч(...) = Тип(...) перед обращением
Не удаётся обновить структуру базыНет монопольного доступа, есть активные сеансыЗавершить сеансы, войти в монопольном режиме

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

Частые вопросы

Можно ли изменить тип документа на другой вид документа?
Нет, напрямую один вид документа в другой платформа не превращает. Данные переносят обработкой: создают документы нужного вида и переносят в них реквизиты и табличные части.
Сохранятся ли данные, если поменять тип реквизита в Конфигураторе?
Только при совместимых типах (например, увеличение длины строки или разрядности числа). При несовместимых — строка в число, число в ссылку — поле очистится при реструктуризации.
Почему пользователь не может сменить тип значения в поле?
Поле привязано к одному типу. Выбор из нескольких типов возможен, только если реквизит объявлен составным. Изменить это может разработчик в конфигурации.
Нужен ли монопольный режим для смены типа реквизита?
Да. Обновление структуры базы данных с реструктуризацией выполняется только в монопольном режиме — активные сеансы пользователей будут завершены.
Как узнать тип значения в коде?
Функцией ТипЗнч(Значение). Результат сравнивают с Тип("СправочникСсылка.Контрагенты") и подобными, чтобы определить конкретный тип.