Module variables don't survive CodeModule.InsertLines call
I am trying to add a button to my worksheet during run-time. This button should just display different worksheet that is also created on during run-time. I added button like this:
Dim btnShowTable
Set btnShowTable = ActiveSheet.Buttons.Add(rowRange.Left + 10, rowRange.Top + 10, rowRange.Width - 20, rowRange.Height - 20)
btnShowTable.Caption = "Show table data"
btnShowTable.OnAction = AddClickHandler_ShowSheet("ClickModule", "TableView", tableSheet)
Function AddClickHandler_ShowSheet(ByVal moduleName As String, ByVal btnName As String, ws As Worksheet)
Dim methodName As String
methodName = btnName & "_" & AddClickHandler_GetId() & "_Click"
Dim LineNum As Long
Dim VBCodeMod As CodeModule
Set VBCodeMod = ThisWorkbook.VBProject.VBComponents(moduleName).CodeModule
With VBCodeMod
LineNum = .CountOfLines + 1
.InsertLines LineNum, _
"Sub " & methodName & "()" & Chr(13) & _
" " & ws.CodeName & ".Select" & Chr(13) & _
"End Sub"
End With
AddClickHandler_ShowSheet = moduleName & "." & methodName
End Function
Function that creates the button is in one module while Ad开发者_开发知识库dClickHandler_ShowSheet is in another.
The idea is that I would have separate module that would contain all these click handlers so that I could easily delete all of them. This works ok. The handlers are created and buttons work as expected. The issue that I have is that, when this InsertLines method is called, all of my module variables in a module that contains the function for button creation are lost. I have 4 module variables
Dim xmldoc As New MSXML2.DOMDocument
Dim xmlDataMap() As DataNode
Dim xmlDataMapLast As Integer
Dim xmlTables As Collection
after a call to InsertLines all of them became empty except for xmlDataMapLast which contains correct value of 14.
If I try to debug this method when I step over InserLines call I get an error "Can't enter break mode at this time." and I can't debug anything until my function ends. If I comment out the call to AddClickHandler_ShowSheet my variables remain intact, so it must be something related to that call.
Am I trying to achieve the impossible or am I just doing it the wrong way?
It's no surprise the module is reset.
In fact, I would expect value types to reset, too. It's a bit of surprise
they survive.
Why would you need to store variables in the module you use for code generation?
Store them in a separate module and only use this module for code generation.
Having that said, why would you dynamically add code in the first place?
OnAction
supports parameters:
Sub asdff()
Worksheets(1).Buttons(1).OnAction = "'Module1.ParametrizedHandler 5, ""Hi there""'"
End Sub
Public Sub ParametrizedHandler(ByVal foo As Long, ByVal bar As String)
MsgBox foo, vbInformation, bar
End Sub
Note the absence of parentheses in the call string, and the single quotes around it.
精彩评论