При обновлении типовых конфигураций 1С (таких как 1С:Розница, 1С:Управление торговлей или 1С:ERP) администраторы и программисты иногда сталкиваются с неприятным симптомом: в карточках физических лиц, контрагентов или партнеров полностью исчезают номера телефонов и адреса электронной почты. При этом в консоли запросов данные отлично видны, а тестирование и исправление (ТИИ) базы данных не приносит никаких результатов.
В этой статье мы подробно разберем, почему возникает эта техническая проблема, как устроен механизм хранения контактной информации в современных версиях «Библиотеки стандартных подсистем» (БСП) и какими способами можно восстановить корректное отображение данных на формах объектов.
Для того чтобы понять природу ошибки, проанализируем архитектуру хранения контактной информации. В старых версиях БСП контактные данные (адреса, телефоны, email) записывались в табличную часть КонтактнаяИнформация объекта-владельца. Текстовое представление полей и структура хранились в колонке ЗначенияПолей в формате XML.
В современных релизах БСП (начиная с версий 3.x) разработчики фирмы «1С» перешли на новый стандарт — хранение структурированных данных контактной информации в формате JSON в колонке Значение. Колонка ЗначенияПолей (XML) теперь используется только для обратной совместимости. Во время обновления конфигурации специальные фоновые обработчики должны автоматически перекодировать старые XML-строки в формат JSON.
Почему же данные видны в консоли запросов, но не отображаются на управляемой форме карточки физлица? Дело в динамическом построении интерфейса БСП:
ФизическиеЛица) программный код БСП считывает структуру из справочника ВидыКонтактнойИнформации.КонтактнаяИнформация физического лица строки, у которых реквизит Вид совпадает со ссылкой на соответствующий вид контактной информации (например, «Телефон физ. лица»).Вид поврежден и содержит битую ссылку (<Объект не найден>) или вовсе пуст, система не может сопоставить эту строку ни с одним из доступных видов КИ.Представление или Значение) и доступна через прямой запрос к СУБД.Основная причина появления значения <Объект не найден> в реквизите Вид — это рассинхронизация уникальных идентификаторов (UUID/GUID) элементов справочника ВидыКонтактнойИнформации. Это происходит по нескольким причинам:
ВидыКонтактнойИнформации не был синхронизирован по GUID или был исключен из обмена. При переносе физических лиц их табличные части ссылаются на GUID видов КИ, которых просто нет в принимающей базе.Обычное Тестирование и исправление (ТИИ) здесь не поможет. В режиме «Очищать ссылки» ТИИ просто сотрет битые GUID, сделав реквизит Вид пустым. В режиме «Создавать объекты» ТИИ создаст пустые элементы без обязательных заполненных реквизитов БСП, которые форма все равно проигнорирует.
---
Если у нас есть вторая («здоровая») база данных, в которой телефоны отображаются корректно, самым быстрым и безопасным решением будет выравнивание уникальных идентификаторов справочника видов КИ.
Выполним следующие шаги:
ВидыКонтактнойИнформации. Настроим выгрузку в файл и выполним ее.Поскольку обработка переносит объекты с сохранением их оригинальных GUID, битые ссылки в табличных частях справочника физических лиц автоматически «оживут», найдя свои элементы в справочнике ВидыКонтактнойИнформации. Контактная информация мгновенно появится на формах.
---
Если «здоровой» копии базы данных под рукой нет, или идентификаторы утеряны безвозвратно, нам потребуется написать внешнюю обработку для восстановления связей и принудительного преобразования старых XML-данных в формат JSON.
Рассмотрим пример программного кода, который обходит справочник физических лиц, находит поврежденные строки контактной информации с типом «Телефон», привязывает их к корректному виду КИ и выполняет конвертацию:
ВыборкаФизЛиц = Справочники.ФизическиеЛица.Выбрать();
Пока ВыборкаФизЛиц.Следующий() Цикл
ОбъектФизЛицо = ВыборкаФизЛиц.ПолучитьОбъект();
Модифицирован = Ложь;
Для Каждого СтрокаКИ Из ОбъектФизЛицо.КонтактнаяИнформация Цикл
// Проверяем, относится ли строка к телефонам
Если СтрокаКИ.Тип = Перечисления.ТипыКонтактнойИнформации.Телефон Тогда
// Проверяем ссылочную целостность реквизита "Вид"
Если СтрокаКИ.Вид.ПолучитьОбъект() = Неопределено Или СтрокаКИ.Вид.Пустая() Тогда
// Назначаем правильный предопределенный вид контактной информации
СтрокаКИ.Вид = Справочники.ВидыКонтактнойИнформации.ТелефонФизЛица;
Модифицирован = Истина;
КонецЕсли;
// Если значение в формате JSON пустое, но есть старые данные в XML (ЗначенияПолей)
Если ПустаяСтрока(СтрокаКИ.Value) И Не ПустаяСтрока(СтрокаКИ.ЗначенияПолей) Тогда
// Применяем стандартную функцию БСП для конвертации структуры XML в строку JSON
Попытка
СтрокаКИ.Значение = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияВJSON(СтрокаКИ.ЗначенияПолей, СтрокаКИ.Вид);
Модифицирован = Истина;
Исключение
ЗаписьЖурналаРегистрации("КонвертацияКИ", УровеньЖурналаРегистрации.Предупреждение, , ,
"Ошибка конвертации для физлица: " + ОбъектФизЛицо.Ссылка + ". Описание: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// Записываем объект только при наличии изменений
Если Модифицирован Тогда
Попытка
ОбъектФизЛицо.Записать();
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Не удалось записать объект: " + ОбъектФизЛицо.Ссылка);
КонецПопытки;
КонецЕсли;
КонецЦикла;
Этот скрипт можно запустить через встроенную обработку «Групповая изменение реквизитов» (с возможностью выполнения произвольного алгоритма) или оформить как отдельную внешнюю обработку. При записи объекта встроенные механизмы БСП дополнительно проверят структуру и окончательно инициализируют все необходимые поля для корректного отображения на управляемой форме.
---
Иногда перекодирование контактной информации в JSON не завершается из-за того, что обновление информационной базы было прервано, либо фоновые задания заблокированы на уровне СУБД или кластера 1С.
Проанализируем состояние процедур обновления в базе данных:
После завершения работы всех фоновых обработчиков БСП выполнит конвертацию данных автоматически, и телефоны вернутся на свои места в интерфейсе программы.