How to select first three rows after pagebreak ("^m") - vba

I've tried to select first three rows after for each of page. It works fine only for first page. After first page I am finding manual page break ("^m") and try to select first three rows, but I got only two. Also this macros was written for Word 2007 and I try to rewrite to Word 2016
Do While .Execute(FindText:="^m") = True
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.HomeKey Unit:=wdLine
Selection.MoveDown Unit:=wdLine, Count:=3, Extend:=wdExtend
Selection.Range.Case = wdLowerCase
Selection.Range.Case = wdTitleWord
headNumber = "2"
lunghezza = 0
cap = Selection.Text
Selection.Delete Unit:=wdCharacter, Count:=1
Selection.TypeText Text:=headNumber
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
If Selection.Text <> vbCr Then
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Selection.TypeParagraph
Selection.MoveUp Unit:=wdLine, Count:=1, Extend:=wdExtend
End If
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Style = ActiveDocument.Styles("Custom Style " + NameOfStyle)

It's not a problem to select the first three lines of a document. I would probably use Selection.GoTo for that instead of trying to find manual breaks. I'm not clear what you want to do with the selection, so I'm going to put this stub of an answer in to show the page and line selection until I get some clarity on that. I tested this with about 10 pages of random text using both natural and manual page breaks, with some cases of multiple consecutive manual page breaks.
Sub test()
Dim p As Integer
For p = 1 To ActiveDocument.ActiveWindow.Panes(1).Pages.Count
Selection.GoTo wdGoToPage, wdGoToAbsolute, p
Selection.MoveDown Unit:=wdLine, Count:=3, Extend:=wdExtend
Next
End Sub

Related

Word VBA Move the focus to the target of Selection.Find.Execute

In word, I can not get the focus to move to the target of
Selection.Find.Execute (findText)
In a word document I have one button that moves the top item from the list of things to do down to a logbook section.
The code to move the item is below; bMoveToLog. Focus stays with the list of things to do. Now I want a button that moves focus down to the logbook following the title "MYLOG" so I can do my timesheets.
There is a list of options I have tried.
How do I move the focus to the target of Selection.Find.Execute?
Private Sub bMoveToLog_Click()
Selection.GoTo What:=wdGoToPage, which:=wdGoToAbsolute
findText = "TODO"
Selection.Find.Execute (findText)
Selection.MoveDown Unit:=wdParagraph, Count:=1, Extend:=wdMove
Selection.MoveDown Unit:=wdParagraph, Count:=1, Extend:=wdExtend
Selection.Cut
findText = "MYLOG"
Selection.Find.Execute (findText)
Selection.MoveDown Unit:=wdParagraph, Count:=2, Extend:=wdMove
Selection.InsertDateTime
Selection.InsertBefore (" ")
Selection.Paste
Selection.GoTo What:=wdGoToPage, which:=wdGoToAbsolute
End Sub
Private Sub bViewLog_Click()
findText = "MYLOG"
myRange = Selection.Find.Execute(findText)
myRange.Select '*** This doesn't work - how do I set focus
End Sub
Options tried
'various attempts
'Selection.MoveDown Unit:=wdParagraph, Count:=2
'Selection.GoToEditableRange wdEditorCurrent
'myRange.Select
'Selection.GoTo what:=wdGoToPage, which:=wdGoToAbsolute
'Selection.MoveDown Unit:=wdParagraph, Count:=2, Extend:=wdMove
'ActiveSheet.Range("D5").Select
'This works but doesn't use search
'Selection.GoTo What:=wdGoToPage, Count:=6
Debugging showed that the search in the ViewLog routine was not performing its job. The search wasn't performed. That was why focus was not left where expected.
It was fixed by adding a Selection.Goto statement before the search to put focus on the page.
New View-Log routine is;
Private Sub bViewLog_Click()
'Selection.GoTo is needed to put focus on a page
Selection.GoTo What:=wdGoToPage, which:=wdGoToAbsolute
findText = "MYLOG"
Selection.Find.Execute (findText)
Selection.MoveDown Unit:=wdParagraph, Count:=2, Extend:=wdMove
End Sub

Blank selected text in VBA Word is coming up as 2 characters

When I run the my VBA code on the following text, it works fine till it gets to the paragraph break. I try to run a test for paragraph breaks but it comes up as FALSE:
OK, so that now we're recording.
Uhm, so I spoke with Berry,
which actually your own berries
team now, right?
The output looks like this:
OK, so that now we're recording. Uhm, so I spoke with Berry, which actually your own berries team now, right
Here is my original code:
Sub OneLine()
Dim charCount As Integer
'Go to End of document and add "
Selection.EndKey Unit:=wdStory
Selection.TypeText Text:=" """
'Go to beginning of Document
Selection.GoTo what:=wdGoToSection, Which:=wdGoToFirst
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
'Count how many characters are in Selection
charCount = Len(Selection)
Set myRange = Selection
myRange.Find.Execute FindText:="""", Forward:=True
'MsgBox (myRange.Find.found)
Do While myRange.Find.found = False
If charCount > 1 Then
Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdMove
Selection.HomeKey Unit:=wdLine, Extend:=wdMove
Selection.TypeBackspace
Selection.TypeText Text:=" "
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
charCount = Len(Selection)
Else
Selection.Delete
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
charCount = Len(Selection)
End If
Set myRange = Selection
myRange.Find.Execute FindText:="""", Forward:=True
'MsgBox (myRange.Find.found)
Loop
Selection.TypeBackspace
Selection.TypeBackspace
Selection.TypeBackspace
Selection.GoTo what:=wdGoToSection, Which:=wdGoToFirst
End Sub
I tried using Find.Text:= "^p" statement with an IF THEN but it came out as FALSE.
Thank you in advanced!
Figured it out.
i used the following lines:
With Selection.Find
.Execute FindText:=vbCrLf
.Forward = True
End With
Originally I was only looking for one thing, paragraph break or line break but not the combo of line feed and carriage return: vbCRLf. I was also using "vbCrLf" which is wrong because at that point it's looking for that string.
This is my final code:
Sub OneLine()
Dim charCount As Integer
'Go to End of document and add "
Selection.EndKey Unit:=wdStory
Selection.TypeText Text:=" """
'Go to beginning of Document
Selection.GoTo what:=wdGoToSection, Which:=wdGoToFirst
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
'Count how many characters are in Selection
charCount = Len(Selection)
Set myRange = Selection
myRange.Find.Execute FindText:=""""
'MsgBox (myRange.Find.found)
Do While myRange.Find.found = False
If charCount > 1 Then
With Selection.Find
.Execute FindText:=vbCrLf
.Forward = True
End With
If ((Selection.Find.found = True) And (charCount = 2)) Then
Selection.HomeKey Unit:=wdLine, Extend:=wdMove
Selection.TypeBackspace
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
charCount = Len(Selection)
Else
Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdMove
Selection.HomeKey Unit:=wdLine, Extend:=wdMove
Selection.TypeBackspace
Selection.TypeText Text:=" "
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
charCount = Len(Selection)
End If
Else
Selection.Delete
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
charCount = Len(Selection)
End If
Set myRange = Selection
myRange.Find.Execute FindText:=""""
'MsgBox (myRange.Find.found)
Loop
Selection.TypeBackspace
Selection.TypeBackspace
Selection.TypeBackspace
Selection.GoTo what:=wdGoToSection, Which:=wdGoToFirst
End Sub

How do I loop an existing macro?

I have a table in MS Word that is 2 columns by 1,000 rows. I made a macro that, in order,
adds a new row below the current one,
merges the two cells in the new row,
cuts and pastes the text from an above cell into the new row,
moves an image over one column, and
adds text to a cell. Once it completes that string of events the cursor is in position to do it all again.
There are no conditions that can screw it up as it runs (i.e. empty cells, etc), I do not need the code to to look for specific things, I just need it to repeat.
What do I need to add to this existing code to have this repeat until the end of the document (specifically 1,000 times).
I have seen code for Excel, but I have not seen code for going through a table in Word.
Selection.MoveDown Unit:=wdParagraph, Count:=2, Extend:=wdExtend
Selection.InsertRowsBelow 1
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.MoveDown Unit:=wdParagraph, Count:=2, Extend:=wdExtend
Selection.Cells.Merge
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.MoveDown Unit:=wdParagraph, Count:=1, Extend:=wdExtend
Selection.Cut
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.PasteAndFormat (wdPasteDefault)
Selection.Font.Size = 4
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Cut
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Selection.PasteAndFormat (wdPasteDefault)
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.Font.Size = 3
Selection.TypeText Text:="Unique specimen identifier not a property tag"
Selection.MoveDown Unit:=wdLine, Count:=2
Selection.MoveLeft Unit:=wdCharacter, Count:=2, Extend:=wdExtend
Selection.MoveLeft Unit:=wdCharacter, Count:=1
All I expect is to be able to run the code once and have it repeat until it hits the end of the document, and if possible to repeat specifically 1,000 times.
I hope this is not too "broad" since I have the code and am asking a specific question.
You can repeat your set of instructions by wrapping it into a For...Next loop, which is fairly standard across VBA applications. This code creates a loop and an 'index' variable, and then tells it to step through that index exactly 1000 times.
For index As Integer = 1 To 1000
Selection.MoveDown Unit:=wdParagraph, Count:=2, Extend:=wdExtend
Selection.InsertRowsBelow 1
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.MoveDown Unit:=wdParagraph, Count:=2, Extend:=wdExtend
Selection.Cells.Merge
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.MoveDown Unit:=wdParagraph, Count:=1, Extend:=wdExtend
Selection.Cut
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.PasteAndFormat (wdPasteDefault)
Selection.Font.Size = 4
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Cut
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Selection.PasteAndFormat (wdPasteDefault)
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.Font.Size = 3
Selection.TypeText Text:="Unique specimen identifier not a property tag"
Selection.MoveDown Unit:=wdLine, Count:=2
Selection.MoveLeft Unit:=wdCharacter, Count:=2, Extend:=wdExtend
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Next
If you ever need to loop something an indeterminate amount of times, for example when a specific criterion is met, you would use a Do...While or Do...Until loop, instead.

Find a line which starts with a term and delete it

I am trying to automatically truncate a long conversation between two people which has been pasted into word.
Input
Jim , 18th November 05:23
Hi!
Sarah , 19th November 06:03
Hello there
I want to format all text from Jim blue, and all text from Sarah red. In order to do this I think I need to follow this process:
Colour every bit of text red
Find a line starting with "Jim ," and format everything after it blue until it reaches a line which starts with "Sarah ,".
Hope this helps
Public Sub ColorMeRedBlue()
Selection.HomeKey Unit:=wdStory
color_the_text = False
For Each line_in_para In ActiveDocument.Paragraphs
text_in_line = line_in_para.Range.Text
check_name = Split(text_in_line, " ")
If InStr("Jim", check_name(0)) Then
color_the_text = False
ElseIf InStr("Sarah", check_name(0)) Then
color_the_text = True
End If
If color_the_text = False Then
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Font.Color = wdColorRed
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.EndKey Unit:=wdLine
Selection.MoveDown Unit:=wdLine, Count:=1
ElseIf color_the_text = True Then
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Font.Color = wdColorBlue
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.EndKey Unit:=wdLine
Selection.MoveDown Unit:=wdLine, Count:=1
End If
Next line_in_para
End Sub

Somehow indicate last line in Word VBA

I have a macro that I use to highlight lines of to do lists to see which step I am on. It's pretty simple. It unhighlights the current line and highlights the next line.
Sub Highlight_Next_Row_Down()
Selection.EndKey Unit:=wdLine
Selection.HomeKey Unit:=wdLine, Extend:=wdExtend
Selection.Range.HighlightColorIndex = wdNoHighlight
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.EndKey Unit:=wdLine
Selection.HomeKey Unit:=wdLine, Extend:=wdExtend
Selection.Range.HighlightColorIndex = wdYellow
End Sub
Now, I want it to just unhighlight the current line when I am on the last line of the document, because then I am finished. I would do this by inserting an if statement around the whole thing (minus the sub statements) which first checks if it's the last line. But, I don't know how to check if a line is the last line. I have googled and haven't found anything.
Similarly, I have a "Highlight_Next_Row_Up" and I want to know how to do the same when I reach the top line.
Thanks for any help
I'm not sure if this is the exact logic you need but this code presenting one of possible way of checking if you are in last line of document.
Sub Highlight_Next_Row_Down()
Selection.EndKey Unit:=wdLine
Selection.HomeKey Unit:=wdLine, Extend:=wdExtend
'here check if this is the end
If Selection.End = ActiveDocument.Bookmarks("\EndOfDoc").Range.End Then
'just unhighlight
Selection.Range.HighlightColorIndex = wdNoHighlight
Else
'your code here
Selection.Range.HighlightColorIndex = wdNoHighlight
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.EndKey Unit:=wdLine
Selection.HomeKey Unit:=wdLine, Extend:=wdExtend
Selection.Range.HighlightColorIndex = wdYellow
End If
End Sub
Please keep in mind that any additional empty paragraph moves end of document somewhere below your the last line of your TEXT.
Another approach one could take is to set take advantage of the MoveDown method's ability to return a variable. If, instead of:
Selection.MoveDown Unit:=wdLine, Count:=1 ,
you write:
c = Selection.MoveDown(wdLine,1) ,
then the variable c will assume a value equal to however many units the selection actually moves. So, as long as the selection is in the body of the text, it moves down one line and c = 1. Whereas, at the end of text, the selection can't move down another line, and so c = 0. That way you set up a simpler control condition:
If c = 0 then...
Do until c = 0...
etc