Бывают ситуации, когда руководитель организации хочет контролировать бухгалтеров и все внесенные ними изменения в документы информационной базы. Есть несколько вариантов, как решить эту задачу. Наиболее рациональный из них и будет рассмотрен в статье, а именно, отправка печатных форм документов в формате xls на электронную почту.
Попутно будет рассмотрено:
- как программно настроить почтовый профиль в 1С;
- как создать почтовое электронное сообщение в 1С;
- как создавать и удалять временные файлы в 1С;
- как добавлять и удалять записи в регистре сведений;
- еще много чего полезного.
Руководителю нужно контролировать своих подчиненных, какие они делают документы, что изменяют в документах, когда и кто проводит их. Для этого есть несколько решений. Например, установить расширенный журнал регистрации всех операций или распечатывать документы на бумаге при каждом их проведении. Недостатки этих вариантов в том, что журналы расширенной регистрации платные, а распечатывать документы - огромный расход бумаги и тонера. Но есть удобное решение - отправлять документы на электронную почту руководителя при первом проведении документа и при последующих проведениях, если в них что-то изменялось. Причем, если документов несколько типов, то они все будут красиво распределены по папочкам у директора в Gmail.
Сложность задачи в том, что иногда может пропадать интернет на несколько минут или его вовсе может не быть некоторое время. Поэтому, это мы тоже предусмотрим.
Мы рассмотрим задачу, когда нужно отправлять 2 типа документов: "Поступление товаров и услуг" и "Реализацию товаров и услуг". Конфигурация у нас Управление торговлей для Украины (2.3.23.1).
Общий алгоритм решения такой:
- Создаем на mail.google.com новый почтовый ящик (можно использовать и имеющийся).
- Настраиваем ярлыки к электронным входящим письмам, чтобы 2 документа автоматически распределялись в разные папки.
- Создадим регистр сведений для внесения данных о неотправленных документах, опять же таки, если в момент проведения пропадал интернет.
- Дальше будем работать с кодом 1С. Создаем общий модуль, где опишем отправку документов на электронную почту, создание почтового профиля, отправку документов в случае обрыва интернета.
- В модуле обычного приложения (у нас обычное приложение, не управляемое), в процедуре ПередНачаломРаботыСистемы() добавим код проверки наличия соединения с интернетом и отправки документов, если интернет есть.
- В модуле нужных документов добавим модульную переменную, в процедуре ПередЗаписью() будем присваивать ей значение. А в ОбработкаПроведения(), в зависимости от значения этой переменной - либо отправлять, либо не отправлять документ.
1. Создание аккаунта Google
Мне кажется, объяснять, как создать аккаунт в Google - это лишнее, но все же, может и пригодится кому.
Заходим на mail.google.com, нажимаем "Создать аккаунт" (Рис. 1). Все :)
![]() |
Рис.1. Создание аккаунта Google |
Более подробней и с картинками можете почитать, к примеру, тут: http://goldbusinessnet.com/poiskovye-sistemy-i-brauzery/gugl-sozdat-akkaunt-google-registraciya-vxod-uchetnaya-zapis/
2. Настройка фильтров для присваивания ярлыков входящим письмам
- Зайти в почту созданного аккаунта.
- Нажать на шестеренку, выбрать "Настройки".
- Нажать на закладку "Фильтры" (Рис. 2).
Рис.2. Настройки фильтров входящей почты - Нажать "Создать новый фильтр". В окне ввести адрес, с которого будут приходить письма, ввести слово, которое будет присутствовать в теме письма, как правило, название документа. Нажать далее (Рис. 3).
Рис.3. Создание фильтра - Присвоить фильтру ярлык. Ярлык - это и будет папка для входящего документа (Рис. 4). Ярлык создается один раз, присваивать можно разным фильтрам.
Рис.4. Продолжение создания фильтра. Присваивание ярлыка - На этом работа с аккаунтом гугл закончена. Переходим к 1С.
3. Создаем регистр сведений
В регистр будем добавлять данные тех документов, что не удалось отправить. Отправлять будем пробовать при следующем старте системы, о чем речь пойдет позже.В регистре будут записи. Каждая строка - отдельный документ, который не удалось отправить из-за обрыва интернет-соединения.
Регистр у нас следующего вида (Рис.5)
Измерения:
ИмяФайла - Строка, длина = 100 знаков
Ресурсы:
СообщениеТекст - Строка, неограниченная длина
ДокНомерДата - Строка, длина = 50 знаков.
![]() |
Рис.5. Регистр сведений ДокументыНаПочту |
4. Создание общего модуля с механизмами отправки документов
Открываем окно конфигурации, находим общие модули, добавляем новый, даем ему имя. И далее в него вставляем код, приведенный ниже.
Внимание! В коде есть процедура СоздатьПрофиль(). Там нужно указывать АдресСервераSMTP, его порт, пароль, пользователя. Так вот, порт прокатывает лишь только тот, где нет SSL шифрования. Через google мне так и не удалось отправить сообщение. Говорят, это можно сделать с помощью программы stunnel (почитать можно здесь http://infostart.ru/public/58093/). Поэтому я настроил отправку через сервер "mail.ukraine.com.ua", порт, указывал без SSL.
//Функция
отправляет документ по электронной почте, с случае обрыва интернета
//ТабДокумент
- это печатная форма нашего документа, сформированная в ОбработкеПроведения
//из
которой мы и входим в текущую процедуру
//Документ
- сам ДокументОбъект
Функция ОтправитьДокументПоЭлектроннойПочте(ТабДокумент, Документ) Экспорт
ТабДокумент.Автомасштаб
= Истина;
//проверяем ДокументОбъект на его
тип. У нас только 2 типа
//проверяем и формируем текстовые
строки для подстановки в тему письма, наименование вложения
//и, если нужно, записи в регистр
сведений
Если ТипЗнч(Документ) = Тип("ДокументОбъект.ПоступлениеТоваровУслуг") Тогда
СтрДокНомер = "Поступление
№" + Документ.Номер;
СтрДокНомерДата =
СтрДокНомер + " от " + Формат(Документ.Дата,"ДФ=dd.MM.yyyy");
СообщениеТекст = "Документ
<Поступление товаров и услуг> был проведен." + Символы.ПС;
ИначеЕсли ТипЗнч(Документ) = Тип("ДокументОбъект.РеализацияТоваровУслуг") Тогда
СтрДокНомер = "Реализация
№" + Документ.Номер;
СтрДокНомерДата =
СтрДокНомер + " от " + Формат(Документ.Дата,"ДФ=dd.MM.yyyy");
СообщениеТекст = "Документ
<Реализация товаров и услуг> был проведен." + Символы.ПС;
КонецЕсли;
//запоминаем имя файла, который
будет записываться на диск в каталог временных файлов,
//(по-умолчанию "C:\Users\user\AppData\Local\Temp")
//а также,
прикрепляться во вложение и, потом, удаляться с временных файлов
Попытка
ИмяФайла =
КаталогВременныхФайлов() + СтрДокНомерДата + " " + Формат(ТекущаяДата(), "ДФ=ddMMyyHHmmss") + ".xls";
ЗаписьФайла(ТабДокумент, ИмяФайла);
Исключение
Сообщить("Ошибка
при записи файла " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
//формируем текст сообщения
СообщениеТекст =
СообщениеТекст + Символы.ПС;
СообщениеТекст = СообщениеТекст
+ "Дата и время документа: " + Документ.Дата + Символы.ПС;
СообщениеТекст =
СообщениеТекст + "Номер документа: "+ Документ.Номер + Символы.ПС;
СообщениеТекст =
СообщениеТекст + Символы.ПС;
СообщениеТекст =
СообщениеТекст + "Контрагент: " + Документ.Контрагент + Символы.ПС;
СообщениеТекст =
СообщениеТекст + "Договор контрагента: " + Документ.ДоговорКонтрагента
+ Символы.ПС;
СообщениеТекст =
СообщениеТекст + "Провел: " +
ПараметрыСеанса.ТекущийПользователь + Символы.ПС;
СообщениеТекст = СообщениеТекст
+ Символы.ПС;
СообщениеТекст =
СообщениеТекст + "Сумма документа: " + Документ.СуммаДокумента
+ " " + Документ.ВалютаДокумента;
//создаем новый объект
ИнтернетПочта и профиль, пытаемся подключиться к почте
Почта = Новый ИнтернетПочта;
Профиль =
СоздатьПрофиль();
Попытка
Почта.Подключиться(Профиль);
Исключение
//если не получилось
подключиться (нет интернета)
Сообщить(" -
Ошибка при подключении" + ОписаниеОшибки());
//добавляем строку в наш
регистр сведений
ДокументыНаПочту =
РегистрыСведений.ДокументыНаПочту.СоздатьНаборЗаписей();
НоваяЗаписьДокументы =
ДокументыНаПочту.Добавить();
НоваяЗаписьДокументы.ИмяФайла = ИмяФайла;
НоваяЗаписьДокументы.СообщениеТекст
= СообщениеТекст;
НоваяЗаписьДокументы.ДокНомерДата
= СтрДокНомерДата;
НоваяЗаписьДокументы.Период =
ТекущаяДата();
ДокументыНаПочту.Записать(Ложь);
Возврат Неопределено;
КонецПопытки;
//создаем сообщение, добавляем
вложение, тему, указываем отправителя,
//получателя, добавляем текст
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Вложения.Добавить(ИмяФайла,
СтрДокНомер);
Сообщение.Тема =
СтрДокНомерДата;
Сообщение.Отправитель.Адрес = "constant@mail.ua";
Сообщение.Тексты.Добавить(СообщениеТекст,
ТипТекстаПочтовогоСообщения.ПростойТекст);
Сообщение.Получатели.Добавить("poluchatel@gmail.com");
//пытаемся отправить почту.
Интернет-соединение у нас точно есть, т.к. мы пробовали
//подключиться
(Почта.Подключиться(Профиль))
//если ошибка при передачи, значит
у вас неправильно указан адрес SMTP сервера
или порт
//порт может быть правильный, но с
SSL шифрованием
(перечитать текст с п.4 этой статьи)
Попытка
Почта.Послать(Сообщение);
Сообщить("Проведенный
документ отправлен на электронную почту!");
Исключение
Сообщить(" -
Ошибка при передаче" + ОписаниеОшибки());
Сообщить("Отключились
от почты - " + ТекущаяДата());
КонецПопытки;
Почта.Отключиться();
//возвращаем имя файла, чтобы его
потом удалить вне этой процедуры
//иначе - не удалится
Возврат ИмяФайла;
КонецФункции
Функция СоздатьПрофиль()
Профиль = Новый ИнтернетПочтовыйПрофиль;
ПрофильАдресСервераSMTP = "mail.ukraine.com.ua";
Профиль.ПортSMTP = 2525;
Профиль.АдресСервераPOP3 = "mail.ukraine.com.ua";
Профиль.ПортPOP3 = 110;
Профиль.Пароль = "password";
Профиль.ПарольSMTP = "password";
Профиль.Пользователь
= "constant@mail.ua";
Профиль.ПользовательSMTP
= "constant@mail.ua";
Профиль.ВремяОжидания
= 50;
Профиль.АутентификацияSMTP
= СпособSMTPАутентификации.ПоУмолчанию;
Возврат Профиль;
КонецФункции
//функция
вызывается при каждом старте системы, если есть записи о
//неотправленных
документах
//возвращает
ТЗ с путями к временным файлам (файлам xls)
Функция ОтправитьПослеОбрыва(Результат) Экспорт
Почта = Новый ИнтернетПочта;
Профиль =
СоздатьПрофиль();
//создаем новую ТЗ
ВременныеФайлы = Новый ТаблицаЗначений;
ВременныеФайлы.Колонки.Добавить("ИмяФайла");
//для каждой строки из регистра
сведений ДокументыНаПочту
//будем пытаться отправить
документ опять
//каждая строка - отдельный
документ
Для каждого СтрРегСв Из Результат Цикл
ИмяФайла = СтрРегСв.ИмяФайла;
СтрДокНомер = Лев(СтрРегСв.ДокНомерДата, СтрДлина(СтрРегСв.ДокНомерДата) - 27);
СтрДокНомерДата = СтрРегСв.ДокНомерДата;
Попытка
Почта.Подключиться(Профиль);
Исключение
//подключиться
опять не удалось, все, - выходим и в следующий раз
//попытаемся
подключиться при следующем старте системы
Возврат
Неопределено;
КонецПопытки;
СообщениеТекст = СтрРегСв.СообщениеТекст;
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Вложения.Добавить(ИмяФайла,
СтрДокНомер);
Сообщение.Тема =
СтрДокНомерДата;
Сообщение.Отправитель.Адрес = "constant@mail.ua";
Сообщение.Тексты.Добавить(СообщениеТекст,
ТипТекстаПочтовогоСообщения.ПростойТекст);
Сообщение.Получатели.Добавить("poluchatel@gmail.com");
//отправка так же, как и в
функции ОтправитьДокументПоЭлектроннойПочте() (выше)
Попытка
Почта.Послать(Сообщение);
Сообщить("Проведенный
документ отправлен на электронную почту!");
Исключение
Сообщить(" -
Ошибка при передаче" + ОписаниеОшибки());
Сообщить("Отключились
от почты - " + ТекущаяДата());
Возврат
Неопределено;
КонецПопытки;
//удаление записи с
регистра сведений
ДокиРегСвд =
РегистрыСведений.ДокументыНаПочту.СоздатьНаборЗаписей();
ДокиРегСвд.Отбор.ИмяФайла.Установить(ИмяФайла);
ДокиРегСвд.Прочитать();
Для Каждого Док Из ДокиРегСвд Цикл
ДокиРегСвд.Удалить(Док);
КонецЦикла;
ДокиРегСвд.Записать();
////
//добавляем путь в нашу ТЗ,
чтобы потом, вне этой функции, его удалить
НовВрФайл =
ВременныеФайлы.Добавить();
НовВрФайл.ИмяФайла = ИмяФайла;
КонецЦикла;
Почта.Отключиться();
Возврат ВременныеФайлы;
КонецФункции
|
5. Модуль обычного приложения, процедура ПередНачаломРаботыСистемы()
//модуль
обычного приложения
Процедура ПередНачаломРаботыСистемы(Отказ)
//...тут типовый код
//в конец процедуры вставляем это:
//из нашего регистра мы выбираем
все записи, чтобы отправить документы
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДокументыНаПочту.ИмяФайла,
| ДокументыНаПочту.СообщениеТекст,
| ДокументыНаПочту.ДокНомерДата
|ИЗ
| РегистрСведений.ДокументыНаПочту
КАК ДокументыНаПочту";
Результат = Запрос.Выполнить().Выгрузить();
//функция общего модуля возвращает
нам ТЗ, с
//путями файла, которые удалось
отправить
ВременныеФайлы =
общМодульДокПочта.ОтправитьПослеОбрыва(Результат);
//если удалось отправить хоть один
файл - удаляем их с диска
Если ВременныеФайлы <> Неопределено
Тогда
Для Каждого ВрФайл Из ВременныеФайлы Цикл
Попытка
УдалитьФайлы(ВрФайл.ИмяФайла);
Исключение
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
|
6. Модуль документа, который мы отправляем
В начало модуля пишем переменную, значение которой будем присваивать в процедуре ПередЗаписью().
Переменная служит для того, чтобы отправлять на почту только тогда, когда проводится измененный документ. Если просто перепроведение - не отправлять.
Перем ОтправлятьНаПочту
|
Процедура ПередЗаписью().
Некоторые строки процедуры, например, вот эта:
ОбработкаТабличныхЧастей.ПриЗаписиПроверитьСтавкуНДС(ЭтотОбъект, Товары)
|
изменяют свойство Модифицированность() и документ будет отправляться всегда, даже если по факту не был изменен пользователем.
Поэтому, лучше всего вставить этот кусок кода в начало процедуры ПередЗаписью().
Если ЭтотОбъект.Модифицированность() Тогда
ОтправлятьНаПочту = Истина;
Иначе
ОтправлятьНаПочту = Ложь;
КонецЕсли;
|
Процедура ОбработкаПроведения()
//в этот
блок (Отказ) нужно вставить наш код
Если Не Отказ Тогда
// тут код типовых механизмов
(движения по регистрам и т.д.),
// после него вставляем:
//{c}onstant-solutions
//если документ проведен и нужно
отправлять на почту
Если Проведен И ОтправлятьНаПочту Тогда
//формируем печатную форму
документа
ТабДокумент =
ПечатьДокумента(Ложь);
//передаем ее в функцию,
где отправим на почту
ВременныйФайл =
общМодульДокПочта
.ОтправитьДокументПоЭлектроннойПочте(ТабДокумент, ЭтотОбъект);
Попытка
УдалитьФайлы(ВременныйФайл);
Исключение
КонецПопытки;
КонецЕсли;
////
КонецЕсли;
|
Комментариев нет:
Отправить комментарий
Спрашивайте, критикуйте, оставьте свое мнение