Имя: Пароль:
1C
1C 7.7
v7: Формирование документа в PDF и последующая отправка по почте из 1С
0 Славянин
 
21.09.15
09:42
Здравствуйте. Поставили задачу организовать отправку по почте счета в пдф формате из 1С. Ребята,может работал кто-нибудь с похожей проблемой? Подскажите в каком направлении двигаться?
1 ДенисЧ
 
21.09.15
09:44
ставь локальный пдф-принтер. Через него формируй файл.
Потом его отправляй  имющимися средствами
2 Ёпрст
 
21.09.15
09:48
либо, йоксель
3 Ёпрст
 
21.09.15
09:49
но, он делает пдф-ку только как картинку.
4 Vladal
 
21.09.15
09:50
переименовало тему.
5 scanduta
 
21.09.15
09:58
делай так

ВременныйФайл = ПолучитьИмяВременногоФайла(".pdf");
        
Таб.Записать(ВременныйФайл,ТипФайлаТабличногоДокумента.PDF);
        
ЗапуститьПриложение(ВременныйФайл);


таб - это табличный документ
6 Славянин
 
21.09.15
09:59
(1) Сейчас через пдф-принтер. А нужно без него
7 Builder
 
21.09.15
10:11
(6) Что не так с принтером?
8 varelchik
 
21.09.15
11:42
Пройся тута на форуме.
Это-то вопрос уже неоднократно разжовували.
9 vcv
 
21.09.15
11:46
(7) Подозреваю, что PDF-принтер задаёт лишние вопросы, которых быть не должно. Типа куда сохранить файл и всё такое.
Я когда-то искал-искал, но так и не нашёл бесплатного PDF-принтера под винду, который бы работал молча, сохранял печатаемые файлы под указанными именами в указанное место.
10 Fedor-1971
 
21.09.15
11:52
(9) за минут 10 находится BullZipPDF - управляемый и бесплатный.
Можешь программно рулить как тебе нравится. При желании можно отловить момент, когда PDF уже создан и доступен к перемещению в целевую папку.
(5) Вопрос по 7.7
11 Dmitry77
 
21.09.15
12:02
можешь открыть в excel. excel умеет сохранять в PDF
12 vcv
 
21.09.15
12:05
(10) Рассматривал его, но так и не увидел, как, в бесплатном варианте, можно отправить задание на принтер с указанием, в какой файл сохранить результат.
13 Builder
 
21.09.15
12:09
(12) Как то так:

    ПДФПринтер = СоздатьОбъект("Bullzip.PDFPrinterSettings");
    ПДФПринтер.SetValue("output", ПутьКФайлу);
    ПДФПринтер.SetValue("ShowSaveAS", "never");
    ПДФПринтер.SetValue("ShowProgress", "no");
    ПДФПринтер.SetValue("ShowProgressFinished", "no");
    ПДФПринтер.SetValue("ShowSettings", "never");
    ПДФПринтер.SetValue("ShowPDF", "no");
    ПДФПринтер.SetValue("ConfirmOverwrite","no");
    ПДФПринтер.WriteSettings();

    ИмяПринтера = "Bullzip PDF Printer";
    Таб.ПараметрыСтраницы(1,,,,,,,,,1,ИмяПринтера);
    Таб.Напечатать(0);
14 Fedor-1971
 
21.09.15
12:40
13+ важно Output - куда деть и Напечатать(0) - без всяких вопросов про принтер (для 8    таб.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);)
15 vcv
 
21.09.15
12:56
Гм. Действительно работает. Правда берёт какие-то левые размеры листа при печати ландшафтных йоксельных документов, но использовать таки можно. Кажется меньше проблем, чем при попытках конвертировать в PDF посредством LibreOffice.
Спасибо.
16 HawkEye
 
21.09.15
20:08
(0) открой в Ворде и сохрани в PDF ))))
17 BalBess
 
22.09.15
07:34
(13) только после печати (т.е. сохранения), нельзя сразу отправлять, т.к. часто файл еще не готов. Особенно при отправке первый раз, пока загрузятся драйвера принтера и т.д.
Я решил так:

Попытка
    Табл.Напечатать(0);
    Успешно = 1;
Исключение
    Успешно = 0;
КонецПопытки;    
Если Успешно = 1 Тогда
    ЖдемСек = 5; //5 сек ждем
    Успешно = 0;
    Для i=1 По ЖдемСек Цикл
        Если ФС.СуществуетФайл(Файл)>0 Тогда
                Успешно = 1;
            Прервать;
        Иначе          
            sleep(1);
        КонецЕсли;
    КонецЦикла;
КонецЕсли;
Возврат Успешно;
18 BalBess
 
22.09.15
07:36
процедура sleep, которую "не видно", может у кого есть другие решения

Процедура sleep(чСекунд = 1) Экспорт
    ИмяПутьСкрипта = КаталогИБ()+"sleep.js";
    Скрипт = СоздатьОбъект("Текст");
    Скрипт.ДобавитьСтроку("WScript.Sleep("+Строка(1000*чСекунд)+");");
    Попытка
        Скрипт.Записать(ИмяПутьСкрипта);
    Исключение
    КонецПопытки;    
    cmdLine="wscript.exe """+ИмяПутьСкрипта + """";
    WshShell = СоздатьОбъект("WScript.Shell");
    WshShell.Run(cmdLine, 0, -1);
КонецПроцедуры
19 BalBess
 
22.09.15
07:51
Саму отправку лучше делать через CDO

objEmail = Createobject("CDO.Message");

через него можно отправлять в формате html
20 BalBess
 
22.09.15
07:56
Вот тоже полезная функция, проверки адреса перед отправкой

//-----------------------------------------------------------------------------
function checkStr(str, badChars) export
    for i=1 to strLen(str) do
        if find(badChars,mid(str,i,1))=0 then return(0) endif;
    enddo;
    return 1;    
endFunction            
//-----------------------------------------------------------------------------
function checkMail(val mail) export
    //Каждый e-mail должен начинаться буквы, цифры, символа подчёркивания или тире.
    //Затем может идти количество разнообразных символов, в том числе точка.
    //Таким образом, составляется первая часть строки адреса до символа (@), а после него идёт доменное имя.
    //Доменные имена состоят из любого числа “слов”, состоящих, в свою очередь, из букв, цифр, тире, разделённых точками.
    //В конце адреса всегда присутствует суффикс, который должен сдержать от 2 до 6 символов.     

    mail=trimAll(mail);
    pos=find(mail,"@");  
    if pos=0 then return(0) endif;    
    login=mid(mail,1,pos-1);
    server=mid(mail,pos+1,strLen(mail));
    if (strLen(login)=0) or ((strLen(server)<4)) then return(0)    endif;    
    pos=find(server,".");
    if (pos=0) or (pos>(strLen(server)-1)) then    return(0)    endif;
    chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.";    
    return (checkStr(login,chars)*checkStr(server,chars));
endFunction
//************************************************
21 BalBess
 
22.09.15
08:00
Перед формированием файла PDF нужно убедиться в наличии виртуального принтера (используется ВК FormEx)

сервис=СоздатьОбъект("Сервис");
спПринтеров=сервис.ПолучитьСписокПринтеров();
РасширениеPDF = ".pdf";
ИмяПринтераPDF = "Bullzip PDF Printer";
ЕстьВиртПринтер = 0;
Для Поз =1 По спПринтеров.РазмерСписка() Цикл
    ТекПринтер=спПринтеров.ПолучитьЗначение(Поз);
    Если ТекПринтер =  ИмяПринтераPDF Тогда
        ЕстьВиртПринтер = 1;
        Прервать;
    КонецЕсли;
КонецЦикла;
Если (ЕстьВиртПринтер = 0) ИЛИ (сервис.ГотовностьПринтера(ТекПринтер)<>0) Тогда
    Сообщить("Не установлен ни один виртуальный принтер! Попробуйте отправить в другом формате..");
    Возврат Успешно;
КонецЕсли;
22 Z1
 
22.09.15
08:35
(all) Извините если off.
А существует какой либо бесплатный , хороший ActiveX
для просмотра pdf внутри 1с приложения ?
23 Fedor-1971
 
22.09.15
09:31
(17) Ну зачем такой огород?
Bull ZIP PDF - может делать файл лога выгрузки, формируется он во время записи PDF, вот и пытайся в цикле удалить лог - когда сможешь, значит PDF-файл принтер больше не держит.
При попытке переместить сам PDF - получишь битый файл.
24 BalBess
 
22.09.15
09:52
(23) какая разница что проверять, существование готового файла или пытаться удалить лог..
я просто хотел сказать, что необходимо делать задержку/проверку между формированием файла и отправкой его по почте.
т.е. процесс формирования асинхронный, 1с дает команду принтеру и продолжает работать.
Просто сам наступал на эти грабли.
Про перемещение PDF никто не говорит, конечно его нельзя перемещать пока не готов
25 Fedor-1971
 
22.09.15
10:01
(24) разница в том, что в каталоге результата файл существует уже в момент начала печати, а Sleep засыпает на время - как вы правильно заметили процесс асинхронный и сколько времени понадобится принтеру на формирование файла ни кто не знает (5 сек или 3 минуты), поэтому лучше опираться на возможности принтера, он точно знает, что печать завершена. Как индикатор - возможность удалить файл лога и реализовать это можно штатными средствами 1С.
26 BalBess
 
22.09.15
11:06
(25) нет, файл не существует, пока он полностью не готов, т.е. он создается (принтером), но с другим именем и в другом месте. Когда готов, переноситься в заданный каталог с нужным именем.
Проверять можно и лог (принципиальной разницы нет) и штатными средствами задержку не сделаешь,
либо тупо проверять в цикле (без задержки), тогда загрузиться процессор на 100%.
Можно точно также проверять существование файла в цикле, без задержки.
У меня кстати код полностью рабочий, работает на 100%. Приведите Ваш код с проверкой лога, штатными средствами.

Эмперическим путем у меня подобрано значение 5 сек. Заметьте, это максимальное значение, обычно хватает и одной секунды. Если за 5 сек файл не успел сформироваться, значит что-то не так с принтером. Как-то так.
27 Fedor-1971
 
22.09.15
12:59
(26) как то так:

НазвФайла=?(имяФайла="", Неопределено, имяФайла);
Попытка  //пытаемся инициализировать принтер
   obj  = Новый COMObject("Bullzip.PDFPrinterSettings");
   obj.SetValue("ShowPDF", "no");
   Если вАрхив ИЛИ ВернутьФайл тогда
     ФайлПДФ=ПолучитьИмяВременногоФайла("PDF");
     ФайлСтатус=ПолучитьИмяВременногоФайла("Ok1C");
     obj.SetValue("Output", ФайлПДФ);
     obj.SetValue("ShowSaveAS", "never"); //без вопросов
     obj.SetValue("StatusFile", ФайлСтатус); //как будет готов докумен, создастся сей файл
    Иначе
     obj.SetValue("ShowSaveAS", "always");//"nofile");//"never");
   КонецЕсли;
   obj.SetValue("ConfirmOverwrite", "no");
   obj.SetValue("ShowSettings", "never");
   obj.SetValue("RememberLastFileName", "no");
   obj.SetValue("RememberLastFolderName", "no");
   obj.SetValue("ShowProgressFinished", "no");
   obj.WriteSettings(True);
  Исключение
   Предупреждение("Нужно установить ""Bullzip PDF Printer"". Обратитесь к администратору.");
   Возврат "";
КонецПопытки;

таб=рез.Таблица;
таб.ИмяПринтера="Bullzip PDF Printer";
Попытка
   таб.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
  Исключение
   Предупреждение("Ошибка создания PDF!!",,"Ошибка");
   Возврат "";
КонецПопытки;

Если вАрхив ИЛИ ВернутьФайл тогда
   фл=новый Файл(ФайлСтатус);
   Пока Не фл.Существует() цикл //ждём создания файла
   КонецЦикла;
   НеГотово=Истина;
   Пока НеГотово цикл
     Попытка
       УдалитьФайлы(ФайлСтатус);
       НеГотово=Ложь;
      Исключение
     КонецПопытки;
   КонецЦикла;
КонецЕсли;

Дальше с файлом можем делать что хотим
28 BalBess
 
23.09.15
06:47
(27) В моем случае, если убрать sleep() получиться тоже самое. Я же говорю разницы нет.
В вашем решении 2 минуса
1. Процессор в этом случае нагружается на 100%, что не есть айс. Особенно когда работает 100 чел в базе
2. Нет условий выхода из цикла. Вдруг что случить с принтером или еще что-то, база зависнет.

Не хочу никого переубеждать, каждый решает сам как захочет.
29 Fedor-1971
 
23.09.15
08:55
(28) Как-то поверхностно рассмотрел код?
1. Код не гоняет счётчик, а пытается удалить файл, что тупо занимает время ОС, а не грузит процессор левыми вычислениями.
2. У меня этот код под УФ, так, что если что-то с принтером проблемы будут на клиентской машине и только.
Но хочу обратить внимание:
  - код:
Попытка
таб.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
  Исключение
   Предупреждение("Ошибка создания PDF!!",,"Ошибка");
   Возврат "";
КонецПопытки;
именно для проблем с принтером.

- проверяется и удаляется файл Лога создания PDF - он создастся и в случае проблем с принтером, так, что ничего не повиснет.
30 Fedor-1971
 
23.09.15
09:04

процедура



процедура рус


[code]
процедура
[/code]
Прошу прощения, проверил работу ручного выделения кода
31 Vladal
 
23.09.15
09:16
(30) Код выделяется автоматически движком форума.
32 Fedor-1971
 
23.09.15
09:22
(31) это да, но в 27 он не захватил кусок, а в 29 прихватил лишнего и не забрал последнюю строку, не красиво получилось.
Собственно проблема только спрятать код под +. Поищу ещё и потом попробую при случае.
33 BalBess
 
23.09.15
09:53
(29) мы немного не поняли друг-друга:
речь была про 7.7, по крайней мере тема заведена в этой ветке. И в ней бесконечные циклы грузят проц на 100%, в не зависимости что он делает.
В 7.7 обычно все работают в терминале, поэтому все проблемы отражаются на сервере.
34 Fedor-1971
 
23.09.15
10:01
(33) Как-то не замечал за 7.7 при долгом цикле нагрузки на проц в 100% вне зависимости от того, что она делает. Когда считает да, когда дёргает файл нет.
На подходе заказ большой доработки на 7.7, при случае проверю теорию про пустой бесконечный цикл и 100% нагрузку на проц.
35 Serginio1
 
23.09.15
10:23
36 Serginio1
 
23.09.15
10:26
37 trdm
 
23.09.15
10:28
(22)  http://get.adobe.com/reader/
DLL file -  Acropdf.dll
ActiveX control name -  AxAcroPDFLib.AxAcroPDF
Насчет хорошести - не пользовался.
38 Serginio1
 
23.09.15
10:31
39 Mordor_1C
 
23.09.15
10:38
В (5) уже решение написано без всяких pdf принтеров.
40 trdm
 
23.09.15
10:48
(39) Вопрос по семерке.
Проблемы невозможно решaть нa том же уровне компетентности, нa котором они возникaют. Альберт Эйнштейн