В современных конфигурациях 1С, таких как ERP или Комплексная автоматизация, работа с адресными данными и телефонами построена на базе БСП (Библиотеки Стандартных Подсистем), подсистема "Контактная информация". При добавлении новых справочников или документов через расширение разработчики часто сталкиваются с тем, что стандартные механизмы не отображают вкладку "Адреса и телефоны", либо данные не сохраняются. Рассмотрим подробно, как правильно настроить справочник Виды контактной информации и как корректно переносить данные программно, избегая распространенных ошибок.
Одной из главных проблем, с которой сталкиваются разработчики при добавлении КИ (контактной информации) к своим объектам, является то, что программно созданная группа видов КИ не отображается в интерфейсе или не подхватывается механизмами БСП. Разберем причины и решение.
1. Правило именования группы
Подсистема БСП жестко привязана к именам предопределенных элементов или их строковым идентификаторам. Если вы добавляете в справочник Претензии (которого нет в типовой конфигурации) возможность ввода контактов, вы должны создать соответствующую группу в справочнике ВидыКонтактнойИнформации.
Критически важно соблюдать правило именования. Имя группы должно формироваться по шаблону:
СправочникПретензии).Если имя будет произвольным (например, "Контакты для претензий"), механизмы БСП при открытии формы не смогут автоматически сопоставить ваш объект с настройками видов контактной информации.
2. Видимость и флаг "Используется"
Даже если группа создана правильно, она может не появиться в списках выбора. В типовых решениях (ERP, КА, УТ) справочник видов контактной информации использует механизм функциональных опций и скрытия неиспользуемых элементов.
После программного создания группы (или добавления ее в расширении) необходимо убедиться, что у этой группы установлен реквизит Используется в значение Истина. Часто этот реквизит не выведен на стандартную форму элемента, и его нужно установить программно или через обработку "Универсальный подбор и обработка объектов".
Пример кода для программного создания группы (выполняется один раз, например, в обработчике обновления):
Процедура СоздатьГруппуВидовКИ()
ИмяГруппы = "СправочникПретензии"; // Строго по имени объекта метаданных
СпрВиды = Справочники.ВидыКонтактнойИнформации;
НайденаяГруппа = СпрВиды.НайтиПоНаименованию(ИмяГруппы);
Если НайденаяГруппа.Пустая() Тогда
НоваяГруппа = СпрВиды.СоздатьГруппу();
НоваяГруппа.Наименование = ИмяГруппы;
НоваяГруппа.ИмяПредопределенногоВида = ИмяГруппы; // Важно для БСП
НоваяГруппа.Используется = Истина;
НоваяГруппа.Записать();
ИначеЕсли НЕ НайденаяГруппа.Используется Тогда
ГруппаОбъект = НайденаяГруппа.ПолучитьОбъект();
ГруппаОбъект.Используется = Истина;
ГруппаОбъект.Записать();
КонецЕсли;
КонецПроцедуры
Рассмотрим ситуацию, когда мы создаем документ "Претензия" на основании "Заказа клиента". Наша задача — перенести контактную информацию (например, телефон клиента) из заказа в претензию. При этом виды контактной информации у "Контрагента" и у "Претензии" — это разные элементы справочника ВидыКонтактнойИнформации.
Внимание! Разбор частой ошибки
В обсуждении на форуме был предложен код, который содержит критическую архитектурную ошибку. Давайте проанализируем, чего делать НЕЛЬЗЯ:
// ОШИБОЧНЫЙ ПОДХОД
Для Каждого СтрокаКонтактовКонтрагентов Из ДанныеЗаполнения.Контрагент.КонтактнаяИнформация Цикл
// ...
ВыбранныйВид = КонтактКонтрагента.Вид.ПолучитьОбъект();
ВыбранныйВид.Родитель = ВыбранныйВидКонтакта; // СМЕНА РОДИТЕЛЯ!
ВыбранныйВид.Записать();
// ...
КонецЦикла;
В этом коде происходит следующее: берется вид информации "Телефон контрагента" (который принадлежит группе "СправочникКонтрагенты") и у него меняется родитель на "СправочникПретензии". Это приведет к тому, что во всей базе у всех контрагентов пропадет отображение телефона, так как этот вид информации "переедет" в другую группу. Никогда не меняйте настройки видов контактной информации при создании документов.
Правильный подход к переносу данных
Чтобы корректно заполнить табличную часть КонтактнаяИнформация, нам нужно:
Вид контактной информации, который относится именно к "СправочникПретензии".Для оптимизации кода и ускорения работы используем метод ЗаполнитьЗначенияСвойств.
Посмотрим на пример правильной реализации:
// Процедура ОбработкаЗаполнения в модуле объекта Справочник.Претензии
// ДанныеЗаполнения - Ссылка на ЗаказКлиента
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказКлиента") Тогда
// 1. Подготовим виды контактной информации для Претензии
// Предполагаем, что в справочнике ВидыКонтактнойИнформации уже созданы элементы
// для претензии, например "Телефон претензии" и "Email претензии".
// Искать их лучше по предопределенному имени или наименованию внутри группы.
ГруппаПретензии = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("СправочникПретензии");
// Для примера найдем вид "Телефон" внутри нашей группы
ВидТелефонПретензии = Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Телефон", Истина, ГруппаПретензии);
// 2. Получим контактную информацию из источника (Контрагента)
ТаблицаКИ_Источника = ДанныеЗаполнения.Контрагент.КонтактнаяИнформация;
Для Каждого СтрокаИсточник Из ТаблицаКИ_Источника Цикл
// Определяем, какой тип контакта мы сейчас обрабатываем
ТипКИ = СтрокаИсточник.Тип; // Перечисление.ТипыКонтактнойИнформации
// Нам нужно сопоставить вид источника с видом приемника.
// Если мы переносим телефон:
Если ТипКИ = Перечисления.ТипыКонтактнойИнформации.Телефон И ЗначениеЗаполнено(ВидТелефонПретензии) Тогда
НоваяСтрока = КонтактнаяИнформация.Добавить();
// Копируем значения полей (НомерТелефона, Представление и т.д.)
// Используем ЗаполнитьЗначенияСвойств, исключая поле "Вид", так как оно отличается
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник, , "Вид, ВидДляСписка");
// Устанавливаем правильный вид для нашего справочника
НоваяСтрока.Вид = ВидТелефонПретензии;
КонецЕсли;
// Аналогично можно добавить логику для Email или Адреса, если найти соответствующие виды
КонецЦикла;
КонецЕсли;
Иногда бывает так: табличная часть КонтактнаяИнформация заполнена программно верно, данные в базе есть (видно через консоль запросов), но на форме вкладка пуста. Разберем основные причины.
1. Кеширование настроек БСП
Подсистема КИ активно использует повторно используемые модули для хранения настроек видов информации. Если вы только что добавили новую группу или вид, сеанс пользователя может еще не знать об этом. Попробуйте перезайти в программу или обновить вспомогательные данные (запустить методы обновления ИБ).
2. Механизм "ПриСозданииНаСервере"
Форма рисует поля контактной информации динамически при открытии. Если в процедуре ПриСозданииНаСервере формы не вызваны соответствующие методы БСП, поля не создадутся. Для работы с процедурами подсистем пригодится справочник по методам БСП с примерами использования.
Убедитесь, что в модуле формы вашего справочника/документа есть вызов:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Стандартный вызов подсистемы КИ
УправлениеКонтактнойИнформацией.ПриСозданииНаСервере(ЭтаФорма, Объект, "ГруппаКонтактнаяИнформация");
КонецПроцедуры
Где "ГруппаКонтактнаяИнформация" — это имя группы на форме (обычно Страница/Вкладка), где должны размещаться поля.
3. Поле "Вид" не соответствует владельцу
Это самая частая проблема при копировании. Если вы скопируете строку из заказа "один в один" (вместе с ссылкой на Вид "Телефон контрагента"), то БСП при отрисовке формы Претензии увидит чужой Вид (родитель которого "СправочникКонтрагенты") и намеренно скроет его, так как он не относится к текущему объекту "СправочникПретензии". Именно поэтому в коде выше мы принудительно подменяем Вид на тот, который принадлежит нашей группе.
Для успешной работы с КИ в собственных объектах:
Справочник[Имя] или Документ[Имя].