PDA

View Full Version : VBA Open Module at specific (variable) procedure



AerosAtar
02-21-2014, 06:47 PM
I have a form I am attempting to create an 'administration page' for to provide some ease-of-use controls for other administrators who are not as confident with Excel/VBA as I am.

One of the sections on this worksheet lists all of the procedures in modules "ThisWorkbook" and "Module1" in separate lists. What I would like to do is have a button that, when clicked, opens the VBA editor on that module at the procedure listed in the currently highlighted cell (or just open the module if the currently active cell is outside the range containing the list).

I have been looking at the various code sections on Programming In The VBA Editor (http://www.cpearson.com/excel/vbe.aspx), but can't figure out how to adapt these to what I want. I have also been unable to find a suitable solution via a Google search (the only potential solution involved Application.Goto, which doesn't seem to work outside of the active worksheet's module).

I have attached my (still very much in progress) administration page. Note that I am initially building this outside of the forms where it will be used, hence there is not a Module1 module within this workbook.

https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA (https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313859#p313859 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313859#p313859)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313855#p313855 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313855#p313855)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313848#p313848 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313848#p313848)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313843#p313843 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313843#p313843)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313792#p313792 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313792#p313792)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313771#p313771 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313771#p313771)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313767#p313767 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313767#p313767)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313746#p313746 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313746#p313746)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313744#p313744 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313744#p313744)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313741#p313741 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40560&p=313741#p313741)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313622#p313622 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313622#p313622)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313575#p313575 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313575#p313575)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313573#p313573 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313573#p313573)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313563#p313563 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313563#p313563)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313555#p313555 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533&p=313555#p313555)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40533 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40533)
https://www.eileenslounge.com/viewtopic.php?f=39&t=40265&p=313468#p313468 (https://www.eileenslounge.com/viewtopic.php?f=39&t=40265&p=313468#p313468)
https://www.eileenslounge.com/viewtopic.php?f=42&t=40505&p=313411#p313411 (https://www.eileenslounge.com/viewtopic.php?f=42&t=40505&p=313411#p313411)
https://www.eileenslounge.com/viewtopic.php?f=32&t=40473&p=313384#p313384 (https://www.eileenslounge.com/viewtopic.php?f=32&t=40473&p=313384#p313384)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40501&p=313382#p313382 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40501&p=313382#p313382)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40501&p=313380#p313380 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40501&p=313380#p313380)
https://www.eileenslounge.com/viewtopic.php?f=30&t=40501&p=313378#p313378 (https://www.eileenslounge.com/viewtopic.php?f=30&t=40501&p=313378#p313378)
https://www.eileenslounge.com/viewtopic.php?f=32&t=40473&p=313305#p313305 (https://www.eileenslounge.com/viewtopic.php?f=32&t=40473&p=313305#p313305)
https://www.eileenslounge.com/viewtopic.php?f=44&t=40455&p=313035#p313035 (https://www.eileenslounge.com/viewtopic.php?f=44&t=40455&p=313035#p313035)
https://www.eileenslounge.com/viewtopic.php?f=18&t=40411&p=312889#p312889 (https://www.eileenslounge.com/viewtopic.php?f=18&t=40411&p=312889#p312889)
https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA (https://www.youtube.com/channel/UCnxwq2aGJRbjOo_MO54oaHA)

p45cal
02-22-2014, 11:37 PM
I've explored this a bit, it may help you a bit to get started.
I added a module1 and put some random procedures in it.
I populated cells AM23 and below with a list of procedures/functions using your existing code to do that.
I selected one of those cells.
I ran the following macro:
Sub blah()

Dim VBAEditor As VBIDE.VBE
Dim VBProj As VBIDE.VBProject
Dim VBComp As VBIDE.VBComponent
Dim CodeMod As VBIDE.CodeModule

Set VBAEditor = Application.VBE
Set VBProj = VBAEditor.ActiveVBProject
Set VBComp = VBProj.VBComponents("Module1")
Set CodeMod = VBComp.CodeModule

VBAEditor.MainWindow.Visible = True
CodeMod.CodePane.Show
LineNum = CodeMod.ProcStartLine(ActiveCell.Value, vbext_pk_Proc)
CodeMod.CodePane.TopLine = LineNum
CodeMod.CodePane.SetSelection LineNum, 1, LineNum, 1
End Sub

Any use?

AerosAtar
02-24-2014, 04:26 PM
That works almost exactly as I want it to! Thank you! :)

The only thing it is missing is just opening the code module without going to a specific sub/function where the ActiveCell is outside of the range containing the lists/the Cell Value is blank - at the moment either of these scenarios causes it to error. The latter should be easy enough (put an If Then statement in to check whether ActiveCell.Value is NULL), but the former is a little more troublesome. Is there an easy way of checking whether the ActiveCell is in a specific range?

p45cal
02-24-2014, 06:26 PM
Is there only ever going to be one code module? It could be quite restrictive if there were only to be one. Is it always going to have the name Module 1? The recording of a macro will frequently create a new one. I can certainly get the vbe to open at the top of module 1:
Dim VBAEditor As VBIDE.VBE
Dim VBProj As VBIDE.VBProject
Dim VBComp As VBIDE.VBComponent
Dim CodeMod As VBIDE.CodeModule

Set VBAEditor = Application.VBE
Set VBProj = VBAEditor.ActiveVBProject
Set VBComp = VBProj.VBComponents("Module1")
Set CodeMod = VBComp.CodeModule

VBAEditor.MainWindow.Visible = True
CodeMod.CodePane.Show
LineNum = 1
If Not Intersect(ActiveCell, ActiveSheet.Range("AM23:AM36").SpecialCells(2)) Is Nothing Then LineNum = CodeMod.ProcStartLine(ActiveCell.Value, vbext_pk_Proc)
CodeMod.CodePane.TopLine = LineNum
CodeMod.CodePane.SetSelection LineNum, 1, LineNum, 1

As an aside, I note that the code which populates that section of the sheet has the line:
Rng(1, 2).Value = ProcKindString(ProcKind)which tries to put the likes of "Sub or Function" in the cell immediately to the right of where the procedure name is placed, but because the cells are merged nothing gets put there. If you were to unmerge some cells in that vicinity that data could become visible/available, furthermore, you could have an additional cell in the row which contains the name of the module that that procedure is in, for example:
Rng(1, 8).Value = .Name which you could later use, either in a loop to run through the code modules, or to allow the single module to have any name by changing the line:
Set VBComp = VBProj.VBComponents("Module1") to:
Set VBComp = VBProj.VBComponents(ActiveCell(, 8).Value)

AerosAtar
02-24-2014, 07:37 PM
That is perfect, thank you! :)

This form will likely only ever have one module (Module1), plus the individual worksheet modules and ThisWorkbook. I don't envisage the need to add any new 'functions' to this form after adding this administration page - perhaps the odd new button, but nothing as major as this. As for the 'redundant' code - that is basically unedited from where I got it from (shown in the code comments) as I don't like messing with things I don't fully understand more than necessary. ;)

That said, I might step back and have another think about the layout of the admin page. At the moment it is designed mainly so that it all fits on one screen, but there is no real reason why scroll=bad (just my own personal preferences). Perhaps somethign to run past my colleagues.

Thanks again for all your help. :)