Pers.narod.ru. Обучение. VBA - делаем буклет на листах A4 |
Оставлю эту заметку на память :-) Мне нужно было напечатать кучу разных буклетов так, чтоб на листе A4 было по 2 страницы, лист оказался заполнен с 2 сторон, а потом можно было сложить книжечку: . На самом деле, в Word подобная возможность есть: меню Файл, Параметры страницы, вкладка Поля, в списке "несколько страниц:" выбрать "Брошюра". Потом Файл, Печать, указать число копий и включить галочку "Двусторонняя печать", чтоб Word ждал, когда мы переложим бумагу. Однако, как я ни перекладывал, приходилось изменять еще и порядок самих листов. А когда этих листов - сотни, не очень удобно. Для начала я захотел понять, какой вообще должен быть порядок страниц:
Этот скрипт просто определяет порядок вывода страниц для двусторонней печати буклетов из Microsoft Word на листе A4, по 2 страницы на лист, с 2 сторон. Сам код тоже весьма прост:
<SCRIPT type="text/javascript"> <!-- function Calc () { var p=parseInt(document.f1.pages.value); if (isNaN(p) || (p<2)) { window.alert ("Укажите число страниц >2"); return false; } document.f1.output.value=""; if (p%4!=0) { p+=(4-p%4); document.f1.output.value+="Число страниц скорректировать до "+p+" пустыми\n"; } var i1=1; var i2=p; document.f1.output.value+="Порядок печати:\n"; var even=1; while (i1<i2) { if (even>0) document.f1.output.value+=""+i2+","+i1+" (перевернуть бумагу) "; else document.f1.output.value+=""+i1+","+i2+"\n"; even=-even; i1++; i2--; } } // --> </SCRIPT>Вызвать его можно так:
<form name="f1"> <table border=0 width=90% align=center> <tr><td> Число страниц:</td><td> <input type=text size=4 maxlength=4 name=pages value=""> <input type=button value="Вывести" onClick="Calc()"> </td></tr><tr><td> Порядок печати:</td><td> <textarea rows=6 cols=60 name="output"></textarea> </td> </tr> </table></form>
Соответствующие команды Word:
Ну а для того, чтоб долго не вводить все эти номера, пришлось переписать процедуру на Visual Basic for Applications, VBA, встроенном во все последние версии офиса. Кстати, вот инструкция, как встроить в Word эту или любую другую процедуру (макрос) на VBA.
Подготовка макроса в Word |
Sub Макрос2() ' ' Макрос2 Макрос ' Макрос записан 05.02.2008 PerS ' End SubПеред строчкой конца процедуры End Sub вставляем следующий код, который и есть наш макрос:
Dim intPages, intPages1, i, NC, i1, i2, n1, n2, Even, R As Integer Dim S As String intPages = ActiveDocument.BuiltInDocumentProperties(wdPropertyPages) If intPages Mod 4 <> 0 Then intPages1 = intPages + (4 - intPages Mod 4) For i = intPages + 1 To intPages1 Selection.GoTo What:=wdGoToPercent, Which:=wdGoToLast, Count:=intPages + 1, Name:="" Selection.InsertBreak Type:=wdPageBreak Next i MsgBox "Число страниц скорректировано до " & intPages1 & " пустыми." Else intPages1 = intPages End If NC = Val(InputBox("Введите число копий:", "Ввод числа копий", "1")) If (NC < 1) Or (NC > 100) Then MsgBox "Число копий должно быть от 1 до 100!" Exit Sub End If i1 = 1 i2 = intPages1 Even = 1 While i1 < i2 If Even > 0 Then n1 = i2: n2 = i1: S = "переверните" Else n1 = i1: n2 = i2: S = "вставьте" End If Application.PrintOut FileName:="", Range:=wdPrintRangeOfPages, Item:= _ wdPrintDocumentContent, Copies:="" & NC, Pages:="" & n1 & "," & n2, PageType:= _ wdPrintAllPages, ManualDuplexPrint:=False, Collate:=True, Background:= _ True, PrintToFile:=False, PrintZoomColumn:=2, PrintZoomRow:=1 i1 = i1 + 1 i2 = i2 - 1 If i1 > i2 Then Exit Sub R = MsgBox("Напечатано: " & n1 & "," & n2 & ". Далее: " & i1 & "," & i2 & _ ". Дождитесь печати, " & S & " бумагу и нажмите подтверждение", vbYesNo, "Печать буклета") If R <> vbYes Then Exit Sub Even = -Even Wend
Увы, быстро встала дурацкая проблема, связанная с тем, что принтер правильно накапливает задания в очереди, но печатает их только после выхода из макроса. Пришлось в этот же убитый зря час сделать другой вариант, который печатает сначала нечетные страницы, а потом четные. Пачка бумаги при этом переворачивается один раз, листы не перекладываются, а логика процедуры, конечно же, несколько меняется:
Dim intPages, intPages1, i, NC, i1, i2, n1, n2, Even, R, K As Integer Dim S As String intPages = ActiveDocument.BuiltInDocumentProperties(wdPropertyPages) If intPages Mod 4 <> 0 Then intPages1 = intPages + (4 - intPages Mod 4) For i = intPages + 1 To intPages1 Selection.GoTo What:=wdGoToPercent, Which:=wdGoToLast, Count:=intPages + 1, Name:="" Selection.InsertBreak Type:=wdPageBreak Next i MsgBox "Число страниц скорректировано до " & intPages1 & " пустыми." Else intPages1 = intPages End If NC = Val(InputBox("Введите число копий:", "Ввод числа копий", "1")) If (NC < 1) Or (NC > 100) Then MsgBox "Число копий должно быть от 1 до 100!" Exit Sub End If Even = Int(Val(InputBox("Введите цифру 1, если печатаем первые стороны, 2- вторые", "Ввод стороны", ""))) If (Even < 1) Or (Even > 2) Then MsgBox "Вводится цифра 1 и или 2!" Exit Sub End If For K = 1 To NC If Even = 1 Then i1 = 1: i2 = intPages1 Else i1 = intPages1 / 2: i2 = i1 + 1 End If For R = 1 To intPages1 / 4 If Even = 1 Then n1 = i2: n2 = i1 Else n1 = i1: n2 = i2 End If Application.PrintOut FileName:="", Range:=wdPrintRangeOfPages, Item:= _ wdPrintDocumentContent, Copies:="1", Pages:="" & n1 & "," & n2, PageType:= _ wdPrintAllPages, ManualDuplexPrint:=False, Background:= _ True, PrintToFile:=False, PrintZoomColumn:=2, PrintZoomRow:=1 If Even = 1 Then i1 = i1 + 2: i2 = i2 - 2 Else i1 = i1 - 2: i2 = i2 + 2 End If Next R Next K MsgBox ("Отправлено на печать")
По той же причине (лень перекладывать листы) пришлось не посылать принтеру число копий, а организовать дополнительный цикл по K для отправки пар страниц по одной. Можно было сделать лучше - например, не вводить повторно число копий, удобней выбирать четную или нечетную стороны и т.д. - но мне хватило и этого. Естественно, встраивание этого кода ничем не отличается от предыдущего.
А здесь эти процедурки приведены лишь как пример автоматизации в Word. Напомню, что на сайте доступны многочисленные скрипты на JavaScript, а в разделе "Обучение" есть еще немного примеров и приложений на VBA.
гостевая; E-mail |