Из опыта работы с типовой конфигурации «1С:Бухгалтерия предприятия, редакция 3.0» у заказчиков довольно редко возникает необходимость настроить учетную запись электронной почты для получения писем. Однако, когда такая потребность возникла, то оказалось, что письма будут получаться исключительно из папки «Входящие» («Inbox»). И если заказчик в своей электронной почте создал определенное количество папок в папке «Входящие», то «1С:Бухгалтерия» эти все папки проигнорирует. Таким образом, у пользователя нет практической возможности настроить получение писем из другой папки.
1-я часть проблемы заключается в том, что в процедуре «ЗагрузитьСообщения» общего модуля «РаботаСПочтовымиСообщениямиСлужебный» отсутствует строка:
Соединение.ТекущийПочтовыйЯщик = <ВыбраннаяПользователемПапка>;
Наличие такой строки в купе с возможностью её передаче во входящем в процедуру параметре «ПараметрыЗагрузки» решили бы первую часть проблемы.
2-я часть проблемы заключается в том, что на форме настройки учетной записи электронной почты нет возможности указать папку, из которой в 1С будут приходить письма.
Ну раз есть проблемы, то они требуют решения. Начнём решение с конца.
Для начала на форме настройки учетной записи электронной почты реализуем следующий алгоритм:
Для возможности получения писем из другой папки, отличной от папки 'Входящие' ('Inbox'), пользователь на форме учетной записи нажимает на кнопку 'Вывести список папок почтового ящика', в сформированной таблице со всеми папками текущей учетной записи выбрать необходимую папку электронного ящика. Выбранная папку должна отразиться в поле 'Папка почтового ящика для получения писем'. После сохранения и повторного открытия формы учетной записи электронной почты указанная папка должна сохраняться.
Создадим расширение и захватим в него процедуру «ПриСозданииНаСервере» с типом вызова «После». В процедуре пропишем создание элементов интерфейса и команд, а также добавим процедуру для восстановления ранее выбранной папки из хранилища значений:
#Область ВНачалеРаботы
&НаСервере
Процедура Дельта24083_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
нРеквизиты = Новый Массив;
нРеквизиты.Добавить(Новый РеквизитФормы("ПапкаПочтовогоЯщикаДляПолученияПисем", Новый ОписаниеТипов("Строка"), , "Папка почтового ящика для получения писем", Ложь));
ИзменитьРеквизиты(нРеквизиты);
ПолеПапкиПочтовогоЯщикаДляПолученияПисем = ЭтаФорма.Элементы.Добавить("ПапкаПочтовогоЯщикаДляПолученияПисем", Тип("ПолеФормы"),Элементы.ИспользоватьУчетнуюЗапись);
ПолеПапкиПочтовогоЯщикаДляПолученияПисем.Вид = ВидПоляФормы.ПолеВвода;
ПолеПапкиПочтовогоЯщикаДляПолученияПисем.ПутьКДанным = "ПапкаПочтовогоЯщикаДляПолученияПисем";
ПолеПапкиПочтовогоЯщикаДляПолученияПисем.ТолькоПросмотр = Истина;
ВосстановитьНастройкиПапокПочтовогоЯщикаИзХранилищаЗначений();
нЭлемент = Элементы.Добавить("ДекорацияСОписаниемДействий", Тип("ДекорацияФормы"), Элементы["НастройкиСоединения"]);
нЭлемент.Вид = ВидДекорацииФормы.Надпись;
нЭлемент.АвтоМаксимальнаяШирина = Ложь;
нЭлемент.Заголовок = "Для возможности получения писем из другой папки, отличной от папки 'Входящие' ('Inbox'), необходимо выполнить следующее:" +
Символы.ПС + "1. Нажать на кнопку 'Вывести список папок почтового ящика'." +
Символы.ПС + "2. В сформированной таблице со всеми папками текущей учетной записи выбрать необходимую папку." +
Символы.ПС + "3. Выбранная папку отразиться в поле 'Папка почтового ящика для получения писем'." +
Символы.ПС + "4. Сохранить текущую настройку учетной записи.";
НовКоманда = ЭтаФорма.Команды.Добавить("ВывестиСписокПапокПочтовогоЯщика");
НовКоманда.Действие = "ВывестиСписокПапокПочтовогоЯщика";
нЭлемент = ЭтаФорма.Элементы.Добавить("ВывестиСписокПапокПочтовогоЯщика", Тип("КнопкаФормы"), Элементы["НастройкиСоединения"]);
нЭлемент.Заголовок = "Вывести список папок почтового ящика";
нЭлемент.ИмяКоманды = "ВывестиСписокПапокПочтовогоЯщика";
КонецПроцедуры
&НаСервере
Процедура ВосстановитьНастройкиПапокПочтовогоЯщикаИзХранилищаЗначений()
//восстановить настройки ТЧ
КлючНастроек = "НастройкиПапокПочтовогоЯщика";
ЗначениеНастроек = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить("НастройкиПапокПочтовогоЯщика", КлючНастроек);
Если ТипЗнч(ЗначениеНастроек) = Тип("Соответствие") Тогда
Попытка
Для Каждого ТекСтрока Из ЗначениеНастроек.Получить("ТаблицаНастроекПочтовогоЯщика") Цикл
Если ТекСтрока.УчетнаяЗапись = Объект.Ссылка Тогда
ЭтаФорма.ПапкаПочтовогоЯщикаДляПолученияПисем = ТекСтрока.НазваниеПапки;
Прервать;
КонецЕсли;
КонецЦикла;
Исключение
//
КонецПопытки;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
Далее реализуем механизм получения списка всех папок электронной почты и вывод на форму таблицы с их названиями:
#Область ПолучениеСпискаПапок
&НаСервере
Функция ВывестиСписокПапокПочтовогоЯщикаНаСервере()
УчетнаяЗапись = Объект.Ссылка;
УстановитьОтключениеБезопасногоРежима(Истина);
Профиль = РаботаСПочтовымиСообщениямиСлужебный.ИнтернетПочтовыйПрофиль(УчетнаяЗапись, Истина);
УстановитьОтключениеБезопасногоРежима(Ложь);
Протокол = ПротоколИнтернетПочты.POP3;
Если ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УчетнаяЗапись, "ПротоколВходящейПочты") = "IMAP" Тогда
Протокол = ПротоколИнтернетПочты.IMAP;
КонецЕсли;
УстановитьОтключениеБезопасногоРежима(Истина);
Соединение = Новый ИнтернетПочта;
Соединение.Подключиться(Профиль, Протокол);
МассивПочтовыхЯщиков = Соединение.ПолучитьПочтовыеЯщики();
Соединение.Отключиться();
УстановитьОтключениеБезопасногоРежима(Ложь);
Если Не Истина Тогда
ТаблицаПапокПочтовогоЯщика = "";
КонецЕсли;
ТаблицаПапокПочтовогоЯщика = Новый ТаблицаЗначений;
ТаблицаПапокПочтовогоЯщика.Колонки.Добавить("НазваниеПапки",Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100)),"Наименование папки");
Тек = 0;
Пока Тек <= МассивПочтовыхЯщиков.Количество()-1 Цикл
НовСтрока = ТаблицаПапокПочтовогоЯщика.Добавить();
НовСтрока.НазваниеПапки = МассивПочтовыхЯщиков[Тек];
Тек = Тек + 1;
КонецЦикла;
ЭтаФорма.ТаблицаПапокПочтовогоЯщика.Загрузить(ТаблицаПапокПочтовогоЯщика);
Возврат МассивПочтовыхЯщиков;
КонецФункции
&НаКлиенте
Процедура ВывестиСписокПапокПочтовогоЯщика(Команда)
СоздатьТаблицуПапокПочтовогоЯщика();
МассивПочтовыхЯщиков = ВывестиСписокПапокПочтовогоЯщикаНаСервере();
КонецПроцедуры
&НаСервере
Процедура СоздатьТаблицуПапокПочтовогоЯщика()
ТаблицаПапокПочтовогоЯщика = Новый ТаблицаЗначений;
ТаблицаПапокПочтовогоЯщика.Колонки.Добавить("НазваниеПапки",Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100)),"Наименование папки");
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("ТаблицаПапокПочтовогоЯщика", Новый ОписаниеТипов("ТаблицаЗначений")));
Для Каждого Колонка Из ТаблицаПапокПочтовогоЯщика.Колонки Цикл
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения,"ТаблицаПапокПочтовогоЯщика" ,Колонка.Заголовок));
КонецЦикла;
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов,);
ВывестиТаблицуЗначенийНаФорму(ЭтаФорма, "ТаблицаПапокПочтовогоЯщика", Элементы["НастройкиСоединения"], "Таблица папок почтового ящика",ТаблицаПапокПочтовогоЯщика);
Элементы["ТаблицаПапокПочтовогоЯщика"].УстановитьДействие("ПриАктивизацииСтроки","ВыбратьПапкуПочтовогоЯщикаДляПолученияПисем");
КонецПроцедуры
&НаСервере
Процедура ВывестиТаблицуЗначенийНаФорму(Форма, ИмяТаблицы, Родитель, ЗаголовокТаблицы, ТЗ,НадоЗагрузить = Ложь) Экспорт
ТаблицаФормы = Форма.Элементы.Добавить(ИмяТаблицы, Тип("ТаблицаФормы"), Родитель);
ТаблицаФормы.ПутьКДанным = ИмяТаблицы;
ТаблицаФормы.Заголовок = ЗаголовокТаблицы;
ТаблицаФормы.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
ТаблицаФормы.ИзменятьПорядокСтрок = Ложь;
ТаблицаФормы.ИзменятьСоставСтрок = Ложь;
ТаблицаФормы.РазрешитьНачалоПеретаскивания = Ложь;
Для Каждого Колонка Из ТЗ.Колонки Цикл
ДобавитьНовуюКолонкуТаблицыЗначений(Форма, ТаблицаФормы, ИмяТаблицы, Колонка.Имя, Колонка.Заголовок);
КонецЦикла;
Если НадоЗагрузить Тогда
Форма[ИмяТаблицы].Загрузить(ТЗ);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ДобавитьНовуюКолонкуТаблицыЗначений(Форма, ТаблицаФормы, ИмяТаблицы, ИмяКолонки, ЗаголовокКолонки, СтруктураСвойств = Неопределено)
НоваяКолонка = Форма.Элементы.Добавить(ИмяТаблицы+ИмяКолонки, Тип("ПолеФормы"), ТаблицаФормы);
НоваяКолонка.Заголовок = ЗаголовокКолонки;
НоваяКолонка.ПутьКДанным = ИмяТаблицы + "." + ИмяКолонки;
НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
Если НЕ СтруктураСвойств = Неопределено Тогда
Для Каждого КлючЗначение Из СтруктураСвойств Цикл
Попытка
НоваяКолонка[КлючЗначение.Ключ] = СтруктураСвойств[КлючЗначение.Ключ];
Исключение
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
В завершении создадим процедуры по установке необходимой папки и сохранению её значения в информационной базе:
#Область ВыборИСохранениеПапки
&НаКлиенте
Процедура ВыбратьПапкуПочтовогоЯщикаДляПолученияПисем(Команда)
ЭтаФорма.ПапкаПочтовогоЯщикаДляПолученияПисем = Команда.ТекущиеДанные.НазваниеПапки;
КонецПроцедуры
&НаСервере
Процедура СохранитьНастройкиПапокПочтовогоЯщикаВХранилищеЗначений()
//сохранить настройки
КлючНастроек = "НастройкиПапокПочтовогоЯщика";
Настройки = Новый Соответствие;
ТаблицаНастроекПочтовогоЯщика = Новый ТаблицаЗначений;
ТаблицаНастроекПочтовогоЯщика.Колонки.Добавить("УчетнаяЗапись");
ТаблицаНастроекПочтовогоЯщика.Колонки.Добавить("НазваниеПапки");
НовСтрока = ТаблицаНастроекПочтовогоЯщика.Добавить();
НовСтрока.УчетнаяЗапись = Объект.Ссылка;
НовСтрока.НазваниеПапки = ЭтаФорма.ПапкаПочтовогоЯщикаДляПолученияПисем;
Настройки.Вставить("ТаблицаНастроекПочтовогоЯщика", ТаблицаНастроекПочтовогоЯщика);
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить("НастройкиПапокПочтовогоЯщика", КлючНастроек, Настройки);
КонецПроцедуры
&НаКлиенте
Процедура Дельта24083_ПослеЗаписиПосле(ПараметрыЗаписи)
СохранитьНастройкиПапокПочтовогоЯщикаВХранилищеЗначений();
КонецПроцедуры
#КонецОбласти
Теперь вернёмся к первой части задачи: захватим в расширение процедуру «ЗагрузитьСообщения» и внесём в неё изменения, касающиеся получению писем из выбранной папки
На самом деле нам нужно только указать в параметре ТекущийПочтовыйЯщик название нужной папки, название которой мы ранее получили и сохранили в свойствах учётной записи (с дальнейшем сохранением её в хранилище общих настроек):
//назначаем текущий почтовый ящик, отличную от ящика "Входящие" ("Inbox")
Попытка
КлючНастроек = "НастройкиПапокПочтовогоЯщика";
ЗначениеНастроек = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить("НастройкиПапокПочтовогоЯщика", КлючНастроек);
Если ТипЗнч(ЗначениеНастроек) = Тип("Соответствие") Тогда
Для Каждого ТекСтрока Из ЗначениеНастроек.Получить("ТаблицаНастроекПочтовогоЯщика") Цикл
Если ТекСтрока.УчетнаяЗапись = УчетнаяЗапись Тогда
Соединение.ТекущийПочтовыйЯщик = ТекСтрока.НазваниеПапки;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Исключение
КонецПопытки;
Далее приводится полностью код захваченной и изменённой в расширении процедуры «ЗагрузитьСообщения»:
&Вместо("ЗагрузитьСообщения")
Функция Дельта24083_ЗагрузитьСообщения(Знач УчетнаяЗапись, Знач ПараметрыЗагрузки)
// Используется для проверки возможности входа на почтовый ящик.
Перем РежимТестирования;
// Получать только заголовки писем.
Перем ПолучениеЗаголовков;
// Приводить почтовые сообщения к простому типу;
Перем ПриводитьСообщенияКТипу;
// Заголовки или идентификаторы писем, полные сообщения по которым требуется получить.
Перем ЗаголовкиИдентификаторы;
Если ПараметрыЗагрузки.Свойство("РежимТестирования") Тогда
РежимТестирования = ПараметрыЗагрузки.РежимТестирования;
Иначе
РежимТестирования = Ложь;
КонецЕсли;
Если ПараметрыЗагрузки.Свойство("ПолучениеЗаголовков") Тогда
ПолучениеЗаголовков = ПараметрыЗагрузки.ПолучениеЗаголовков;
Иначе
ПолучениеЗаголовков = Ложь;
КонецЕсли;
УстановитьОтключениеБезопасногоРежима(Истина);
Профиль = ИнтернетПочтовыйПрофиль(УчетнаяЗапись, Истина);
УстановитьОтключениеБезопасногоРежима(Ложь);
Если ПараметрыЗагрузки.Свойство("ЗаголовкиИдентификаторы") Тогда
ЗаголовкиИдентификаторы = ПараметрыЗагрузки.ЗаголовкиИдентификаторы;
Иначе
ЗаголовкиИдентификаторы = Новый Массив;
КонецЕсли;
НаборСообщенийДляУдаления = Новый Массив;
Протокол = ПротоколИнтернетПочты.POP3;
Если ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УчетнаяЗапись, "ПротоколВходящейПочты") = "IMAP" Тогда
Протокол = ПротоколИнтернетПочты.IMAP;
КонецЕсли;
УстановитьОтключениеБезопасногоРежима(Истина);
Соединение = Новый ИнтернетПочта;
Соединение.Подключиться(Профиль, Протокол);
//назначаем текущий почтовый ящик, отличную от ящика "Входящие" ("Inbox")
Попытка
КлючНастроек = "НастройкиПапокПочтовогоЯщика";
ЗначениеНастроек = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить("НастройкиПапокПочтовогоЯщика", КлючНастроек);
Если ТипЗнч(ЗначениеНастроек) = Тип("Соответствие") Тогда
Для Каждого ТекСтрока Из ЗначениеНастроек.Получить("ТаблицаНастроекПочтовогоЯщика") Цикл
Если ТекСтрока.УчетнаяЗапись = УчетнаяЗапись Тогда
Соединение.ТекущийПочтовыйЯщик = ТекСтрока.НазваниеПапки;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Исключение
КонецПопытки;
Попытка
Если ПолучениеЗаголовков Тогда
НаборПисем = Соединение.ПолучитьЗаголовки();
ИначеЕсли Не РежимТестирования Тогда
НастройкиТранспорта = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(УчетнаяЗапись, "ПротоколВходящейПочты,ОставлятьКопииСообщенийНаСервере,ПериодХраненияСообщенийНаСервере");
Если НастройкиТранспорта.ПротоколВходящейПочты = "IMAP" Тогда
НастройкиТранспорта.ОставлятьКопииСообщенийНаСервере = Истина;
НастройкиТранспорта.ПериодХраненияСообщенийНаСервере = 0;
КонецЕсли;
Если НастройкиТранспорта.ОставлятьКопииСообщенийНаСервере Тогда
Если ЗаголовкиИдентификаторы.Количество() = 0 И НастройкиТранспорта.ПериодХраненияСообщенийНаСервере > 0 Тогда
Заголовки = Соединение.ПолучитьЗаголовки();
НаборСообщенийДляУдаления = Новый Массив;
Для Каждого ЭлементЗаголовок Из Заголовки Цикл
ТекущаяДата = ТекущаяДатаСеанса();
РазницаДат = (ТекущаяДата - ЭлементЗаголовок.ДатаОтправления) / (3600*24);
Если РазницаДат >= НастройкиТранспорта.ПериодХраненияСообщенийНаСервере Тогда
НаборСообщенийДляУдаления.Добавить(ЭлементЗаголовок);
КонецЕсли;
КонецЦикла;
КонецЕсли;
АвтоматическиУдалятьСообщенияПриВыбореССервера = Ложь;
Иначе
АвтоматическиУдалятьСообщенияПриВыбореССервера = Истина;
КонецЕсли;
НаборПисем = Соединение.Выбрать(АвтоматическиУдалятьСообщенияПриВыбореССервера, ЗаголовкиИдентификаторы);
Если НаборСообщенийДляУдаления.Количество() > 0 Тогда
Соединение.УдалитьСообщения(НаборСообщенийДляУдаления);
КонецЕсли;
КонецЕсли;
Соединение.Отключиться();
Исключение
Попытка
Соединение.Отключиться();
Исключение // АПК:280
// Обработка и журналирование исключения не требуется, т.к.
// в вызывающий код передается исходное исключение, которое будет там обработано.
КонецПопытки;
ВызватьИсключение;
КонецПопытки;
УстановитьОтключениеБезопасногоРежима(Ложь);
Если РежимТестирования Тогда
Возврат Истина;
КонецЕсли;
Если ПараметрыЗагрузки.Свойство("ПриводитьСообщенияКТипу") Тогда
ПриводитьСообщенияКТипу = ПараметрыЗагрузки.ПриводитьСообщенияКТипу;
Иначе
ПриводитьСообщенияКТипу = Истина;
КонецЕсли;
НаборСообщений = НаборПисем;
Если ПриводитьСообщенияКТипу Тогда
Если ПараметрыЗагрузки.Свойство("Колонки") Тогда
НаборСообщений = АдаптированныйНаборПисем(НаборПисем, ПараметрыЗагрузки.Колонки);
Иначе
НаборСообщений = АдаптированныйНаборПисем(НаборПисем);
КонецЕсли;
КонецЕсли;
Возврат НаборСообщений;
КонецФункции
С помощью приведённых в данной публикации картинок, описания и модулей вы можете самостоятельно создать расширение для работы с конкретной папкой почтового ящика. Или можете скачать уже готовое расширение.
Разработка и тестирование обработки осуществлялись на типовой конфигурации «1С:Бухгалтерия предприятия, редакция 3.0 (3.0.115.15)» и платформе 1С:Предприятие 8.3 (8.3.19.1229).
Примечание:
1. Решение построено на использовании расширения и его не получится применить для базовой версии «1С:Бухгалтерия».
2. Все вносимые изменения будут выполнены исключительно с помощью программного кода без внесения изменений в структуру метаданных.