В процессе работы с конфигурациями на базе 1С:Предприятие 8.3, такими как Управление торговлей 11 или CRM, часто возникает задача автоматизации отправки электронной почты. Несмотря на наличие встроенного почтового клиента в 1С, многие руководители и сотрудники предпочитают использовать привычный Microsoft Outlook. В этой статье мы разберем, как при нажатии на адрес электронной почты в карточке клиента автоматически открывать новое письмо в Outlook с уже заполненным адресом получателя.
Для решения этой задачи нам потребуется использовать механизм COM-соединения с внешним приложением и функции библиотеки стандартных подсистем (БСП) для получения контактной информации. Мы проанализируем ситуацию, когда конфигурация находится на поддержке, и внесем изменения через механизм расширений.
Для начала рассмотрим программный код, который позволяет инициализировать приложение Outlook и создать в нем новый объект письма. Основным инструментом здесь выступает объект COMОбъект("Outlook.Application"). Проанализируем пример кода, который создает пустое письмо:
Попытка
objOutlook = Новый COMОбъект("Outlook.Application");
Исключение
objOutlook = Неопределено;
Сообщить("Не удалось запустить Outlook. Проверьте, установлено ли приложение на компьютере.");
Возврат;
КонецПопытки;
myItem = objOutlook.CreateItem(0); // 0 соответствует объекту olMailItem
myItem.Subject = "Тема письма: " + ТекущаяДата();
myItem.HTMLBODY = "Добрый день! Текст сообщения.";
// Вместо жестко прописанного адреса нам нужно подставить переменную
// myRecipient = myItem.Recipients.Add("test@mail.ru");
В данном примере мы используем метод CreateItem(0), который создает форму нового электронного письма. Важно понимать, что если Outlook уже запущен, 1С подключится к существующему процессу, в противном случае будет предпринята попытка запуска нового процесса в фоновом режиме.
Чтобы письмо не отправлялось "в никуда" или на один и тот же адрес, нам необходимо динамически получать email того партнера или контактного лица, на которого мы нажали в интерфейсе. В современных конфигурациях вся контактная информация хранится в специальных табличных частях или регистре сведений КонтактнаяИнформация. Для доступа к ней мы будем использовать программный интерфейс БСП.
Выясним причину, по которой прямое обращение к реквизитам объекта может не сработать: email в 1С — это не просто строка, а запись с определенным видом (рабочий, личный и т.д.). Рассмотрим функцию общего модуля УправлениеКонтактнойИнформацией, которая поможет нам извлечь адрес:
// Пример получения адреса через функции БСП
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(СсылкаНаКонтрагента);
ВидКИ = Справочники.ВидыКонтактнойИнформации.EmailПартнера; // Или EmailКонтрагента
РезультатКИ = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъектов(МассивОбъектов, , ВидКИ);
Если РезультатКИ.Количество() > 0 Тогда
НужныйАдрес = РезультатКИ[0].Представление;
КонецЕсли;
Проанализируем этот подход подробнее. Метод КонтактнаяИнформацияОбъектов возвращает таблицу значений, в которой поле Представление как раз содержит текстовую строку с электронным адресом. Именно это значение мы и будем передавать в наш COM-объект.
Поскольку наша задача — изменить поведение системы, не снимая основную конфигурацию с поддержки, мы воспользуемся механизмом расширений. Нам нужно перехватить событие нажатия на поле email в форме элемента справочника Партнеры или Контрагенты.
Разберем по шагам алгоритм действий в расширении:
Нажатие для этого поля.СтандартнаяОбработка = Ложь. Это критически важно, так как именно эта команда предотвращает открытие встроенного почтового клиента 1С.Посмотрим на пример итоговой процедуры в модуле формы расширения:
&НаКлиенте
Процедура Расш1_КонтактнаяИнформацияЗначениеНажатие(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Отключаем встроенный почтовый клиент
ТекущиеДанные = Элементы.КонтактнаяИнформация.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Проверяем, что нажали именно на Email
Если ТекущиеДанные.Тип = ПредопределенноеЗначение("Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты") Тогда
ЗапуститьOutlookСАдресом(ТекущиеДанные.Представление);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗапуститьOutlookСАдресом(ВыбранныйEmail)
Попытка
objOutlook = Новый COMОбъект("Outlook.Application");
myItem = objOutlook.CreateItem(0);
// Заполняем получателя
myItem.To = ВыбранныйEmail;
// Можно также заполнить тему и тело письма
myItem.Subject = "Письмо из 1С";
myItem.HTMLBODY = "<p>Текст сообщения...</p>";
// Делаем окно Outlook видимым для пользователя
myItem.Display();
// Очищаем переменную для освобождения памяти
objOutlook = Неопределено;
Исключение
Сообщить("Ошибка при вызове Outlook: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Рассмотрим ситуацию, когда использование COM-объекта затруднено (например, из-за ограничений прав доступа или особенностей работы антивирусного ПО). Существует более простой, "легкий" способ открыть почтовый клиент по умолчанию — использование системного протокола mailto. Этот метод также откроет Outlook, если он назначен в Windows программой для работы с почтой по умолчанию.
Разберем пример кода для этого метода:
&НаКлиенте
Процедура ОткрытьЧерезПротокол(АдресПочты)
ПараметрыЗапуска = "mailto:" + АдресПочты + "?subject=Заголовок&body=ТекстПисьма";
ЗапуститьПриложение(ПараметрыЗапуска);
КонецПроцедуры
Преимущество этого метода заключается в том, что нам не нужно инициализировать тяжеловесный COMОбъект, что положительно сказывается на скорости отклика интерфейса. Однако mailto имеет ограничения по длине текста и сложности форматирования (сложно вставить полноценную HTML-подпись или вложения).
Работая с внешними приложениями через COM, мы должны учитывать несколько нюансов:
objOutlook = Неопределено), чтобы избежать "зависания" процесса outlook.exe в диспетчере задач после закрытия 1С.myItem.Attachments.Add("ПутьКФайлу"). Файл предварительно должен быть сохранен во временное хранилище или на диск.Таким образом, мы выяснили, что для решения задачи необходимо совместить возможности 1С по извлечению контактной информации и возможности Windows по управлению внешними приложениями. Использование расширений позволяет реализовать это максимально чисто, не нарушая типовую логику конфигурации и сохраняя возможность обновления системы.