Как изменить отступ после преобразования всех абзацев в таблицу в документе Word с помощью VBA?

Я регулярно работаю с большими документами Word. Мне нужно преобразовать все абзацы в таблицу.

Пример структуры исходного документа:

Как изменить отступ после преобразования всех абзацев в таблицу в документе Word с помощью VBA?

После преобразования (Вставка -> Таблица -> Преобразовать текст в таблицу) Word теряет информацию об отступах для случайных абзацев. Целевой документ:

Как изменить отступ после преобразования всех абзацев в таблицу в документе Word с помощью VBA?

Как видите, отступы для абзацев «в» и «г» исчезли. Не знаю почему, но это случается довольно часто.

Он должен быть точно таким же, как и в исходных документах:

Как изменить отступ после преобразования всех абзацев в таблицу в документе Word с помощью VBA?

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

Это моя первая попытка использовать VBA, я начал так:

Dim sourceDocument, targetDocument As Document
Dim myRange As Range
Set sourceDocument = ActiveDocument
Set targetDocument = Documents.Add(ActiveDocument.FullName)
Set myRange = targetDocument.Range(Start:=targetDocument.paragraphs(1).Range.Start, End:=targetDocument.paragraphs(targetDocument.paragraphs.Count).Range.End)
myRange.converttotable Separator:=wdSeparateByParagraphs
Dim i As Integer
For i = 1 To targetDocument.Tables(1).Range.Rows.Count
    targetDocument.Tables(1).Range.Rows(i).Range.Cells(1).Range.paragraphs(1).LeftIndent = sourceDocument.paragraphs(i).LeftIndent
    targetDocument.Tables(1).Range.Rows(i).Range.Cells(1).Range.paragraphs(1).FirstLineIndent = sourceDocument.paragraphs(i).FirstLineIndent
Next i

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

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

Итак, мой вопрос: как сопоставить исходные абзацы с целевыми абзацами в таблицах (исключая исходные таблицы и целевые вложенные таблицы)?

А может есть другой способ преобразования абзацев в таблицу с правильным отступом?

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

Zeflik 11.04.2019 11:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
277
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Затем применяется отступ от соответствующего абзаца в массиве с использованием счетчика циклов (плюс 1, так как массивы отсчитываются от 0).

Sub RestoreParaIndents()
    Dim sourceDocument As Document, targetDocument As Document
    Dim myRange As Range
    Set sourceDocument = ActiveDocument
    Set targetDocument = Documents.Add(ActiveDocument.FullName)
    Set myRange = targetDocument.content  

    'Get an array of all paragraphs not in a table in the source document
    'This will provide the indent information in the loop for the target document
    Dim aParas() As Paragraph, para As Paragraph
    Dim counterPara As Long
    counterPara = 0
    For Each para In sourceDocument.Paragraphs
        If Not para.Range.Information(wdWithInTable) Then
            ReDim Preserve aParas(counterPara)
            Set aParas(counterPara) = para
            counterPara = counterPara + 1
        End If
    Next

    myRange.ConvertToTable Separator:=wdSeparateByParagraphs

    Dim i As Long
    Dim rw As Row, rng As Range
    For i = 1 To targetDocument.Tables(1).Range.Rows.Count
        Set rw = targetDocument.Tables(1).Range.Rows(i)
        Set rng = rw.Range.Cells(1).Range

        'If the cell contains multiple paragraphs then in contains
        'a nested table. Skip the table and go to the end (last paragraph)
        If rng.Paragraphs.Count > 1 Then
            Set rng = rng.Paragraphs.Last.Range
        End If
        rng.Paragraphs(1).LeftIndent = aParas(i - 1).LeftIndent
        rng.Paragraphs(1).FirstLineIndent = aParas(i - 1).FirstLineIndent 
    Next i
End Sub

МОЙ БОГ! Это именно то, что я искал! Спасибо :) Есть ли возможность дополнительно обнаружить и пропустить все абзацы, принадлежащие оглавлению? Если нет, то можно как есть :)

Zeflik 12.04.2019 16:02

Я решил эту дополнительную проблему, просто удалив все экземпляры TOC из исходного документа перед сбором исходных абзацев. Целевое оглавление содержит несколько абзацев и опускается, как вложенные таблицы.

Zeflik 23.04.2019 20:49

Другие вопросы по теме

Похожие вопросы

Пользовательская форма Excel VBA — использование той же формы для создания непрерывных данных
Сравнение 2 динамических массивов разных размеров и просмотр, сколько совпадений
Доступ: значения поля со списком зависят от предыдущего поля со списком
Параметр (Private WithEvents As Sheet1) sheetUI = Sheet1 вызывает ошибку 438: объект не поддерживает это свойство или метод
Код для объединения соседних ячеек с использованием VBA больше не работает, и я не могу найти проблему
Как я могу исправить ошибку времени выполнения 430 из-за импорта пользовательской DLL в проект VBA
Скопируйте столбец A, вставьте для каждого другого столбца, затем отсортируйте
Как использовать условие If/then для значения массива Variant/double?
Как отфильтровать данные в одном столбце, а затем получить значение в другом столбце, связанном с отфильтрованными данными
Ячейка щелчка события