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?
OnErr0r
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
Option Explicit
Dim NumericOnly As cEvents
Private Sub Form_Load()
Set NumericOnly = New cEvents
NumericOnly.Add Text1
NumericOnly.Add Text2
NumericOnly.Add Text3
MsgBox "You can only type numbers in any textbox in the collection class"
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set NumericOnly = Nothing
End Sub
' begin cEvent.cls
Option Explicit
Public WithEvents txtText As TextBox
Private Sub txtText_Change() ' handle pasting
If Not IsNumeric(txtText.Text) Then txtText.Text = vbNullString
End Sub
Private Sub txtText_KeyPress(KeyAscii As Integer) ' numeric only and backspace
If (KeyAscii < 48 Or KeyAscii > 57) And Not KeyAscii = vbKeyBack Then KeyAscii = 0
End Sub
' begin cEvents.cls (note it's plural)
Option Explicit
' 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
Else
mColGenerics.Add clsAny, Key
End If
Set Add = clsAny ' Return a reference to the new textbox
End Function
Public Function Count() As Long
Count = mColGenerics.Count
End Function
Public Sub Delete(ByVal Index As Variant)
mColGenerics.Remove Index
End Sub
Public Function Item(ByVal Index As Variant) As cEvent
Set Item = mColGenerics.Item(Index)
End Function
Public Function NewEnum() As IUnknown ' Tools - Procedure attributes - NewEnum - Advanced - Procedure ID = -4
Set NewEnum = mColGenerics.[_NewEnum]
End Function
Private Sub Class_Initialize()
Set mColGenerics = New Collection
End Sub
Private Sub Class_Terminate()
Set mColGenerics = Nothing
End Sub
passel
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
End Sub
Private Sub Label1_Click(Index As Integer)
mylabClick Label1(Index), Index, 1
End Sub
Private Sub Label2_Click(Index As Integer)
mylabClick Label2(Index), Index, 2
End Sub
Thanks for the suggestions, but I actually found an easy way round, and only needed a single larger array.
Lar_19
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
End Sub
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.