При разработке в среде 1С:Предприятие 8 часто возникает необходимость предоставить пользователю возможность ввода адреса с проверкой по классификатору ФИАС (ГАР). Типовые конфигурации уже содержат мощный механизм для работы с адресами — подсистему «Контактная информация» из состава Библиотеки стандартных подсистем (БСП). Однако у начинающих разработчиков часто возникают трудности, когда нужно подключить этот функционал не к стандартным реквизитам КИ, а к произвольному реквизиту справочника или документа (например, к реквизиту «Адрес подразделения»).
В этой статье мы подробно разберем, почему простая передача текста в форму ввода адреса не работает, как устроена архитектура хранения контактной информации в БСП и как правильно реализовать интерактивный ввод адреса по ФИАС с сохранением структуры данных.
Рассмотрим типичную ошибку. Разработчик пытается открыть стандартную форму ввода адреса БСП и передает туда текстовую строку, содержащую адрес:
Параметры = Новый Структура("Представление", Объект.АдресПодразделения);
ОткрытьФорму("Обработка.РасширенныйВводКонтактнойИнформации.Форма.ВводАдреса", Параметры);
При таком подходе форма ввода адреса откроется абсолютно пустой или предложит ввести адрес в свободной форме. Почему так происходит? Дело в том, что адресный классификатор ФИАС оперирует не просто текстовыми строками, а уникальными идентификаторами (GUID) адресных объектов (регионов, городов, улиц, домов). Чтобы форма ввода адреса БСП смогла отобразить ранее введенный адрес в виде разложенных по полям элементов, ей необходимо передать не текстовое представление, а специальную сериализованную структуру данных (в формате XML или JSON).
Поэтому для полноценной работы адресного классификатора нам всегда необходимо хранить два значения:
Строка) — текстовая строка, которая выводится на форму и используется в печатных формах (например, "101000, г. Москва, ул. Ленина, д. 5").Строка, неограниченной длины) — скрытая XML- или JSON-структура, содержащая все коды и идентификаторы ФИАС для этого адреса.---
Разберем процесс реализации по шагам. Прежде всего, нам необходимо создать два реквизита в нашем объекте метаданных (например, в справочнике Подразделения):
АдресПодразделения (тип Строка, длина, например, 150-250 символов). Этот реквизит будет отвечать за хранение понятного человеку текста.АдресПодразделенияЗначение (тип Строка, длина Неограничена). В этом реквизите БСП будет хранить сериализованные структурированные данные.Вынесем реквизит АдресПодразделения на управляемую форму. Для элемента формы (поле ввода) установим свойство КнопкаВыбора в значение Да. Реквизит АдресПодразделенияЗначение выносить на форму не требуется.
---
Теперь перейдем к написанию кода управляемой формы. Нам необходимо перехватить стандартное событие начала выбора для поля ввода адреса, отменить стандартную обработку и вызвать форму БСП. Выясним, как сделать это правильно с использованием штатного API БСП.
Для этого объявим обработчик события НачалоВыбора для нашего элемента формы:
&НаКлиенте
Процедура АдресПодразделенияНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
// Отменяем стандартный выбор, так как мы будем открывать форму БСП вручную
СтандартнаяОбработка = Ложь;
// Нам понадобится ссылка на вид контактной информации.
// В БСП все настройки адресов привязаны к справочнику "ВидыКонтактнойИнформации".
// Мы можем использовать предопределенный вид КИ или создать свой.
ВидАдреса = ПредопределенноеЗначение("Справочник.ВидыКонтактнойИнформации.АдресПодразделения");
// Создаем описание оповещения, которое сработает после закрытия формы ввода адреса
ОписаниеОповещения = Новый ОписаниеОповещения("АдресПодразделенияЗавершениеВыбора", ЭтотОбъект);
// Формируем параметры для открытия формы с помощью штатного общего модуля БСП
ПараметрыФормы = УправлениеКонтактнойИнформациейКлиент.ПараметрыФормыКонтактнойИнформации(
ВидАдреса,
Объект.АдресПодразделенияЗначение,
Объект.АдресПодразделения
);
// Открываем форму ввода адреса БСП
УправлениеКонтактнойИнформациейКлиент.ОткрытьФормуКонтактнойИнформации(
ПараметрыФормы,
ЭтотОбъект,
ОписаниеОповещения
);
КонецПроцедуры
Проанализируем этот код подробнее. Функция УправлениеКонтактнойИнформациейКлиент.ПараметрыФормыКонтактнойИнформации принимает три ключевых параметра: вид КИ, текущее сериализованное значение (хранится в базе данных) и текущее текстовое представление. Благодаря этому при повторном открытии формы БСП автоматически считает XML- или JSON-структуру и заполнит все поля ФИАС (индекс, город, улицу) корректно. Для изучения API и быстрого поиска примеров вызова функций библиотеки можно использовать справочник по методам БСП.
---
После того как пользователь выберет адрес в форме классификатора и нажмет кнопку «ОК», управление будет передано в процедуру, которую мы указали в ОписаниеОповещения. Нам необходимо получить возвращенные данные и записать их в наши реквизиты объекта.
Реализуем экспортную процедуру обработки выбора:
&НаКлиенте
Процедура АдресПодразделенияЗавершениеВыбора(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
// Если пользователь закрыл форму крестиком или нажал "Отмена", результат будет Неопределено
Если РезультатЗакрытия = Неопределено Тогда
Возврат;
КонецЕсли;
// Записываем полученные данные в реквизиты объекта
// РезультатЗакрытия содержит структуру с полями "Представление" и "КонтактнаяИнформация"
Объект.АдресПодразделения = РезультатЗакрытия.Представление;
Объект.АдресПодразделенияЗначение = РезультатЗакрытия.КонтактнаяИнформация;
// Устанавливаем признак модифицированности формы, чтобы платформа предложила сохранить изменения
ЭтаФорма.Модифицированность = Истина;
КонецПроцедуры
Обратите внимание на свойство РезультатЗакрытия.КонтактнаяИнформация. Именно в нем БСП возвращает полную XML- или JSON-структуру адреса со всеми внутренними идентификаторами ФИАС. При записи объекта эта строка сохранится в базу данных, и при следующем редактировании адрес откроется без потери структуры.
---
Рассмотрим ситуацию, когда в вашей конфигурации используются измененные или устаревшие механизмы БСП, и стандартный общий модуль УправлениеКонтактнойИнформациейКлиент недоступен или изменен. В этом случае мы можем вызвать форму напрямую через платформенный метод ОткрытьФорму, но нам всё равно придется вручную передавать параметры.
Посмотрим на пример реализации такого обходного пути:
&НаКлиенте
Процедура АдресПодразделенияНачалоВыбораАльтернативный(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ПараметрыФормы = Новый Структура;
// Передаем структурированное значение XML/JSON в параметр "Значение"
ПараметрыФормы.Вставить("Значение", Объект.АдресПодразделенияЗначение);
// Передаем текстовую строку в параметр "Представление"
ПараметрыФормы.Вставить("Представление", Объект.АдресПодразделения);
// Для корректной инициализации ФИАС форме БСП часто требуется знать вид КИ
ВидАдреса = ПредопределенноеЗначение("Справочник.ВидыКонтактнойИнформации.АдресПодразделения");
ПараметрыФормы.Вставить("ВидРедактирования", ВидАдреса);
ОписаниеОповещения = Новый ОписаниеОповещения("АдресПодразделенияЗавершениеВыбораАльтернативный", ЭтотОбъект);
// Открываем конкретную форму обработки ввода КИ напрямую
ОткрытьФорму(
"Обработка.РасширенныйВводКонтактнойИнформации.Форма.ВводАдреса",
ПараметрыФормы,
ЭтотОбъект,
, , ,
ОписаниеОповещения,
РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
);
КонецПроцедуры
&НаКлиенте
Процедура АдресПодразделенияЗавершениеВыбораАльтернативный(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
Если РезультатЗакрытия = Неопределено Тогда
Возврат;
КонецЕсли;
// В зависимости от версии БСП, структура результата может незначительно отличаться.
// Обычно возвращаются свойства "Представление" и "КонтактнаяИнформация" (или "Значение").
Объект.Address = РезультатЗакрытия.Представление;
Если РезультатЗакрытия.Свойство("КонтактнаяИнформация") Тогда
Объект.АдресПодразделенияЗначение = РезультатЗакрытия.КонтактнаяИнформация;
ИначеЕсли РезультатЗакрытия.Свойство("Значение") Тогда
Объект.АдресПодразделенияЗначение = РезультатЗакрытия.Значение;
КонецЕсли;
КонецПроцедуры
---
Некоторые разработчики из-за нежелания разбираться с БСП или создавать дополнительные реквизиты хранят адрес просто в виде строки неограниченной длины и разрешают пользователям писать туда всё, что угодно. Мы настоятельно не рекомендуем использовать этот подход по следующим причинам:
Таким образом, один раз потратив время на создание вспомогательного реквизита АдресПодразделенияЗначение и интеграцию с БСП, мы избавляем себя и пользователей от множества проблем в будущем.