Работа с электронной почтой в среде 1С:Предприятие — одна из самых востребованных задач, будь то отправка счетов клиентам или рассылка уведомлений о согласовании документов. Однако часто разработчики сталкиваются с досадной ошибкой: {ОбщийМодуль...}: Ошибка при вызове метода контекста (Подключиться): Несоответствие типов (параметр номер '1'). На первый взгляд код выглядит идеально, параметры заполнены, но система упорно отказывается устанавливать соединение. Проанализируем эту ситуацию на примере конфигурации «Управление торговлей 10.3» и выясним, почему так происходит.
Метод Подключиться() объекта ИнтернетПочта ожидает в качестве первого (и единственного) параметра объект типа ИнтернетПочтовыйПрофиль. Ошибка «Несоответствие типов» прямо говорит о том, что вместо ожидаемого объекта профиля в метод передается нечто иное — чаще всего это обычная ссылка на элемент справочника (СправочникСсылка.ПочтовыеПрофили).
Рассмотрим подробнее типичную ситуацию. В коде может присутствовать переменная с именем, совпадающим с именем реквизита формы или объекта, например, ПрофильПочты. Если на форме есть поле ввода, связанное с реквизитом ПрофильПочты, то при определенных условиях платформа 1С может отдать приоритет значению реквизита (ссылке), а не локальной переменной, которую вы только что инициализировали в коде.
Давайте посмотрим на пример кода, который часто приводит к подобным сбоям:
Процедура ОтправитьНажатие(Элемент)
// Здесь ПрофильПочты — это реквизит объекта (ссылка на справочник)
ПрофильПочты = ОтправитьПисьмоНаСогласование.ПараметрыПочтовогоПрофиля(ЭтотОбъект.ПрофильПочты);
// Пытаемся сформировать сообщение
Сообщение = ОтправитьПисьмоНаСогласование.СформироватьСообщение(ПрофильПочты, ЭтотОбъект, ПутьДоФайла);
// И здесь происходит фатальный вызов
ОтправитьПисьмоНаСогласование.ОтправитьПисьмо(ПрофильПочты, Сообщение);
КонецПроцедуры
Проанализируем ситуацию: в строке инициализации переменной ПрофильПочты мы вызываем функцию, которая должна вернуть объект ИнтернетПочтовыйПрофиль. Однако, если ПрофильПочты также является именем реквизита самого справочника или документа, возникает конфликт имен. Платформа в момент передачи параметра в процедуру ОтправитьПисьмо может подставить значение реквизита объекта (ссылку), вместо локальной переменной.
Самый простой и эффективный способ решения — переименование локальной переменной так, чтобы она не пересекалась с именами реквизитов формы или объекта. Рассмотрим исправленный вариант кода:
Процедура ОтправитьНажатие(Элемент)
// Используем уникальное имя переменной, например, СтруктураПрофиля или ОбъектПрофиля
ОбъектПрофиля = ОтправитьПисьмоНаСогласование.ПараметрыПочтовогоПрофиля(ЭтотОбъект.ПрофильПочты);
Сообщение = ОтправитьПисьмоНаСогласование.СформироватьСообщение(ОбъектПрофиля, ЭтотОбъект, ПутьДоФайла);
// Теперь передаем именно объект типа ИнтернетПочтовыйПрофиль
ОтправитьПисьмоНаСогласование.ОтправитьПисьмо(ОбъектПрофиля, Сообщение);
КонецПроцедуры
Выясним причину, почему в одних случаях (например, для документов) код работал, а в других (для справочников) — нет. Скорее всего, в форме документа реквизит назывался иначе, или переменная была определена в контексте, где не было прямого доступа к реквизитам с таким же именем. Использование префиксов или четких имен (например, тк_Профиль) помогает избежать таких "плавающих" ошибок.
Посмотрим на пример функции, которая корректно создает объект профиля. Обратите внимание на использование свойств SSL и аутентификации, которые критически важны для современных почтовых сервисов.
Функция ПараметрыПочтовогоПрофиля(ПочтовыйПрофильСсылка) Экспорт
НовыйПрофиль = Новый ИнтернетПочтовыйПрофиль;
// Заполняем параметры из ссылки на справочник
НовыйПрофиль.АдресСервераSMTP = ПочтовыйПрофильСсылка.АдресSMTP;
НовыйПрофиль.ПортSMTP = ПочтовыйПрофильСсылка.ПортSMTP;
НовыйПрофиль.ПользовательSMTP = ПочтовыйПрофильСсылка.Логин;
НовыйПрофиль.ПарольSMTP = ПочтовыйПрофильСсылка.Пароль;
// Важные настройки для современных серверов (Gmail, Yandex, Mail.ru)
НовыйПрофиль.ИспользоватьSSLSMTP = Истина;
НовыйПрофиль.АутентификацияSMTP = СпособSMTPАутентификации.ПоУмолчанию;
НовыйПрофиль.Таймаут = 60;
Возврат НовыйПрофиль;
КонецФункции
Для того чтобы ваша программа не "падала" при каждой неудачной попытке связи, разберем, как правильно обернуть процесс подключения в блок Попытка...Исключение:
Процедура ОтправитьПисьмо(ПрофильОбъект, СообщениеОбъект) Экспорт
Почта = Новый ИнтернетПочта;
Попытка
// Здесь важно убедиться, что ПрофильОбъект имеет тип ИнтернетПочтовыйПрофиль
Почта.Подключиться(ПрофильОбъект);
Почта.Послать(СообщениеОбъект);
Сообщить("Письмо успешно отправлено!");
Исключение
Сообщить("Ошибка при отправке: " + ОписаниеОшибки());
КонецПопытки;
// Всегда отключаемся, чтобы освободить сессию
Почта.Отключиться();
КонецПроцедуры
Помимо несоответствия типов, существуют и другие подводные камни при работе с ИнтернетПочта в старых конфигурациях на платформе 8.3:
ИспользоватьSSLSMTP = Истина. Для порта 587 (STARTTLS) в некоторых версиях платформы 1С требуются специфические настройки или использование внешних компонент.АутентификацияSMTP заполнено значением из системного перечисления СпособSMTPАутентификации.Таким образом, мы проанализировали ситуацию и выяснили, что даже корректный с виду код может давать сбои из-за особенностей работы контекста формы 1С. Всегда используйте уникальные имена переменных и внимательно следите за типами данных, передаваемыми в методы встроенного языка.