I have a UserForm that reads data from a file and dynamically fills a Frame control with other Frame controls that themselves are filled with Labels describing that data. So, there's one big Frame control — DisplayFrame — put onto the UserForm using the Toolbox, and at runtime when the file is opened other smaller Frame controls — cFrame1, cFrame2, etc — are added inside the DisplayFrame control, with labels like NameLabel, DateLabel, added to each cFrame.
I'd like the user to be able to select any of the cFrames, then click a button on the user form and for another window to open with all of the data inside the labels (plus additional data) in that cFrame.
By select, I mean that when the user clicks on ANY of the labels inside a particular cFrame — or the cFrame itself — the color of the cFrame and all its elements change and that particular cFrame is recorded as being the current selection. The tricky part, I think, is that the color of any previously selected cFrame should change back to the default color.
I've created a Class called FrameGroup to hold all the cFrames that are created. I defined the click event of the FrameGroup class to change color when it is selected and to hold the data of the cFrame just selected.
<<Class FrameGroup>>
Public WithEvents FrameGroup As Frame
Private cName As String
Private cDay As String
Private Sub FrameGroup_Click()
cName = FrameGroup.Controls(0).Caption
cDay = FrameGroup.Controls(1).Caption
' If current cFrame was selected before, then deselect it
' by returning to default color
If FrameGroup.BackColor = &H8000000D Then
FrameGroup.BackColor = &H80000005
FrameGroup.Controls(0).BackColor = &H80000005
FrameGroup.Controls(1).BackColor = &H80000005
Else
' Select cFrame by changing color
FrameGroup.BackColor = &H8000000D
FrameGroup.Controls(0).BackColor = &H8000000D
FrameGroup.Controls(1).BackColor = &H8000000D
End If
End Sub
<<Code for UserForm>>
Dim FrameList() As New FrameGroup
Private Sub UserForm_Initialize()
Dim TextLine As String
Dim Text() As String
Dim LineNo As Integer
' Open file containing saved Color Scales
Open file For Input As #1
LineNo = 0
Do Until EOF(1)
Line Input #1, TextLine
Text = Split(TextLine, ",")
' Making CFrame
Dim currCFrame As Frame
Set currCFrame = DisplayFrame.Controls.Add("Forms.Frame.1", "cFrame" & LineNo, True)
' Adding labels
Dim NameLabel As Control
Set NameLabel = currCFrame.Controls.Add("Forms.Label.1", "Name" & LineNo, True)
Dim DateLabel As Control
Set DateLabel = currCFrame.Controls.Add("Forms.Label.1", "DateCreated" & LineNo, True)
' Increment line number
LineNo = LineNo + 1
' Adding new frame to frame group
ReDim Preserve FrameList(1 To LineNo + 1)
Set FrameList(LineNo).FrameGroup = currCFrame
Loop
' Close file once we are done reading color scales from it
Close #1
End Sub
What happens is that only when the cFrame is clicked does anything happen--not when any of the labels inside are clicked. And I don't know how to make it so that when a cFrame is clicked, the color of the previously selected cFrame is also changed to the default color.
I've tried to look up how to do something like this, and solutions like this seem to bring up a different class module for cFrame and its labels and a intermediary class handling communications between two classes, but this seems complicated. If I followed this design, I'd probably need another intermediary between cFrame and the button being clicked to load data, right? I don't want to make this more complicated than it needs to be, but I also would like to create a sustainable and robust solution. Any help would be appreciated.
Label Click put in and clicking in another frame gives the other frames the default color, Tried to minimize the adjustments to your code below:
'<<Class FrameGroup>>
Public WithEvents FrameGroup As MSForms.Frame
Public WithEvents LabelGroup As MSForms.Label
Private cName As String
Private cDay As String
Private Sub FrameGroup_Click()
Dim ctl As MSForms.Control
cName = FrameGroup.Controls(0).Caption
cDay = FrameGroup.Controls(1).Caption
For Each ctl In FrameGroup.Parent.Controls
ctl.BackColor = &H80000005
Next
FrameGroup.BackColor = &H8000000D
FrameGroup.Controls(0).BackColor = &H8000000D
FrameGroup.Controls(1).BackColor = &H8000000D
End Sub
Private Sub LabelGroup_Click()
Dim ctl As MSForms.Control
cName = LabelGroup.Parent.Controls(0).Caption
cDay = LabelGroup.Parent.Controls(1).Caption
For Each ctl In LabelGroup.Parent.Parent.Controls
ctl.BackColor = &H80000005
Next
LabelGroup.Parent.BackColor = &H8000000D
LabelGroup.Parent.Controls(0).BackColor = &H8000000D
LabelGroup.Parent.Controls(1).BackColor = &H8000000D
End Sub
'<<Code for UserForm>>
Dim FrameList() As New FrameGroup
Private Sub UserForm_Initialize()
Dim TextLine As String
Dim Text() As String
Dim LineNo As Integer
' Open file containing saved Color Scales
Open file For Input As #1
LineNo = 0
Do Until EOF(1)
Line Input #1, TextLine
Text = Split(TextLine, ",")
' Making CFrame
Dim currCFrame As Frame
Set currCFrame = DisplayFrame.Controls.Add("Forms.Frame.1", "cFrame" & LineNo, True)
' Adding labels
Dim NameLabel As Control
Set NameLabel = currCFrame.Controls.Add("Forms.Label.1", "Name" & LineNo, True)
Dim DateLabel As Control
Set DateLabel = currCFrame.Controls.Add("Forms.Label.1", "DateCreated" & LineNo, True)
' Increment line number
LineNo = LineNo + 1
' Adding new controls to frame group
ReDim Preserve FrameList(1 To 3 * (LineNo + 1))
Set FrameList(3 * (LineNo) + 1).FrameGroup = currCFrame
Set FrameList(3 * (LineNo) + 2).LabelGroup = DateLabel
Set FrameList(3 * (LineNo) + 3).LabelGroup = NameLabel
Loop
' Close file once we are done reading color scales from it
Close #1
End Sub