Как программно скопировать адрес прописки в фактический адрес для физических лиц в 1С?

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

В процессе работы с базами данных 1С часто возникает ситуация, когда необходимо привести в порядок контактную информацию. Типичный пример: у физического лица заполнен адрес регистрации (прописки), но не указан фактический адрес проживания. Чтобы не вводить данные вручную для тысяч сотрудников, мы можем автоматизировать этот процесс. В этой статье мы подробно разберем, как реализовать программную синхронизацию адресов, используя современные инструменты платформы 1С:Предприятие 8.3.

Понимание структуры хранения данных контактной информации

Прежде чем приступать к написанию кода, давайте проанализируем, как 1С хранит информацию об адресах. В современных конфигурациях (таких как ЗУП 3.1, БП 3.0, УТ 11), построенных на базе Библиотеки стандартных подсистем (БСП), контактная информация не хранится в простых реквизитах справочника.

Рассмотрим основные особенности:

  1. Табличная часть: Все адреса, телефоны и email хранятся в табличной части КонтактнаяИнформация соответствующего справочника (например, Справочник.ФизическиеЛица).
  2. Виды контактной информации: Каждая строка в этой таблице имеет поле Вид, которое ссылается на справочник ВидыКонтактнойИнформации. Для физических лиц это обычно предопределенные элементы, такие как АдресМестаПроживания и АдресРегистрации.
  3. Сложная структура (ЗначенияПолей): Это самое важное. Адрес в 1С — это не просто строка "г. Москва, ул. Ленина...". В поле ЗначенияПолей хранится детальная структура в формате XML или JSON, содержащая коды ФИАС (ГАР), индексы и идентификаторы домов. Простое копирование текста из колонки "Представление" не сделает адрес валидным для системы.

Метод 1: Использование механизмов БСП (Рекомендуемый)

Разберем наиболее правильный и безопасный способ — использование общего модуля УправлениеКонтактнойИнформацией. Этот метод гарантирует, что все служебные поля (включая идентификаторы ФИАС) будут перенесены корректно.

Выясним алгоритм действий:

  1. Получаем данные текущего адреса (например, прописки).
  2. Проверяем наличие фактического адреса.
  3. Если его нет, записываем данные прописки в вид "Фактический адрес".

Посмотрим на пример программной реализации:


// Выбираем физическое лицо для обработки
ФизЛицоОбъект = ВыбранноеФизЛицо.ПолучитьОбъект();

// Определим виды контактной информации
ВидПрописка = Справочники.ВидыКонтактнойИнформации.ФизическоеЛицоАдресРегистрации;
ВидФактический = Справочники.ВидыКонтактнойИнформации.ФизическоеЛицоАдресМестаПроживания;

// Получаем таблицу всей контактной информации объекта
ТаблицаКИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(ФизЛицоОбъект.Ссылка);

// Ищем строку с пропиской
СтрокаПрописки = ТаблицаКИ.Найти(ВидПрописка, "Вид");

// Проверяем, есть ли уже фактический адрес
СтрокаФактический = ТаблицаКИ.Найти(ВидФактический, "Вид");

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

Метод 2: Прямая работа с табличной частью

Если по каким-то причинам использование процедур БСП затруднено, мы можем рассмотреть вариант прямого манипулирования строками табличной части. Это допустимо, если мы четко понимаем структуру данных.

Проанализируем ситуацию: нам нужно проверить строки табличной части КонтактнаяИнформация. Если мы находим строку прописки, мы должны создать точно такую же строку, но изменить в ней Вид на фактический адрес.

Рассмотрим пример реализации:


Для Каждого СтрКИ Из ФизЛицоОбъект.КонтактнаяИнформация Цикл
    Если СтрКИ.Вид = ВидПрописка Тогда
        // Проверяем, нет ли уже заполненного фактического адреса
        ПараметрыОтбора = Новый Структура("Вид", ВидФактический);
        НайденныеСтроки = ФизЛицоОбъект.КонтактнаяИнформация.НайтиСтроки(ПараметрыОтбора);
        
        Если НайденныеСтроки.Количество() = 0 Тогда
            НоваяСтр = ФизЛицоОбъект.КонтактнаяИнформация.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтр, СтрКИ, , "Вид");
            НоваяСтр.Вид = ВидФактический;
            НоваяСтр.Тип = Перечисления.ТипыКонтактнойИнформации.Адрес;
        ИначеЕсли ПустаяСтрока(НайденныеСтроки[0].Представление) Тогда
            ЗаполнитьЗначенияСвойств(НайденныеСтроки[0], СтрКИ, , "Вид");
        КонецЕсли;
        
        Прервать; 
    КонецЕсли;
КонецЦикла;

Массовая обработка данных (более 1000 записей)

Когда стоит задача обработать 1000 и более физических лиц, выполнение этого кода в обычном цикле может занять значительное время и заблокировать работу других пользователей. Выясним, как оптимизировать этот процесс.

Советы по оптимизации:

  1. Запрос вместо перебора: Сначала выполните запрос к базе данных, чтобы получить только те физические лица, у которых заполнена прописка, но отсутствует фактический адрес. Это отсечет лишние объекты.
  2. Транзакции и порции: Выполняйте запись объектов порциями (например, по 200–500 человек) в одной транзакции. Это значительно ускорит работу дисковой подсистемы.
  3. Отключение проверок: При массовой записи можно использовать ОбменДанными.Загрузка = Истина, чтобы пропустить дополнительные проверки в модуле объекта (но будьте осторожны, это может привести к нарушению логики некоторых проверок).

Пример оптимизированного цикла обработки:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ФизическиеЛица.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.ФизическиеЛица КАК ФизическиеЛица
    |ГДЕ
    |	ФизическиеЛица.КонтактнаяИнформация.Вид = &ВидПрописка
    |	И НЕ ФизическиеЛица.Ссылка В
    |			(ВЫБРАТЬ
    |				КИ.Ссылка
    |			ИЗ
    |				Справочник.ФизическиеЛица.КонтактнаяИнформация КАК КИ
    |			ГДЕ
    |				КИ.Вид = &ВидФактический
    |				И КИ.Представление <> """")";

Запрос.УстановитьПараметр("ВидПрописка", ВидПрописка);
Запрос.УстановитьПараметр("ВидФактический", ВидФактический);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    // Здесь вызываем процедуру обновления адреса
    ОбновитьАдресаФизЛица(Выборка.Ссылка);
КонецЦикла;

Важные нюансы работы с ФИАС/ГАР

При работе с адресами крайне важно сохранять целостность данных классификатора. Если в вашей базе включена проверка адресов, то простое копирование поля Представление приведет к тому, что адрес в карточке будет гореть красным как "некорректный".

Всегда переносите поле ЗначенияПолей. Именно в нем хранятся уникальные идентификаторы (GUID) из государственного адресного реестра. Если адрес был привязан к ФИАС в прописке, то при копировании ЗначенияПолей он останется привязанным и в фактическом адресе.

Также стоит помнить о флаге "Совпадает с адресом регистрации", который реализован во многих типовых конфигурациях. Иногда система сама умеет подтягивать адрес регистрации в фактический, если последний не заполнен. Прежде чем писать сложную обработку, убедитесь, что в вашей конфигурации этот механизм не настроен на уровне функциональных опций или настроек учета.

Рассмотренные нами методы позволяют быстро и корректно выполнить синхронизацию контактной информации, соблюдая все требования платформы 1С и БСП.

← На главную