View Full Version : Need macro to split large word doc by headings
Philkp
06-08-2010, 11:30 AM
I have a large word doc (220 pages) that has several heading levels in it.
The need is to be able to split the doc into smaller documents for each Heading 1 , Heading 2
So say I have the following structure
1
1.1
text
1.2
text
1.3
text
2
2.1
text
2.2
text
3
3.1
text
Note that each of my heading 1 sections does not have any text directly under it.
Also each Heading 1, Heading 2 etc begin on a new page in my large doc, which means that the first page has only the heading 1 title for Section 1 and nothing else in it.
Can anyone please help here with a macro I can use to split this doc?
See attached doc.
fumei
06-08-2010, 12:42 PM
It would be MUCH easier if the document used whatr Word considers Sections.
"my heading 1 sections"
You are refering to what is in your mind, not what Word considers Sections. There is only 1 Section in the document. One.
You need to be a bit more specific. What - exactly - does this mean?
"The need is to be able to split the doc into smaller documents for each Heading 1 , Heading 2"
Taking your example:
1
1.1
text
1.2
text
1.3
text
2
2.1
text
2.2
text
3
3.1
text
Does that mean you want:
SEPARATE DOCUMENT:
1
SEPARATE DOCUMENT:
1.1
text
SEPARATE DOCUMENT:
1.2
text
SEPARATE DOCUMENT:
1.3
text
SEPARATE DOCUMENT:
2
SEPARATE DOCUMENT:
2.1
text
SEPARATE DOCUMENT:
2.2
text
SEPARATE DOCUMENT:
3
SEPARATE DOCUMENT:
3.1
text
That is what "split the doc into smaller documents for each Heading 1 , Heading 2" actually states. But do you actually, really, mean:
SEPARATE DOCUMENT:
1
1.1
text
1.2
text
1.3
text
SEPARATE DOCUMENT:
2
2.1
text
2.2
text
SEPARATE DOCUMENT:
3
3.1
text
The 1, 2, 3 - as you point out - have no text really. It seems odd to make a separate document, thus I suspect you want your Heading 1 included with some document...but with each 1.2, 1.3 etc? In other words, do you want the heading text repeated for each Heading 2 document? That gets a little trickier.
Start with being very very specific.
BTW: you do not need to post the whole document. A sample up to, say, 3.1 would have been sufficient.
Again, if the document was structured using real Word Sections this would be very easy to do. As it is, I am sure it can be done, but it will take a wee bit of fussing. But you need to be very specific.
Philkp
06-08-2010, 12:50 PM
Hi fumei,
Thank you for your response. This is exactly what I am looking for, as you mentioned. Unfortunately, I have no control over the doc (meaning I am not the author per-se) so I cannot get it done in sections, I am simply a consumer of this doc and I need to break it up into seperate docs for each Heading 1 (even though it has no text) and seperate docs for each Heading 2, exactly as shown in the example below
[quote=fumei]Does that mean you want:
SEPARATE DOCUMENT:
1
SEPARATE DOCUMENT:
1.1
text
SEPARATE DOCUMENT:
1.2
text
SEPARATE DOCUMENT:
1.3
text
SEPARATE DOCUMENT:
2
SEPARATE DOCUMENT:
2.1
text
SEPARATE DOCUMENT:
2.2
text
SEPARATE DOCUMENT:
3
SEPARATE DOCUMENT:
3.1
text
That is what "split the doc into smaller documents for each Heading 1 , Heading 2" actually states. quote]
Philkp
06-08-2010, 12:53 PM
Here is some code I found on the net, but it does not work properly with my doc posted in the initial posting for some reason, if anyone can crack the issue that would be great
Sub Split_Hdr2()
Dim TotalLines As Long
Dim X As Long
Dim Groups() As Long
Dim Counter As Long
Dim y As Long
Dim FilePath As String
Dim FileName() As String
FilePath = ActiveDocument.Path
Selection.GoTo What:=wdGoToLine, Which:=wdGoToAbsolute, Count:=1
Do
TotalLines = Selection.Range.Information(wdFirstCharacterLineNumber)
Selection.MoveDown Unit:=wdLine, Count:=1
Loop While TotalLines <> Selection.Range.Information(wdFirstCharacterLineNumber)
Selection.GoTo What:=wdGoToLine, Which:=wdGoToAbsolute, Count:=1
For X = 1 To TotalLines
If Selection.Style = "Heading 2" Then
Counter = Counter + 1
ReDim Preserve Groups(1 To Counter)
ReDim Preserve FileName(1 To Counter)
Groups(Counter) = X
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
FileName(Counter) = Selection.Text
FileName(Counter) = Left(Selection.Text, Len(FileName(Counter)) - 1)
Selection.HomeKey Unit:=wdLine, Extend:=wdExtend
End If
Selection.MoveDown Unit:=wdLine, Count:=1
Next
Counter = Counter + 1
ReDim Preserve Groups(1 To Counter)
Groups(Counter) = TotalLines
For X = 1 To UBound(Groups) - 1
y = Groups(X + 1) - Groups(X)
Selection.GoTo What:=wdGoToLine, Which:=wdGoToAbsolute, Count:=Groups(X)
Selection.MoveDown Unit:=wdLine, Count:=y, Extend:=wdExtend
Selection.Copy
Documents.Add
Selection.Paste
ActiveDocument.SaveAs FilePath & "\" & FileName(X) & ".doc"
ActiveDocument.Close
Next X
End Sub
fumei
06-08-2010, 01:17 PM
I have succeeded in doing what I think you want. Here is the logic.
1. find each Heading 1 and put a section break BEFORE it.
2. delete Section 1, as it is a new Section BEFORE the first Heading 1 (and thus is empty)
3. extract each Section into a TEMP doc
4. in the TEMP doc, get the text of the first paragraph (the Heading 1 text)
5. find each Heading 2, and put a section break BEFORE it
6. delete Section 1 (with the Heading 1 text - now in a string variable)
Pause: to be clear, what has happened so far is a TEMP doc with separate Sections for 1.1, 1.2, 1,3 ....1.x. OK?
7. for each Section in TEMP doc (1.1, 1.2, 1.3.....1.x) make a new document, and put that Section into it.
8. add the string of the original Heading 1 to the start of each doc
9. get the numbering string of the first paragraph (Heading 1, i.e. "1.1", "1.3" etc.) and use that for a filename SaveAs.
Thus:
NewDoc: "yadda_1.1.doc"
1 (text)
1.1
text
NewDoc: "yadda_1.2.doc"
1 (text)
1.2
text
NewDoc: "yadda_1.3.doc"
1 (text)
1.3
text
fumei
06-08-2010, 01:23 PM
Regarding the code you posted....
Selection.GoTo What:=wdGoToLine, Which:=wdGoToAbsolute, Count:=1
Do
TotalLines = Selection.Range.Information(wdFirstCharacterLineNumber)
Selection.MoveDown Unit:=wdLine, Count:=1
Loop While TotalLines <> Selection.Range.Information(wdFirstCharacterLineNumber)
this is truly bizarre coding! CRAZY!
Philkp
06-08-2010, 02:25 PM
this makes absolute sense from a logic perspective and should hopefully be able to get me what I am looking for.
I am fairly new to VB so any chance this is something you could pass on code for me ? truely appreciate the tonne of help fumei
I have succeeded in doing what I think you want. Here is the logic.
1. find each Heading 1 and put a section break BEFORE it.
2. delete Section 1, as it is a new Section BEFORE the first Heading 1 (and thus is empty)
3. extract each Section into a TEMP doc
4. in the TEMP doc, get the text of the first paragraph (the Heading 1 text)
5. find each Heading 2, and put a section break BEFORE it
6. delete Section 1 (with the Heading 1 text - now in a string variable)
Pause: to be clear, what has happened so far is a TEMP doc with separate Sections for 1.1, 1.2, 1,3 ....1.x. OK?
7. for each Section in TEMP doc (1.1, 1.2, 1.3.....1.x) make a new document, and put that Section into it.
8. add the string of the original Heading 1 to the start of each doc
9. get the numbering string of the first paragraph (Heading 1, i.e. "1.1", "1.3" etc.) and use that for a filename SaveAs.
Thus:
NewDoc: "yadda_1.1.doc"
1 (text)
1.1
text
NewDoc: "yadda_1.2.doc"
1 (text)
1.2
text
NewDoc: "yadda_1.3.doc"
1 (text)
1.3
text
fumei
06-09-2010, 08:41 AM
Ok, but that does NOT do what you said you wanted.
You want:
1 - separate doc
1.1 separate doc (WITHOUT the text of 1)
1.2 separate doc (WITHOUT the text of 1)
1.3 separate doc (WITHOUT the text of 1)
etc.
My code does:
NO separate doc of 1
1.1 separate doc (WITH the text of 1)
1.2 separate doc (WITH the text of 1)
1.3 separate doc (WITH the text of 1)
etc.
1. I will say it again. Be very specific. Tell me - EXACTLY, PRECISELY - what you are trying to do.
2. Using the logic I posted, have you tried anything yourself? Recording a macro perhaps?
Philkp
06-09-2010, 09:19 AM
Hi fumei
Here is what I am looking to achieve
1 - separate doc
1.1 separate doc (WITHOUT the text of 1)
1.2 separate doc (WITHOUT the text of 1)
1.3 separate doc (WITHOUT the text of 1)
2 - separate doc
2.1 separate doc (WITHOUT the text of 2)
2.2 separate doc (WITHOUT the text of 2)
2.3 separate doc (WITHOUT the text of 2)
and so on.
fumei
06-09-2010, 10:31 AM
Ok. Then we change the logic a wee bit.
1. find each Heading 1 and put a section break BEFORE it.
Result: 1, 1.1, 1.2.....1.x all in ONE Section, 2, 2.1, 2.2....2.x all in ONE Section.
2. extract each Section into a TEMP doc
Result: a new TEMP document of 1, 1.1, 1.2, 1.3....1.x
3. find each Heading 2, and put a section break BEFORE it
Result: Section = 1, Section 2 = 1.1, Section 3 = 1.2.....Section x = 1.x
Still with me?
4. extract each Section (of the TEMP doc) into a new document. You probably do not know how to do this, and since it does a have a non-intuitive wee (but important) point:
Sub ExtractEachSection()
Dim r As Range
Dim oSection As Section
For Each oSection In TEMPDoc.Sections
' assuming we are working with a temp doc object
' make range object THAT Section range
Set r = oSection.Range
' move it back one character to NOT include Section break
r.MoveEnd Unit:=wdCharacter, Count:=-1
' make new document
Documents.Add
' make new document range = current section range
ActiveDocument.Range = r
' save new doc
ActiveDocument SaveAs Filename:=??????????
ActiveDocument.Close
Next
End Sub
It is that truncating of the Section break that is significant.
I want to say welcome to the forum, and I want to say again, that it is important that you really think things out, and state what it is you want to do EXACTLY, PRECISELY.
You say you want a bunch of new documents. Fine. How do you want to name them? Where do you want to put them? In the same folder as the original doc? Someplace else?
BTW: you did not answer the question about if you have tried anything, like recording a macro. I want to be very clear that this is not a place to get off-the-shelf solutions. We are not a Help Desk, nor a solution centre. We are here to help people learn, to understand, not to hand out complete solutions. I know you are a beginner. We all were at one time. So I am going to post an almost solution for you. But you must understand that the point of this forum is for YOU to gain knowledge, and therefore YOU need to work at it.
Your solution will be something like:
Option Explicit
Sub SeparateHeadings()
Dim oPara As Paragraph
Dim r As Range
' break into 1.... and 2.... sections
For Each oPara In ActiveDocument.Paragraphs
If oPara.Style = "Heading 1" Then
Set r = oPara.Range
With r
.Collapse 1
.InsertBreak Type:=wdSectionBreakContinuous
End With
End If
Next
' break THOSE sections into 1.1, 1.2....
For Each oPara In ActiveDocument.Paragraphs
If oPara.Style = "Heading 2" Then
Set r = oPara.Range
With r
.Collapse 1
.InsertBreak Type:=wdSectionBreakContinuous
End With
End If
Next
End Sub
Sub EachSectionToDoc()
Dim oSection As Section
Dim TEMPDoc As Document
Dim r As Range
For Each oSection In ActiveDocument.Sections
' make range object THAT Section range
Set r = oSection.Range
' move it back one character to NOT include Section break
r.MoveEnd Unit:=wdCharacter, Count:=-1
' make new document
Set TEMPDoc = Documents.Add
' make new document range = current section range
TEMPDoc.Range = r
' save new doc
Tempdoc.SaveAs Filename:=??????????
TEMPDoc.Close
Set TEMPDoc = Nothing
Next
End Sub
Sub LetsDoIt()
Call SeparateHeadings
Call EachSectionToDoc
End Sub
Note that the SaveAs for each document is NOT complete...as you did not state what you want to do.
Tinbendr
06-10-2010, 06:19 PM
Here's my effort. It separates the file by looking for the Style "Heading 1".
Sub ParseFileByHeading()
Dim aDoc As Document
Dim bDoc As Document
Dim Rng As Range
Dim Rng1 As Range
Dim Rng2 As Range
Dim Counter As Long
Dim Ans$
Ans$ = InputBox("Enter Filename", "Incremental number added")
If Ans$ <> "" Then
Set aDoc = ActiveDocument
Set Rng1 = aDoc.Range
Set Rng2 = Rng1.Duplicate
Do
With Rng1.Find
.ClearFormatting
.MatchWildcards = False
.Forward = True
.Format = True
.Style = "Heading 1"
.Execute
End With
If Rng1.Find.Found Then
Counter = Counter + 1
Rng2.Start = Rng1.End + 1
With Rng2.Find
.ClearFormatting
.MatchWildcards = False
.Forward = True
.Format = True
.Style = "Heading 1"
.Execute
End With
If Rng2.Find.Found Then
Rng2.Select
Rng2.Collapse wdCollapseEnd
Rng2.MoveEnd wdParagraph, -1
Set Rng = aDoc.Range(Rng1.Start, Rng2.End)
Set bDoc = Documents.Add
bDoc.Content.FormattedText = Rng
bDoc.SaveAs Ans$ & Counter, wdFormatDocument
bDoc.Close
Else
'This collects from the last Heading 1
'to the end of the document.
If Rng2.End < aDoc.Range.End Then
Set bDoc = Documents.Add
Rng2.Collapse wdCollapseEnd
Rng2.MoveEnd wdParagraph, -2
Set Rng = aDoc.Range(Rng2.Start, aDoc.Range.End)
bDoc.Content.FormattedText = Rng
bDoc.SaveAs Ans$ & Counter, wdFormatDocument
bDoc.Close
End If
End If
End If
Loop Until Not Rng1.Find.Found
'This is closing End If from Ans$
End If
End Sub I did run into one anomaly though. Section four header wasn't formatted properly, so it kept lumping three and four together. Once I reformatted the header to include the whole line, it worked as expected.
Cheers,
David
new23
09-19-2010, 09:37 AM
Tinbendr,
Your macro works fine on my word -2007.
Thanks !!!:clap:
But, is it possible - every new file to have a name exactly - as the text in headings style, instead text I typed in box .
I`m using serbian Latin in text.
Thanks
Ivan
:beerchug:
Here's my effort. It separates the file by looking for the Style "Heading 1".
Sub ParseFileByHeading()
Dim aDoc As Document
Dim bDoc As Document
Dim Rng As Range
Dim Rng1 As Range
Dim Rng2 As Range
Dim Counter As Long
Dim Ans$
Ans$ = InputBox("Enter Filename", "Incremental number added")
If Ans$ <> "" Then
Set aDoc = ActiveDocument
Set Rng1 = aDoc.Range
Set Rng2 = Rng1.Duplicate
Do
With Rng1.Find
.ClearFormatting
.MatchWildcards = False
.Forward = True
.Format = True
.Style = "Heading 1"
.Execute
End With
If Rng1.Find.Found Then
Counter = Counter + 1
Rng2.Start = Rng1.End + 1
With Rng2.Find
.ClearFormatting
.MatchWildcards = False
.Forward = True
.Format = True
.Style = "Heading 1"
.Execute
End With
If Rng2.Find.Found Then
Rng2.Select
Rng2.Collapse wdCollapseEnd
Rng2.MoveEnd wdParagraph, -1
Set Rng = aDoc.Range(Rng1.Start, Rng2.End)
Set bDoc = Documents.Add
bDoc.Content.FormattedText = Rng
bDoc.SaveAs Ans$ & Counter, wdFormatDocument
bDoc.Close
Else
'This collects from the last Heading 1
'to the end of the document.
If Rng2.End < aDoc.Range.End Then
Set bDoc = Documents.Add
Rng2.Collapse wdCollapseEnd
Rng2.MoveEnd wdParagraph, -2
Set Rng = aDoc.Range(Rng2.Start, aDoc.Range.End)
bDoc.Content.FormattedText = Rng
bDoc.SaveAs Ans$ & Counter, wdFormatDocument
bDoc.Close
End If
End If
End If
Loop Until Not Rng1.Find.Found
'This is closing End If from Ans$
End If
End Sub I did run into one anomaly though. Section four header wasn't formatted properly, so it kept lumping three and four together. Once I reformatted the header to include the whole line, it worked as expected.
Cheers,
David
Tinbendr
09-20-2010, 10:39 AM
But, is it possible - every new file to have a name exactly - as the text in headings style, instead text I typed in box .
I`m using serbian Latin in text.It should look for 'Heading 1' (which is a style name) no matter what the font name.
If you asking to split the document based on font name, then we'll have to adjust it.
new23
09-20-2010, 03:36 PM
4544[/ATTACH]
It should look for 'Heading 1' (which is a style name) no matter what the font name.
If you asking to split the document based on font name, then we'll have to adjust it.
I`m having a list of exam questions in word document, and formated tham as heading1.
The name of exam is "Ustav" ...means Constitusion (law -bar exam)
I`ll attach document...so U can see it.
I typed "Ustavno" in macro input box, ( "incremental number added" - b.t.w. don`t know meaning,.....enter file name....... and result were separate files named like "Ustavno1, Ustavno2, Ustavno 3.....etc)
I was expecting output separate files to be exactly named like headings are ...
First file- "68. Pravo na rehabilitaciju i naknadu štete" and text below in no spacing style .....second file "81. Prava pripadnika nacionalnih manjina"...and text below in no spacing style....third file - "82. Pravo na očuvanje posebnosti" ...and text below ( in no spacing style)....etc
Thanks again, and sorry for taking Your time.
Best regards
Ivan
Tinbendr
09-20-2010, 06:40 PM
I was expecting output separate files to be exactly named like headings are ...
I understand now.
I think I have it working now. Attached is the new version.
Run the one in module 1, not module 2.
David
new23
09-21-2010, 03:18 AM
I understand now.
I think I have it working now. Attached is the new version.
Run the one in module 1, not module 2.
David
It doesn`t work
Here is image -after run module1
Or I`m doing something wrong..
Ivan
Tinbendr
09-22-2010, 07:45 AM
There are two O's in Option Explicit. Take one out.
new23
09-22-2010, 12:31 PM
It Works!
Thanks!
Ivan
gentle
09-25-2010, 01:54 PM
Hi
I have taken the two macros that where submitted by Tinbendr and joined them .
(used the sample named exam TM.doc )
The results is now that when the output files are saved they will be marked with a number in the front and then the "heading 1" keeping it in the same order that was in the original document.
The only difference is you have to put a word at the bottom of your original document eg..END and also make it a “header 1”. (this is to get the last one to be added)
The document will be names as follows :
2 _ 68. Pravo na rehabilitaciju i naknadu štete
3 _ 81. Prava pripadnika nacionalnih manjina
4 _ 82. Pravo na očuvanje posebnosti
Run the one in module 3 for .doc
And module 4 if you want rtf.
Sub ParseFileByHeadingSaveDoc()
Dim aDoc As Document
Dim bDoc As Document
Dim Rng As Range
Dim Rng1 As Range
Dim Rng2 As Range
Dim Counter As Long
Dim Ans$
'Ans$ = InputBox("Enter Filename", "Incremental number added")
'If Ans$ <> "" Then
Set aDoc = ActiveDocument
Set Rng1 = aDoc.Range
Set Rng2 = Rng1.Duplicate
Do
With Rng1.Find
.ClearFormatting
.MatchWildcards = False
.Forward = True
.Format = True
.Style = "Heading 1"
.Execute
End With
If Rng1.Find.Found Then
Ans$ = Rng1.Text
Counter = Counter + 1
Rng2.Start = Rng1.End + 1
With Rng2.Find
.ClearFormatting
.MatchWildcards = False
.Forward = True
.Format = True
.Style = "Heading 1"
.Execute
End With
If Rng2.Find.Found Then
Rng2.Select
Rng2.Collapse wdCollapseEnd
Rng2.MoveEnd wdParagraph, -1
Set Rng = aDoc.Range(Rng1.Start, Rng2.End)
Set bDoc = Documents.Add
bDoc.Content.FormattedText = Rng
If Ans$ <> "" Then
bDoc.SaveAs Counter + 1 & " _ " & Left(Ans$, Len(Ans$) - 2) & ".doc", wdFormatDocument
'bDoc.SaveAs Ans$ & Counter, wdFormatDocument
bDoc.Close
Else
'This collects from the last Heading 1
'to the end of the document.
If Rng2.End < aDoc.Range.End Then
Set bDoc = Documents.Add
Rng2.Collapse wdCollapseEnd
Rng2.MoveEnd wdParagraph, -2
Set Rng = aDoc.Range(Rng2.Start, aDoc.Range.End)
bDoc.Content.FormattedText = Rng
If Ans$ <> "" Then
bDoc.SaveAs Counter + 1 & " _ " & Left(Ans$, Len(Ans$) - 2) & ".doc", wdFormatDocument
'bDoc.SaveAs Ans$ & Counter, wdFormatDocument
bDoc.Close
End If
End If
End If
End If
End If
Loop Until Not Rng1.Find.Found
'This is closing End If from Ans$
End Sub
Sample has been renamed.
Thank you for the info that was posted by all.
I was able to get an answer to my own question posted.
:clap:
new23
09-26-2010, 09:09 AM
"Run the one in module 3 for .doc And module 4 if you want rtf."
It works too.
(and module 4 for .html and module 5 for .one and module 6 for .pdf ? ):thumb
marsh
06-07-2014, 04:26 PM
"The results is now that when the output files are saved they will be marked with a number in the front and then the "heading 1" keeping it in the same order that was in the original document.
The only difference is you have to put a word at the bottom of your original document eg..END and also make it a “header 1”. (this is to get the last one to be added)"
Hi Gentle
Iam not able to add the last section of the document when i split the document using headings though i put sample word at the end of the original document. Pls help and thank you in advance.
Regards
marsh
marsh
06-08-2014, 06:26 AM
Hi Tinbendr,
Can you pls attach the new version of code which you attached to Ivan
Thank you,
Marsh
nappi90
07-31-2014, 02:44 AM
Hey,
im trying to get a code that splits a large document in several doc.files and saves them automatically.
SEPARATE DOCUMENT:
1
text
SEPARATE DOCUMENT:
1.1
text
SEPARATE DOCUMENT:
1.2
text
SEPARATE DOCUMENT:
2
text
SEPARATE DOCUMENT:
2.1
text
and so on.
Sub SplitHeadingLevel1()
Dim AppWD As Object
Dim rng As Word.Range
Dim sStyle As Word.Style
Dim aDoc As New Word.Document
Dim oDoc As New Word.Document
Set AppWD = CreateObject("Word.Application") 'Word als Object starten
AppWD.Documents.Open "C:\Users\VW2COZ6\Test\Documents\text.doc"
AppWD.Visible = False
Set aDoc = AppWD.ActiveDocument
Set rng = aDoc.Content
With rng.Find
.Style = wdStyleHeading1
.Execute
Do While .Found = True
rng.Select
rng.Bookmarks("\HeadingLevel").Range.Select
If Asc(Mid(rng.Text, 1, 1)) = 12 Then ' Manueller Seitenwechsel?
AppWD.Selection.Start = Selection.Start + 1
End If
AppWD.Selection.Copy
Set oDoc = Documents.Add
oDoc.Range.PasteSpecial
SplitHeadingLevel2 oDoc, AppWD
With Dialogs(wdDialogFileSaveAs)
.Name = ActiveDocument.Path & "\" & Left(rng.Paragraphs(1).Range.Text, _
Len(rng.Paragraphs(1).Range.Text) - 1)
.Show
End With
.Execute Forward:=True
Loop
End With
AppWD.Documents("C:\Users\VW2COZ6\Test\Documents\text.doc").Close SaveChanges:=False
AppWD.Quit
End Sub
Sub SplitHeadingLevel2(oDoc2 As Word.Document, AppWD As Object)
Dim rng2 As Word.Range
Dim oDoc As New Word.Document
Set rng2 = oDoc2.Content
With rng2.Find
.Style = wdStyleHeading2
.Execute
Do While .Found = True
rng2.Select
rng2.Bookmarks("\HeadingLevel").Range.Select
If Asc(Mid(rng2.Text, 1, 1)) = 12 Then ' Manueller Seitenwechsel?
AppWD.Selection.Start = Selection.Start + 1
End If
AppWD.Selection.Copy
Set oDoc = Documents.Add
oDoc.Range.PasteSpecial
With Dialogs(wdDialogFileSaveAs)
.Name = ActiveDocument.Path & "\" & Left(rng2.Paragraphs(1).Range.Text, _
Len(rng2.Paragraphs(1).Range.Text) - 1)
.Show
End With
.Execute Forward:=True
Loop
End With
End Sub
i was trying to write a sub SplitHeadingLevel1 that returns heading 1 like:
SEPARATE DOCUMENT:
1
text
and another sub SplitHeadingLevel2 that returns heading 2 that returns docs like:
SEPARATE DOCUMENT:
1.1
text
SEPARATE DOCUMENT:
1.2
text
but sub1 returns docs containing heading2
and i still havent managed to save the files automatically...
Would be nice if you could help me :D:)
Apsis0215
02-10-2017, 04:53 PM
Wanted to put my 2 cents in 2 years later so I can find it again : )
Attribute VB_Name = "SPLIT_BY_HEADINGS"
Option Explicit
Sub SplitByPara()
Dim aDoc As Document
Dim bDoc As Document
Dim rng As Range
Dim fp As String
Dim fn As String
Dim Counter As Long
Dim Ans$
Dim para As Paragraph
Dim ParaLast As Paragraph
Dim i
Set aDoc = ActiveDocument
''Cread subfolder for paragraphs
If aDoc.Path > "" Then
On Error Resume Next
fp = aDoc.Path & "\" & aDoc.Name
VBA.MkDir (fp)
fp = fp & "\"
On Error GoTo 0
End If
Set ParaLast = aDoc.Paragraphs.Last
For i = aDoc.Paragraphs.Count - 1 To 1 Step -1 ''paras from next-to-last to first
Set para = aDoc.Paragraphs(i)
''If para.Style = "Heading 1" And para.Range.Text > "" Then
If Parastyles(para, Array("Heading 1*", "Heading 2*", "*Appendix*")) And para.Range.Text > "" Then
'Do While para.Style = "Heading 1" And I > 1 ''count in sequential headings
' I = I - 1
' Set para = ActiveDocument.Paragraphs(I)
'Loop
'''copy form para2 to para
Set rng = ActiveDocument.Range(para.Range.Start, ParaLast.Range.End)
rng.Expand Word.wdCollapseStart
'rng.MoveEnd wdParagraph, -2
fn = StrFormat(Format(i, "00000") & "-" & para.Range.ListFormat.ListString & "-" & Left(Trim(para.Range.Text), 64))
Set bDoc = Documents.Add
bDoc.Content.FormattedText = rng
On Error Resume Next
bDoc.SaveAs fp & fn, Word.wdFormatDocument
On Error GoTo 0
bDoc.Close False
End If
Next i
End Sub
Private Function Parastyles(para As Paragraph, strStyles) As Boolean
Dim i As Integer
Dim K As Integer
i = -1
On Error Resume Next
i = UBound(strStyles)
On Error GoTo 0
For K = 0 To i
If para.Style Like strStyles(K) Then
Parastyles = True
Exit Function
End If
Next K
End Function
Private Function StrFormat(strString As String) As String
Dim regex As New regexp
With regex
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "[^a-zA-Z0-9\-]"
End With
StrFormat = regex.Replace(strString, "-")
With regex
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "\-{1,}"
End With
StrFormat = regex.Replace(StrFormat, "-")
End Function
Apsis0215
02-11-2017, 06:32 PM
Attribute VB_Name = "SPLIT_BY_HEADINGS"
Option Explicit
Sub SplitByPara()
Dim aDoc As Document
Dim bDoc As Document
Dim rng As Range
Const levels = 2
Dim FP As String
Dim fn As String
Dim Counter As Long
Dim Ans$
Dim para As Paragraph
Dim ParaLast As Paragraph
Dim I
Set aDoc = ActiveDocument
FP = aDoc.Path & "\" & StrFormat(aDoc.Name)
NewFolder FP
Set ParaLast = aDoc.Paragraphs.Last
For I = aDoc.Paragraphs.Count - 1 To 1 Step -1 ''paras from next-to-last to first
Set para = aDoc.Paragraphs(I)
''If para.Style = "Heading 1" And para.Range.Text > "" Then
If Parastyles(para, Array("Heading 1*", "Heading 2*", "*Appendix*")) And para.Range.Text > "" Then
'''copy form para2 to para
Set rng = ActiveDocument.Range(para.Range.Start, ParaLast.Range.Start)
fn = PadParanums(para.Range.ListFormat.ListLevelNumber, 2) & "-" & Left(Trim(para.Range.Text), 64)
fn = StrFormat(fn)
Set bDoc = Documents.Add
bDoc.Content.FormattedText = rng
On Error Resume Next
VBA.Kill FP & fn
bDoc.SaveAs FP & fn, Word.wdFormatDocument
On Error GoTo 0
bDoc.Close False
Set ParaLast = para
ParaLast.Range.MoveStart wdParagraph - 1
End If
Next I
End Sub
Private Function PadParanums(strString As String, Optional levels As Integer) As String '' add 0's in numbered formats
Dim x
Dim I, xI
strString = StrFormat(strString)
x = Split(strString, "-")
Const format = "000"
xI = -1
On Error Resume Next
xI = UBound(x)
On Error GoTo 0
For I = 0 To xI
If x(I) Like "*#*" Then
PadParanums = PadParanums & Right(format & x(I), 3) & "-"
End If
Next I
For I = UBound(Split(PadParanums, "-")) To levels - 1 ''use padparanums to determine number of levels defined then add padded 000- for remining
PadParanums = PadParanums & format & "-"
Next I
PadParanums = StrFormat(PadParanums)
End Function
Private Function Parastyles(para As Paragraph, strStyles) As Boolean
Dim I As Integer
Dim K As Integer
I = -1
On Error Resume Next
I = UBound(strStyles)
On Error GoTo 0
For K = 0 To I
If para.Style Like strStyles(K) Then
Parastyles = True
Exit Function
End If
Next K
End Function
Function StrFormat(strString As String) As String
Dim regex As New regexp
With regex
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "[^a-zA-Z0-9\-]"
End With
StrFormat = regex.Replace(strString, "-")
With regex
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "\-{1,}"
End With
StrFormat = regex.Replace(StrFormat, "-")
'''Remove trailing dashes
With regex
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = "\-{1,}(?=\s|$)"
End With
StrFormat = regex.Replace(StrFormat, "")
End Function
Sub NewFolder(FP As String, Optional DoNotOpen As Boolean)
Dim OpenFold As Variant
Dim oShell As Object
Dim Wnd As Object
''Dim strFolder
''OpenFold = "mysubfolder"
''strFolder = "U:\myfolder\" & OpenFold
Set oShell = CreateObject("Shell.Application")
''Wnd.LocationName
''Cread subfolder for paragraphs
On Error Resume Next
VBA.MkDir (FP)
FP = FP & "\"
On Error GoTo 0
For Each Wnd In oShell.Windows
Debug.Print Wnd.Document.Folder.Self.Path
'' If Wnd.LocationName = "Windows Explorer" Then
If LCase(Wnd.Document.Folder.Self.Path & "\") = LCase(FP) Then
Wnd.Visible = True
Exit Sub
End If
''End If
Next Wnd
If Not DoNotOpen Then Shell "C:\WINDOWS\explorer.exe """ & FP & "", vbNormalFocus
End Sub
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.