vba - Passing a parameter to an event handler procedure -
i generating scripting dictionary using 1 button on userform, using populate listbox, , need use same dictionary using second button on form. have declared dictionary either using binding so:
dim isindict new scripting.dictionary
or late binding so
dim isindict object ... set isindict = createobject("scripting.dictionary")
when try pass dictionary other button so:
private sub okbutton_click(isindict scripting.dictionary) 'if binding private sub okbutton_click(isindict object) 'if late binding
i following error: "procedure declaration not match description of event or procedure having same name" on line.
any ideas i'm doing wrong?
an event handler has specific signature, owned specific interface: can't change signature, otherwise member won't match interface-defined signature , won't compile - you've observed.
why that?
say have commandbutton
class, handles native win32 messages , dispatches them - might this:
public event click() private sub handlenativewin32click() raiseevent click end sub
now somewhere else in code, want use class , handle click
event:
private withevents mybutton commandbutton private sub mybutton_click() 'button clicked end sub
notice handler method named [eventsource]_[eventname]
- that's hard-wired in vba, , can't change that. , if try make interface public members have underscores in names, you'll run problems. that's why pascalcase
(without underscores) no matter in standard libraries.
so compiler knows you're handling mybutton.click
event, because there's method named mybutton_click
. looks @ parameters - if there's mismatch, wrong: that parameter isn't on interface, how event provider going supply parameter?. throws compile-time error, telling you need either make signature match, or rename procedure doesn't it's handling mybutton.click
anymore.
when drop control onto form, you're getting public withevents button1 commandbutton
module-level variable, free: that's how can use button1
in code refer specific button, , how click
handler procedure named button1_click
. note if rename button not handler, procedure no longer handle button's click
event. can use rubberduck's refactor/rename tool on form designer correctly rename control without breaking code.
variables in vba can in 1 of 3 scopes: global, module, or procedure level.
when do:
sub dosomething() dim foo end sub
you're declaring local-scope variable.
every module has declarations section @ top, can declare module-scope variables (and other things).
option explicit private foo sub dosomething() end sub
here foo
module-scope variable: every single procedure in module can access - read , write.
so if have data want pass between procedures , can't alter signatures, next best option declare module-scope variable.
[ignores global scope on purpose]
about as new
- consider this:
public sub test() dim foo collection set foo = new collection set foo = nothing foo.add 42 debug.print foo.count end sub
this code blows run-time error 91 "object variable not set", because when foo.add
executes, foo
's reference nothing
, means there's no valid object pointer work with. consider this:
public sub test() dim foo new collection set foo = nothing foo.add 42 debug.print foo.count end sub
this code outputs 1, because as new
keeps object alive in weird, unintuitive , confusing way. avoid as new
possible.
Comments
Post a Comment