Что делать, если реквизит пропал из конфигуратора, но отображается и работает в 1С:Предприятии?

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

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

Выясним причины рассинхронизации метаданных и базы данных

Проанализируем основные факторы, которые приводят к подобному поведению системы:

  1. Последствия некорректного динамического обновления. При частом применении механизма динамического обновления (обновления «на лету» без монопольного захвата базы) таблицы конфигурации базы данных (Config, ConfigSave, Params) могут войти в несогласованное состояние. В СУБД физическая колонка таблицы (например, _FldXXXX) остается существующей, серверные процессы 1С продолжают работать со старым кэшем схемы данных, тогда как конфигуратор уже считает реквизит удаленным.
  2. Наличие реквизита в подключенном расширении конфигурации. Если реквизит был добавлен через механизм расширений, он не будет отображаться в основном дереве конфигурации, но при этом будет полноценно доступен в режиме пользователя и в программном коде.
  3. Переименование реквизита с сохранением синонима. Возможно, разработчик переименовал имя реквизита в конфигураторе, оставив прежний синоним, из-за чего визуально на форме отображается привычное имя, а в коде обращение идет к старому свойству через закэшированные контексты.
  4. Зависание кэша метаданных на сервере 1С:Предприятия. Очистка локального кэша на клиенте не сбрасывает закэшированные структуры кластера серверов (каталог snccntx в srvinfo), из-за чего рабочие процессы rphost продолжают отдавать клиентам устаревшую структуру объекта.

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

Если в дереве метаданных конфигуратора просто создать новый реквизит с тем же именем, платформа сгенерирует для него новый уникальный идентификатор (GUID). В таблице СУБД будет выделена новая колонка (например, _FldYYYY), которая не будет связана со старой колонкой (_FldXXXX). При первой же полноценной реструктуризации старая колонка будет удалена СУБД, а новая окажется абсолютно пустой. Это приведет к безвозвратной потере всех исторических значений реквизита.

Шаг 1. Диагностика и проверка расширений

Прежде чем приступать к исправлению структуры, проверим текущее состояние базы:

  1. Откроем меню Конфигурация — Расширения конфигурации и убедимся, что реквизит не был добавлен в одном из активных расширений.
  2. Проверим соответствие имени реквизита и синонима в свойствах объекта.
  3. С помощью функции ПолучитьСтруктуруХраненияБазыДанных() программно проверим наличие физической колонки в СУБД.

Посмотрим на пример кода для проверки структуры хранения в базе данных:


СтруктураБазы = ПолучитьСтруктуруХраненияБазыДанных();
ТаблицаНоменклатуры = СтруктураБазы.Найти("Справочник.Номенклатура", "Имя");

Если ТаблицаНоменклатуры <> Неопределено Тогда
    Для Каждого Поле Из ТаблицаНоменклатуры.Поля Цикл
        Сообщить("Имя поля: " + Поле.ИмяПоля + " | Имя в СУБД: " + Поле.ИмяТаблицыХранения);
    КонецЦикла;
КонецЕсли;

Шаг 2. Обязательная выгрузка и сохранение данных

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

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


// Создадим структуру для сохранения соответствия ссылок и значений
МассивДанных = Новый Массив;

Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    ОбъектСсылка = Выборка.Ссылка;
    
    // Проверяем наличие реквизита у объекта
    Попытка
        ЗначениеРеквизита = Выборка.R1;
    Исключение
        ЗначениеРеквизита = Неопределено;
    КонецПопытки;
    
    Если ЗначениеРеквизита <> Неопределено Тогда
        ЭлементСписка = Новый Структура;
        ЭлементСписка.Вставить("УИД", Строка(ОбъектСсылка.УникальныйИдентификатор()));
        ЭлементСписка.Вставить("Значение", ЗначениеРеквизита);
        МассивДанных.Добавить(ЭлементСписка);
    КонецЕсли;
КонецЦикла;

// Записываем массив данных в файл формата JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл("C:\temp\backup_R1.json");
ЗаписатьJSON(ЗаписьJSON, МассивДанных);
ЗаписьJSON.Закрыть();

Сообщить("Выгрузка успешно завершена. Сохранено записей: " + МассивДанных.Количество());

Шаг 3. Очистка кэша и синхронизация конфигураций

Разберем по шагам действия по очистке служебных кэшей для устранения рассинхронизации:

  1. Создадим полную резервную копию информационной базы (выгрузка файла .dt или бэкап средствами СУБД).
  2. Для клиент-серверного варианта: остановим службу сервера 1C:Enterprise 8.3 Server Agent. В каталоге кластера (srvinfo) удалим временные файлы рабочих процессов и кэша (папки с именами сессий и snccntx).
  3. Запустим службу сервера и выполним очистку локального кэша на клиентских машинах (каталоги %LocalAppData%\1C\1Cv8 и %AppData%\1C\1Cv8).
  4. Откроем базу в конфигураторе в монопольном режиме. Сохраним конфигурацию в файл (Конфигурация — Сохранить конфигурацию в файл, получив файл .cf).
  5. Выполним полную перезагрузку метаданных: выберем пункт Конфигурация — Загрузить конфигурацию из файла и укажем сохраненный .cf. Данная операция принудительно перезаписывает таблицы Config и ConfigSave, устраняя остаточные следы динамических обновлений.
  6. Выполним Администрирование — Тестирование и исправление информационной базы с проверкой логической и ссылочной целостности.

Шаг 4. Восстановление реквизита и обратная загрузка данных

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

  1. В конфигураторе добавим реквизит R1 в справочник Номенклатура с нужным типом данных.
  2. Выполним обновление конфигурации базы данных (клавиша F7) в монопольном режиме.
  3. Запустим базу в режиме «1С:Предприятие» и загрузим сохраненные данные обратно с помощью внешней обработки.

Посмотрим на пример программной загрузки значений реквизита из ранее сохраненного файла JSON:


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл("C:\temp\backup_R1.json");
МассивДанных = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

Для Каждого Элемент Из МассивДанных Цикл
    СсылкаНаНоменклатуру = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(Элемент.УИД));
    
    // Проверяем, существует ли элемент в базе
    ОбъектНоменклатуры = СсылкаНаНоменклатуру.ПолучитьОбъект();
    Если ОбъектНоменклатуры <> Неопределено Тогда
        ОбъектНоменклатуры.R1 = Элемент.Значение;
        Попытка
            // Записываем объект без вызова лишних проверок при необходимости
            ОбъектНоменклатуры.Записать();
        Исключение
            Сообщить("Ошибка при записи элемента: " + СсылкаНаНоменклатуру + " (" + ОписаниеОшибки() + ")");
        КонецПопытки;
    КонецЕсли;
КонецЦикла;

Сообщить("Загрузка данных реквизита R1 завершена.");

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

← На главную