问题
I might be bad at googling as I couldn't find the answer to below question:
Sub TEST()
Dim sthstring as string
sthstring = "Hello World"
end sub
While we all know it's easy to use msgbox to print "Hello world", is it possible to print out the variable's name (which in this case, "sthstring") and how?
EDIT: please do not provide with answer such as:
Dim someotherstring as string
someotherstring = "sthstring"
as I meant to find a way to print the 'name' of the variable, thanks
回答1:
After reading comments I think you may find this answer useful.
VBA doesn't support reflection just like @Monty Wild has mentioned already but adding references to Microsoft Visual Basic for Applications Extensibility 5.3 grants you the access the VBE object. You can then iterate object modules in your VBA Project and retrieve the entire code for a module in a String format.
Consider the following (Stick it in a new workbook's Module1)
Sub Main()
Dim code As String
code = GetCodeModule("Module1")
Debug.Print code
End Sub
Private Function GetCodeModule(ByVal codeModuleName As String) As String
Dim VBProj As VBIDE.VBProject
Dim VBComp As VBIDE.VBComponent
Dim CodeMod As VBIDE.CodeModule
Set VBProj = ThisWorkbook.VBProject
Set VBComp = VBProj.VBComponents(codeModuleName)
Set CodeMod = VBComp.CodeModule
GetCodeModule = CodeMod.Lines(1, CodeMod.CountOfLines)
End Function
Your code variable now stores the exact code that is in your Module1 you can check that by opening the Immediate Window ctrl+g.
You may want to write/use some sort of a Find function to disassemble the String components to retrieve variable names and values but I wouldn't recommend doing it as it's can get quite tricky.
回答2:
You can go a step further that simply accessing the code.
Updating the excellent code from Pearson to
- show that setting the reference to Microsoft Visual Basic for Applications Extensibility 5.3 isnt a pre-requisite to access the VBIDE
- actually parse out any
Dim XX As Stringin any codemodule and report it
sample output
Dim sthstring As String (Module1 at: Line: 2)
Dim strSub As String (Module2 at: Line: 2)
Dim FindWhat As String (Module2 at: Line: 11)
Dim ProcName As String (Module3 at: Line: 9)
code
Sub GetVariable()
Dim strSub As String
strSub = "As String"
Call SearchCodeModule(strSub)
End Sub
Function SearchCodeModule(ByVal strSub) Dim VBProj As Object Dim VBComp As Object Dim CodeMod As Object Dim FindWhat As String Dim SL As Long ' start line Dim EL As Long ' end line Dim SC As Long ' start column Dim EC As Long ' end column Dim Found As Boolean
Set VBProj = ActiveWorkbook.VBProject
For Each VBComp In VBProj.VBComponents
Set CodeMod = VBComp.CodeModule
With CodeMod
SL = 1
EL = .CountOfLines
SC = 1
EC = 255
Found = .Find(target:=strSub, StartLine:=SL, StartColumn:=SC, _
EndLine:=EL, EndColumn:=EC, _
wholeword:=False, MatchCase:=False, patternsearch:=False)
Do Until Found = False
If Left$(Trim(.Lines(SL, 1)), 3) = "Dim" Then Debug.Print Trim(.Lines(SL, 1) & " (" & CStr(VBComp.Name) & " at: Line: " & CStr(SL)) & ")"
EL = .CountOfLines
SC = EC + 1
EC = 255
Found = .Find(target:=strSub, StartLine:=SL, StartColumn:=SC, _
EndLine:=EL, EndColumn:=EC, _
wholeword:=True, MatchCase:=False, patternsearch:=False)
Loop
End With
Next VBComp
End Function
回答3:
This is difficult to do directly, as VBA does not have reflection, i.e. cannot directly reference itself.
However;
Since in a comment you mention that you want to write code that references itself, you can do so by referencing Microsoft Visual Basic for Applications Extensibility 5.3 in the tools/references dialog. This gives you the ability to reference VBA code, and from there you could write code that prints itself out.
See
- MSFT reference 1, and
- MSFT reference 2
回答4:
That is likely impossible, as variable names are just pointers to data. You can have several variables that all point to the same object (although in VBA I do not believe strings are treated as objects so that would not be possible, with the exception of a ByRef function call).
来源:https://stackoverflow.com/questions/24173082/print-a-variables-name