Разбить текстовый документ на новые файлы, сохраняя форматирование - PullRequest
0 голосов
/ 03 сентября 2018

С этой страницы

https://www.extendoffice.com/documents/word/966-word-split-documents-into-multiple-documents.html?page_comment=2

Я получаю этот рабочий VBA, который НЕ сохраняет форматирование текста

Sub SplitNotes(delim As String, strFilename As String)
    Dim doc As Document
    Dim arrNotes
    Dim I As Long
    Dim X As Long
    Dim Response As Integer
    arrNotes = Split(ActiveDocument.Range, delim)
    Response = MsgBox("This will split the document into " & UBound(arrNotes) + 1 & " sections.Do you wish to proceed?", 4)
    If Response = 7 Then Exit Sub
    For I = LBound(arrNotes) To UBound(arrNotes)
        If Trim(arrNotes(I)) <> "" Then
            X = X + 1
            Set doc = Documents.Add
            doc.Range = arrNotes(I) ' does NOT keep formatting wdFormatOriginalFormatting
            doc.SaveAs ThisDocument.Path & "\" & strFilename & Format(X, "000")
            doc.Close True
        End If
    Next I
End Sub

Sub test()
    'delimiter & filename
    SplitNotes "///", "Notes "
End Sub

Этот вопрос звучит идентично, но оставляет реализацию до читателя.

Разделить документ Word на несколько частей и сохранить текстовый формат

Как бы я изменил код, который я вставил выше, чтобы сохранить форматирование текста между /// и следующим /// (или концом файла)

Или, что еще лучше, разделить на формат HEADING1, сохранив заголовок и сохранив файл с именем = заголовок

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

ОП запросил макрос для разделения документа с заданным стилем заголовка. Следующий код делает именно это и может использоваться как есть в качестве справочного материала для внесения поправок в приведенный выше код.

Есть несколько предостережений.

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

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

Поля, которые зависят от других полей (например, полей seq), будут зависеть от отсутствия полей, от которых они зависят, например, первое поле последовательности в вашем выборе станет 1.

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

Это мой первый пост в StackOverflow, поэтому я надеюсь, что он соответствует этикету и полезен для ОП.

Option Explicit

Public Sub SaveAllChapters()

Dim myCollectionOfChapters                          As Collection
Dim myChapter                                       As Word.Range

    Set myCollectionOfChapters = GetAllChapters

    For Each myChapter In myCollectionOfChapters
        SaveChapter myChapter
    Next

End Sub


Public Sub SaveChapter(thisChapter As Word.Range)

Dim myDoc                                               As Word.Document

    Set myDoc = Documents.Add

    With myDoc
        .Range.FormattedText = thisChapter.FormattedText
        .SaveAs2 FileName:=safeName(thisChapter.Paragraphs.First.Range.Text)
        .Close False

    End With

End Sub

Public Function safeName(ByVal thisString As String) As String
'Ensures there are no illegal filename characters in a string to be used as a filename

Dim invalidFilenameCharacters()                             As String
Dim myIndex                                                 As Long

    invalidFilenameCharacters = Split("9,10,11,13,34,42,47,58,60,62,63,92,124", ",")

    For myIndex = 0 To UBound(invalidFilenameCharacters)
        thisString = Replace(thisString, Chr$(invalidFilenameCharacters(myIndex)), Chr$(95))

    Next

    safeName = thisString

End Function

Public Function GetAllChapters() As Collection

Dim myCollection                                    As New Collection
Dim myRange                                         As Word.Range

    Set myRange = Nothing

    Do While GetChapter(myRange)
        myCollection.Add myRange.Duplicate
    Loop

    Set GetAllChapters = myCollection

End Function

Public Function GetChapter(thisRange, Optional thisStyle As WdBuiltinStyle = wdStyleHeading1) As Boolean
' Searches backwards through the document from the start of thisRange
' thisRange is extended to include text upto, but not including the previous heading 1 style
' Returns false if the heading style is not found or if the start of the range matches the start of the document

Dim searchRange                                   As Word.Range

    If thisRange Is Nothing Then
        Set thisRange = ActiveDocument.StoryRanges(wdMainTextStory)
        thisRange.Collapse Direction:=wdCollapseEnd
        Set searchRange = thisRange.Duplicate

    Else
        thisRange.Collapse Direction:=wdCollapseStart
        Set searchRange = thisRange.Duplicate

    End If

    With searchRange.Find
        .ClearFormatting
        .Format = True
        .Style = thisStyle
        .Wrap = wdFindStop
        .Text = vbNullString
        .Forward = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
        .Execute

        If Not .Found Then
            GetChapter = False
            thisRange.Start = thisRange.Document.StoryRanges(wdMainTextStory).Start
            thisRange.End = searchRange.End

        Else
            GetChapter = True
            thisRange.Start = searchRange.Start

        End If

    End With

End Function
0 голосов
/ 04 сентября 2018

Хорошо, вот концепция, нужна работа:

Sub SplitNotes(delim As String, strFilename As String)
    Dim doc As Document
    Dim arrNotes
    Dim I As Long
    Dim X As Long
    Dim Response As Integer

    Dim rngFound As Range
    Set rngFound = ActiveDocument.Range
    rngFound.Collapse wdCollapseStart

    rngFound.Select

    With Selection.Find
        .Text = delim
        .MatchWholeWord = True
        Do While .Execute(Forward:=True)
            rngFound.End = Selection.Range.Start
            Set doc = Documents.Add
            doc.Range.InsertXML rngFound.WordOpenXML
            doc.SaveAs ThisDocument.Path & "\" & strFilename & Format(X, "000")
            doc.Close True
            rngFound.Start = Selection.Range.End
            rngFound.End = Selection.Range.End
        Loop
    End With

    rngFound.End = ActiveDocument.Range.End
    Set doc = Documents.Add
    doc.Range.InsertXML rngFound.WordOpenXML
    doc.SaveAs ThisDocument.Path & "\" & strFilename & Format(X, "000")
    doc.Close True
End Sub


Sub test()
    'delimiter & filename
    SplitNotes "///", "Notes "
End Sub

Основная проблема, которую решает этот вопрос, заключается в сохранении форматирования. Вместо сохранения текста вы сохраняете базовый XML. Это будет означать, что массив довольно большой ... если документ большой, он может задохнуться.

Я полагаю, что если это не сработает, это произойдет из-за того, что разделитель по-разному представлен в XML, в этом случае вы можете изменить разделитель и протестировать снова.

...