I am attempting to loop the a specific set of frames within each Multipage page in my VBA User_Form. However, it does not seem like I can use a variable object name with each frame control like I can with the pages.
I am getting an error
object doesn't support this property or method
at the following line
For Each cCont in Me.MultiPage1.Pages(PageName).Frames(DataFrame).Controls
My Code
Do While x <= Me.MultiPage1.Pages.Count
PageName = "Page" & CStr(x)
DataFrame = "DataFrame" & CStr(x)
For Each cCont In Me.MultiPage1.Pages(PageName).Frames(DataFrame).Controls
You actually can't iterate the way you would think you could.
First, you need to iterate through all Pages of your MultiPage1.
Second, loop through all Controls inside the current Page , and check if they are of type Frame, if they are you can iterate inside the Frame but the syntax is a little different (see in the code below).
Code
Option Explicit
Private Sub IterateIn_MultiPage()
Dim x As Long, j As Long
Dim cCont As Control
For x = 0 To Me.MultiPage1.Pages.Count - 1 ' <-- loop through all MultiPage Pages
For Each cCont In Me.MultiPage1.Pages(x).Controls ' <-- loop through controls of current page
If TypeOf cCont Is Frame Then ' <-- check if control type is Frame
For j = 0 To cCont.Controls.Count - 1 '<-- loop through all items related to the current Frame collection
MsgBox cCont.Controls(j).Name '<-- display a message box
Next j
End If
Next cCont
Next x
End Sub
Thanks for the help on putting together the code #Shai, for anyone else wondering what the final code looks like here it is. This loops through each frame within each multipage and pastes the caption of checked checkboxes in my desired range.
Option Explicit
Sub IterateIn_MultiPage()
Dim x As Long, j As Long
Dim cCont As Control
Dim counter As Integer
Dim y As Integer
Dim Range As String
y = 1
For x = 0 To ImportData.MultiPage1.Pages.Count - 1
counter = 0
For Each cCont In ImportData.MultiPage1.Pages(x).Controls
Do While counter < 1
If TypeOf cCont Is Frame Then
For j = 0 To cCont.Controls.Count - 1
If cCont.Controls(j).Value = True Then
Range = "E" & y
If counter = 0 Then
Worksheets("Calculations").Range(Range) = cCont.Controls(j).Caption
counter = counter + 1
ElseIf counter = 1 Then
Worksheets("Calculations").Range(Range) = Worksheets("Calculations").Range(Range) & " & " & cCont.Controls(j).Caption
y = y + 1
End If
End If
Next j
End If
Loop
Next cCont
Next x
End Sub
Related
Hello,
I am trying to set up a form which is a calendar from which the user can select a date (by default the current month appears). The form consists of 42 command buttons (I have left the default name ie. CommandButton1) which I am setting the day number.
At the moment I have a long-winded section of code for each button (I used Excel to generate this rather than type it all out) which locks and hides the button if it is outside of the month in question which looks like this:
NewDate.CommandButton1.Caption = Format(DATlngFirstMonth - DATintDayNumFirst + DATintX, "dd")
If DATintX < DATintDayNumFirst Then
With NewDate.CommandButton1
.Locked = True
.Visible = DATbooShowExtraDays
.ForeColor = RGB(150, 150, 150)
End With
Else
With NewDate.CommandButton1
.Locked = False
.Visible = True
.ForeColor = RGB(0, 0, 0)
End With
End If
I know that I can refer to a command button by:
Dim objCommandButton As Object
Set objCommandButton = NewDate.CommandButton1
..which neatens the code up somewhat. But what I would like to do is refer to the command button as a string so I can loop through all 42, ie.
Dim n as integer
n = 1
Do Until n > 42
Set objCommandButton = NewDate.CommandButton & n
'Some operations
n = n + 1
Loop
Many thanks in advance for assistance.
You can loop through all controls of the form. Try
Sub LoopButtons()
Dim it As Object
For Each it In NewDate.Controls
Debug.Print it.Name
Next it
End Sub
Then you can put conditional expression (if ... then) in place of Debug.Print or whatever. For example
If Instr(it.Name, "CommandButton") Then
'do your code
end if
Here's code which iterates over ActiveX controls on active sheet:
Sub IterateOverActiveXControlsByName()
Dim x As Integer
Dim oleObjs As OLEObjects
Dim ctrl As MSForms.CommandButton
Set oleObjs = ActiveSheet.OLEObjects
For x = 1 To 10
Set ctrl = oleObjs("CommandButton" & x).Object
Next
End Sub
(For future reference) Is it possible do something like this
For i = 0 to 11
array(i) = Label(i)
Next
Instead of brute forcing it by making 12 lines of something like
array(0) = Label0, array(1) = Label1, etc.
yes it is
for instance
Private Sub CommandButton1_Click()
ReDim myArray(0 To Me.Controls.count - 1) As MSForms.Label '<~~ declare this array with the maximum possible dimensions
Dim lblCounter As Long
Dim ctrl As MSForms.Control
With Me '<~~ this refers to the UserForm object of which code pane you placed this code into
For Each ctrl In .Controls '<~~ loop through UserForm controls
If TypeName(ctrl) = "Label" Then '<~~ if you find a "Label"...
Set myArray(lblCounter) = ctrl '<~~ ... then store it in your array...
lblCount = lblCounter + 1 '<~~ ... and update the label counter
End If
Next ctrl
End With
If lblCounter > 0 Then ReDim Preserve myArray(0 To lblCounter - 1) '<~~ if you actually found at least one label, then redim your array with proper dimensions
End Sub
of course you can place it in any event sub/eventhandler that has access to your Userform Controls collection
I have a 16*16 matrix and I'm trying to define them as a matrix series in vb.net. Then i make some visual shows with this matrix like led shows.
Dim n As Integer = 16
Dim l As Integer = 16
Dim x(n - 1, l - 1) As Integer
Dim i, j, k As Integer
For i = 0 To n - 1
For j = 0 To l - 1
For k = 1 To 256
If j= k mod16 then
buton(k) = x(i, j)
end if
Next
Next
Next***
I try to apply an algorithm. But it doesn't work. How can i accomplish this? Thanks for your interests..
OK I wrote something like this a while ago - I've adapted it to your needs and it runs ok on my pc. You need to create you array X like this
Dim x(15,15) As Button
To fill the array with buttons, use this method..
Private Sub InitializeArray()
Dim btnslist As New List(Of Button)
Dim btnNum As Integer
Dim btnName As String
Dim splitButtonName() As String
'add all the buttons to a list
For Each btnControl As Object In Controls
Dim btn As Button
'get button number and add it to the list if it is >0 and <=256
If TypeOf btnControl Is Button Then
btn = CType(btnControl, Button)
'get the button number
splitButtonName = Split(btn.Name, "n")
If CInt(splitButtonName(1)) > 0 And CInt(splitButtonName(1)) <= 256 Then
btnslist.Add(btn)
End If
End If
Next
'add the buttons to the matrix in the right order
For i As Integer = 0 To 15
For j As Integer = 0 To 15
For k As Integer = 0 To 255
btnNum = i * 16 + j + 1
btnName = "Button" & btnNum.ToString
If btnslist(k).Name = btnName Then
x(i, j) = btnslist(k)
Exit For
End If
Next
Next
Next
End Sub
i made a report for taking output of employees in a company.i made a code for that.but it only show the first items checked.how to impliment for loop in this.
Dim i As Integer
Dim j As Integer
Dim k As Integer
For i = 0 To Employee_Bank_dtl.CheckedListBox1.Items.Count - 1 Step i + 1
If Employee_Bank_dtl.CheckedListBox1.GetItemCheckState(i) = CheckState.Checked Then
Dim xx As String = (CType(Employee_Bank_dtl.CheckedListBox1.Items(i), DataRowView))("VC_BRNAME")
For j = 0 To Employee_Bank_dtl.CheckedListBox2.Items.Count - 1 Step j + 1
If Employee_Bank_dtl.CheckedListBox2.GetItemCheckState(j) = CheckState.Checked Then
Dim yy As String = (CType(Employee_Bank_dtl.CheckedListBox2.Items(j), DataRowView))("vc_empstatus")
For k = 0 To Employee_Bank_dtl.CheckedListBox3.Items.Count - 1 Step k + 1
If Employee_Bank_dtl.CheckedListBox3.GetItemCheckState(k) = CheckState.Checked Then
Dim zz As String = (CType(Employee_Bank_dtl.CheckedListBox3.Items(k), DataRowView))("vc_value")
Dim str = "xxxxxxxxxxxxxx"
conobj.readdata(str)
conobj._adpt.Fill(Me.DataSet10.BRANCH_MAST)
Me.ReportViewer1.RefreshReport()
End If
Next
End If
Next
End If
Next i
You should increment through the collection of items like this not the way you are doing it. You should be able to find the properties you are looking for. Set a break point within the inner loop and right click on quickwatch on the item and you will see all the properties of that item which will contain what your looking for.
For Each item In CheckedListBox1.Items
'set the item property to the right property that holds "VC_BRNAME"
If item.property = "VC_BRNAME" Then
End If
If item.checkstate.checked = True Then
End If
Next
Its my mistake replacing k + 1 to +1 in the 3rd loop will got the right answer
I have UserForm4 which contains CheckBox1...19 and also OptionButton1...3, along with TextBox1, CommandButton1, 2.
When OptionButton 1 = True I want to loop through all CheckBoxes and set each to True.
The error I get states "Cannot find object" and i = 21, n = 23. How are they getting that high, when I only have 19 CheckBoxes?
Thanks!
Private Sub OptionButton1_Click()
Dim ctrl As Control
Dim i As Integer
Dim n As Integer
n = 0
For Each ctrl In UserForm4.Controls
If TypeOf ctrl Is MSForms.CheckBox Then
n = n + 1
End If
Next ctrl
For i = 1 To n
If UserForm4.Controls("CheckBox" & i) = False Then
UserForm4.Controls("CheckBox" & i) = True
End If
Next i
End Sub
Did you create more than 19 initially and delete some? Each VBA object has a unique name. Doing this the way you are doing it is likely to cause all sorts of problems.
For example, if you create 10 CheckBoxes and delete 8 of them, the remaining two might be named Checkbox8 and Checkbox9. So your loop will not hit them at all.
Also, why not do something like the following:
Private Sub OptionButton1_Click()
Dim ctrl As Control
Dim i As Integer
Dim n As Integer
n = 0
For Each ctrl In UserForm4.Controls
'this will make your problem really obvious
debug.print ctrl.name
If TypeOf ctrl Is MSForms.CheckBox Then
ctrl.value = True
End If
Next ctrl
End Sub