Nickolay.info. Обучение. 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

Увы, быстро встала дурацкая проблема, связанная с тем, что принтер правильно накапливает задания в очереди, но печатает их только после выхода из макроса. Пришлось в этот же убитый зря час сделать другой вариант, который печатает сначала нечетные страницы, а потом четные. Пачка бумаги при этом переворачивается один раз, листы не перекладываются, а логика процедуры, конечно же, несколько меняется:

 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.

Рейтинг@Mail.ru
вверх гостевая; E-mail