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
Related
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
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
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
I wanted to develop a program such a way that when up or down arrow moved, highlight the entire line of text. So when I go up or down with arrow keys it highlight the line where my cursor is.
So I developed this code.
Application.ScreenUpdating = False
Dim currentPosition As Range
Set currentPosition = Selection.Range 'pick up current cursor position
Selection.WholeStory
Selection.Range.HighlightColorIndex = wdNoHighlight
currentPosition.Select 'return cursor to original position
Selection.Range.HighlightColorIndex = wdYellow
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Range.HighlightColorIndex = wdYellow
'Unselect the line
Application.Selection.EndOf
Application.ScreenUpdating = True
Then I tried to assign this macro to both Up arrow key and Down arrow key. Then I realised that we can't assign one macro for 2 key combinations. So I created 2 macros like this. (Content is same. Only name is different.).
And assigned SelectLineUp to Up arrow key and assigned SelectLineDown to down arrow key.
Sub SelectLineUp()
Application.ScreenUpdating = False
Dim currentPosition As Range
Set currentPosition = Selection.Range 'pick up current cursor position
Selection.WholeStory
Selection.Range.HighlightColorIndex = wdNoHighlight
currentPosition.Select 'return cursor to original position
Selection.Range.HighlightColorIndex = wdYellow
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Range.HighlightColorIndex = wdYellow
'Unselect the line
Application.Selection.EndOf
Application.ScreenUpdating = True
End Sub
And this is for down arrow
Sub SelectLineDown()
Application.ScreenUpdating = False
Dim currentPosition As Range
Set currentPosition = Selection.Range 'pick up current cursor position
Selection.WholeStory
Selection.Range.HighlightColorIndex = wdNoHighlight
currentPosition.Select 'return cursor to original position
Selection.Range.HighlightColorIndex = wdYellow
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Range.HighlightColorIndex = wdYellow
'Unselect the line
Application.Selection.EndOf
Application.ScreenUpdating = True
End Sub
Now the problem is when I press down arrow in the keybord it works as I intended. But when I press Up arrow, it still goes down dirrenction in the document. Highly appreciate if you can tell me what I have done wrong.
The following works for me. I used some additional methods for changing the Selection (or Range) locations, such as MoveEnd, MoveStart and Collapse. Note the change for the highlight setting of the entire document, so that you don't have to change the Selection.
If you use F8 to step through the code, and switch between the VBA Editor and document windows, you can see how these methods work. The details can be found in the VBA Help.
Sub SelectLineUp()
Application.ScreenUpdating = False
ActiveDocument.content.HighlightColorIndex = wdNoHighlight
Selection.MoveEnd wdLine, -1
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Range.HighlightColorIndex = wdYellow
'Unselect the line
Application.Selection.StartOf
Application.ScreenUpdating = True
End Sub
Sub SelectLineDown()
Application.ScreenUpdating = False
ActiveDocument.content.HighlightColorIndex = wdNoHighlight
Selection.MoveStart wdLine, 1
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.Range.HighlightColorIndex = wdYellow
'Unselect the line
Application.Selection.Collapse wdCollapseStart
Application.ScreenUpdating = True
End Sub
Try this out. This works for me, while keeping the code very DRY.
Option Explicit
Private Declare Function GetKeyState Lib "user32.dll" (ByVal nKey As Long) As Integer
Public Sub KeyUpOrDown()
Dim keyUp As Boolean
keyUp = CBool(GetKeyState(vbKeyUp) And &H80) ' Was "keyup" pressed
If (keyUp) Then
Selection.MoveUp Unit:=wdLine
Call HighlightLine
Else
Selection.MoveDown Unit:=wdLine
Call HighlightLine
End If
End Sub
Private Sub HighlightLine()
Application.ScreenUpdating = False
Dim currPosition As Range
Set currPosition = Selection.Range
ActiveDocument.Content.HighlightColorIndex = wdNoHighlight
Selection.Expand Unit:=wdLine
Selection.Range.HighlightColorIndex = wdYellow
currPosition.Select
End Sub
Both trigger keys can be bounded to the public subroutine "KeyUpOrDown".
I like the way this works, because it has a native feel. As you hinted in your code, the selection point does not get collapsed to one side but it maintains it's original position while switching line.
Another big one is the simulated key press event using the external "user32.dll" library.
I hope you'd find it useful.
Thank you.
A little performance improvement in the accepted answer. Un highlighting whole document takes too much time if you have 400 pages book. Also the code doesn't return you to same cursor position.
I have modified the code a little bit to solve both issues:
Add this to declaration section.
Dim currSelection As Range
bind these macros to up and down keys
Sub UpKey()
Application.ScreenUpdating = False
'get current position
Dim currPosition As Range
Set currPosition = Selection.Range
'remove highlight from previous line
If Not currSelection Is Nothing Then
currSelection.HighlightColorIndex = wdNoHighlight
End If
'move and highlight new line
Selection.MoveUp Unit:=wdLine
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Set currSelection = Selection.Range
Selection.Range.HighlightColorIndex = wdYellow
'get back to old spot and move the line
currPosition.Select
Selection.MoveUp Unit:=wdLine
Application.ScreenUpdating = True
End Sub
Sub DownKey()
Application.ScreenUpdating = False
Dim currPosition As Range
Set currPosition = Selection.Range
If Not currSelection Is Nothing Then
currSelection.HighlightColorIndex = wdNoHighlight
End If
Selection.MoveDown Unit:=wdLine
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Set currSelection = Selection.Range
Selection.Range.HighlightColorIndex = wdYellow
currPosition.Select
Selection.MoveDown Unit:=wdLine
Application.ScreenUpdating = True
End Sub
Note: If for some reason a row stays highlighted then take cursor to the row and move up or down once.
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