Відправлення друкованих форм 1С як малюнка (tif, gif, etc.) по E-mail PDF Печать E-mail

Постановка завдання, історія

Усе почалося до банального просто - улюблений директор сказав "Хочу!". Аргументація була наступною:
  • Переводиться много паперу для печатки й відправлення по факсу (клієнтів багато, тому отправленние рахунки відразу викидаються: знайти потрібний документ навіть через день - нереально)
  • Електронна пошта "є в наші дні у всіх і кожного" (те, що сам директор нею не користується - інше питання :-) )
  • Витрачається менше часу персоналу (не потрібно сидіти й чекати перед факсом, стартувати, "пройшло"/"не пройшло", ...)
  • Легше вести облік коли й що було відправлено.
сначала ставилося питання відправлення документів взагалі - що може бути проще? Зберегти таблицю як файл MS-Excel, викликати зовнішню програму отправки з параметрами - і все. Потім виникли сумніву:
  • А от клієнти відредагують файл - і будуть доводити що ми такий і відправили,
  • У файлі передається малюнок печатки - вони його зможуть використати з якою-небудь темною метою.
  • сразу ж було запропоновано відправити як малюнок, благо я знав, що це можно зробити, але як - ще не представляв. Згода отримана, і от начались пошуки відповідних програм...

    Підбор потрібного інструментарію

    некоторое час я намагаюся використати безкоштовні програми, а не ломать ті, за які потрібно платити гроші. Так що однією з умов (не головним, але в результаті виконаним майже на 100%) була бесплатность інструментарію
    Зрозуміло, що для одержання малюнка на виходе потрібний віртуальний принтер, на який можна друкувати будь-який документ. Вихідним форматом був обраний tiff як досить распространенний, припускаючи що його можна буде конвертувати в любой формат, якщо виникне необхідність. Були випробувані багато хто принтери, зустрінуті в просторах Internet'а, як безкоштовні, так і нет. Більшість із них уміють друкувати крім шуканого tiff ще й pdf документи, але не один не задовольняв умовам передачі в них зовнішніх параметров (важливо було вказати місце збереження й можливе ім'я файлу для зменшення колізій, оскільки робота відбувається на сервері терминалов). В остаточному підсумку вибір припав на AFPL Ghostscript 8.14 for Win32 і драйвер переадресації порту принтера RedMon.
    Ghost Script уміє конвертувати дані з ps, eps, pdf у різні формати (ті ж ps, eps, pdf, мови принтерів начебто PCL6 від HP, і рисунки). Одержувати данние він може як з файлу, так і із вхідного потока (stdin для присвячених). RedMon уміють дані, отримані від драйвера принтера, передавати як вхідний потік обраній програмі. кроме того встановлює трохи системних змінних, одну з которих (%REDMON_USER% - ім'я користувача, що друкує документ) ми будемо використати
    итак - використовуваний режим зв'язування: установка PS принтера в системі, указание йому віртуального порту RedMon, пересилання вихідного PS потоку от принтера на Ghost Script, формування tif по зазначених настроюваннях
    настройки для режиму роботи Ghost Script зберігаються у файлі одному для всех, тому в схему додамо ще одну ланку: RedMon передає дані не Ghost Script, а скрипту WSH, а вже він відкоригувавши настроювання під пользователя, передає далі потік для Ghost Script. Тому ще одна программа, що нам потрібна: Windows Script 5.6 for Windows. Потрібна саме версія 5.6, оскільки в убудованій в Windows 2000 версії 5.1 відсутній необхідний метод Exec().
    Ще можливо нам знадобиться компонент для висновку малюнків із прозорим тлом. Поки доводиться використати Active_BMP, що згадує на передчасно покійному hare.ru. етот компонент уміє відображати прозорими тільки 2-х кольорові bmp (по крайней мері тільки з ними в мене вийшло домогтися прозорості), але за відсутністю кращого... :-) (Якщо хто знає безкоштовний Active компонент для відображення gif із прозорим шаром - скажіть у форум або мило)
    Властиво для відправлення пошти з командного рядка я вже півроку користуюся Postie, тому шукати нічого нового не довелося.

    Приступимося (установка й реєстрація програм)

    Установка WSH проблем не викликає (звичайно, якщо ви не спробуєте встановити версію для 9X/NT4 на 2000/XP, як я це зробив, причому усвідомив це тільки взявшись за статтю - уже місяць сервер живе в цьому режимі :-) ): запуск scripten.exe (scr56en.exe), відповіді на всі питання, перезавантаження
    Установка Ghost Script не вимагає навіть перезавантаження. Єдиний момент - від намагається за замовчуванням установиться в каталог %SystemDrive%\gs - я його встановлював в %SystemDrive%\Tools\gs - так мені зручніше. (нижче в дужках я буду писати свої настроювання, з якими в мене працює живаючи система).
    Для установки RedMon потрібно його розпакувати в якийсь каталог (%SystemDrive%\Tools\RedMon) и запустити setup.exe з нього. У файлах readme.txt і redmon.hlp находится докладна інформація з установки й стандартного настроювання redmon.
    Реєстрація Active_BMP здійснюється розпакуванням файлів у каталог (%SystemDrive%\Tools\OLE\ActiveBMP) і запуском із цього каталогу "regsvr32 Bmp_1c.ocx".
    в подальшому каталоги з RedMon і Active_BMP нам не знадобляться, так що про їх сміло можна забути (але не видаляти зовсім з диска :-) ).
    Postie установлюється простим витяг його в потрібний каталог (%SystemDrive%\Tools\Postie).
    Тепер нам необхідно настроїти принтер. для цього з папки принтери вибираємо "Додати". Тип принтера - локальний, відмовляємося від автоматичного пошуку й додаємо порт: тип порта: Redirect Port, ім'я: RPT1. На наступному кроці вибираємо модель PS-принтера (в RedMon рекомендується Apple LaserWriter II NT або Apple Color LaserWriter 12/600 якщо ви хочете кольорове зображення). Я використав Apple LaserWriter II NT, т.к. мені потрібно було чорно-біле зображення. Відразу після цього я переименовал принтер у більше відповідне його функціям назва: "Send EMail". теперь нам необхідно настроїти порт. Для цього відкриваємо настроювання принтера, шукаємо сторінку "Порти" і тиснемо кнопку "Конфігурувати порт".
    Подальші настроювання відрізняються від стандартних, описаних в redmon.hlp:
    • "Redirect this port to the program:"="cscript.exe" (без лапок, природно),
    • "Arguments for this programs are:"="Наш\Скрипт\З\Повним\Шляхом.js" (%SystemDrive%\Tools\gs\PrnUser.js) (у лапках, якщо шлях містить пробіли),
    • "Output:"="Program handles output"
    • "Run:"="Hidden"
    • "Run as user" знята (у мене викликало помилку, якщо встановлено)
    • "Shut down delay:"="300"
    Кнопку "Log file" нужна під час налагодження всієї системи відправлення пошти, хоча можна залишити запись балки й у робочому режимі - однаково він перезаписується, а не накапливается.

    Угоди про настроювання

    скрипт, що ми вказали в настроюваннях порту, приймає дані з принтера й відповідно до настроювань, збереженим із зовнішньої програми (1С или іншої), відправляє його поштою як малюнок (у скрипте предусмотрени перевірки на коректність значень). Оскільки единственное, що ми можемо одержати із друкованого завдання - це ім'я пользователя (%REDMON_USER%), те з кожним користувачем ми будем працювати в його каталозі, при цьому одночасна печатка 2-х заданий від одного користувача неможлива. (Якщо вам удасться передати в скрипт іншу інформацію з 1С, наприклад: унікальний ідентифікатор задания або ім'я файлу - повідомите мені). У мене використається самописний компонент SysTools для одержання профілю користувача по його імені. поскольку він ще тільки в альфа-версії викладати не буду, якщо кому нужен - вистелю поштою. Отже, припустимо, у нас є каталог, в котором зберігаються даних користувачів (%MyProfiles%\User1, %MyProfiles%\User2, ...). До особистому каталозі користувача ми будемо створювати підкаталог SendMail для відправлення пошти
    Тимчасові файли для роботи ми будемо зберігати в тимчасовому каталозі (змінна %TEMP% для системи, оскільки запускатися скрипт буде від імені Local service).
    Всі інші настроювання й шляхи до файлів задані в змінні спочатку скрипта - їх можна (і потрібно) змінити для себе
    Файл, у якому 1С зберігає настроювання називається %UserProfile%\SendMail\mail.ini і має наступну структуру: кожний рядок - поле=значення, крім поля BODY, що обов'язково йде останнім і може бути розтягнуте на кілька рядків

    Пишемо програму

    в цьому розділі будуть показані й пояснені тексти декількох модулів, входящих у демонстраційну конфігурацію. Скрипт мовою JavaScript здесь описаний не буде, оскільки не відповідає тематиці розділу. надеюсь - коментарів усередині скрипта буде досить для що побажали разобраться в його роботі
    Оскільки в 1С не передбачена модульна организация програм, те складні речі я звичайно ладу за такою схемою: законченная функціональність - у зовнішній обробці, параметри в которую передаються через Списокзначений, и вспомагательная процедура/функція в глобальному модулі, що цей список заповнює з параметрів. Так була зроблено й тут.
    Функція запиту параметрів відправлення пошти (кому, від кого, тема та ін.) у глобальному модулі виглядає так:
    // ===============================
    // Пропонує змінити параметри відправлення пошти
    // Повертає ім'я файлу настроювань або порожній рядок при невдачі
    функция глпараметриотправкипочти(Заголовок,Кому,Откого,Копія="",
    Тема="",Повідомлення="",Заборонити="", Безформи=0) Експорт
        Перем Сп, Каталог, Имяфайла, Т;
        
        // Установлюємо параметри обробки
        Сп=Создатьобъект("Списокзначений");
        Сп.Установити("Заголовок",Заголовок);
        Сп.Установити("Кому",Кому);
        Сп.Установити("Откого",Откого);
        //Сп.Установити("Откогофирма"," Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script "); - адреса за замовчуванням, якщо Откого не заданий
        Сп.Установити("Копія",Копія);
        Сп.Установити("Тема",Тема);
        Сп.Установити("Повідомлення",Повідомлення);
        Сп.Установити("Заборонити",Заборонити);
        Сп.Установити("Тихийрежим",Безформи);
        // Викликаємо обробку підтвердження параметрів
        Откритьформумодально("Звіт", Сп, Каталогиб()+"ExtForms\Параметриотправкипочти.ert");
        
        // Якщо натиснуто "Скасування" - виходимо
        Якщо Пустоезначение(Сп)=1 Тоді Повернення ""; Конецесли;
        
        // Зчитуємо повернуті значення
        Откого=Рядок(Сп.Одержати("Откого"));
        Кому=Рядок(Сп.Одержати("Кому"));
        Копія=Рядок(Сп.Одержати("Копія"));
        Тема=Рядок(Сп.Одержати("Тема"));
        Повідомлення=Рядок(Сп.Одержати("Повідомлення"));
        Спроба
            Каталог=Каталогсистемногопользователя();
            Якщо Пустаястрока(Каталог)=1 Тоді Повернення ""; Конецесли; // Невідомий користувач
            
            Каталог=Каталог+Каталогпочти;
            
            // Очікуємо завершення попереднього завдання
            Відповідь="Повтор";
            Поки (ФС.Существуетфайл(Каталог+Файлфлага)=1) АБО
             (ФС.Существуетфайл(Каталог+Файлнастроек)=1) Цикл
                Текствопроса=Текущеевремя()+": Очікується завершення завдання."+
                 Разделительстрок+"Автоматичний повтор через 5 секунд...";
                Відповідь=Питання(Текствопроса, "Повтор+Скасування", 5);
                // Можливість перервати очікування
                Якщо Відповідь="Скасування" Тоді Перервати; Конецесли;
            Конеццикла;
            Якщо Відповідь="Скасування" Тоді
                Имяфайла="";
            Інакше
                // Записуємо параметри у файл
                Имяфайла=Каталог+Файлнастроек;
                Т=Создатьобъект("Текст");
                Т.Добавитьстроку("TO="+ Кому);
                Т.Добавитьстроку("FROM="+ Откого);
                Т.Добавитьстроку("CC="+ Копія);
                Т.Добавитьстроку("BCC="+ Откого);
                Т.Добавитьстроку("SUBJ="+ Тема);
                Т.Добавитьстроку("ORG="+ "Тестова конфігурація Send E-Mail");
                Т.Добавитьстроку("BODY="+ Повідомлення);
                Т.Записати(Имяфайла);
            Конецесли;
        Виключення
            Повідомити(Описаниеошибки(),"!!!");
            Повернення "";
        Конецпопитки;
        
        Повернення Имяфайла;
    конецфункции
    У цій функції передані параметри записуються в список значень, що передається зовнішній обробці Параметриотправкипочти.ert у підкаталозі ExtForms каталогу бази даних. Запит параметрів має вигляд:

    Повернуті значення записуються у файл, параметри якого (шлях, ім'я, і т.п.) задані наприкінці глобального модуля
    в самій обробці нічого цікавого немає: читання параметрів зі списку, отображение й перевірка параметрів при натисканні кнопки Відправити. Якщо не задани необхідні параметри (Откого, Кому) або адреси E-Mail зазначені не правильно - буде видані повідомлення й форма не закриється
    Розглянемо параметри виклику даной функції:
    • Заголовок - заголовок форми, на малюнку - синій напис "Тестовий документ №3 від 30.04.04";
    • Кому, Откого, Копія - E-mail або список E-Mail'ов (через ",");
    • Тема, Повідомлення - відповідні параметри листа;
    • Заборонити - які поля заборонені для редагування (на малюнку - поле Тема);
    • Безформи - якщо 1: форма не відображається й при правильних параметрах лист відправиться автоматично.
    следующая функція викликає цю і якщо все пройшло успішно - викликає внешнюю обробку для невеликий предподготовки таблиці при печатці й отправки її:
    // ======================================
    // Запит параметрів, предподготовка таблиці й відправлення пошти
    функция глотправитьпопочтерисунок(Таб, Знач Заголовок, Знач Кому, Знач Откого,
    Знач Копія="", Знач Тема="", Знач Повідомлення="",
    Знач Заборонити="", Знач Безформи=0, Знач Масштаб=0) Експорт
        Перем Сп, Файл;
        
        // Запитуємо підтвердження параметрів
        Файл=глпараметриотправкипочти(Заголовок,Кому,Откого,
         Копія,Тема,Повідомлення,Заборонити,Безформи);
        
        Якщо Пустаястрока(Файл)=1 Тоді
            Повідомити("Пошта не була відправлена","!");
            Повернення 0;
        Конецесли;
        
        // Установлюємо значення для відправлення й инициализируем відправлення
        Сп=Создатьобъект("Списокзначений");
        Сп.Установити("Таблиця", Таб);
        Сп.Установити("Масштаб", Масштаб);
        Откритьформумодально("Звіт", Сп, Каталогиб()+"ExtForms\Отправитькакрисунок.ert");
        
        Стаб=Символтабуляции;
        глзаписатьлог("Отправитьпопочтерисунок", Шаблон(
         "Откого:[Откого]"+Стаб+"Кому:[Кому]"+Стаб+"Копія:[Копія]"+Стаб+"Тема:[Тема]"));
        // У цей момент пішло на принтер, але можливо ще не обробилося
        Повідомити("Відправляється. Очікуйте копію листа на адресу: "+Откого);
        Повернення 1;
    конецфункции
    Тут уже бпрольшая функциональность перенесена на обробку. Вона (обробка) взагалі не откривается, тільки виконує деякі дії. Рассмортим параметри:
    • Таб - Значення типу "Таблиця", що і будемо друкувати;
    • Заголовок, Кому, Откого, Копія, Тема, Повідомлення, Заборонити, Безформи - просто передаються у функцію глпараметриотправкипочти й докладно розглянуті в ній;
    • Масштаб - масштаб печатки таблиці. Якщо не заданий - автомасштаб по ширині.
    В обробці всього 2 процедури: Проверитьпараметр для перевірки коректності переданих значень і Приоткритии, у якій підготовляється й друкується таблиця. Виглядає весь модуль обробки так:
    перем Принтер;
    // ======================================
    функция Проверитьпараметр(Сп, Назв, Всеок, Обязат=1, Умолч="", Тип="")
        Зн=Сп.Одержати(Назв);
        Якщо (Пустоезначение(Зн)=1) Тоді
            Якщо (Обязат=1) Тоді
                Всеок=0;
                Повідомити(Шаблон("Не заданий обов'язковий параметр: '[Назв]'"),"!");
            Інакше
                Зн=Умолч;
            Конецесли;
        Конецесли;
        Якщо Пустаястрока(Тип)=0 Тоді
            Типзн=Типзначениястр(Зн);
            Якщо Нрег(Типзн)Нрег(Тип) Тоді
                Всеок=0;
                Повідомити(Шаблон("Для '[Назв]' не вірний тип ('[Типзн]'). Очікуваний тип: '[Тип]'"),"!");
            Конецесли;
        Конецесли;
        
        Повернення Зн;
    конецфункции
    // ======================================
    процедура Приоткритии()
        // Перевіримо коректність виклику
        Шлях=""; Назв="";
        Расположениефайла(Шлях, Назв);
        Назв=Стрзаменить(Назв,".ert","")+": ";
        Статусвозврата(0); // а взагалі не потрібно відкривати!
        Всеок=1;
        Якщо Форма.Модальнийрежим()=0 Тоді
            Повідомити(Назв+"Запустите обробку в модальному режимі!","!");
            Всеок=0;
        Конецесли;
        Сп=Форма.Параметр;
        Якщо Типзначениястр(Сп)"Списокзначений" Тоді
            Повідомити(Назв+"Як параметр необхідний Списокзначений!","!");
            Всеок=0;
        Конецесли;
        Якщо Всеок=0 Тоді Повернення; Конецесли;
        
        Таб=Проверитьпараметр(Сп, "Таблиця", Всеок, 1, "", "Таблиця");
        Масштаб=Число(Проверитьпараметр(Сп, "Масштаб", Всеок, 0, -1));
        
        Якщо Всеок=0 Тоді Повернення; Конецесли;
        Стан("Обробка таблиці...");
        Таб.Область().Цветтекста(0); // Все чорне, крім...
        // Пробіжимося по всіх осередках і поміняємо контроль=авто,
        // тобто червоний кольори на негативних значеннях
        // на чорні кольори
        Для И1=1 По Таб.Висотатаблици() Цикл
            Для И2=1 По Таб.Ширинатаблици() Цикл
                Обл=Таб.Область(И1,И2,И1,И2);
                Якщо Обл.Контроль()=5 Тоді Обл.Контроль(1);
                Иначеесли Обл.Контроль()=6 Тоді Обл.Контроль(3);
                Конецесли;
            Конеццикла;
        Конеццикла;
        // Щоб параметри печатки не плуталися з іншими - даємо їм ім'я
        Таб.Опції(,,,,"Як малюнок "+Принтер,,,);
        // Тільки книжкова орієнтація
        Таб.Параметристраници(1,,,5,5,5,5,,,,,Принтер);
        // Автомасштабирование по ширині, якщо явно не заданий масштаб
        Якщо Масштаб>0 Тоді Таб.Параметристраници(,Масштаб,,,,,,,,,,);
        Інакше Таб.Параметристраници(,,,,,,,,,1,,); Конецесли;
        // Тільки 1 екземпляр
        Таб.Екземпляровнастранице(1);
        Таб.Количествоекземпляров(1);
        // Уперед!
        Таб.Надрукувати(0);
    конецпроцедури
    принтер="Send EMail";
    вот практично й усе, що стосується програми в 1С. Деякі сервісні функции, які не були описані тут, можна подивитися в прикладі конфигурации. У такий спосіб нічого складного тут немає. Більше сложностей викликає настроювання системи для правильної роботи. Виглядає отправленний документ приблизно так:

    Зауваження в процесі експлуатації

    сразу скажу - у бойовому режимі система працює недовго (з 15.04.2004), но навіть за цей час були замічені деякі "особливості" роботи:
  • Формат tiff виявився не таким вуж стандартним. Тому довелося його замінити на png. Зробити це потрібно у двох місцях: у суфіксі вихідного файлу в скрипте (щоб Postie правильно поставив його Content-Type:) і в настроюваннях GS (параметр -sDEVICE=pngmono собственно й задає вихідний формат файлу). Можна замінити й на ще более стандартний jpeg, але при цьому сильно виросте розмір файлу. ДО сожалению gif уже не підтримується в поточній версії GS (як я зрозумів з документации - через можливі проблеми з ліцензуванням цього формата). Можна добится підтримки gif, видерши її з исходников предидущих версій і перекомпілювавши поточну, але я поки цього не робив. возникла думка передавати в настроечном файлі (%UserProfile%\SendMail\mail.ini) параметри, як відправляти зображення (jpeg, tif, png; color/mono; ...) і в скрипте динамічно міняти.
  • PostScript шрифти, що йдуть у поставці GS, не так добре "вилизані", як TrueType. потому росіяни букви виглядають масніше англиских. Поки скарг на це не било :-)
  • У новій версії Postie у мене чомусь не працює ключ -bcc (помилки не видає, але й не відправляє по зазначених адресах). Так і не розібрався - довелося відкотиться на стару версію (POSTIE Version 4)
  • Хоча ломать нічого й не довелося, але все-таки ми порушуємо ліцензію Postie, которий "free for personal use". Може хто знає іншу програму отправки пошти з коммандной рядка?
  • Подяки

    Моєму улюбленому директорові - за невгамовний розум і нові цікаві завдання
    вадиму Ханасюку - за неопубліковану тут, але корисний компонент SysInfo (одержання каталогу профілю користувача по імені) і допомога в поиске потрібного софта
    Всім співробітникам, які не заважали працювати

    Посилання

    ("Исп." - використається в мене й працює) Программаисп.Cтраничка з описаниемпрямая посилання для накачування AFPL Ghostscript 8.14 for Win32 + http://www.geocities.com/Silicon Valley/5682/Ghostscript.html ftp://mirror.cs.wisc.edu/pub/mirrors /ghost/AFPL/gs814/gs814w32.exe RedMon + http://www.cs.wisc. edu/~ghost/redmon ftp://mirror.cs.wisc.edu/ pub/mirrors/ ghost/ghostgum/redmon17.zip Windows Script 5.6 for Windows 9X/ME/NT4   http://msdn.microsoft.com/ downloads/list/webdev.asp http://download.microsoft.com/download/ 4/c/9/4c9e63f1-617f-4c6d-8faf-c2868f670c1c/scr56en.exe Windows Script 5.6 for Windows 2000/XP + http://msdn.microsoft.com/ downloads/list/webdev.asp http://download.microsoft.com/ download/ 2/8/a/28a5a346-1be1-4049 -b554-3bc5f3174353/scripten.exe Active_BMP + http://1c.proclub.ru/modules/ mydownloads/personal. php?cid=111&lid=2725 http://1c.proclub.ru/modules/mydown loads/visit.php?lid=2725&cid=111 Postie Personal Edition WIN32   http://www.infradig.com http://www.infradig.com/ downloads/postie.exe Postie Version 4 + http://zmn.newmail.ru/ freesoftware.html http://zmn.newmail.ru/ freesoftware/postie.zip Демонстраційна конфігурація +   filesforarticles/kivals/ sendimageemail.zip

     

    © Kivals 2004-04-30

    Джерело http://club.shelek.com/

     
    « Пред.   След. »