Link to home
Start Free TrialLog in
Avatar of Richard Quadling
Richard QuadlingFlag for United Kingdom of Great Britain and Northern Ireland

asked on

How do I create a single onClick sub for multiple command buttons.

Hi

I have been given an Access MDB to convert to an ADP. Part of the work is to speed things up and make the code "better".

One part of the application is a touch screen keypad.

Each "button" is a command button. Each button has a tag indicating its value.(0 to 9).

Each button has a separate onclick event handler.

I want to use a single event handler for all buttons.

In Delphi, I can do this and the first parameter of the onclick event handler is the object that generated the click event (normally the button).

So 10 buttons all with the same onclick event handler can be done as the first parameter would be obj_cmd_button and obj_cmd_button.tag would give the tag value (which is all I'm interested in).

How do I do this in MS Access.

Currently the subs are ...

Private Sub cmd0_Click()
    On Error GoTo Err_cmd0_Click
    AddValue (cmd0.Tag)

Exit_cmd0_Click:
    Exit Sub

Err_cmd0_Click:
    MsgBox Err.Description
    Resume Exit_cmd0_Click
End Sub


With 10 of them, it is a bit of a pain.

Now extend that to the alphanumeric keypads!!!! 36 nearly identical subs!!!!

Is there a parameter I can add (like there is in Delphi) ?


Avatar of Richard Quadling
Richard Quadling
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

I found ...

http://msdn.microsoft.com/library/en-us/dv_vstechart/html/controlarrays.asp?frame=true

Specifically ...

The event handler syntax in Visual Basic .NET makes it easier for a set of controls to share event handlers without the need for control arrays. An event handler looks like the following: (RQuadling: This is very similar to Delphi's way - object first and appropriate event parameters next).

Private Sub txtName_Enter(ByVal sender As Object, _
      ByVal e As System.EventArgs) _
      Handles txtName.Enter
End Sub

This event handler manages the Enter event for the text box named txtName. Notice that the generated name of the event handler is similar to the name given to event procedures in Visual Basic 6.0. ****However, in Visual Basic 6.0, the name of the event procedure defined the control and event that the procedure handled.**** In .NET, the event handler name has no intrinsic meaning. The above event handler could be rewritten as:

Private Sub ProcessEnter(ByVal sender As Object, _
      ByVal e As System.EventArgs) _
      Handles txtName.Enter
End Sub


NOTE:**** Have I answerd my own question ? ****
Avatar of Jim Horn
Private Sub cmd0_Click()
Call DoMyStuff(cmd0.Tag)   'or just DoMyStuff(0)
End Sub

Private Sub cmd1_Click()
Call DoMyStuff(cmd1.Tag)   'or just DoMyStuff(1)
End Sub

Private Sub cmd2_Click()
Call DoMyStuff(cmd2.Tag)   'or just DoMyStuff(2)
End Sub

'etc.  Then, include this in your form...

Private Sub DoMyStuff(SomeValue as Whatever)
'Your code goes here
End Sub

Also, not sure if this answers your question, but if you ever want to refer to any of the command buttons, with a variable number (your Tag) in code...

Me("cmd" & SomeVariable)  '... will be the same as hard-typing Me.cmd0 when SomeVariable=0

Hope this helps.
-Jim
So I ABSOLUTELY need to have a sub per event per control. I cannot use 1 sub for many controls?

Ideally I want ...

Private Sub cmd_group_Click(cmd_x)
' cmd_x.Tag is what I want
end sub

and have the onclick event handler for cmd_0, cmd_1, cmd_2, etc all use cmd_group_click
ASKER CERTIFIED SOLUTION
Avatar of Jim Horn
Jim Horn
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks.

"Also, not sure if this answers your question, but if you ever want to refer to any of the command buttons, with a variable number (your Tag) in code...

Me("cmd" & SomeVariable)  '... will be the same as hard-typing Me.cmd0 when SomeVariable=0

Hope this helps.
-Jim"

I just read about "me". Sounds similar to "this" in other languages.
Yep.  Me. takes on the Form object or Report object of wherever the code resides when coding in forms and reports.  
Thanks for the grade.  Good luck with your project.  -Jim
OOI. Is there a "self" concept?

Not sure if I'd ever use one in Access, but static methods, class constants, etc. can be accessed via self
I'm not familiar with 'self'.  What does it do?

>but static methods,
In any separate code module you can always have a Public Sub Whatever(), and it can be called from anywhere in your app.

>class constants
Not sure what you mean here.  You can have public enumercations, and Types, and class objects (>Access'97).

My biggest issue is I don't use ANY MS coding. All PHP now.

And with MDB(Frontend) to MDB(Backend) the code was using DAO.

Now I've got an MS SQL db with the data in it and using an .ADP, I have to use ADO. Which is different.

So it is line by line checking, refactoring where necessary.



With this question, I've converted all the subs to a 1 liner. Looks a lot more readable ...

Private Sub cmd0_Click()
    AddValue (cmd0)
End Sub
...
A static method is a method for a class which can be called OUTSIDE of an instance of the class but has all the mechansims of that class.

A common usage is to have a singleton method which either creates an instance of the class and returns it OR returns the previously created instance.

A class constant is just like any other constant but is only effective with the class.

Maybe VB hasn't got these.
Well, I'm chiming in here about 2 years too late, but I had this same problem in Access.  After scratching my head for several hours, I ran into a solution TOTALLY BY ACCIDENT.  It appears to be an Undocumented "feature" of Acess and/or VBA (probably VBA):

So here's the trick:

1. Declare a class module level variable of the CommandBarButton Type WithEvents:
Dim WithEvents m_mybutton as Office.CommandBarButton
2. When you build your CommandBar, set your module variable (m_mybutton) = to each new commandbarbutton that you add:
Set m_myButton = myCommandBar.controls.add(add your parameters here)
3. For each and every control that you set your variable to, SET THE TAG PROPERTY TO BE THE SAME VALUE
m_myButton.Tag = "WhateverYouLike So Long as It's the same"

Voila!  The m_myButton_click event handles each and every button.

Why, I don't have any clue.

Tim

Ha. That was/is nearly the exact opposite of what I want.

Imagine a calculator. The numbers all work exactly the same. Just the value is different. By setting the tag to the value and having a common procedure which can see the tag.

Having moved from purely MS Access to MS SQL with MS Access frontend, we did the decent thing and turned the whole thing into a web app using PHP.

I'm much happier now than I was then.

Yes, SQL is very cool.  I'm glad you're happier.

I don't think what I propose is the exact opposite of what you want, however.  The only switch you'd have to make is that you'd have to put the calculator value in the .Parameter property or some other property and instead set the .Tag property to be exactly the same for each choice.  In this manner, only one "on_click" event is required and the event can check the .Parameter to see which button was actually clicked.  It's really awesome and elegant - just terribly undocumented.

Actually, I just went back and re-read your original posting.  I see that you're talkng abouot on-screen buttons.  My technique actually works with commandbar buttons, so the functionality might not be the same.

nice to hear from you and glad things are going well.