Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

VBA tips - подсказки и решения на VBA


Word позволяет использовать для колонтитулы для оформления документов. При этом доступно различное содержимое для колонтитулов первой страницы раздела, четных и нечетных страниц. Но нет возможности задавать отдельное форматирование для последней страницы раздела. А иногда это бывает очень нужно. Как раз такая ситуация возникла у Владимира:

По ГОСТ18675-79, если текст в разделе заканчивается на нечетной странице, то номер этой страницы должен иметь вид n/n+1, например 7/8, так как на следующей - четной странице текст отсутствует, а новый раздел начинается с нечетной страницы (9). Предыдущие страницы имеют нормальную нумерацию. Можно ли в Ворде реализовать такую нумерацию автоматически?

Задача нетривиальная, но тем не менее решаемая.

Итак, что требуется? Требуется каким-то образом различать последнюю страницу раздела. Если она четная, то выводить обычный номер страницы, а если нечетная — выводить дробный номер. Понятно, что эту задачу, если и можно решить, то только с помощью полей: нужно составить такое поле, которое бы проверяло нечетность страницы и ее положение в разделе.

Как определить, что данная страница нечетная? Очень просто, с помощью поля { =MOD({ PAGE };2) }.

Как определить номер страницы, которой заканчивается раздел? Здесь без макросов не обойтись. Допустим, мы определили номер страницы документа, последней в конкретном разделе, но как передать значение из макроса в поле? Нужен посредник. В качестве такого посредника я использовал переменные документа, значение которых можно прочитать с помощью поля { DOCVARIABLE <имя_переменной> }. При этом нужно еще и различать номер раздела, в который это поле вставлено, т.е. в имени переменной должно быть значение поля { DOCVARIABLE <имя_переменной> }. Таким образом, поле для получения значения переменной, содержащей имя раздела я составил таким образом: {=INT({ DOCVARIABLE { QUOTE Sec{ SECTION }PageCount } }) } и переменная, содержащая, скажем, номер страницы, которой заканчивается третий раздел, будет иметь имя Sec3PageCount.

Таковы предпосылки.

Код макроса, определяющего номер последней страницы для каждого раздела и записывает их в переменные документа:

1 Sub GOSTNumbering() 2 On Error Resume Next 3 Dim oSec As Section 'Переменная для перечисления разделов 4 Dim nPagesCountEndSec As Long 'Количество страниц, заполненных текстом, до конца раздела 5 6 For Each oSec In ThisDocument.Sections 7 'Количество страниц до конца раздела 8 nPagesCountEndSec = oSec.Range.Information(wdActiveEndAdjustedPageNumber) 9 'Добавляем переменную в документ 10 ActiveDocument.Variables.Add "Sec" & oSec.Index & "PageCount", nPagesCountEndSec 11 If Err.Number = 5903 Then 'Если такая переменная в документе уже есть 12 'Обновляем значение переменной 13 ThisDocument.Variables("Sec" & oSec.Index & "PageCount").Value = nPagesCountEndSec 14 'Очищаем ошибку 15 Err.Clear 16 End If 17 Next 18 19 'Обновляем поля в документе 20 ThisDocument.Fields.Update 21 End Sub

После выполнения макроса нужно добавить поле в колонтитул страниц, которое будет выводить номер в нужном формате. Весь код поля выглядит так:

{ IF {=(({ =MOD({ PAGE };2) }<>0)*({PAGE}={=INT({ DOCVARIABLE { QUOTE Sec{ SECTION }PageCount } }) })*({ PAGE }<{ NUMPAGES }) )} = 1 { QUOTE { PAGE }/{ =SUM({ PAGE };1) } } { PAGE } }

В этом поле условие для оператора If составлено из двух условий: первое проверяет нечетность страницы, а второе — что номер страницы равен числу хранящемуся в переменной документа для данного раздела. Эти условия объединены с помощью оператора умножения *, выполняющего роль логической операции And.

Если в документе нужно различать колонтитулы четных и нечетных страниц, то код поля упростится, если его разместить только в колонтитуле нечетных страниц:

{ IF {PAGE}={=INT({ DOCVARIABLE { QUOTE Sec{ SECTION }PageCount } }) } { QUOTE { PAGE }/{ =SUM({ PAGE };1) } } { PAGE } }

Файл с примером, можно скачать по этой ссылке


В избранное