Как программно изменить контактную информацию (адрес, телефон, email) в 1С:Бухгалтерии предприятия 3.0?

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

При работе с конфигурациями на платформе 1С:Предприятие 8.3, особенно с теми, что используют Библиотеку стандартных подсистем (БСП), часто возникает необходимость программного изменения контактной информации (КИ) объектов, таких как справочники "Контрагенты", "ФизическиеЛица" или "Организации" — для этого подойдёт автоматическое заполнение реквизитов и контактов по ИНН. Пользователи нередко сталкиваются с ситуацией, когда после программного заполнения КИ, данные не отображаются в карточке объекта или исчезают после повторной записи. Работа с контактной информацией объектов требует понимания внутренних механизмов БСП. Давайте вместе разберем эту проблему и найдем эффективные решения.

Наш читатель столкнулся именно с такой проблемой: в отличии от предыдущей версии 2.0, где контактная информация хранилась в регистрах сведений, в Бухгалтерии предприятия 3.0 она располагается в табличной части справочника. После программной очистки табличной части и добавления новых строк, таких как фактический адрес, телефон и электронная почта, в карточке контрагента отображается только юридический адрес. Остальная информация попросту не видна. Это указывает на то, что прямое заполнение табличной части не всегда приводит к желаемому результату.

Рассмотрим первоначальный код, с которым столкнулся наш читатель:


&НаСервере
Процедура ЗаполнитьКонтактнуюИнфомрацияНаСервере

    Контрагент1 = Контрагент.ПолучитьОбъект;
    Контрагент1.КонтактнаяИнформация.Очистить;

    Стр1 = Контрагент1.КонтактнаяИнформация.Добавить;
    Стр1.Тип = Перечисления.ТипыКонтактнойИнформации.Адрес;
    Стр1.Вид = Справочники.ВидыКонтактнойИнформации.ФактАдресКонтрагента;
    Стр1.Представление = "Адрес 2 Представление";
    Стр1.Страна = Справочники.СтраныМира.Россия;
    Стр1.Регион = "Москва г";
    Стр1.ВидДляСписка = Справочники.ВидыКонтактнойИнформации.ФактАдресКонтрагента;

    Стр = Контрагент1.КонтактнаяИнформация.Добавить;
    Стр.Тип = Перечисления.ТипыКонтактнойИнформации.Адрес;
    Стр.Вид = Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента;
    Стр.Представление = "Юр Адрес";
    Стр.Страна = Справочники.СтраныМира.Россия;
    Стр.ВидДляСписка = Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента;
    Стр.Регион = "Москва г";

    Стр2 = Контрагент1.КонтактнаяИнформация.Добавить;
    Стр2.Тип = Перечисления.ТипыКонтактнойИнформации.Телефон;
    Стр2.Вид = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента;
    Стр2.Представление = "8 8 8 8 ";
    Стр2.ВидДляСписка = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента;

    Стр3 = Контрагент1.КонтактнаяИнформация.Добавить;
    Стр3.Тип = Перечисления.ТипыКонтактнойИнформации.АдресЭлектроннойПочты;
    Стр3.Вид = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента; // Ошибка: Вид должен соответствовать типу
    Стр3.Представление = "8 8 8 8 ";
    Стр3.ВидДляСписка = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента; // Ошибка: Вид должен соответствовать типу

    Контрагент1.Записать;
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьКонтактнуюИнфомрация(Команда)
    ЗаполнитьКонтактнуюИнфомрацияНаСервере;
КонецПроцедуры

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

Ключевая роль поля "ЗначенияПолей" в хранении контактной информации

Главная причина, по которой контактная информация не отображается или исчезает после записи, заключается в некорректном или отсутствующем заполнении поля ЗначенияПолей в табличной части КонтактнаяИнформация. В конфигурациях на БСП это поле хранит структурированное представление контактных данных в формате XML-схемы (XDTO) или JSON. Если это поле не заполнено или содержит неверные данные, система не сможет правильно интерпретировать и отобразить информацию, даже если поле Представление заполнено текстовым значением.

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

Для формирования XML-представления контактной информации мы будем использовать функции общего модуля УправлениеКонтактнойИнформациейСлужебный. Давайте рассмотрим подробнее.

Шаг 1: Формирование XDTO-объекта на основе представления

Мы используем функцию УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOПоПредставлению() для создания объекта XDTO, который будет содержать контактную информацию в структурированном виде. Эта функция принимает текстовое представление КИ и её тип.

Шаг 2: Преобразование XDTO-объекта в XML-строку

Полученный XDTO-объект затем преобразуется в XML-строку с помощью функции УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOВXML(). Именно эта XML-строка и должна быть записана в поле ЗначенияПолей.

Шаг 3: Запись контактной информации в объект

Для записи контактной информации в табличную часть объекта рекомендуется использовать функцию УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(). Эта функция правильно обрабатывает все внутренние детали, включая заполнение ЗначенияПолей, и обеспечивает корректное отображение данных.

Рассмотрим пример кода, который демонстрирует этот подход (адаптировано из сообщений 8 и 17):


&НаСервере
Процедура ЗаполнитьКонтактнуюИнфомрацияНаСервереПоБСП()

    КонтрагентОбъект = Справочники.Контрагенты.НайтиПоКоду("000000001").ПолучитьОбъект(); // Получаем объект контрагента
    Если КонтрагентОбъект = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Очищаем текущую контактную информацию (если необходимо)
    КонтрагентОбъект.КонтактнаяИнформация.Очистить(); 

    // --- Юридический адрес ---
    ПредставлениеАдресаЮр = "123456, Москва г, Тверская ул, д 1, офис 10";
    ВидКИЮрАдрес = Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента;
    ТипКИЮрАдрес = ВидКИЮрАдрес.Тип; // Обычно Перечисления.ТипыКонтактнойИнформации.Адрес

    ОбъектXDTOКИЮрАдрес = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOПоПредставлению(ПредставлениеАдресаЮр, ТипКИЮрАдрес);
    ЗначенияПолейXMLЮрАдрес = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOВXML(ОбъектXDTOКИЮрАдрес);
    УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(КонтрагентОбъект, ЗначенияПолейXMLЮрАдрес, ВидКИЮрАдрес, ТипКИЮрАдрес);

    // --- Фактический адрес ---
    ПредставлениеАдресаФакт = "123457, Москва г, Ленина ул, д 2, кв 5";
    ВидКИФактАдрес = Справочники.ВидыКонтактнойИнформации.ФактАдресКонтрагента;
    ТипКИФактАдрес = ВидКИФактАдрес.Тип; // Обычно Перечисления.ТипыКонтактнойИнформации.Адрес

    ОбъектXDTOКИФактАдрес = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOПоПредставлению(ПредставлениеАдресаФакт, ТипКИФактАдрес);
    ЗначенияПолейXMLФактАдрес = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOВXML(ОбъектXDTOКИФактАдрес);
    УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(КонтрагентОбъект, ЗначенияПолейXMLФактАдрес, ВидКИФактАдрес, ТипКИФактАдрес);

    // --- Телефон ---
    ПредставлениеТелефона = "+7 (495) 123-45-67";
    ВидКИТелефона = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента;
    ТипКИТелефона = ВидКИТелефона.Тип; // Обычно Перечисления.ТипыКонтактнойИнформации.Телефон

    ОбъектXDTOКИТелефона = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOПоПредставлению(ПредставлениеТелефона, ТипКИТелефона);
    ЗначенияПолейXMLТелефона = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOВXML(ОбъектXDTOКИТелефона);
    УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(КонтрагентОбъект, ЗначенияПолейXMLТелефона, ВидКИТелефона, ТипКИТелефона);

    // --- Электронная почта ---
    ПредставлениеПочты = "info@example.com";
    ВидКИПочты = Справочники.ВидыКонтактнойИнформации.ЭлектроннаяПочтаКонтрагента; // Используем правильный вид
    ТипКИПочты = ВидКИПочты.Тип; // Обычно Перечисления.ТипыКонтактнойИнформации.АдресЭлектроннойПочты

    ОбъектXDTOКИПочты = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOПоПредставлению(ПредставлениеПочты, ТипКИПочты);
    ЗначенияПолейXMLПочты = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOВXML(ОбъектXDTOКИПочты);
    УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(КонтрагентОбъект, ЗначенияПолейXMLПочты, ВидКИПочты, ТипКИПочты);

    КонтрагентОбъект.Записать(); // Обязательно записываем объект после всех изменений
    Сообщить("Контактная информация успешно обновлена для контрагента " + КонтрагентОбъект.Наименование);

КонецПроцедуры

В этом примере мы видим, как для каждого типа контактной информации (адрес, телефон, email) сначала формируется XML-строка через XDTO-объект, а затем эта строка используется для записи КИ с помощью типовой функции.

Упрощенная запись и замена контактной информации с помощью `ДобавитьКонтактнуюИнформацию`

Платформа 1С:Предприятие 8.3 предоставляет еще более удобную функцию для добавления и замены контактной информации – это процедура УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию(). Эта функция позволяет сократить объем кода, так как она самостоятельно формирует необходимое внутреннее представление данных (включая ЗначенияПолей) и управляет процессом записи.

Рассмотрим её параметры:

  1. СсылкаИлиОбъект: Ссылка или объект владельца контактной информации (например, СправочникСсылка.Контрагенты или СправочникОбъект.Контрагенты). Если передана ссылка, то владелец будет записан автоматически после добавления КИ. Если передан объект, то КИ будет добавлена без записи, и мы должны будем записать объект самостоятельно.
  2. ЗначениеИлиПредставление: Строковое представление контактной информации (например, "г. Москва, ул. Тверская, 1" или "+7 (495) 123-45-67"). Функция сама разберет его и сформирует необходимые XDTO/JSON.
  3. ВидКонтактнойИнформации: Ссылка на элемент справочника ВидыКонтактнойИнформации, определяющий тип КИ.
  4. Дата: Дата, с которой будет действовать запись (актуально для КИ с историей изменений). Если не указана, используется текущая дата сеанса.
  5. Замещать: Булево. Если Истина (по умолчанию), то вся существующая контактная информация по данному виду будет заменена. Если Ложь, то запись будет добавлена. Если вид КИ не разрешает ввод нескольких значений, а КИ объекта уже содержит запись, новая запись не будет добавлена. Этот параметр очень полезен для избежания дублирования и обеспечения актуальности данных.

Приведем пример использования этой функции (на основе сообщения 28):


&НаСервере
Процедура ЗаполнитьКонтактнуюИнфомрацияСЗамещением()

    КонтрагентСсылка = Справочники.Контрагенты.НайтиПоКоду("000000001"); // Получаем ссылку на контрагента
    Если КонтрагентСсылка = Неопределено Тогда
        Сообщить("Контрагент не найден!");
        Возврат;
    КонецЕсли;

    // --- Юридический адрес ---
    ПредставлениеАдресаЮр = "123456, Москва г, Тверская ул, д 1, офис 10";
    ВидКИЮрАдрес = Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента;
    УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию(
        КонтрагентСсылка, 
        ПредставлениеАдресаЮр, 
        ВидКИЮрАдрес, 
        ТекущаяДата(), 
        Истина // Замещать существующий ЮрАдрес
    );

    // --- Фактический адрес ---
    ПредставлениеАдресаФакт = "123457, Москва г, Ленина ул, д 2, кв 5";
    ВидКИФактАдрес = Справочники.ВидыКонтактнойИнформации.ФактАдресКонтрагента;
    УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию(
        КонтрагентСсылка, 
        ПредставлениеАдресаФакт, 
        ВидКИФактАдрес, 
        ТекущаяДата(), 
        Истина // Замещать существующий ФактАдрес
    );

    // --- Телефон ---
    ПредставлениеТелефона = "+7 (495) 123-45-67";
    ВидКИТелефона = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента;
    УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию(
        КонтрагентСсылка, 
        ПредставлениеТелефона, 
        ВидКИТелефона, 
        ТекущаяДата(), 
        Истина // Замещать существующий Телефон
    );
    
    // --- Дополнительный телефон (если вид позволяет) ---
    ПредставлениеДопТелефона = "+7 (916) 987-65-43";
    ВидКИТелефона2 = Справочники.ВидыКонтактнойИнформации.ТелефонКонтрагента; // Или другой вид, если настроен
    УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию(
        КонтрагентСсылка, 
        ПредставлениеДопТелефона, 
        ВидКИТелефона2, 
        ТекущаяДата(), 
        Ложь // Добавить новый телефон, не замещая существующий (если вид КИ это позволяет)
    );

    // --- Электронная почта ---
    ПредставлениеПочты = "new.info@example.com";
    ВидКИПочты = Справочники.ВидыКонтактнойИнформации.ЭлектроннаяПочтаКонтрагента;
    УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию(
        КонтрагентСсылка, 
        ПредставлениеПочты, 
        ВидКИПочты, 
        ТекущаяДата(), 
        Истина // Замещать существующую Почту
    );

    Сообщить("Контактная информация успешно обновлена для контрагента " + КонтрагентСсылка);

КонецПроцедуры

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

Работа с адресами через специализированные функции

Заполнение адресов является одним из наиболее сложных аспектов, поскольку адрес – это структурированные данные, которые система стремится разобрать на компоненты (страна, регион, город, улица, дом и т.д.) с использованием адресного классификатора (ФИАС/ГАР). Если адрес не может быть разобран, он может быть сохранен как "свободная форма", что приводит к проблемам с функциональностью (например, проверкой адреса).

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

Например, процедура УправлениеКонтактнойИнформацией.ЗаполнитьПоляВЗаписиПоПредставлению() позволяет заполнить поля записи контактной информации из строкового представления. Давайте посмотрим на пример, который был предложен в обсуждении (сообщение 27), который использует работу с набором записей регистра сведений для КИ, что было характерно для старых подходов или определенных сценариев БСП:


&НаСервере
Процедура ЗаполнитьАдресЧерезНаборЗаписей(КонтрагентСсылка, АдресДляЗаписи)

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

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

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

    // Запишем весь набор обратно в регистр сведений / табличную часть
    Набор.Записать(Истина); // Истина означает "очистить существующие и записать новые"

    Сообщить("Адреса для контрагента " + КонтрагентСсылка.Наименование + " обновлены.");

КонецПроцедуры

Этот подход демонстрирует, как можно работать с контактной информацией через набор записей, используя вспомогательные функции для заполнения полей. Однако, наиболее универсальным и рекомендуемым является использование УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию(), которая сама управляет всеми внутренними механизмами, включая работу с наборами и табличными частями, в зависимости от внутренней реализации БСП.

Возможные проблемы и их решения

  1. Контактная информация не отображается или исчезает при записи объекта:

    • Причина: Это самая распространенная проблема, связанная с некорректным заполнением поля ЗначенияПолей в табличной части КонтактнаяИнформация. Если это поле пустое или содержит неверный XML/JSON, система не может отобразить данные в форме, а при последующей записи объекта (даже если вы не переключались на вкладку КИ) эта "некорректная" запись может быть удалена.
    • Решение: Всегда используйте типовые функции БСП (УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOПоПредставлению, УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияXDTOВXML, УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию или УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию) для формирования и записи контактной информации. Эти функции гарантируют правильное заполнение всех необходимых полей, включая ЗначенияПолей.
  2. Адрес сохраняется как свободная форма, хотя должен разбираться по ФИАС:

    • Причина: Система не смогла корректно разобрать строковое представление адреса на компоненты (например, из-за опечаток, неполного или неформализованного адреса, отсутствия актуального адресного классификатора).
    • Решение: Убедитесь, что строковое представление адреса максимально соответствует формату ФИАС. Проверьте актуальность загруженного адресного классификатора. При использовании ДобавитьКонтактнуюИнформацию, старайтесь передавать максимально полный и точный адрес. Если необходим детальный контроль, можно использовать функции для получения и работы со структурой адреса, а затем формировать XML.
  3. Телефон или адрес контрагента не отображается, хотя у него есть КИ:

    • Причина: В некоторых конфигурациях (например, 1С:ERP, 1С:УТ, а также в 1С:Бухгалтерии при определенных настройках) существует раздельный учет партнеров и контрагентов. Контактная информация может быть привязана к объекту "Партнеры", а не напрямую к "Контрагенты". Если для контрагента указан партнер, и настройка "Независимо вести партнеров и контрагентов" отключена, КИ может браться от партнера.
    • Решение: Проверьте настройки программы (обычно в разделе "Администрирование" – "CRM и продажи" или "Настройки CRM") на наличие опции "Независимо вести партнеров и контрагентов". Если она отключена, возможно, потребуется изменять КИ у соответствующего партнера. Для этой задачи есть перенос контактной информации между контрагентами и физлицами.
  4. Дублирование контактной информации:

    • Причина: При повторном вызове функций добавления без предварительной очистки или указания замены.
    • Решение: Используйте параметр Замещать = Истина в функции УправлениеКонтактнойИнформацией.ДобавитьКонтактнуюИнформацию(), если вы хотите заменить существующую КИ по данному виду. Если вы хотите добавить несколько записей одного вида (например, несколько телефонов), убедитесь, что вид контактной информации это позволяет, и используйте Замещать = Ложь. Также можно предварительно очистить табличную часть КонтактнаяИнформация, если вы полностью перезаписываете все данные, но это менее гибкий подход.

Общие рекомендации и лучшие практики

Для эффективной и безошибочной работы с контактной информацией в 1С:Предприятии 8.3, особенно в конфигурациях на БСП, придерживайтесь следующих принципов:

  1. Всегда используйте типовые функции БСП: Это главное правило. Функции общего модуля УправлениеКонтактнойИнформацией и УправлениеКонтактнойИнформациейСлужебный разработаны для корректной работы с подсистемой и учитывают все внутренние механизмы платформы. Избегайте прямого манипулирования табличной частью КонтактнаяИнформация, если вы не уверены в необходимости заполнения всех полей, включая ЗначенияПолей.
  2. Проверяйте свойства ВидовКонтактнойИнформации: Каждый элемент справочника ВидыКонтактнойИнформации имеет настройки, которые влияют на его поведение, например, Тип, РежимРедактирования (в диалоге или свободной форме), возможность множественного ввода. Убедитесь, что используемый ВидКИ соответствует вашим ожиданиям.
  3. Используйте отладчик: Если возникли сложности, пошаговое выполнение кода в отладчике (удобно через инструменты разработчика для отладки кода на сервере), особенно при ручном вводе контактной информации через интерфейс, поможет вам понять, какие поля и каким образом заполняются системой. Обратите особое внимание на поле ЗначенияПолей.
  4. Обращайтесь к документации 1С:ИТС: Раздел по Библиотеке стандартных подсистем на ИТС содержит подробное описание подсистемы "Контактная информация", её архитектуры и рекомендованных программных интерфейсов. Это лучший источник актуальной и достоверной информации.

Применяя эти подходы, вы сможете программно изменять контактную информацию в 1С:Бухгалтерии предприятия 3.0 и других конфигурациях на БСП эффективно, надежно и без возникновения скрытых ошибок.

← На главную