В процессе работы с базами данных 1С часто возникает ситуация, когда необходимо привести в порядок контактную информацию. Типичный пример: у физического лица заполнен адрес регистрации (прописки), но не указан фактический адрес проживания. Чтобы не вводить данные вручную для тысяч сотрудников, мы можем автоматизировать этот процесс. В этой статье мы подробно разберем, как реализовать программную синхронизацию адресов, используя современные инструменты платформы 1С:Предприятие 8.3.
Прежде чем приступать к написанию кода, давайте проанализируем, как 1С хранит информацию об адресах. В современных конфигурациях (таких как ЗУП 3.1, БП 3.0, УТ 11), построенных на базе Библиотеки стандартных подсистем (БСП), контактная информация не хранится в простых реквизитах справочника.
Рассмотрим основные особенности:
КонтактнаяИнформация соответствующего справочника (например, Справочник.ФизическиеЛица).Вид, которое ссылается на справочник ВидыКонтактнойИнформации. Для физических лиц это обычно предопределенные элементы, такие как АдресМестаПроживания и АдресРегистрации.ЗначенияПолей хранится детальная структура в формате XML или JSON, содержащая коды ФИАС (ГАР), индексы и идентификаторы домов. Простое копирование текста из колонки "Представление" не сделает адрес валидным для системы.Разберем наиболее правильный и безопасный способ — использование общего модуля УправлениеКонтактнойИнформацией. Этот метод гарантирует, что все служебные поля (включая идентификаторы ФИАС) будут перенесены корректно.
Выясним алгоритм действий:
Посмотрим на пример программной реализации:
// Выбираем физическое лицо для обработки
ФизЛицоОбъект = ВыбранноеФизЛицо.ПолучитьОбъект();
// Определим виды контактной информации
ВидПрописка = Справочники.ВидыКонтактнойИнформации.ФизическоеЛицоАдресРегистрации;
ВидФактический = Справочники.ВидыКонтактнойИнформации.ФизическоеЛицоАдресМестаПроживания;
// Получаем таблицу всей контактной информации объекта
ТаблицаКИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(ФизЛицоОбъект.Ссылка);
// Ищем строку с пропиской
СтрокаПрописки = ТаблицаКИ.Найти(ВидПрописка, "Вид");
// Проверяем, есть ли уже фактический адрес
СтрокаФактический = ТаблицаКИ.Найти(ВидФактический, "Вид");
Если СтрокаПрописки <> Неопределено И (СтрокаФактический = Неопределено Или ПустаяСтрока(СтрокаФактический.Представление)) Тогда
// Создаем новую структуру для записи
ДанныеДляЗаписи = Новый Структура;
ДанныеДляЗаписи.Вставить("Вид", ВидФактический);
ДанныеДляЗаписи.Вставить("Представление", СтрокаПрописки.Представление);
ДанныеДляЗаписи.Вставить("ЗначенияПолей", СтрокаПрописки.ЗначенияПолей); // Копируем структуру ФИАС
// Используем БСП для корректной записи
УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(ФизЛицоОбъект, ДанныеДляЗаписи, ВидФактический);
ФизЛицоОбъект.Записать();
КонецЕсли;
Если по каким-то причинам использование процедур БСП затруднено, мы можем рассмотреть вариант прямого манипулирования строками табличной части. Это допустимо, если мы четко понимаем структуру данных.
Проанализируем ситуацию: нам нужно проверить строки табличной части КонтактнаяИнформация. Если мы находим строку прописки, мы должны создать точно такую же строку, но изменить в ней Вид на фактический адрес.
Рассмотрим пример реализации:
Для Каждого СтрКИ Из ФизЛицоОбъект.КонтактнаяИнформация Цикл
Если СтрКИ.Вид = ВидПрописка Тогда
// Проверяем, нет ли уже заполненного фактического адреса
ПараметрыОтбора = Новый Структура("Вид", ВидФактический);
НайденныеСтроки = ФизЛицоОбъект.КонтактнаяИнформация.НайтиСтроки(ПараметрыОтбора);
Если НайденныеСтроки.Количество() = 0 Тогда
НоваяСтр = ФизЛицоОбъект.КонтактнаяИнформация.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтр, СтрКИ, , "Вид");
НоваяСтр.Вид = ВидФактический;
НоваяСтр.Тип = Перечисления.ТипыКонтактнойИнформации.Адрес;
ИначеЕсли ПустаяСтрока(НайденныеСтроки[0].Представление) Тогда
ЗаполнитьЗначенияСвойств(НайденныеСтроки[0], СтрКИ, , "Вид");
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
Когда стоит задача обработать 1000 и более физических лиц, выполнение этого кода в обычном цикле может занять значительное время и заблокировать работу других пользователей. Выясним, как оптимизировать этот процесс.
Советы по оптимизации:
ОбменДанными.Загрузка = Истина, чтобы пропустить дополнительные проверки в модуле объекта (но будьте осторожны, это может привести к нарушению логики некоторых проверок).Пример оптимизированного цикла обработки:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФизическиеЛица.Ссылка КАК Ссылка
|ИЗ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
|ГДЕ
| ФизическиеЛица.КонтактнаяИнформация.Вид = &ВидПрописка
| И НЕ ФизическиеЛица.Ссылка В
| (ВЫБРАТЬ
| КИ.Ссылка
| ИЗ
| Справочник.ФизическиеЛица.КонтактнаяИнформация КАК КИ
| ГДЕ
| КИ.Вид = &ВидФактический
| И КИ.Представление <> """")";
Запрос.УстановитьПараметр("ВидПрописка", ВидПрописка);
Запрос.УстановитьПараметр("ВидФактический", ВидФактический);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Здесь вызываем процедуру обновления адреса
ОбновитьАдресаФизЛица(Выборка.Ссылка);
КонецЦикла;
При работе с адресами крайне важно сохранять целостность данных классификатора. Если в вашей базе включена проверка адресов, то простое копирование поля Представление приведет к тому, что адрес в карточке будет гореть красным как "некорректный".
Всегда переносите поле ЗначенияПолей. Именно в нем хранятся уникальные идентификаторы (GUID) из государственного адресного реестра. Если адрес был привязан к ФИАС в прописке, то при копировании ЗначенияПолей он останется привязанным и в фактическом адресе.
Также стоит помнить о флаге "Совпадает с адресом регистрации", который реализован во многих типовых конфигурациях. Иногда система сама умеет подтягивать адрес регистрации в фактический, если последний не заполнен. Прежде чем писать сложную обработку, убедитесь, что в вашей конфигурации этот механизм не настроен на уровне функциональных опций или настроек учета.
Рассмотренные нами методы позволяют быстро и корректно выполнить синхронизацию контактной информации, соблюдая все требования платформы 1С и БСП.