Well, the title is because I had a hard time walking through some unbearable docs and finding what I was looking for so, if these keywords can help for other google searches…
Then, when quitting Excel, all previously marked lines of code are lost and it is very frustrating when you have to go to sleep or Excel crashes 🙂
So, in a moment of pure madness I thought it could be possible, and even not too hard, to just save those line bookmarks and restore them at start up…
You will tell me there are other choices: don’t sleep.. or use some powerful add-ins like MZ-Tools or Rubberduck, but I would like to have a native solution and understand what the problem is.
To cut to the edge, here is the core of my problem:
'sub to move cursor to a selected line and add a line bookmark: Public Sub AddBmkOnly(ByVal CompName As String, ByVal numLine As Long) Application.VBE.VBProjects("VBAProject") _ .VBComponents(CompName).CodeModule.CodePane _ .SetSelection numLine, 1, numLine, 1 Application.VBE.CommandBars("Edit").Controls(18).Controls(1).Execute 'the only way I could find it to work End Sub
1) with only one call it works!
Public Sub test_addBmk() Call AddBmkOnly("module 1", 10) End Sub
2) once there are more, or in a loop for example:
Public Sub test_addBmk() Call AddBmkOnly("module 1", 10) 'cursor is just moved to selected line Call AddBmkOnly("module 2", 5) 'line bookmark is added only in the last opened/activated/selected/visible/shown/focused on..? codepane '... End Sub
Place your cursor inside the 2nd
test_addBmk, run and you will see a beautiful cyan blue mark appearing in the margin of your “module 2” at line 5 but that’s all, no where else.
I well tried to add this kind of lines in
AddBmkOnly to keep focus/active state, but it has no effect:
With Application.VBE.VBProjects("VBAProject").VBComponents(CompName) .Activate .CodeModule.CodePane.Window.SetFocus .CodeModule.VBE.ActiveCodePane.Show '...? end with
I tried adding some
Debug.Print, loop to 1M or likes to see if it was due to some latency/refreshing effect, but no effect either.
It could have something to do with the active state of the module or codepane window, but I can’t find a working combination (also, closing the last pane –
.ActiveCodePane.Window.Close – will avoid a bookmark to be added too).
It seems also that the focus is lost before an anchor is added, whatever I try, or the ‘add bookmark’ menu action doesn’t see where to apply…. or it is something else…
test_addBmk() multiple times doesn’t work neither, the only way I found is creating ‘one action’ buttons in an Excel sheet, as many as the number of bookmarks I needed… that’s not funny.
What am I doing wrong? Is it even possible the way I’m trying? How can I add more than a single bookmark?
You need to active the code pane before you invoke the menu item:
Public Sub AddBmkOnly(ByVal CompName As String, ByVal numLine As Long) Dim editor As VBE Dim project As VBProject Dim component As VBComponent Set editor = Application.VBE Set project = Application.VBE.VBProjects("VBAProject") Set component = project.VBComponents(CompName) component.CodeModule.CodePane.SetSelection numLine, 1, numLine, 1 component.Activate Application.VBE.CommandBars("Edit").Controls("&Toggle Bookmark").Execute 'the only way I could find it to work... almost[*] End Sub
Note that this won’t work if you try to step through it in a debugger, because each time you step it sets the active pane back to the code that you’re executing.
A couple other notes:
- You should be testing the number of code lines before trying to set the selection – if
numLineis higher than the lines of code in the module, that’s an application error.
Callshould be considered deprecated – there’s absolutely no reason to use it.
- You should avoid hard coding an index in the
Controlscollection – other add-ins can modify these, so who knows what you’ll get.
- Thanks for mentioning Rubberduck! (I’m a contributor)
This version of the above works for me.
Public Sub test_addBmk() Call AddBmkOnly("module1", 10) Call AddBmkOnly("module2", 5) End Sub Public Sub AddBmkOnly(ByVal CompName As String, ByVal numLine As Long) Dim editor As VBE Dim project As VBProject Dim component As VBComponent Set editor = Application.VBE Set project = Application.VBE.VBProjects("VBAProject") Set component = project.VBComponents(CompName) component.CodeModule.CodePane.SetSelection numLine, 1, numLine, 1 component.Activate: DoEvents editor.CommandBars("Edit").Controls("&Toggle Bookmark").Execute DoEvents End Sub