При попытке выгрузить адреса электронной почты контрагентов из 1С:Управление торговлей 10.3 начинающие разработчики часто сталкиваются с ошибкой: Поле объекта не обнаружено (КонтактнаяИнформация). В этой статье мы подробно разберем, почему возникает эта ошибка, где физически хранятся контакты в обычных формах 1С и как правильно написать запрос для получения полного списка всех e-mail.
Проанализируем ситуацию: в коде происходит попытка обратиться к выборке справочника как к реквизиту или табличной части: КонИнфо = СпрК.КонтактнаяИнформация;. Однако в типовой конфигурации «Управление торговлей» редакции 10.3 (а также в УПП 1.3 и Комплексной автоматизации 1.1) у справочника Контрагенты нет реквизита или табличной части с именем КонтактнаяИнформация.
Вся контактная информация (телефоны, адреса, e-mail) хранится в отдельном независимом объекте системы — **Регистре сведений КонтактнаяИнформация**.
Рассмотрим структуру этого регистра сведений:
Объект (Измерение) — ссылка на владельца контактной информации (может быть ссылкой на справочники Контрагенты, КонтактныеЛицаКонтрагентов, Пользователи, Организации и др.).Тип (Измерение) — тип информации, принимает значение из перечисления Перечисление.ТипыКонтактнойИнформации (например, АдресЭлектроннойПочты, Телефон).Вид (Измерение) — ссылка на справочник ВидыКонтактнойИнформации (например, «E-mail контрагента»).Представление (Ресурс) — текстовая строка с адресом или телефоном в том виде, в котором её ввел пользователь.---
Для эффективного и быстрого получения данных разберем написание запроса к базе данных. Запрос выполняется непосредственно на стороне СУБД, что обеспечивает высокую скорость обработки даже на больших базах данных.
Рассмотрим пример кода, который выбирает наименование контрагента и все привязанные к нему электронные адреса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Наименование КАК Контрагент,
| КонтактнаяИнформация.Представление КАК Email
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
| ПО Контрагенты.Ссылка = КонтактнаяИнформация.Объект
|ГДЕ
| КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)
| И НЕ Контрагенты.ЭтоГруппа";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить("Контрагент: " + Выборка.Контрагент + " | E-mail: " + Выборка.Email);
КонецЦикла;
---
На практике менеджеры часто записывают адреса электронной почты не в карточку самого контрагента, а в карточки контактных лиц этого контрагента (подчиненный справочник КонтактныеЛицаКонтрагентов). Чтобы не потерять важные контакты, разберем по шагам, как объединить почту самого контрагента и его контактных лиц.
Проанализируем следующий запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Наименование КАК Контрагент,
| КонтактнаяИнформация.Представление КАК Email,
| ""Контрагент"" КАК Источник
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
| ПО Контрагенты.Ссылка = КонтактнаяИнформация.Объект
|ГДЕ
| КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)
| И НЕ Контрагенты.ЭтоГруппа
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| КонтактныеЛица.Владелец.Наименование КАК Контрагент,
| КонтактнаяИнформация.Представление КАК Email,
| ""Контактное лицо: "" + КонтактныеЛица.Наименование КАК Источник
|ИЗ
| Справочник.КонтактныеЛицаКонтрагентов КАК КонтактныеЛица
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
| ПО КонтактныеЛица.Ссылка = КонтактнаяИнформация.Объект
|ГДЕ
| КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты)";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Контрагент + " (" + Выборка.Источник + "): " + Выборка.Email);
КонецЦикла;
---
Рассмотрим вариант с использованием набора записей регистра сведений. Этот способ менее производителен на крупных базах, но позволяет быстро прочитать записи регистра напрямую из кода без написания текста запроса:
ТабПочта = Новый ТаблицаЗначений;
ТабПочта.Колонки.Добавить("Объект");
ТабПочта.Колонки.Добавить("Почта");
НЗ = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
НЗ.Отбор.Тип.Установить(Перечисления.ТипыКонтактнойИнформации.АдресЭлектроннойПочты);
НЗ.Прочитать();
Для Каждого Запись Из НЗ Цикл
Если ТипЗнч(Запись.Объект) = Тип("СправочникСсылка.Контрагенты")
ИЛИ ТипЗнч(Запись.Объект) = Тип("СправочникСсылка.КонтактныеЛицаКонтрагентов") Тогда
НоваяСтр = ТабПочта.Добавить();
НоваяСтр.Объект = Запись.Объект;
НоваяСтр.Почта = Запись.Представление;
КонецЕсли;
КонецЦикла;
Важное предупреждение: Использование метода СоздатьНаборЗаписей().Прочитать() загружает весь объем записей регистра выбранного типа в оперативную память. Если в вашей базе десятки тысяч контрагентов, предпочтительнее использовать методы Способа 1 и Способа 2 с языком запросов 1С.
---
Если задача состоит в том, чтобы разово получить список электронных адресов контрагентов для рассылки или анализа, писать программный код или обработку не обязательно. В 1С:Управление торговлей 10.3 есть встроенный типовой отчет.
Посмотрим, как им воспользоваться:
Контрагенты или Контактные лица контрагентов.Файл → Сохранить как....Таким образом, мы разглядели все основные способы извлечения e-mail контрагентов — от написания оптимизированных запросов на языке 1С до применения встроенных отчетов конфигурации.