PDA

View Full Version : [SOLVED:] Help - macro to insert a return before each capital letter in selected text failing



Divadog
11-15-2022, 09:18 AM
Hi,

I need help with a macro that will insert a hard return before every capital letter in a selected text range. I do not want to either delete or change the capital letters in any way.

I am copying Medieval poetry from an image file into a Word document using a screen capture and OCR program (ShareX). Unfortunately, the hard returns in the image are not recognized.

So text formatted like the following,

That thou forget not this for nothing;
But look, thou hold it well in thy mind,
For the best thou shalt it find.
For, as the wise man saith and proveth,

becomes a single paragraph rather than formatted poetry when I paste it into a Word Document:

Child, I bid thee on my blessing, That thou forget not this for nothing; But look, thou hold it well in thy mind, For the best thou shalt it find. For, as the wise man saith and proveth,

forcing me to insert hard returns manually

I want to use a VBA macro to insert hard returns in the original text into my Word document

After consulting various Internet Word websites, I wrote a macro based on the following principles:



Find each of the capitals in the selected text with a FIND statement
Note:

Invariably a capital letter starts a new line of verse.
If there are any exceptions I would manually edit them.


While the Find code is running insert a hard return before every capital letter.


This is the resulting macro:


Sub InsertReturnsBeforeCapitalLetters()
'Find all captial letters in selected range and insert a hard return before each one
With Selection.Find
Selection.Find.ClearFormatting
With Selection.Find
.Text = "[A-Z]"
.Replacement.Text = " "
.Forward = True
.Wrap = wdFindAsk
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = True
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
'Insert a paragraph return before each capital letter found
Do While Selection.Find.Found
'Do I need 'Selection.InsertBefore' here?
Selection.InsertBreak
Loop
End With
End Sub

Unfortunately it is not reformatting the select text for reasons I cannot determine. The text remains unchanged.

I would be grateful for any help forum members could give me in this regard.

My kind thanks for your help, advice and suggestions.

June7
11-15-2022, 10:25 AM
I see nothing that inserts a carriage return/line feed.

I doubt Word VBA is case sensitive by default. Most likely A=a.

And if you did get the insert to work, what do you think would happen if text contains proper name?

Divadog
11-15-2022, 12:32 PM
I see nothing that inserts a carriage return/line feed.

I doubt Word VBA is case sensitive by default. Most likely A=a.

And if you did get the insert to work, what do you think would happen if text contains proper name?

Thanks for your comment. I very much appreciate it.

I'm a novice user of Word VBA, but as far as I know Word VBA can be case sensitive. If you again look at my code you should notice two things. Firstly, I am using wild chads to search for capitals: My understanding is [A-Z] stands for any capital letter. Secondly, I have set the Find parameter 'MatchWildcards' to 'True'.

Here is an example of a vba search for capital letters using wild cards:


Sub Demo()
Dim fRng As Range
With Selection.Find
.ClearFormatting
.Text = "[A-Z]{3}"
.MatchWildcards = True
.Wrap = wdFindContinue
.Forward = True
Do While .Execute = True
Set fRng = ActiveDocument.Range(Start:=Selection.Start, End:=Selection.End)
If Len(fRng.Words(1)) > 4 And fRng.Words(1).Case = 1 Then _
fRng.Words(1).Font.Color = wdColorDarkRed
Loop
End With
Set fRng = Nothing
End Sub

Source: https://stackoverflow.com/questions/53300311/find-words-with-more-than-one-capital-letter-in-word-vba

My problem is that I don't have enough knowledge of Word VBA to get my macro to work.

Thanks again for your comments. I very much appreciate them.

rollis13
11-15-2022, 02:54 PM
Hi to all.
This is the best I could handle. As per your example in post #1 try this but it will error on "Child, I bid ...":
Option Explicit
Sub InsertReturnsBeforeCapitalLetters_new()
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = " (<[A-Z]*)"
.Replacement.Text = "^p\1"
.MatchWildcards = True
.Forward = True
.Wrap = wdFindAsk
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub

Divadog
11-16-2022, 08:40 AM
Hi,

Thanks for your suggestion. I very much appreciate it. Unfortunately it chrashes on "Selection.Find.Execute Replace:=wdReplaceAll" with the error message, Run-time error ‘5623’, “The replacement text contains a group number that’s out of range”

Anyway, I do not think your suggestion will do what I want. Your replacement statement in 'Selection.Find' looks like it will replace the capital letter with a line break. I do not want the capital letter replaced. I want a line break (return whatever) inserted before the capital letters. I need the capital letters since they are an integral part of the text.

Since my original post I have revised my macro to the following:


With Selection.Find
Selection.Find.ClearFormatting
With Selection.Find
.Text = "[A-Z]"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = True
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Do While Selection.Find.Found = True
Selection.InsertBefore vbNewLine
Loop
End With


This is the text I am working with:

All that have young people, good manners set them to learn; To their elders with gentle conditions let do nor say no harm. If they do ill, wise men may report their parents soon How should they teach other good, belike themselves cary none. A good father maketh good children, if wisdom be them within,

When I run this macro (with a stop statement) I get the following result:




All that have young people, good manners set them to learn; To their elders with gentle conditions let do nor say no harm. If they do ill, wise men may report their parents soon How should they teach other good, belike themselves cary none. A good father maketh good children, if wisdom be them within,

It would seem that the find statement is not advancing through the selected text. Instead, it keeps finding the very first capital letter and only inserting a line break before this capital letter (note: to get the above result I ran the macro three times with a Stop statement). I have tried starting it at the second capital letter, but I get the same result.

I have tried changing the line break insertion Do While loop, but to no avail e.g.:

Do while Selection.Find.Found = true or Selection.Find.Execute

So if you or anyone else has any suggestions as to how I can make the Selection.Find statement run through the whole selected text, I would be grateful.

My problem seems to be that I cannot get the Selection.Find statement to advance to each capital letter. This is even though I have Wrap set to 'Wrap = wdFindContinue". I am not sure where the problem lies: in the Selection.Find statement or in the Do Loop/Execute statement.

Thanks again for your suggestion. I very much appreciate it.

rollis13
11-16-2022, 09:47 AM
No idea on how you used my suggestion but if you create a new clean file and paste my macro as it is it will work exactly for what it's supposed to do, that is, insert a Return before every capital letter.

Divadog
11-16-2022, 11:51 AM
No idea on how you used my suggestion but if you create a new clean file and paste my macro as it is it will work exactly for what it's supposed to do, that is, insert a Return before every capital letter.

Sorry, I made a mistake running your macro. I've run it again and it works great.

Thanks so much for your kind effort and help.

Again, my apologies for not running your macro correctly in the first place.

rollis13
11-16-2022, 11:59 AM
Now I'm much happier having been of some help:beerchug:.