Какой самый быстрый способ определить, занимает ли таблица две страницы? - PullRequest
1 голос
/ 20 января 2020

Первоначальная проблема, которая привела меня к изучению VBA, заключается в следующем:

У вас есть таблица длиной до 10 000 строк (несколько сотен страниц) в документе Word. Таблица имеет заголовок в виде абзаца над первой строкой. Этот заголовок оформлен так, что он ссылается на оглавление (Style = "Caption"). Таблица должна быть разбита на последнюю строку на каждой странице, а заголовок должен быть вставлен перед новой таблицей, но в другом стиле, который не связан с оглавлением (Style = "Caption Cont").

Первая страница будет выглядеть следующим образом: linked to the ToC

Вторая страница будет выглядеть следующим образом: not linked to ToC

Мое первое решение было относительно хаккейным и совсем не элегантным. Мне удалось собрать следующее решение, которое работает довольно хорошо. Однако первоначальный процесс определения номера строки, при которой таблица пересекает страницы, довольно медленный из-за использования Range.Information. Мне интересно, есть ли более быстрый способ определить нижний ряд на странице.

Помещение документа в wdNormalView сбрасывает около секунды на страницу, даже с Application.ScreenUpdating = False ...

Программа требует, чтобы курсор находился где-то внутри таблицы, что нормально а не функциональность, которую я буду sh удалять.

В настоящее время он обрабатывает около 120 страниц в минуту, причем большая часть времени тратится на определение строки, на которую нужно разделить (т. е. splitNum). Я уверен, что это может быть намного быстрее с другим методом определения splitNum.

Я НЕ МОГУ ДОБАВИТЬ ДОПОЛНИТЕЛЬНУЮ СТРОКУ В ТАБЛИЦУ ДЛЯ ЦЕЛЕЙ ИСПОЛЬЗОВАНИЯ «ПОВТОРНЫЕ СТРОКИ ЗАГОЛОВОК». Это будет нарушать правила, которые применяются в моей отрасли, и несоответствующий документ может иметь огромное значение для компании и будущего бизнеса

Код:

Sub tblSplit()

Dim timeCheck As Double

Application.ScreenUpdating = False
Application.ActiveWindow.View = wdNormalView

timeCheck = Time

On Error GoTo ErrH

Dim crossRef As Range, delRange As Range, tblR As Range, newTbl As Range
Dim tblNumField As Range, tblNum As String

Set tblNumField = Selection.Tables(1).Range
tblNumField.MoveStart wdParagraph, -1
tblNum = tblNumField.Words(2)


Set crossRef = Selection.Tables(1).Range
Set thisTbl = Selection.Tables(1).Rows(1).Range
Set tblR = Selection.Tables(1).Range

Вставить перекрестную ссылку к заголовку со стилем «Caption Cont»

crossRef.Move wdCharacter, -2
crossRef.InsertCrossReference ReferenceType:="Table", ReferenceKind:= _
        wdOnlyCaptionText, ReferenceItem:=tblNum, InsertAsHyperlink:=True, _
        IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" "
crossRef.Text = vbCr & " (Cont.)" & vbTab


crossRef.MoveStart wdCharacter, 1
crossRef.Style = "Caption Cont."
crossRef.Collapse wdCollapseStart

crossRef.InsertCrossReference ReferenceType:="Table", ReferenceKind:= _
        wdOnlyLabelAndNumber, ReferenceItem:=tblNum, InsertAsHyperlink:=True, _
        IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" "
crossRef.MoveEnd wdParagraph, 1

Удалить дублирующийся заголовок

Set delRange = crossRef.Duplicate

crossRef.MoveEnd wdParagraph, 1
crossRef.Copy
delRange.Text = vbNullString

Найти строку, в которой таблица занимает две страницы

Dim splitNum As Long, n As Long, i As Long, pageNum As Long
pageNum = tblR.Rows(1).Range.Information(wdActiveEndAdjustedPageNumber)
i = 15
    Do
       If tblR.Rows(i).Next.Range.Information(wdActiveEndAdjustedPageNumber) <> pageNum Then
            splitNum = i
            Exit Do

        End If
        i = i + 1
    Loop Until i = 100 'arbitrary cap to prevent infinite loop

n = 1

Разделение и форматирование

Do
    DoEvents


    'Split and format
    tblR.Tables(n).Split (splitNum)
    tblR.Tables(n).Rows.Last.Borders(wdBorderBottom).LineStyle = wdLineStyleSingle

    'Paste the stuff
    Set newTbl = tblR.Tables(n + 1).Range
    newTbl.Move wdParagraph, -2
    newTbl.Paste
    newTbl.MoveEnd wdParagraph, 1
    'Clear excess
    newTbl.Paragraphs.Last.Range.Text = vbNullString

    'Next
    n = n + 1
Loop Until tblR.Tables(n).Rows.Count < splitNum

Восстановление состояния, времени отчета, безопасного выхода и установка обработчика ошибок для отладки

Application.ActiveWindow.View = wdPrintView
Application.ScreenUpdating = True
MsgBox "Pages completed: " & n & vbCr & _
    "Time (sec): " & DateDiff("s", timeCheck, Time) & vbCr & _
    "Seconds per page: " & CDbl(DateDiff("s", timeCheck, Time)) / CDbl(n) & vbCr & _
    "Pages per minute: " & n / DateDiff("s", timeCheck, Time) * 60


Exit Sub

ErrH:
    Application.ScreenUpdating = True
    Err.Raise Err.Number
    Stop

End Sub

Ответы [ 3 ]

1 голос
/ 20 января 2020

Вот обходной путь, который создает впечатление, что абзац отделен от таблицы, но это действительно первая строка. Я создал таблицу данных с несколькими сотнями строк, а затем вставил новую строку в верхней части таблицы. Абзац переходит в этот пустой ряд вверху. Предполагая, что в остальной части таблицы включены границы, отключите верхнюю, левую и правую границы только для первой строки. Затем включите «повторить строку заголовка». Когда все готово, это выглядит так:

enter image description here

, а затем вторая страница:

enter image description here

0 голосов
/ 21 января 2020

Основная проблема, с которой вы столкнетесь при использовании любого метода разделения таблиц, заключается в том, что он не учитывает тот факт, что Word использует активный драйвер принтера для оптимизации макета страницы.

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

Что касается ваших махинаций в стиле 'Caption' / 'Caption Cont', то все это совершенно не нужно, если вы создаете полный -с строкой для заголовка вверху таблицы и пометить как первую, так и вторую строки как строки заголовка таблицы. В оглавлении появится только запись в верхней части таблицы. Код не требуется.

0 голосов
/ 20 января 2020

Это можно сделать намного проще, вставив копию заголовка таблицы в строку в верхней части второй части разделенной таблицы.

  1. Разделить таблицу в конце первой страницы, как вы уже делаете. Остальные действия теперь сосредоточены на второй части таблицы.
  2. Для второй части таблицы вставьте одну строку в верхней части таблицы.
  3. Сделайте новую единственную строку повторяющимся заголовком таблицы.
  4. Вставьте копию заголовок таблицы в строке вверху второй части таблицы.

Это обеспечит эффект, которого вы пытаетесь достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...