Reputation: 5281
Goal: Using VBA in Word, I'd like to be able to type or paste text into a Word document, then make sure each line word wraps at a set amount of characters (typically 50, although this can change). I'd rather not use the ruler at the top of the document to manually adjust, especially when the fonts are not constant-width!
Failed Attempts: I've tried to use the following, resulting in an error "Value out of range":
Public Sub setWordsPerLine()
ActiveDocument.PageSetup.CharsLine = 50
End Sub
I've also tried to insert a return character every 50 characters in a paragraph. However this is leading to a type mismatch error:
For Each pg In ActiveDocument.Paragraphs
b = pg.Range.Characters.Count
c = 50
If b > c Then
For atch = c To pg.Range.Characters.Count Step c
ActiveDocument.Range(pg.Range.Characters(atch)).InsertBefore (Chr(13))
Next
End If
Next
Help Needed:
Is there another method, property, or function that I should be using to do this? Paragraphs.RightIndent = x
is based on points, not characters.
Upvotes: 1
Views: 3605
Reputation: 5281
The other answer here by KazJaw works well, but I've modified to include some improvements, and wanted to post the modification in case someone else runs across this problem.
The improvements include:
Using a more elegant method to determine if in the middle of a word, by replacing
If Len(Trim(ActiveDocument.Range(char_index - 1, char_index + 1).Text)) < 2 Then
with
If ActiveDocument.Range(char_index).Text = " " Or _
ActiveDocument.Range(char_index).Text = "-" Then
Here is the modified code, again thanks to KazJaw for the original solution.
Public Sub wrap_words()
'adapted from stackoverflow
'https://stackoverflow.com/a/19109049/2658159
Dim para_index As Paragraph
Dim para_index_numchars, char_index, para_index_start As Long
'set the max line length constraint
Const line_max As Byte = 50
'loop through each paragraph
For Each para_index In ActiveDocument.Paragraphs
'find number of characters
para_index_numchars = para_index.Range.Characters.Count
'find the paragraph starting point
para_index_start = para_index.Range.Start
'if the paragraph has more than the predetermined amount of characters,
If para_index_numchars > line_max Then
'loop through each character starting with line_max position
'and stepping by line_max position, to the end of the paragraph
For char_index = (para_index_start + line_max) To _
(para_index_start + para_index_numchars) Step line_max
'if there is not a word in this position...
If ActiveDocument.Range(char_index).Text = " " Or _
ActiveDocument.Range(char_index).Text = "-" Then
'...just insert new line mark
ActiveDocument.Range(char_index, char_index).InsertAfter Chr(13)
Else
'... if there is a word, or a hyphenated word that
'can be split, move to the beginnng of word or the
'end of the hyphenated section.
ActiveDocument.Range(char_index, char_index).Select
Selection.MoveLeft unit:=wdWord, Count:=1
'insert newline at the beginning
Selection.InsertBefore Chr(13)
'since a new paragraph created before the word,
'the previous paragraph structure has changed.
'change char_index to reflect that change.
char_index = Selection.Start
End If
Next
End If
Next
End Sub
Upvotes: 0
Reputation: 19067
I have improved the second solution of yours which is now working fine. (I made some test with simple lorem ipsum
document).
Sub qTest_line()
Dim PG As Paragraph
Dim B, C, ATCH, S
For Each PG In ActiveDocument.Paragraphs
B = PG.Range.Characters.Count
S = PG.Range.Start
C = 50
If B > C Then
For ATCH = (S + C) To (S + B) Step C
'check the position
If Len(Trim(ActiveDocument.Range(ATCH - 1, ATCH + 1).Text)) < 2 Then
'just insert new line mark
ActiveDocument.Range(ATCH, ATCH).InsertAfter Chr(11)
Else
'move to the beginnng of word
ActiveDocument.Range(ATCH, ATCH).Select
Selection.MoveLeft wdWord
Selection.InsertBefore Chr(11)
ATCH = Selection.Start
End If
Next
End If
Next
End Sub
Upvotes: 1