Страница 2 из 3

Добавлено: Чт апр 15, 2010 23:47
Igor_A.
Batya
а вы сами видели, как при этом идет печать?
когда надо выровнять по центру или заполнить страницу, или хотя бы распечатать as is, irfan печатает полную фигню, с выравниванием "вверх-вправо" или вообще непонятно как.

Добавлено: Пт апр 16, 2010 12:28
Batya
Видел :(
Поэтому и написал "например".
Помню, что хорошо печатал ACDSee, но сейчас он у меня не установлен, и не знаю, работает ли он с печатью через командную строку.
Под рукой оказался XnView. В принципе неплохо печатает группу файлов, правда через интнрфейс.

Добавлено: Сб апр 17, 2010 20:46
Igor_A.
промежуточное решение всё-таки нашел.
использовать плагин imagine не в режиме плагина, а в режима программы, через экзешник, для групповой печати. складываем все графические файлы в одну папку (как пример), запускаем Imagine.exe, в открытом окне находим папку, Ctrl+A, Ctrl+P, появляется диалог печати, в котором все помеченные по Ctrl+A файлы "склеиваются" в один многостраничный документ, который улетает на печать всеми страницами сразу. причем выбрав вариант форматирования для первого листа, это наследование форматирования будет передано на все следующие листы при печати автоматически. почти то что надо, но через какой-нибудь скрипт (как для док-файлов) все-таки было бы удобнее.

Добавлено: Пн фев 10, 2014 00:26
Cobblestone-TLT
Здравствуйте! Есть ли возможность с помощью скрипта заставить печатать Word только указанную страницу выделенных в панели документов.
Нужно для пакетной печати двухстраничных актов на принтере, не поддерживающем двухстороннюю печать. Идея такая, сортируешь файлы (скажем по имени), жмешь кнопку настроенную параметром на печать 1-й страницы, скрипт последовательно открывает все файлы в Word и печатает указанную страницу (или напрямую отправляет на печать, минуя запуск самого Word'а, не знаю просто как именно это реализовано, но страницей выше рассматривалась уже пакетная печать документов Word), затем перекладываешь бумагу в принтере из "выходного" лотка во "входной", инвертируешь порядок сортировки выделенных файлов и жмешь кнопку для печати 2-й страницы.
Юмористов от советов типа "купи себе нормальный принтер" прошу воздержаться :) (принтер, точнее МФУ, и так "нормальное", печатает даже А3, но двухсторонней печати нет и не будет :( ). "Сливать" файлы перед печатью в один и печатать по очереди четные и нечетные страницы - тоже выход, но во-первых неудобно, во-вторых не всегда возможно (разные колонтитулы у файлов, бывает страницы пронумерованы и т.д.).
Заставить пакетно печатать документы Word в принципе, как я понял, возможно. Прошу знатоков переделать имеющийся скрипт таким образом, чтобы можно было явно задать печатаемую страницу.
Спасибо!

Добавлено: Ср фев 12, 2014 05:55
Flasher
Cobblestone-TLT
Задаём диапазоны так же как и в диалоге печати:
objW.PrintOut 1,,,,,,,Copies,"1,2,6-8,100-115"
Можно добавить параметр без проблем. О других опциях метода можно почитать на msdn.

Добавлено: Ср фев 12, 2014 10:10
Cobblestone-TLT
Flasher
Сделал две копии скрипта Print1.vbs и Print2.vbs (для печати первой и второй страницы соответственно), так же создал две кнопки по предложенному на первой странице образцу, поправил все пути в кнопках на свои, в параметрах изменил <<%L>> на {{%L}} (решил, что так будет правильно, раз в самом скрипте MultiRun.vbs начало и конец списка обозначены именно этими символами, но... ничего не происходит, точнее вываливается ошибка сценария MultiRun.vbs d строке 44, символ 4 (" WSH.Run L, 7, (Mode(1) = 0)" - эта строка).

Что делаю не так самому разобраться не получается. Нет ли возможности выложить готовый вариант кнопки под конкретную задачу (разумеется пути к MultiRun.vbs и Print(1/2).vbs поправлю сам :) )

Posted after 12 minutes:

p.s. с работой кнопки разобрался! Потребовалось взять пути к скриптам и {{%L}} в параметрах в кавычки.

Теперь ситуация следующая: Печатаются все страницы документа, не смотря на то, что отвечающая за это строка в файле Print1.vbs имеет вид

Код: Выделить всё

objW.PrintOut 1,,,,,,,Copies,"1"
Posted after 14 minutes:

По ссылке что-то более или менее "полезное" для себя обнаружил вот это:
This example prints the first three pages of the document in the active window.

ActiveDocument.ActiveWindow.PrintOut _
Range:=wdPrintFromTo, From:="1", To:="3"
Но как подобную конструкцию внедрить в скрипт не понимаю, а при добавлении через запятую в кавычках диапазон печати в строке

Код: Выделить всё

objW.PrintOut 1,,,,,,,Copies
- у меня почему-то не срабатывает :(

Добавлено: Ср фев 12, 2014 17:17
Lev
а так?

Код: Выделить всё

objW.PrintOut 1, , 4, , , , , Copies, "1"
'objW.PrintOut 1, , 4, , , , , Copies, "2"

Добавлено: Ср фев 12, 2014 18:18
Cobblestone-TLT
Lev
Да! То, что нужно! Огромное спасибо!

Добавлено: Ср фев 12, 2014 18:44
Flasher
Cobblestone-TLT
А это, чтобы 5-ым параметром задавать, дабы не плодить копии скрипта:
'Номера страниц
If WScript.Arguments.Count > 4 Then Pages = WScript.Arguments(4)

'Печатаем в фоне
objW.PrintOut 1,,4,,,,,Copies,Pages
т.е. параметры кнопки, например, такие будут: {{%L}} "" 1251 "" 1

Добавлено: Ср фев 12, 2014 19:26
Cobblestone-TLT
Flasher
Странно но так не работает

Строка параметров кнопки:

Код: Выделить всё

"{{%L}}" "" "" "" 1
Какая-то обработка проходит, что-то в панели задач мигает, но печатине происходит.

Posted after 9 minutes:

p.s. End If после проверки наличия 4-го параметра поставил уже сам, но все ровно ничего не печатается

Posted after 19 minutes:

Опытным путем выяснилось, что при наличии в строке параментров чего-то кроме пути списка все перестает работать.

Например кнопка со строкой параметров (старая версия скрипта, без проверки 5-го параметра) - печатает.
Со строками параметров

Код: Выделить всё

"{{%L}} "" "" 3
или

Код: Выделить всё

"{{%L}} "" 1251
или

Код: Выделить всё

"{{%L}} "" "" ""
- не печатает

Добавлено: Ср фев 12, 2014 19:34
Flasher
Cobblestone-TLT писал(а):p.s. End If после проверки наличия 4-го параметра поставил уже сам, но все ровно ничего не печатается
Это не нужно.
Cobblestone-TLT писал(а):не печатает
А в очередь что-то складывается?

Добавлено: Ср фев 12, 2014 19:39
Cobblestone-TLT
Flasher
Нет, очередь пустая

Добавлено: Сб фев 15, 2014 16:37
Batya
Нда... "Давно не брал я шашки в руки." (с) :)

Код: Выделить всё

'==========================================================================
' Печать нескольких документов с помощью MS Word
'
' Параметры:
' {Файл-список} [{Принтер} [{Кодовая страница} [{Количество копий} [{Номер(а) страниц}]]]]
' При пустом параметре (указывается "") используются значения по умолчанию
'
' Пример параметров при вызове из TC:
' %WL \\Host\HostPrinter 1251 "" "1"
'
' Автор - Batya
'==========================================================================
Option Explicit
Dim Docs
'================= Изменяемые параметры ===================================
Const TimeLimit = 30      'Время ожидания окончания печати в сек.
Const Margin    = 1.5     'Поля в см
'Список расширений документов с наличием форматирования
Docs = Array("rtf","doc","docx")
'==========================================================================
Dim FSO, WSH, objW, Mess, ListF, List, Printer, CodePage, Copies, Pages, F
'Дюймы, выраженные в см., для вычисления полей
Const Inch = 2.538
SetMess
Set WSH = CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
'Включаем режим ручной обработки ошибок
On Error Resume Next
CheckParam                                         :CheckErr 1,0
'Создаем объект Word
Set objW = CreateObject("Word.Application")        :CheckErr 1,1
'Если задан принтер
If Printer <> "" Then objW.ActivePrinter = Printer :CheckErr 1,1 : WScript.Sleep 500
'Цикл по файлам
For Each F In List
  If Trim(F) <> "" Then
    F = GetPath(F)
    'Обрабатываем только файлы
    If FSO.FileExists(F) Then Print(F)             :CheckErr 0,1
  End If
Next
'Отключаем режим ручной обработки ошибок
On Error Goto 0
'Закрываем Word
objW.Quit 0
'Сообщение об окончании работы
MessBox Mess(99), 3
'Выход
Quit 0

'Открытие и печать документа
Sub Print(pFile)
  Dim Doc, MarginPt, StartTime, WdPrintOutRange
  'Открываем документ
  Set Doc = objW.Documents.Open(pFile,False,True,False,,,,,,,CodePage)
  'Задаем поля для документов без оформления
  If InStr(1, "\" & Join(Docs, "\") & "\", "\" & FSO.GetExtensionName(pFile) & "\", 1) > 0 Then
    'Поля в пунктах (1/72 дюйма)
    MarginPt = Margin/Inch * 72
    With Doc.PageSetup
      .LeftMargin   = MarginPt
      .RightMargin  = MarginPt
      .TopMargin    = MarginPt
      .BottomMargin = MarginPt
    End With
  End If
  If Pages <> "" Then
    WdPrintOutRange = 4
  Else
    WdPrintOutRange = 0
  End If
  'Печатаем
  objW.PrintOut True,,WdPrintOutRange,,,,,Copies,Pages
  'Включаем таймер ожидания окончания печати
  StartTime = Timer
  'Ждем, пока закончится печать
  Do Until objW.BackgroundPrintingStatus = 0
    'Если ожидаем уже больше заданного лимита, выходим с ошибкой
    If (Timer - StartTime) > TimeLimit Then Err.Raise vbObjectError + 4, Mess(0), Mess(4)
    'Пауза 0.1 сек.
    WScript.Sleep 100
  Loop
  'Закрываем документ
  Doc.Close(False)
  Set Doc = Nothing
End Sub

'Проверка параметров
Sub CheckParam
  Dim lArg
  Set lArg = WScript.Arguments
  If lArg.Count = 0 Then Err.Raise vbObjectError + 1, Mess(0), Mess(1)
  'Файл-список
  ListF = GetPath(lArg(0))
  If Not FSO.FileExists(ListF) Then Err.Raise vbObjectError + 2, Mess(0), Mess(2)
  'Массив файлов\папок
  List = Split(FSO.OpenTextFile(ListF, 1, False, -1).ReadAll, vbNewLine)
  'Принтер
  Printer  = "" : If lArg.Count > 1 Then Printer  = lArg(1)
  'Кодовая страница
  CodePage = "" : If lArg.Count > 2 Then CodePage = lArg(2)
  'Количество копий
  Copies   = 1  : If lArg.Count > 3 Then Copies   = lArg(3)
  If Copies = "" Then Copies = 1
  If Not IsNumeric(Copies) Then Err.Raise vbObjectError + 3, Mess(0), Mess(3)
  'Номер(а) страниц
  Pages = ""    : If lArg.Count > 4 Then Pages    = lArg(4)
End Sub

'Сообщение
Function MessBox(pMess, pMode)
  Dim lIcon
  Select Case pMode
    Case 1 lIcon = vbCritical    + vbOKOnly
    Case 2 lIcon = vbExclamation + vbOKOnly
    Case 3 lIcon = vbInformation + vbOKOnly
    Case 4 lIcon = vbExclamation + vbOKCancel
  End Select
  MessBox = MsgBox(pMess, lIcon, Mess(0))
End Function

Function GetPath(pPath)
  GetPath = FSO.GetAbsolutePathName(WSH.ExpandEnvironmentStrings(pPath))
End Function

'Проверка ошибок
Sub CheckErr(pMode1, pMode2)
  Dim Flag
  If Err.Number <> 0 Then
    If pMode1 = 1 Then 'Безусловный выход
      'Выводим сообщение
      MessBox Mess(-1) & Err.Description, 1
      Flag = vbOK
    Else 'Выход по запросу
      'Выводим сообщение
      Flag = MessBox(Mess(-1) & Err.Description & Mess(-2), 4)
    End If
    If Flag = vbOK Then
      If pMode2 = 1 Then
        If IsObject(Doc)  Then Doc.Close(False)
        If IsObject(objW) Then objW.Quit
      End If
      Quit Err.Number
    End If
  End If
End Sub

'Задание массива сообщений
Sub SetMess
  Set Mess = CreateObject("Scripting.Dictionary")
  With Mess
    .Add -1, "Возникла ошибка:" & vbNewLine & vbNewLine
    .Add -2, vbNewLine & vbNewLine & "Прервать работу скрипта?"
    .Add  0, "Печать документов"
    .Add  1, "Не указаны входные параметры!"
    .Add  2, "Файл-список не существует!"
    .Add  3, "Указано некорректное количество копий!"
    .Add  4, "Превышено время ожидания окончания печати."
    .Add 99, "Операция завершена."
  End With
End Sub

'Выход
Sub Quit(pQuitCode)
  Set Mess = Nothing
  Set objW = Nothing
  Set WSH  = Nothing
  Set FSO  = Nothing
  WScript.Quit pQuitCode
End Sub
Тестировал не очень много - бумаги жалко. Так что, сильно не пинайте, если что :)

P.S. Скрипт получился не маленьким, т.к. приоритет отдаю читабельности кода, нежели компактности.

Добавлено: Сб фев 15, 2014 22:23
Flasher
Batya писал(а):приоритет отдаю читабельности кода, нежели компактности
Тут компактность

Код: Выделить всё

If Printer <> "" Then objW.ActivePrinter = Printer :CheckErr 1,1 : WScript.Sleep 500
а тут ... :?:

Код: Выделить всё

  If Pages <> "" Then 
    WdPrintOutRange = 4 
  Else 
    WdPrintOutRange = 0 
  End If
Может, я неправильно понимаю слово "читабельность"?

А c какой целью ты List упрятал в процедуру?

Код: Выделить всё

List = Split(FSO.OpenTextFile(ListF, 1, False, -1).ReadAll, vbNewLine)
For Each F In List 
  If Trim(F) <> "" Then 
    F = GetPath(F) 
    'Обрабатываем только файлы 
    If FSO.FileExists(F) Then Print(F)             :CheckErr 0,1 
  End If 
Next
не лучше заменить на?:

Код: Выделить всё

Set List = FSO.GetFile(ListF).OpenAsTextStream(1, -1) 
Do While Not List.AtEndOfStream 
  F = GetPath(List.ReadLine)
  If FSO.FileExists(F) Then Print(F)             :CheckErr 0,1
Loop : List.Close
Ты вроде любишь память экономить.
Я бы добавил момент, когда печать не прошла, но ошибок не было, как в случае выше.
В шапку таки стоит добавить обязательность параметров.
И как я вижу, ты убрал отправку сообщений админу, что было лишним для "простых смертных".
Кстати, я бы и под другие офисные форматы скрипт допилил, скажем, под Exel/PowerPoint там строчек 10 всего требуется. Не точно по теме топика, но всё же.

И у меня касаемо старого и нового скрипта вопрос. Почему ты пишешь в качестве примера сетевой путь к принтеру? Обычные имена по идее должны работать.

Добавлено: Пн фев 17, 2014 13:38
Batya
Flasher писал(а):Тут компактность

Код: Выделить всё

If Printer <> "" Then objW.ActivePrinter = Printer :CheckErr 1,1 : WScript.Sleep 500
Здесь такой вид строки, потому что вызывается процедура CheckErr - её я вызываю там же, где проверяемый код.
Flasher писал(а):а тут ... :?:

Код: Выделить всё

  If Pages <> "" Then 
    WdPrintOutRange = 4 
  Else 
    WdPrintOutRange = 0 
  End If
Может, я неправильно понимаю слово "читабельность"?
А разве это не читабельно?
Flasher писал(а):А c какой целью ты List упрятал в процедуру?
Потому что, на мой взгляд, это логично - List это глобальный массив файлов, и начитываю я его в процедуре проверки входных параметров.
Flasher писал(а):не лучше заменить на?:
...
Ты вроде любишь память экономить.
Я не вижу большой разницы, т.к. даже с трудом не представляю себе ситуации, когда список документов для печати в Word может быть такого размера, что это будет сказываться на памяти.
Flasher писал(а):Я бы добавил момент, когда печать не прошла, но ошибок не было, как в случае выше.
Не понял. Можно подробнее?
Flasher писал(а):В шапку таки стоит добавить обязательность параметров.
У меня это указывается стандартным способом - с помощью квадратных скобок.
Flasher писал(а):И как я вижу, ты убрал отправку сообщений админу, что было лишним для "простых смертных".
Просто скрипт для единичной печати - это мой служебный скрипт, который я не стал переделывать, а выложил как есть.
В данном же случае, я переписывал скрипт для решения задачи с форума и посчитал, что отправка сообщений админам является лишней. Если это кому-то надо, верну.
Flasher писал(а):Кстати, я бы и под другие офисные форматы скрипт допилил, скажем, под Exel/PowerPoint там строчек 10 всего требуется. Не точно по теме топика, но всё же.
У этих объектов совсем другая объектная модель. Не вижу смысла всё сваливать в одну кучу. Если у тебя есть желание, сделай.
Flasher писал(а):И у меня касаемо старого и нового скрипта вопрос. Почему ты пишешь в качестве примера сетевой путь к принтеру? Обычные имена по идее должны работать.
Может быть. Исходный скрипт писал очень давно и практически не использовал этот параметр. В принципе, пример же НЕ является некорректным?