Как программно установить основной E-mail в 1С

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

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

Где искать данные контактной информации

Первым делом выясним причину, по которой поле «E-mail» отсутствует в таблице справочника. В современных конфигурациях 1С (особенно построенных на базе БСП) контактная информация не является частью реквизитов объекта. Она хранится в специальном регистре сведений КонтактнаяИнформация. Чтобы понять, как программно отметить адрес основным, проанализируем структуру этого регистра. Основные измерения, которые нам понадобятся:

Флаг «Основной» в программном коде соответствует ресурсу ЗначениеПоУмолчанию с типом Булево.

Алгоритм работы с Набором Записей

Рассмотрим ситуацию, когда у одного объекта может быть несколько адресов электронной почты (рабочая и личная). Нам нужно установить приоритет: если заполнена рабочая почта, делаем основной её; если только личная — делаем основной личную. При этом важно помнить: у одного объекта для одного типа контактной информации (Email) может быть только одна основная запись. Если мы установим ЗначениеПоУмолчанию = Истина для одной строки, мы обязаны сбросить его в Ложь для всех остальных строк этого же типа у данного объекта.

Разберем пример кода, который обходит справочник и обновляет регистр через СоздатьНаборЗаписей:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ИТ_КонтактныеЛица.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.ИТ_КонтактныеЛица КАК ИТ_КонтактныеЛица";

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

// Определим виды КИ, которые нас интересуют
РабочаяПочта = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Рабочая почта");
ЛичнаяПочта = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Личная почта");

Пока Выборка.Следующий() Цикл
    // Создаем набор записей с отбором по объекту
    НаборЗаписей = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Объект.Установить(Выборка.Ссылка);
    НаборЗаписей.Прочитать();
    
    Если НаборЗаписей.Количество() > 0 Тогда
        ЕстьРабочаяПочта = Ложь;
        ЕстьИзменения = Ложь;
        СтрЛичнаяПочта = Неопределено;
        
        // Первый проход: сбрасываем старые флаги и ищем приоритетные виды
        Для Каждого СтрНабора Из НаборЗаписей Цикл
            Если СтрНабора.Тип = Перечисления.ТипыКонтактнойИнформации.АдресЭлектроннойПочты Тогда
                // Сначала снимаем признак основного у всех
                Если СтрНабора.ЗначениеПоУмолчанию Тогда
                    СтрНабора.ЗначениеПоУмолчанию = Ложь;
                    ЕстьИзменения = Истина;
                КонецЕсли;
                
                Если СтрНабора.Вид = РабочаяПочта Тогда
                    ЕстьРабочаяПочта = Истина;
                    СтрНабора.ЗначениеПоУмолчанию = Истина;
                    ЕстьИзменения = Истина;
                ИначеЕсли СтрНабора.Вид = ЛичнаяПочта Тогда
                    СтрЛичнаяПочта = СтрНабора;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
        
        // Если рабочей почты не было, но нашли личную - ставим основной её
        Если Не ЕстьРабочаяПочта И СтрЛичнаяПочта <> Неопределено Тогда
            СтрЛичнаяПочта.ЗначениеПоУмолчанию = Истина;
            ЕстьИзменения = Истина;
        КонецЕсли;
        
        // Записываем только если были изменения, чтобы не плодить лишние транзакции
        Если ЕстьИзменения Тогда
            НаборЗаписей.Записать();
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Оптимизация через Менеджер Записи

Проанализируем другой подход. Если нам нужно точечно изменить только конкретные записи, удобнее использовать СоздатьМенеджерЗаписи. Этот метод позволяет не читать весь набор данных по объекту, а обращаться к конкретной строке по ключу (Объект + Тип + Вид). Посмотрим на пример реализации, когда мы выбираем объекты запросом сразу из регистра:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |   КонтактнаяИнформация.Объект КАК Объект
    |ИЗ
    |   РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
    |ГДЕ
    |   КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)
    |   И КонтактнаяИнформация.Объект ССЫЛКА Справочник.ИТ_КонтактныеЛица";

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

Запись = РегистрыСведений.КонтактнаяИнформация.СоздатьМенеджерЗаписи();
ВидРабочая = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Рабочий E-Mail");

Пока Выборка.Следующий() Цикл
    // Пытаемся прочитать конкретную запись для установки флага
    Запись.Объект = Выборка.Объект;
    Запись.Тип = Перечисления.ТипыКонтактнойИнформации.АдресЭлектроннойПочты;
    Запись.Вид = ВидРабочая;
    Запись.Прочитать();
    
    Если Запись.Выбран() Тогда
        Запись.ЗначениеПоУмолчанию = Истина;
        Запись.Записать(Истина); // Истина означает замещение
    КонецЕсли;
КонецЦикла;

Важные нюансы и рекомендации

При выполнении подобных задач следует учитывать несколько критически важных моментов, которые помогут избежать ошибок в данных:

  1. Поиск вида контактной информации: Использование НайтиПоНаименованию считается плохим тоном, так как пользователи могут изменить название вида (например, переименовать «Рабочая почта» в «E-mail основной»). Если ваша конфигурация использует БСП, лучше обращаться к предопределенным элементам или использовать поиск по внутреннему идентификатору/имени, заданному в метаданных.
  2. Дублирование в табличных частях: Выясним важную деталь — во многих современных конфигурациях 1С данные контактной информации дублируются в табличной части самого справочника (например, ТЧ КонтактнаяИнформация у справочника Контрагенты). Если вы обновите только регистр, при открытии формы объекта пользователь может увидеть старые данные. В идеале после изменения регистра следует вызвать программную перезапись объекта или использовать методы общего модуля УправлениеКонтактнойИнформацией для синхронизации.
  3. Транзакции: Если справочник содержит десятки тысяч записей, выполнение записи в цикле может занять много времени. Рассмотрим возможность оборачивания процесса в транзакцию порциями (например, по 1000 элементов), чтобы ускорить работу.
  4. Проверка на пустое представление: Перед установкой адреса основным, полезно проверить, заполнено ли само поле Представление или АдресЭП. Нет смысла делать основной пустую запись.

Таким образом, мы выяснили, что задача «Установить основным» сводится к корректному обновлению ресурса ЗначениеПоУмолчанию в регистре сведений КонтактнаяИнформация. Выбор между НаборомЗаписей и МенеджеромЗаписи зависит от сложности вашей логики: если нужно анализировать сразу все виды почты одного контакта — используйте набор; если нужно просто включить флаг для конкретного вида — достаточно менеджера записи.

← На главную