Почему возникает ошибка «Значение не является значением объектного типа» при отправке почты и как правильно организовать рассылку в 1С?

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

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

Разбор технической причины ошибки: Конфликт имен переменных

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

Рассмотрим пример кода, который вызывает ошибку:


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

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


ПочтовыйАгент = Новый ИнтернетПочта;
Попытка
    ПочтовыйАгент.Подключиться(УчетнаяЗапись);
    ПочтовыйАгент.Послать(Письмо);
    ПочтовыйАгент.Отключиться();
Исключение
    Сообщить("Ошибка почтовой службы: " + ОписаниеОшибки());
КонецПопытки;

Почему нельзя отправлять письма в процедуре «ОбработкаПроведения»?

Теперь перейдем к более важному — архитектурному вопросу. Многие начинающие разработчики пытаются вставить код отправки уведомлений прямо в процедуру проведения документа. Рассмотрим, какие опасности это таит в себе:

  1. Блокировка транзакции: Процедура ОбработкаПроведения выполняется внутри транзакции базы данных. Пока 1С ждет ответа от сервера Rambler или Mail.ru (а это может занять до 120 секунд по таймауту), все таблицы, задействованные в проведении, заблокированы. Другие пользователи не смогут проводить документы или строить отчеты.
  2. Риск отката транзакции: Представьте ситуацию: письмо успешно ушло адресату через Почта.Послать(), но через строку ниже код 1С обнаружил нехватку товара на складе и установил Отказ = Истина. Транзакция откатывается, документ не проведен, но письмо уже отправлено. Пользователь исправит ошибку, нажмет «Провести» снова — и клиент получит второе (дублирующее) письмо.
  3. Проблемы доступа к файлам: При проведении код исполняется на сервере 1С. Если вы пытаетесь прикрепить файл с рабочего стола пользователя (путь типа C:\Users\Admin\Desktop\...), сервер 1С его не найдет, так как у него своя файловая система и свои права доступа.

Правильная архитектура: Использование очереди сообщений

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

Шаг 1. Запись намерения в транзакции:

В процедуре ОбработкаПроведения мы просто фиксируем факт того, что письмо должно быть отправлено. Запись в регистр произойдет только в том случае, если документ будет успешно проведен.


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // Проверка условий (билеты, баллы и т.д.)
    Если РезОтветов >= 2 Тогда
        // Записываем данные для отправки в специальный РегистрСведений.ОчередьПисем
        НоваяЗапись = РегистрыСведений.ОчередьПисем.СоздатьМенеджерЗаписи();
        НоваяЗапись.Период = ТекущаяДата();
        НоваяЗапись.Документ = Ссылка;
        НоваяЗапись.АдресПолучателя = "client@yandex.ru";
        НоваяЗапись.Статус = Перечисления.СтатусыОтправки.ВТорговле;
        НоваяЗапись.Записать();
    КонецЕсли;
КонецПроцедуры

Шаг 2. Отправка через регламентное задание:

Создадим отдельную процедуру в общем модуле, которая будет запускаться сервером в фоновом режиме раз в минуту. Она будет выбирать из регистра все необработанные записи и отправлять их.


Процедура ОтправитьПочтуИзОчереди() Экспорт
    Выборка = РегистрыСведений.ОчередьПисем.Выбрать(Новый Структура("Статус", Перечисления.СтатусыОтправки.ВТорговле));
    
    ПочтовыйПрофиль = ПолучитьНастройкиПочты(); // Функция возвращает ИнтернетПочтовыйПрофиль
    Почта = Новый ИнтернетПочта;
    
    Попытка
        Почта.Подключиться(ПочтовыйПрофиль);
        Пока Выборка.Следующий() Цикл
            // Формируем и отправляем письмо
            // ... код формирования сообщения ...
            Почта.Послать(Сообщение);
            
            // Помечаем как отправленное
            Менеджер = Выборка.ПолучитьМенеджерЗаписи();
            Менеджер.Статус = Перечисления.СтатусыОтправки.Отправлено;
            Менеджер.Записать();
        КонецЦикла;
        Почта.Отключиться();
    Исключение
        // Логируем ошибку, чтобы не прерывать работу пользователей
        ЗаписьЖурналаРегистрации("ОтправкаПочты", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Важные настройки для современных почтовых сервисов

Разберем еще один критический момент: почему даже правильный код может выдавать «Ошибку авторизации». Современные сервисы (Rambler, Yandex, Gmail) запрещают использование основного пароля от почты в сторонних программах.

Что нужно проверить в настройках почтового ящика:

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

← На главную