Как извлечь адрес получателя и текст из объектов 1С ИнтернетПочтовыеАдреса и ИнтернетТекстыПочтовогоСообщения?

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

При автоматизации работы с электронной почтой в 1С:Предприятии 8.3 разработчики часто сталкиваются с ситуацией, когда ожидаемые строковые значения, такие как адрес получателя или тело сообщения, возвращаются в виде специализированных объектов-коллекций: ИнтернетПочтовыеАдреса и ИнтернетТекстыПочтовогоСообщения. Это может вызвать замешательство, особенно если вы привыкли к прямому доступу к свойствам объектов или ожидаете увидеть раскрывающиеся ветки в отладчике. В этой статье мы подробно разберем, как правильно работать с этими коллекциями для извлечения всей необходимой информации.

Проблема: Возвращаемые объекты — это коллекции, а не простые значения

Когда вы получаете почтовое сообщение через объекты ИнтернетПочта в 1С, некоторые его свойства, например, Письмо.Получатели или Письмо.Тексты, не возвращают напрямую строку с адресом или телом сообщения. Вместо этого они возвращают объекты типов ИнтернетПочтовыеАдреса и ИнтернетТекстыПочтовогоСообщения. Эти объекты являются коллекциями, что означает, что они могут содержать несколько элементов. Например, у письма может быть несколько получателей или несколько версий текста (простой текст и HTML).

Один из распространенных моментов, вводящих в заблуждение, возникает при отладке. Пользователь, привыкший к функционалу отладчика 1С, может искать привычный значок «плюс» в кружочке рядом с именем объекта, который позволяет раскрыть его свойства. Отсутствие такого значка часто приводит к мысли, что это не объект вовсе или что он пуст. Однако в данном случае это сигнал, что перед нами именно коллекция, которую необходимо перебрать для доступа к её элементам.

Рассмотрим фрагмент исходного кода, который демонстрирует эту ситуацию:


Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераIMAP = "imap.mail.ru";
Профиль.ПортIMAP = 143; // Или 993 для защищенного соединения
Профиль.ПользовательIMAP = "ваш_логин";
Профиль.ПарольIMAP = "ваш_пароль";

Почта = Новый ИнтернетПочта;
Почта.Подключиться(Профиль,ПротоколИнтернетПочты.IMAP);

// Указываем папку "Отправленные"
Почта.ТекущийПочтовыйЯщик = "Отправленные";

Отбор = Новый Структура;
// Отбираем письма за последние 100 дней
Отбор.Вставить("ПослеДатыОтправления", ТекущаяДата() - 24*60*60*100); 

Заголовки = Почта.ПолучитьЗаголовки(Отбор);

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

МассивСообщений = Почта.Выбрать(Ложь, Заголовки, Ложь);

Для Каждого Письмо Из МассивСообщений Цикл
    Сообщить("------------------------------------");
    Сообщить("Идентификатор: " + Письмо.ИдентификаторСообщения);
    Сообщить("Тема: " + Письмо.Тема);
    Сообщить("Отправитель: " + Письмо.Отправитель.Адрес);
    Сообщить("Дата отправления: " + Письмо.ДатаОтправления);

    // Здесь xMail2 возвращает объект типа ИнтернетПочтовыеАдреса
    Перем xMail2;
    xMail2 = Письмо.Получатели; 
    Сообщить("xMail2: " + xMail2); // Выведет "ИнтернетПочтовыеАдреса"

    // Здесь xText2 возвращает объект типа ИнтернетТекстыПочтовогоСообщения
    Перем xText2;
    xText2 = Письмо.Тексты;
    Сообщить("xText2: " + xText2); // Выведет "ИнтернетТекстыПочтовогоСообщения"
    Сообщить("------------------------------------");
КонецЦикла;

Почта.Отключиться();

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

Извлечение адресов получателей из коллекции ИнтернетПочтовыеАдреса

Объект ИнтернетПочтовыеАдреса представляет собой коллекцию элементов, каждый из которых имеет тип ИнтернетПочтовыйАдрес. Поскольку одно электронное письмо может быть адресовано нескольким получателям (в полях "Кому", "Копия", "Скрытая копия"), 1С предоставляет эти адреса в виде коллекции. Чтобы получить каждый отдельный адрес, нам необходимо перебрать эту коллекцию.

Каждый элемент коллекции, который является объектом ИнтернетПочтовыйАдрес, имеет свойство Адрес. Это свойство содержит непосредственно электронный адрес получателя. Давайте модифицируем наш код, чтобы правильно извлекать и отображать адреса всех получателей:


// ... (код подключения к почте и получения сообщений) ...

Для Каждого Письмо Из МассивСообщений Цикл
    Сообщить("------------------------------------");
    Сообщить("Идентификатор: " + Письмо.ИдентификаторСообщения);
    Сообщить("Тема: " + Письмо.Тема);
    Сообщить("Отправитель: " + Письмо.Отправитель.Адрес);
    Сообщить("Дата отправления: " + Письмо.ДатаОтправления);

    // Получаем адреса получателей
    Если Письмо.Получатели.Количество() > 0 Тогда
        Сообщить("Получатели:");
        Для Каждого Получатель Из Письмо.Получатели Цикл
            // Каждый 'Получатель' здесь - это объект типа ИнтернетПочтовыйАдрес
            Сообщить("  Адрес получателя: " + Получатель.Адрес);
            // Если нужен также Имя получателя: Сообщить("  Имя получателя: " + Получатель.Имя);
        КонецЦикла;
    Иначе
        Сообщить("Получатели не указаны в явном виде.");
    КонецЕсли;

    // ... (далее будем извлекать текст) ...

КонецЦикла;
Почта.Отключиться();

В этом примере мы используем цикл Для Каждого...Из...Цикл. Мы итерируем по коллекции Письмо.Получатели, где каждая итерация возвращает отдельный объект Получатель типа ИнтернетПочтовыйАдрес. Затем мы обращаемся к свойству Адрес этого объекта, чтобы получить строковое представление электронного адреса. Аналогично можно получить и свойство Имя, если оно заполнено.

Извлечение текста сообщения из коллекции ИнтернетТекстыПочтовогоСообщения

Аналогично ситуации с адресами получателей, текст почтового сообщения также возвращается в виде коллекции — ИнтернетТекстыПочтовогоСообщения. Это логично, поскольку современное электронное письмо часто содержит текст в нескольких форматах одновременно: например, простой текстовый формат (Plain Text) для совместимости и формат HTML для красивого оформления с изображениями и форматированием. Коллекция ИнтернетТекстыПочтовогоСообщения содержит элементы типа ИнтернетТекстПочтовогоСообщения.

Каждый элемент ИнтернетТекстПочтовогоСообщения обладает двумя ключевыми свойствами, которые нас интересуют:

  1. Текст: Это свойство содержит непосредственное содержимое сообщения (строку).
  2. ТипТекста: Это перечисление ТипТекстаПочтовогоСообщения, которое позволяет определить формат текста. Возможные значения — ПростойТекст или HTML.

Для того чтобы получить текст сообщения, мы, как и в предыдущем случае, должны перебрать коллекцию Письмо.Тексты и затем выбрать нужный формат текста. Чаще всего для простого отображения или анализа достаточно получить именно простой текст.

Давайте дополним наш пример для извлечения текста сообщения:


// ... (предыдущий код до цикла, включая извлечение получателей) ...

Для Каждого Письмо Из МассивСообщений Цикл
    Сообщить("------------------------------------");
    Сообщить("Идентификатор: " + Письмо.ИдентификаторСообщения);
    Сообщить("Тема: " + Письмо.Тема);
    Сообщить("Отправитель: " + Письмо.Отправитель.Адрес);
    Сообщить("Дата отправления: " + Письмо.ДатаОтправления);

    // ... (код для получения получателей) ...

    // Извлекаем текст сообщения
    Если Письмо.Тексты.Количество() > 0 Тогда
        Сообщить("Тексты сообщения:");
        Для Каждого ТекстПисьма Из Письмо.Тексты Цикл
            // Каждый 'ТекстПисьма' здесь - это объект типа ИнтернетТекстПочтовогоСообщения
            Если ТекстПисьма.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст Тогда
                Сообщить("  Текст (простой):");
                Сообщить("    " + ТекстПисьма.Текст);
            ИначеЕсли ТекстПисьма.ТипТекста = ТипТекстаПочтовогоСообщения.HTML Тогда
                Сообщить("  Текст (HTML-версия):");
                // HTML-текст может быть очень длинным, поэтому мы можем решить вывести его частично
                // или просто отметить его наличие, если полный текст не требуется.
                // Сообщить("    " + ТекстПисьма.Текст); // Вывод полного HTML может быть избыточным
                Сообщить("    Присутствует HTML-версия текста (часто большая).");
            КонецЕсли;
        КонецЦикла;
    Иначе
        Сообщить("Текст сообщения отсутствует.");
    КонецЕсли;

    Сообщить("------------------------------------"); // Разделитель для удобства
КонецЦикла;
Почта.Отключиться();

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

Часто возникает необходимость получить только простой текст, если он доступен, и игнорировать HTML-версию, или наоборот. Мы можем создать вспомогательную функцию для более удобного извлечения конкретного типа текста:


// ... (начало кода) ...

// Вспомогательная функция для получения текста конкретного типа
Функция ПолучитьТекстИзКоллекции(КоллекцияТекстов, ТипТекстаДляПоиска) Экспорт
    Для Каждого ЭлементТекста Из КоллекцияТекстов Цикл
        Если ЭлементТекста.ТипТекста = ТипТекстаДляПоиска Тогда
            Возврат ЭлементТекста.Текст;
        КонецЕсли;
    КонецЦикла;
    Возврат ""; // Если текст нужного типа не найден
КонецФункции

// ... (в основном цикле после получения сообщений) ...

Для Каждого Письмо Из МассивСообщений Цикл
    Сообщить("------------------------------------");
    Сообщить("Тема: " + Письмо.Тема);
    Сообщить("Отправитель: " + Письмо.Отправитель.Адрес);

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

    // Пример использования функции для получения HTML-текста
    Перем HTMLТекстПисьма;
    HTMLТекстПисьма = ПолучитьТекстИзКоллекции(Письмо.Тексты, ТипТекстаПочтовогоСообщения.HTML);
    Если Не ПустаяСтрока(HTMLТекстПисьма) Тогда
        Сообщить("HTML-текст письма присутствует.");
        // Сообщить(HTMLТекстПисьма); // Если необходимо вывести весь HTML
    Иначе
        Сообщить("HTML-текст письма не найден.");
    КонецЕсли;

    // ... (продолжение обработки других реквизитов) ...

    Сообщить("------------------------------------");
КонецЦикла;

Эта вспомогательная функция делает код более чистым и позволяет легко получить нужный формат текста. Она перебирает коллекцию КоллекцияТекстов и возвращает Текст первого найденного элемента с соответствующим ТипТекста.

Заключение и важные моменты

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

Всегда активно используйте Синтакс-Помощник (СП) в 1С. Это ваш основной инструмент для получения детальной информации о типах возвращаемых значений, свойствах и методах объектов. Если в отладчике вы видите тип объекта, но не видите значка "плюс" для его раскрытия, это часто является верным признаком того, что перед вами не одиночный объект со свойствами, а коллекция (например, Массив, СписокЗначений, Соответствие, ТаблицаЗначений или специализированные коллекции вроде ИнтернетПочтовыеАдреса). В таких случаях всегда применяйте цикл Для Каждого...Из...Цикл для доступа к содержимому.

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

← На главную