В процессе разработки в среде 1С:Предприятие программисты иногда сталкиваются с аномальным поведением метаданных. Одна из таких загадочных проблем — самопроизвольное изменение типа данных в ресурсе или реквизите регистра сведений. Например, вы создаете ресурс с типом ПеречислениеСсылка, но при записи данных поле очищается, а консоль запросов показывает, что тип значения внезапно превратился в СправочникСсылка (часто пустую). Рассмотрим подробно, почему это происходит, как диагностировать проблему и какими методами ее можно окончательно устранить.
Прежде всего, разберем внутренние механизмы платформы. 1С хранит описание структуры базы данных в специальных системных таблицах (таких как Config, DBSchema и Params). Каждому типу данных (справочнику, документу, перечислению) присваивается внутренний числовой идентификатор — TypeID. Когда мы сталкиваемся с тем, что перечисление «превращается» в справочник, это верный признак рассинхронизации между конфигурацией, которую видит платформа, и реальной структурой таблиц в SQL-базе.
Выясним основные причины такого поведения:
Чтобы понять, что именно «видит» база данных, нам недостаточно просто посмотреть на форму записи. Проанализируем ситуацию с помощью запроса. В консоли запросов попробуем выполнить следующий код, чтобы увидеть реальный тип значения, хранящийся в базе:
ВЫБРАТЬ
ТИПЗНАЧЕНИЯ(ИмяРегистра.ИмяРесурса) КАК ТипДанных,
ИмяРегистра.ИмяРесурса КАК ЗначениеРесурса
ИЗ
РегистрСведений.ИмяРегистра КАК ИмяРегистра
Если запрос возвращает тип, отличный от Перечисление, воспользуемся функцией ВЫРАЗИТЬ. Это поможет нам проверить, сохраняется ли типизация на уровне SQL-запроса:
ВЫБРАТЬ
ВЫРАЗИТЬ(ИмяРегистра.ИмяРесурса КАК Перечисление.ИмяВашегоПеречисления) КАК Статус
ИЗ
РегистрСведений.ИмяРегистра КАК ИмяРегистра
Если данный запрос выдает NULL или ошибку, значит, проблема зарыта глубоко в структуре SQL и простое перевыбор типа в конфигураторе не поможет.
Прежде чем переходить к радикальным мерам, выполним стандартные процедуры оздоровления базы. Посмотрим на последовательность действий:
%AppData%\1C\1cv8.snacc в каталоге сеансовых данных. Именно там могут храниться «кривые» скомпилированные описания типов.Проанализируем влияние дополнительных слоев метаданных. Если вы используете расширения, попробуйте временно их отключить. Часто бывает, что расширение «держит» старую структуру объекта, не давая основной конфигурации корректно применить изменения типа.
Также стоит обратить внимание на Хранилище конфигурации. Если объект был удален и создан заново под тем же именем, у него меняется внутренний UID. Если один разработчик затянул изменения, а у другого в этот момент была открыта старая версия, при помещении в хранилище может возникнуть «разрыв». В таком случае рекомендуется полностью удалить объект из конфигурации, зафиксировать изменения в хранилище, а затем создать его заново.
Если стандартное ТИИ и чистка кеша не помогли, воспользуемся проверенным методом «выгрузки-загрузки». Разберем, почему это работает: при выгрузке в файл .dt сохраняются только данные и логическая структура. При последующей загрузке в новую базу платформа создает все таблицы SQL «с нуля», что гарантированно очищает базу от мусорных записей в системных таблицах Params и DBSchema.
Если и это не помогает, или вы не можете сейчас прервать работу пользователей для долгой выгрузки, применим метод «пересоздания объекта»:
Для опытных администраторов существует путь исправления через SQL Management Studio. Однако помните, что прямое редактирование таблиц 1С лишает вас поддержки вендора. Тем не менее, иногда полезно проверить таблицу _Config на наличие дублирующихся записей о структуре регистра. Если вы видите, что для одного и того же объекта метаданных существует несколько описаний, это подтверждает теорию о сбое при динамическом обновлении.
Подводя итог, можно сказать, что проблема с подменой типа — это всегда следствие некорректного обновления структуры базы. Сочетание очистки серверного кеша (папка snacc), реструктуризации таблиц и, в крайнем случае, пересоздания объекта в конфигураторе позволяет полностью устранить этот неприятный баг.