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