I have 6 label arrays, each one containing about 80 items each, all of these labels, I want all of the labels to have to same on keypress and on click events etc. Is there an easy way of doing this other than reverting to a single array with 480 items?
09-06-2003, 10:18 AM
I know of a couple ways to do that. One would be to just go ahead and create one event per control array and then call the same function in each event.
The other involves a collection class and adding each control to a collection. That way there is a single event for each control in the collection. Here is how I've seen it done:
' Add three textboxes to your form
' begin form code
Dim NumericOnly As cEvents
Private Sub Form_Load()
Set NumericOnly = New cEvents
MsgBox "You can only type numbers in any textbox in the collection class"
Private Sub Form_Unload(Cancel As Integer)
Set NumericOnly = Nothing
' begin cEvent.cls
Public WithEvents txtText As TextBox
Private Sub txtText_Change() ' handle pasting
If Not IsNumeric(txtText.Text) Then txtText.Text = vbNullString
Private Sub txtText_KeyPress(KeyAscii As Integer) ' numeric only and backspace
If (KeyAscii < 48 Or KeyAscii > 57) And Not KeyAscii = vbKeyBack Then KeyAscii = 0
' begin cEvents.cls (note it's plural)
' Originally found in a vbpj article
Private mColGenerics As Collection
Public Function Add(ByVal txtAny As TextBox, Optional ByVal Key As String = "") As cEvent
Dim clsAny As cEvent
Set clsAny = New cEvent
Set clsAny.txtText = txtAny
If LenB(Key) = 0 Then
mColGenerics.Add clsAny, Key
Set Add = clsAny ' Return a reference to the new textbox
Public Function Count() As Long
Count = mColGenerics.Count
Public Sub Delete(ByVal Index As Variant)
Public Function Item(ByVal Index As Variant) As cEvent
Set Item = mColGenerics.Item(Index)
Public Function NewEnum() As IUnknown ' Tools - Procedure attributes - NewEnum - Advanced - Procedure ID = -4
Set NewEnum = mColGenerics.[_NewEnum]
Private Sub Class_Initialize()
Set mColGenerics = New Collection
Private Sub Class_Terminate()
Set mColGenerics = Nothing
09-06-2003, 10:41 AM
Not being real comfortable with classes yet, myself, I would go with
OnErrOr's first suggestion of having a shared routine that each "group" of
labels would call.
Since I don't know what you want to do with the labels, I'll give an example
where I pass everything that should be needed. You may decide that you can do without some of the parameters.
mylagClick is the common click procedure that each "group" would call
from their click routine. You can pass the label control itself, so that
you could modify it's caption, or make in invisible, or whatever other
property you may want to change.
I also pass the index, and the "group" separately in case you want to
use them, although as in my example, you can get the index from the
label parameter itself, and you could examine the .Name property to
identify the group. You could also store the "group" in the .tag property
and then the only argument in this case would be the control.
Private Sub mylabClick(lab As Label, Index As Integer, grp As Integer)
'lab.Caption = Val(grp) & " " & Val(Index)
lab.Caption = lab.Name & " " & lab.Index
Private Sub Label1_Click(Index As Integer)
mylabClick Label1(Index), Index, 1
Private Sub Label2_Click(Index As Integer)
mylabClick Label2(Index), Index, 2
Thanks for the suggestions, but I actually found an easy way round, and only needed a single larger array.
09-07-2003, 07:45 PM
And you're going to share your discovery, right? :)
Theres nothing particularly clever about my solution, I simply needed to know which column and row a selected item was in. I did this by creating a sub to work it out
Private Sub CalcGridPos()
iSelectedColumn = iSelected Mod iNoColumns
iSelectedRow = Int(iSelected / iNoColumns) + 1
If iSelectedColumn = 0 Then iSelectedColumn = iNoColumns: iSelectedRow = iSelectedRow - 1
I've attached the control i'm working on, its work in progress so the code is abit messy and uncommented. Any comments are welcome.