helpf.pro
Регистрация

v8.2: Еще раз о печати из 1С в PDF

hanio
04.10.2011 23:16Прочитано: 11513
у меня 8.2 УТ релиз 10.3.12. Я реализовал печать из 1С в PDF, как описывать долго просто скажу что использую ОткрытьПриложение куда посылаю команду запуска Adobe ридера с ключами которые открывают ридер посылают на печать файл и закрывают ридер. На малом количестве номенклатуры все замечательно работает, но если вопрос встает печати большого количества строк то у меня происходит вот что - открывается ридер но при этом все сразу пытаются открыться и послаться на печать как итог - почти полное зависание компьютера до момента распечатки.Оперативки 2 гига они выжираются полностью. У кого какие есть предложения, может открывать ридер как COM объект, попробовать bullzip, короче наверно я не первый кому приходилось настраивать печать качественных сертификатов...
Изменено 04.10.11 23:17:04
Yandex
Возможно, вас также заинтересует
Реклама на портале
typeharley
05.10.2011 11:08Ответ № 1
Кто создает у тебя документ? Создается ли он вообще? Ридер его вручную вообще открывает?
hanio
05.10.2011 21:31Ответ № 2
документ Реализация там я в модуль подвесил процедуру, кнопку на форму кинул и у меня ридер все начинает открывать только потом он выжирает всю оперативку, на принтер идет в час по чайной ложке и прочие неприятности. Файлы PDF Я а понимаю громоздкие некоторые вообще 23 мегабайта один файл в принтер пропихивают. Мне интересно есть ли какие мысли кто и как это решал возможно
E_Migachev
06.10.2011 17:02Ответ № 3
(2) hanio, я делал просто - печать табличного документа в файл PDF через bullzip и все работало быстро
hanio
06.10.2011 20:30Ответ № 4
тогда вопрос как ты настроил что буллзип печатал? я его установил а где сделать мапинг на реальный принтер?
E_Migachev
07.10.2011 12:15Ответ № 5
зачем маппинг? ты к в коде делаешь печать и у казываешь булзип и он сохраняет напечатанное в файл
hanio
07.10.2011 12:30Ответ № 6
так мне не надо сохранять у меня уже они есть файлы PDF их надо отправить на печать.
Код 1C v 8.х
 	// Функция формирует реестр качественных и сразу открывает качественные из внешних данных
Функция ПечатьКИ()
Док = ЭтотОбъект.Ссылка;
СведенияОПоставщике = УправлениеКонтактнойИнформацией.СведенияОЮрФизЛице(Док.Организация,Док.Дата);
АдресПоставщика = ФормированиеПечатныхФорм.ОписаниеОрганизации(СведенияОПоставщике, "ЮридическийАдрес,Телефоны");

ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.ПолеСверху = 0;
ТабДокумент.ПолеСлева = 5;
ТабДокумент.ПолеСнизу = 0;
ТабДокумент.ПолеСправа = 5;
ТабДокумент.РазмерКолонтитулаСверху = 0;
ТабДокумент.РазмерКолонтитулаСнизу = 0;
ТабДокумент.АвтоМасштаб = Истина;
ТабДокумент.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;

ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваровУслуг_КИ";

Макет = ПолучитьМакет("РеестрКачественных");

Область = Макет.ПолучитьОбласть("Шапка");
Область.Параметры.Заголовок1 = "Товарно-сопроводительные документы к накладной "+Док+", "+Док.Контрагент.НаименованиеПолное;
Область.Параметры.Заголовок2 = "Реестр сертификатов и удостоверений качества, подлинники или заверенные копии которых хранятся в "+Док.Организация.НаименованиеПолное+" по адресу: г. Пермь, ул. Карпинского, 91е";
ТабДокумент.Вывести(Область);

ТЗ_Исключений = Новый ТаблицаЗначений; // ТЗ для выявления дублирующихся номеров
ТЗ_Исключений.Колонки.Добавить("НомерКачественного");
ТЗ_Исключений.Колонки.Добавить("Качественный");
ТЗ_Врем = Новый ТаблицаЗначений; // ТЗ для 3-х сертификатов которые ноходятся в запросе
ТЗ_Врем.Колонки.Добавить("НомерКачественного");

Запрос = Новый Запрос;

Для Каждого Эл Из Док.Товары Цикл

Запрос.Текст = "ВЫБРАТЬ
| ВложенныйЗапрос.СертификатСоответствия,
| ВложенныйЗапрос.Номенклатура,
| ВложенныйЗапрос1.СертификатКачества
|ИЗ
| (ВЫБРАТЬ
| смСертификатыСоответствия.Номенклатура КАК Номенклатура,
| смСертификатыСоответствия.СертификатСоответствия КАК СертификатСоответствия
| ИЗ
| РегистрСведений.смСертификатыСоответствия КАК смСертификатыСоответствия
| ГДЕ
| смСертификатыСоответствия.Номенклатура В(&ТМЦ)
| И смСертификатыСоответствия.ВыводитьВсегда = ИСТИНА
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.смОсновнойСертификатСоответствия
| ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ГДЕ
| Номенклатура.Ссылка В(&ТМЦ)
| И Номенклатура.смОсновнойСертификатСоответствия <> &НеВыбранОсновнойСертификат) КАК ВложенныйЗапрос
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ПЕРВЫЕ 3
| смСертификатыКачества.Номенклатура КАК Номенклатура,
| смСертификатыКачества.СертификатКачества КАК СертификатКачества
| ИЗ
| РегистрСведений.смСертификатыКачества КАК смСертификатыКачества
| ГДЕ
| смСертификатыКачества.Номенклатура = &ТМЦ
|
| УПОРЯДОЧИТЬ ПО
| смСертификатыКачества.СертификатКачества.ДатаВыработки УБЫВ) КАК ВложенныйЗапрос1
| ПО ВложенныйЗапрос.Номенклатура = ВложенныйЗапрос1.Номенклатура
|
|СГРУППИРОВАТЬ ПО
| ВложенныйЗапрос.СертификатСоответствия,
| ВложенныйЗапрос.Номенклатура,
| ВложенныйЗапрос1.СертификатКачества";

Запрос.УстановитьПараметр("ТМЦ",Эл.Номенклатура);
Запрос.УстановитьПараметр("НеВыбранОсновнойСертификат",Справочники.смСертификатыСоответствия.ПустаяСсылка());

Ном = 0;
СтрокаДатВыработки = "";

ТЗ_Врем = Запрос.Выполнить().Выгрузить();
ТЗ_Врем.Свернуть("СертификатКачества, СертификатСоответствия, Номенклатура");
ТЗ_Врем.ВыбратьСтроку();

Для Каждого ТекСтр Из ТЗ_Врем Цикл
Если Не ПустаяСтрока(ТекСтр.СертификатКачества.НомерКачественного) Тогда
Отбор = Новый Структура;
Отбор.Вставить("НомерКачественного", ТекСтр.СертификатКачества.НомерКачественного);
Поиск = ТЗ_Исключений.НайтиСтроки(Отбор);
Если Поиск.Количество() > 0 Тогда
//ДубльНайден = 1;
Продолжить;
Иначе
НоваяСтрока = ТЗ_Исключений.Добавить();
НоваяСтрока.НомерКачественного = ТекСтр.СертификатКачества.НомерКачественного;
НоваяСтрока.Качественный = ТекСтр.СертификатКачества;
СтрокаДатВыработки = СтрокаДатВыработки + Строка(Формат(ТекСтр.СертификатКачества.ДатаВыработки, "ДФ=dd.MM.yyyy")) + " ";
КонецЕсли;
Иначе
Сообщить("У товара " + Эл.Номенклатура.Наименование + " есть качественный с пустым номером, надо установить и распечатать его вручную");
КонецЕсли;
КонецЦикла;
//ТЗ_Исключений.ВыбратьСтроку();

Сертификат = Запрос.Выполнить().Выбрать();

Область = Макет.ПолучитьОбласть("Строка");
Если Сертификат.Количество() > 0 Тогда
Пока Сертификат.Следующий() Цикл
ФайлКачественного = Сертификат.СертификатКачества.ПутьКФайлуУдостоверенияКачества;
Если ПустаяСтрока(ФайлКачественного) Тогда
Сообщить("Для товара " + Эл.Номенклатура.Наименование + " не указан архивный файл, устраните ошибку");
//Продолжить;
КонецЕсли;
Ном=Ном+1;
Область.Параметры.Ном = Ном;
Область.Параметры.Товар = Сертификат.Номенклатура;
Область.Параметры.Производитель = Сертификат.СертификатСоответствия.Производитель;
Область.Параметры.НТД = Сертификат.СертификатСоответствия.ГОСТ;
Область.Параметры.УКДата = Сертификат.СертификатКачества.ДатаКачественного;
Область.Параметры.УКНомер = Сертификат.СертификатКачества.НомерКачественного;
Область.Параметры.СертНомер = Сертификат.СертификатСоответствия.НомерСвидетельстваГосРегистрации;
Область.Параметры.СертРегНомер = Сертификат.СертификатСоответствия.Код;
Область.Параметры.СертОрган = Сертификат.СертификатСоответствия.ОрганПоСертификации;
Область.Параметры.СертСрокД = Строка(Формат(Сертификат.СертификатСоответствия.ДатаВыдачи,"ДФ=dd.MM.yyyy")) + "-" + Строка(Формат(Сертификат.СертификатСоответствия.ДатаОкончания,"ДФ=dd.MM.yyyy"));
Область.Параметры.Температура = Строка(Сертификат.Номенклатура.ТемператураОт)+"-"+Строка(Сертификат.Номенклатура.ТемператураДо)+" °C";
Область.Параметры.УКДатаВыработки = Сертификат.СертификатКачества.ДатаВыработки;
Область.ТекущаяОбласть.ИспользованиеРасшифровки = ИспользованиеРасшифровкиТабличногоДокумента.Строка;
Область.ТекущаяОбласть.Расшифровка = Сертификат.СертификатКачества.Ссылка;
Область.Параметры.УКГоденДо = Сертификат.СертификатКачества.ДатаВыработки + 60 * 60 * 24 * Сертификат.Номенклатура.СрокГодности;
//Если Сертификат[0].СертификатСоответствия.ДатаОкончания <= Формат(СсылкаНаОбъект.Дата,"ДФ=dd.MM.yyyy") Тогда
// Сообщить("Сертификат " + Сертификат[0].Номенклатура.Наименование + " просрочен - " + Формат(Сертификат[0].СертификатСоответствия.ДатаОкончания, "ДФ=dd.MM.yyyy"), СтатусСообщения.Внимание);
//КонецЕсли;
ТабДокумент.Вывести(Область);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Область = Макет.ПолучитьОбласть("Подвал");
Область.Параметры.Фирма = Док.Организация.НаименованиеПолное;
ТабДокумент.Вывести(Область);
ТабДокумент.АвтоМасштаб=Истина;
ТабДокумент.ТолькоПросмотр = Истина;

// печать качественных
ПутьККачественным = Константы.смКаталогСертификатовКачества.Получить();

Если ПустаяСтрока(ПутьККачественным) Тогда
Предупреждение("Не задан каталог хранения качественных.");
//Возврат;
КонецЕсли;

//УдалитьФайлы(КаталогВременныхФайлов(), "*.pdf");
Для Каждого ТекущаяСтрока Из ТЗ_Исключений Цикл
// теперь начинаем разархивирование
ФайлКачественного = ТекущаяСтрока.Качественный.ПутьКФайлуУдостоверенияКачества;
ПутьКФайлуКачественного = ПутьККачественным + ФайлКачественного;
Если Прав(ФайлКачественного,3) = "zip" Тогда

Архив = Новый ЧтениеZipФайла(ПутьКФайлуКачественного);

СуществуетФайл = НайтиФайлы(КаталогВременныхФайлов() + Архив.Элементы[0].Имя);
//Сообщить(Архив.Элементы[0].Имя);

// проверка на то что такой сертификат уже открывался (тогда винда выдает что не может создать такой же файл)
Если СуществуетФайл.Количество() = 0 Тогда
Архив.Извлечь(Архив.Элементы[0], КаталогВременныхФайлов(), РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
ЗапуститьПриложение("C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe /N /T " + КаталогВременныхФайлов() + Архив.Элементы[0].Имя, КаталогВременныхФайлов(), Ложь)
//+ PrinterName [ PrinterDriver [ PrinterPort ] ]" + КаталогВременныхФайлов() + Архив.Элементы[0].Имя);
Иначе
ЗапуститьПриложение("C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe /N /T " + КаталогВременныхФайлов() + Архив.Элементы[0].Имя, КаталогВременныхФайлов(), Ложь)
КонецЕсли;
//УдалитьФайлы(КаталогВременныхФайлов(),"*.pdf");
//Архив.Закрыть();
Иначе
ЗапуститьПриложение(ПутьККачественным + Сертификат.СертификатКачества.ПутьКФайлуУдостоверенияКачества);
КонецЕсли;
КонецЦикла;

// запишем в РТУ свойство печати реестра кач
Докум=Док.ПолучитьОбъект();
Если Докум.СтатусКач <> Перечисления.СтатусКач.Напечатан Тогда
Докум.СтатусКач=Перечисления.СтатусКач.Напечатан;
Докум.Записать();
КонецЕсли;

Возврат ТабДокумент;

КонецФункции

Изменено 10.10.11 13:46:58 по причине: Разукрасил код
hanio
07.10.2011 12:36Ответ № 7
вот функция, запрос собирает по каждому элементу номенклатуры 3 последних сертификата, сворачиваю по ним чтобы откинуть дубли, затем откидываю дубли по номерам (не нужны качественные у которых одинаковый номер даже если все остальные параметры разные), затем вывожу в макет все собранные качественные. И на закуску вывожу все эти качественные на печать.
E_Migachev
07.10.2011 17:01Ответ № 8
ну и в чем вопрос-то?
печатаешь через командную строку установленного адобе ридера
hanio
10.10.2011 13:35Ответ № 9
вопрос в том что при таком варианте выкатывается все и сразу и принтер захлебывается, оперативка кончается, короче комп висит. Сам вариант неплох если печать ограничена одной-тремя строками в табличном поле, если чуть больше то есть риск подвесить все. Сам вопрос - можно ли как то из 1С отследить что адоб отработал и закрылся. На край подскажите какие методы есть в случае если я сделаю СОМ соединение, а именно - сайлент открытие передаваемого фала, печать и закрытие.
E_Migachev
10.10.2011 13:53Ответ № 10
через сом к чему ты хочешь подключиться?
а узнать адоб отработал или нет только через WHS
hanio
10.10.2011 15:56Ответ № 11
Через СОМ думаю открывать файл, на печать его отправлять и закрывать. а что такое WHS и есть ли это в 1С?
E_Migachev
10.10.2011 16:26Ответ № 12
(11) hanio, через сом это будет еще хуже!
Windows Script Host (WSH)
вот пример получения списка запущенных процессов (он для 7.7, для 8.х замени создание объекта)
Код 1C v 7.x
   Файл=СоздатьОбъект("Текст");
Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl");
Скрипт.Language="vbscript";
ТекстЗапроса="
|Function S_electProcess
| Dim ServicesSet
| Dim Items
| Set ServicesSet = GetObject(""winmgmts:{impersonationLevel=impersonate}!."")
| Set Items = ServicesSet.ExecQuery(""S_elect * from Win32_Process"")
| For Each Item in Items
| S_electProcess = S_electProcess & Item.Name & "" "" & Item.Handle & "";""
| Next
|End Function";
Скрипт.AddCode(ТекстЗапроса);
СтрПроцессов = СтрЗаменить(Скрипт.Run("S_electProcess"),";",РазделительСтрок);
Для СчЦикла = 1 По СтрКоличествоСтрок(СтрПроцессов) Цикл
Файл.ДобавитьСтроку(СтрПолучитьСтроку(СтрПроцессов,СчЦикла));
КонецЦикла;
Файл.Записать()

или
Код 1C v 7.x
 // ПолучитьПроцессы()

//| .Caption 'краткое описание объекта

//| .CommandLine 'командная строка запуска процесса, если таковая есть

//| .CreationDate 'дата и время начала выполнения процесса

//| .CSName 'имя компьютера

//| .ExecutablePath 'полный путь к исполняемому файлу процесса

//| .ParentProcessId 'PID родительского процесса

//| .ProcessId 'PID процесса

//******************************************************************************

Процедура ПолучитьПроцессы()
СписокПроцессов.УдалитьСтроки();
Попытка
ScrptCtrl=СоздатьОбъект("MSScriptControl.ScriptControl");
ScrptCtrl.Language="vbscript";
ScrptCtrl.AddCode("
|Function GetProcess()
| strInfo=vbNullString
| Set objService = GetObject(""winmgmts:{ImpersonationLevel=Impersonate}!\\.\root\cimv2"")
| Set colProcess = objService.ExecQuery(""S_elect * from Win32_Process"")
| For Each objProc in colProcess
| dtmInstallDate = objProc.CreationDate
| dtmInstallTime = TypeName(objProc.CreationDate)
| strInfo = strInfo & objProc.Caption & vbTab & objProc.ProcessId & vbTab & objProc.ParentProcessId & vbTab
| if VarType(objProc.CreationDate) = vbString Then
| tDate = objProc.CreationDate
| strInfo = strInfo & Mid(tDate,7,2) & ""."" & Mid(tDate,5,2) & ""."" & Mid(tDate,3,2) & vbTab & Mid(tDate,9,2) & "":"" & Mid(tDate,11,2) & "":"" & Mid(tDate,13,2) & vbTab
| else
| strInfo = strInfo & vbTab & vbTab
| End If
| strInfo=strInfo & objProc.Priority & vbTab & objProc.Handle & vbTab & objProc.ExecutablePath & vbTab
| objProc.GetOwner User, Domain
| objProc.GetOwnerSid Sid
| strInfo=strInfo & objProc.CSName & vbTab & Domain & vbTab & User & vbTab & Sid & vbCrLf
| Next
| GetProcess = strInfo
|End Function
|");
Текст=ScrptCtrl.Run("GetProcess");
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
КолвоПроцессов = СтрКоличествоСтрок(Текст);
Для ы=1 по КолвоПроцессов Цикл
СписокПроцессов.НоваяСтрока();
СтрКомп = СтрПолучитьСтроку(Текст,ы);
СписокПроцессов.Caption = ПолучитьПараметр(СтрКомп);
СписокПроцессов.ProcessId = ПолучитьПараметр(СтрКомп);
СписокПроцессов.ParentProcessId = ПолучитьПараметр(СтрКомп);
СписокПроцессов.CreatDate = ПолучитьПараметр(СтрКомп);
СписокПроцессов.CreatTime = ПолучитьПараметр(СтрКомп);
СписокПроцессов.Priority = ПолучитьПараметр(СтрКомп);
СписокПроцессов.Handle = ПолучитьПараметр(СтрКомп);
СписокПроцессов.ExecutablePath = ПолучитьПараметр(СтрКомп);
СписокПроцессов.CSName = ПолучитьПараметр(СтрКомп);
СписокПроцессов.Domain = ПолучитьПараметр(СтрКомп);
СписокПроцессов.User = ПолучитьПараметр(СтрКомп);
СписокПроцессов.Sid = ПолучитьПараметр(СтрКомп);
КонецЦикла;
ScrptCtrl = 0;
КонецПроцедуры // ПолучитьПроцессы()
E_Migachev
10.10.2011 16:31Ответ № 13
а вот удаление процесса для 8.х
Код 1C v 8.х
 Функция УдалитьПроцесс (ИмяКомпьютера, НазваниеПроцесса, Логин, Пароль) Экспорт  
Попытка COM = Новый COMОбъект ("WbemScripting.SWbemLocator");
Серв = COM.ConnectServer(СокрЛп(ИмяКомпьютера), "\root\cimv2", СокрЛП(Логин), СокрЛП(Пароль));
СписокПроцессов = Серв.execQuery("S_elect * from Win32_Process Where Name = '"+СокрЛП(НазваниеПроцесса)+"'");
Для каждого item Из СписокПроцессов Цикл
item.Terminate();
КонецЦикла;
Исключение
Возврат Ложь;
КонецПопытки;

Возврат Истина;
КонецФункции

из нее сделай процедуру получения списка процесов:
СписокПроцессов = Серв.execQuery("S_elect * from Win32_Process");

P.S. в S_elect везде убери _
Изменено 10.10.11 16:32:12
hanio
10.10.2011 16:38Ответ № 14
ага уже что-то обрисовывается, спасибо потестю этот вариант
hanio
10.10.2011 16:40Ответ № 15
а если я хочу через СОМ сразу открывать Adobe Reader ? то как тогда код выглядит?
E_Migachev
10.10.2011 17:07Ответ № 16
(15) hanio, никогда так с ним не работал, поищи в инете мож чего найдется
hanio
11.10.2011 08:13Ответ № 17
А где ты находишь в инете хотя бы названия СОМ объектов я по Adobe даже название не могу понять как звучит? я нашел тут хорошую страницу где указаны многие программы и ключи запуска может пригодится - http://benzcode.blogspot.com/2008/08/collection-of-command-line-switches.html
E_Migachev
11.10.2011 10:41Ответ № 18
(17) hanio, а кстати! - попробуй через Foxit Reader
для определения СОМ объектов Adobe используй ActiveX/COM Inspector - 1.0

Вот еще ActiveX компонент http://www.quickpdflibrary.com/free/lite.php
hanio
12.10.2011 08:47Ответ № 19
Вопрос закрываю решил через Foxit Reader с ключем /p
E_Migachev
12.10.2011 10:30Ответ № 20
+ (19) инфа по параметрам командной строки для Foxit Reader, может кому понадобиться:
Открыть PDF файл:
"Foxit Reader.exe" PdfFile

Открыть PDF файл на странице 7:
"Foxit Reader.exe" PdfFile -n 7

Установить Foxit Reader программой по умолчанию, для открытия PDF файлом:
"Foxit Reader.exe" -Register

Напечатать PDF файл на принетере установленном по умолчанию:
"Foxit Reader.exe" PdfFile /p

Напечатать PDF файл на принетере PrinterName:
"Foxit Reader.exe" PdfFile /t PrinterName
hanio
06.03.2012 07:51Ответ № 21
Вопрос закрыт!
Подсказка:Вы можете добавить любую страничку в Социальные закладки щелкнув по значку соцсетей (в вверху)
Вы не можете отправить комментарий анонимно, пожалуйста войдите или зарегистрируйтесь.