Форум программистов
 
Регистрация на форуме тут, о проблемах пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль

Купить рекламу на форуме 15-35 тыс рублей в месяц

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Word
Регистрация

Восстановить пароль
Повторная активизация e-mail


Оплата за обучение в Kata Academy только после твоего трудоустройства в IT, начни карьеру Middle Java-разработчика


Ответ
 
Опции темы Поиск в этой теме
Старый 11.10.2009, 17:09   #1
akokin
Пользователь
 
Регистрация: 02.08.2008
Сообщений: 94
По умолчанию Вставка особой нумерации на нечетные страницы с разрывом страницы

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

Код:
Код:
Sub insNumPageOdd2()
Dim hf As HeaderFooter
Dim hfRange As Range
Dim i As Long
'On Error Resume Next
With ActiveDocument
   .ActiveWindow.View.ShowFieldCodes = True
   .Sections(1).PageSetup.DifferentFirstPageHeaderFooter = True     
.PageSetup.OddAndEvenPagesHeaderFooter = True 
   For i = .Sections.count To 1 Step -1
      For Each hf In .Sections(1).Footers
         hf.Range.Delete
      Next hf
      .Sections(i).Footers(wdHeaderFooterPrimary).PageNumbers.Add PageNumberAlignment:=wdAlignPageNumberOutside
      Set hf = .Sections(i).Footers(wdHeaderFooterEvenPages) 
      hf.LinkToPrevious = False
      
      'если страница нечетная
         If Not hf.Exists = False Then
            .Sections(i).Footers(wdHeaderFooterPrimary).Range.Select
            With Selection
               .Fields.Add Range:=Selection.Range, Type:=wdFieldPage, PreserveFormatting:=False
               .MoveEnd wdCharacter, 3
               .TypeText "/"
               .Fields.Add Range:=Selection.Range, Type:=wdFieldExpression, PreserveFormatting:=False
               .MoveRight wdCharacter, 4
               .Fields.Add Range:=Selection.Range, Type:=wdFieldPage, PreserveFormatting:=False
               .TypeText "+1"
            End With
         End If
   Next i
   .Range(0, 0).Select
   .ActiveWindow.View.Type = wdPrintView
   .ActiveWindow.View.Zoom.PageFit = wdPageFitBestFit
   .ActiveWindow.View.ShowFieldCodes = False
End With
End Sub
Вложения
Тип файла: doc особая нумерация для нечетных страниц.doc (64.5 Кб, 23 просмотров)
akokin вне форума Ответить с цитированием
Старый 11.10.2009, 17:42   #2
БуреВестник
Пользователь
 
Регистрация: 19.09.2009
Сообщений: 69
По умолчанию

Здесь сама концепция неправильная - в одном разделе не могут быть разные колонтитулы чётных и нечётных страниц: все колонтитулы чётных страниц одинаковы, все колонтитулы нечётных страниц - одинаковые. Исключение составляет только первая страница раздела, на которой может быть уникальный колонтитул.
БуреВестник вне форума Ответить с цитированием
Старый 11.10.2009, 18:55   #3
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,835
По умолчанию

Я тоже задумался над этой проблемой. Ее можно было бы решить и без макросов, только полями, но все упирается в проблему определения количества страниц в разделе. А макросом, конечно, проще. Чуть позже решу, ближе к полуночи
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума Ответить с цитированием
Старый 12.10.2009, 16:00   #4
akokin
Пользователь
 
Регистрация: 02.08.2008
Сообщений: 94
По умолчанию

Александр, спасибо. Буду ждать, ибо вопрос и меня зацепил так, что вчера полдня убил на раздумья...
akokin вне форума Ответить с цитированием
Старый 12.10.2009, 16:39   #5
БуреВестник
Пользователь
 
Регистрация: 19.09.2009
Сообщений: 69
По умолчанию

Я даже не читая кода (плохо понимаю, что там), уже нашёл 3 ошибки:
  1. Ты путаешь Разрыв страницы с Разрывом раздела. Здесь речь не о Разрыве страницы, а о Разрыве Раздела.
  2. И зачем ты на пустых листах вставляешь Разрывы разделов? Я так понимаю, потому что ты хочешь вставить пустую страницу, т.к. речь идёт о двусторонней печати. Для вставки пустых страниц при двусторонней печати надо использовать Разрыв раздела с чётной страницы или Разрыв раздела с нечётной страницы.
  3. Ничего у вас не получится: если вы вставите какой-то особый номер страницы на одной нечётной странице, то он будет такой же на всех остальных нечётных страницах, а надо, как я понимаю, чтобы особый номер был только на одной нечётной странице - последней в разделе.

Последний раз редактировалось БуреВестник; 12.10.2009 в 16:46.
БуреВестник вне форума Ответить с цитированием
Старый 12.10.2009, 16:47   #6
akokin
Пользователь
 
Регистрация: 02.08.2008
Сообщений: 94
По умолчанию

Цитата:
Сообщение от БуреВестник Посмотреть сообщение
Я даже не читая кода (плохо понимаю, что там), уже нашёл 3 ошибки:[*]Ты путаешь Разрыв страницы с Разрывом раздела. Здесь речь не о Разрыве страницы, а о Разрыве Раздела.
Не путаю. Я разрываю страницу (прерываю один раздел) и вставляю новый раздел. Возможно, путаница в терминологиии.
Цитата:
[*]И зачем ты на пустых листах вставляешь Разрывы разделов? Я так понимаю, потому что ты хочешь вставить пустую страницу, т.к. речь идёт о двусторонней печати. Для вставки пустых страниц при двусторонней печати надо использовать Разрыв раздела с чётной страницы или Разрыв раздела с нечётной страницы.
Это сделано по смыслу вопроса. Страница четная после нечетной пустая. Как будет печатать автор вопроса меня не волнует, мне важно было сделать так, чтобы максимально приблизиться к результату. Но ты прав, я просто не обратил на это внимания по привычке...
Цитата:
[*]Ничего у вас не получится: если вы вставите какой-то особый номер страницы на одной нечётной странице, то будет такой же на всех остальных нечётных страницах, а надо, как я понимаю, чтобы особый номер был только на одной нечётной странице - последней в разделе.
Правильно понимаешь. Но не стоит быть столь категоричным. Практика покажет...
akokin вне форума Ответить с цитированием
Старый 12.10.2009, 17:59   #7
БуреВестник
Пользователь
 
Регистрация: 19.09.2009
Сообщений: 69
По умолчанию

Единственно, что можно сделать, но неизвестно как - это создать новое свойство DifferentLastPageHeaderFooter объекта PageSetup. А затем в диалоговое окно Параметры страницы добавить галочку: различать колонтитулы последней страницы.
БуреВестник вне форума Ответить с цитированием
Старый 13.10.2009, 02:42   #8
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,835
По умолчанию Задачка, однако

Да, задачка!
Конечно, добавить отдельное свойство документа это нереально. А вот поработать с колонтитулами и полями — очень даже можно.
Тут у меня получилось кое-что.
Рассуждал я так.
  1. Что нам нужно? Нужно, чтобы на нечетной странице, если она является последней в разделе, стоял через черту еще и номер следующей страницы.
  2. Что мы можем узнать стандартными средствами (полями)? Номер текущей страницы, номер раздела, количество страниц в документе. Не густо.
  3. Как получить разное содержимое в колонтитулах разных разделов? Двумя путями: полями и, собственно, сделав колонтитулы разными.
Теперь начинаем думать
Поскольку речь идет о нумерации страниц, то колонтитулы скорее всего одинаковые во всех разделах. Следовательно, нужно оперировать полями.
В своем первом посте этой темы я говорил, что все упирается в определение того, является ли данная страница последней в разделе. Или, перефразируя, равен ли номер данной страницы номеру страницы, которой заканчивается раздел?
Как можно получить номер страницы, которой заканчивается раздел? Макросом.
Как полученное значение использовать в поле? Сохранить его либо в закладку, либо в переменную документа, т.к. значение того и другого можно подставить в поле. Я решил использовать переменные документа.
Вот этот макрос:
Код:
Sub StupidNumbering()
'Такое название потому, что я считаю глупым следовать стандартам,
'разработанным бог знает когда и не несущим практической пользы
  On Error Resume Next
  Dim oSec As Section 'Переменная для перечисления разделов
  Dim nPagesCountEndSec As Long 'Количество страниц от начала документа до конца раздела
  Dim ovar As Variable 'Переменная для перечисления переменных документа
  
  For Each oSec In ActiveDocument.Sections
    'Количество страниц до конца раздела
    nPagesCountEndSec = ActiveDocument.Range(0, oSec.Range.End).ComputeStatistics(wdStatisticPages) - IIf(oSec.Index = ActiveDocument.Sections.Count, 0, 2)
    'Добавляем переменную в документ
    ActiveDocument.Variables.Add "Sec" & oSec.Index & "PageCount", nPagesCountEndSec
    If Err.Number = 5903 Then 'Если такая переменная в документе уже есть
      'Обновляем значение переменной
      ActiveDocument.Variables("Sec" & oSec.Index & "PageCount").Value = nPagesCountEndSec
      'Очищаем ошибку
      Err.Clear
    End If
  Next
  'Обновляем поля в документе
  ActiveDocument.Fields.Update
  'Это для контроля имен переменных и их значений. На
  'функциональность это не влияет.
  For Each ovar In ActiveDocument.Variables
    Debug.Print ovar.Name & vbTab & ovar.Value
  Next
End Sub
Макрос определяем количество страниц до конца каждого раздела в документе и записывает это число в соответствующую переменную документа, имя которой имеет вид Sec<Номер_раздела>PageCount.
Далее, это имя переменной нужно подставить в поле.
Заглянув куда надо и потратив около часа времени, я пришел к такой вот формуле:

Что в этой формуле? Оператор IF, проверяющий логическое выражение: если страница нечетная (остаток от деления на 2 не равен нулю) и номер страницы равен числу, хранящемуся в соответствующей переменной документа, то выводим номер страницы, а через черту номер следующей. Если же условие не выполняется, т.е. страница четная или не последняя в разделе, то просто показываем номер страницы.
Остальные подробности можно узнать в приложении к этому посту
Лучше день потерять — потом за пять минут долететь!©

Последний раз редактировалось viter.alex; 13.10.2009 в 05:43. Причина: Удалил вложение. Дал ссылку на исправленый вариант.
viter.alex вне форума Ответить с цитированием
Старый 13.10.2009, 05:03   #9
БуреВестник
Пользователь
 
Регистрация: 19.09.2009
Сообщений: 69
По умолчанию

viter.alex
буду теперь знать, что в одном разделе можно сделать разные колонтитулы. Только для этого надо быть программистом или делать такое надо периодически.
Хотя сейчас подумал, я не прав, можно и простому человеку делать такую нумерацию, даже не вникая в коды макроса и поля. Просто надо вставить код поля во все колонтитулы документа, а в VBA добавить код макроса. Вывести кнопку на панель инструментов и каждый сможет сделать нумерацию согласно ГОСТу от 79 года. Единственно надо не забыть применить макрос перед печатью, а то будет много брака.
Кстати во вложенном файле всё нормально только в 1 разделе.

Последний раз редактировалось БуреВестник; 13.10.2009 в 05:33.
БуреВестник вне форума Ответить с цитированием
Старый 13.10.2009, 05:07   #10
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,835
По умолчанию Ошибка вышла.

Приведенный макрос считает не совсем то, что нам нужно. Нам же нужно получить номер страницы, которая последняя в разделе и к тому же содержит текст. А макрос это не учитывает. Ну да это легко исправить. Вместо строки
Код:
nPagesCountEndSec = ActiveDocument.Range(0, oSec.Range.End).ComputeStatistics(wdStatisticPages) - IIf(oSec.Index = ActiveDocument.Sections.Count, 0, 2)
которая мне не нравилась с самого начала своей растянутостью, нужно записать более компактный код:
Код:
nPagesCountEndSec = oSec.Range.Information(wdActiveEndPageNumber)
Вроде бы все. Колонтитулы могут быть как одинаковые для четных и нечетных страниц, так и разные. Во втором случае проверять нечетность страниц не нужно, а код поля поместить только в колонтитул нечетной.

2 БуреВестник. А я уже исправился. Файл перезаливать не буду, думаю макрос исправите сами
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума Ответить с цитированием
Ответ
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Статус страницы! nikolai_P PHP 6 17.09.2009 09:03
Страницы Grek55 Софт 2 06.05.2009 10:34
Динамическое изменение URL страницы в JavaScript без перезагрузки страницы ilusha JavaScript, Ajax 7 25.02.2009 09:59
Как сделать разрыв страницы печати по условию и узнать номер страницы Leanna Microsoft Office Excel 2 21.01.2008 06:59
разметка страницы. Gambler Microsoft Office Word 0 29.10.2006 21:24

Реклама для незарегистрированных, регистрация на форуме