|
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.
|
|