The name of a frame in a loop - vba

I want to add a Control in every for in my application. Let's say I have 5 frames...
I want to do someting like this:
Set cControl = Me!iooly&i.Controls.Add("Forms.Label.1", "str12" & i, True)
With cControl
.Caption = "1/2"
.Width = 20
.Height = 8
.Top = 10
.Left = 435
End With
i is a counting variable
the problems is that Me!iooly&i ... Can I do this operation when my frames have names la iooly1, iooly2, iooly3 and so on?

Your Me is presumably a form? This won’t work. Also, the Me!iooly&i syntax doesn’t work, this only works if your string is a constant.
You can use the Forms collection though:
Set cControl = Forms("iooly" & i).Controls.Add(…)
This is assuming that the form already exists. If it doesn’t, you need to first load it.

Related

Adding multiple userform controls at runtime

I have created a userform with a static label to instruct the user to check certain part numbers. The form will also have a static button to submit the input. However, I need the checkboxes to be made at runtime since it won't be certain how many checkboxes there will be every time the form is shown. There would be a max of twelve boxes, but most of the time only one or two boxes would be needed and I'd prefer to show only what's needed instead of having blank checkboxes. I've made a for loop to add the boxes.
Currently I can add one checkbox to the form, but in the record I'm working with there are supposed to be three. Everything that I am seeing online about dynamically adding controls mainly pertains to adding events to the controls, but I don't need events, just the controls. Can anyone see what I need to add/change in my code:
Private WithEvents chkbox As MSForms.CheckBox
Private Sub UserForm_Activate()
For i = 1 To 12
If PNArray(i) Like "A*" And ChangeArray(i) = "New Part Number:" Then
With Me.Controls
Set chkbox = .Add("Forms.checkbox.1", "chkbox" & i, True)
With chkbox
.Width = 108
.Height = 18
.Top = 30 * i
.Left = 54
.Caption = PNArray(i)
End With
End With
End If
Next i
End Sub
Thanks
After some researching, the problem is .Top=30*i. You multiply always by index of array, when you want all checkboxes same distance. You need another variable to do that. Try like this:
Dim ZZ As Byte ' count of checkboxes
ZZ = 0
For i = 1 To 12
If PNArray(i) Like "A*" And ChangeArray(i) = "New Part Number:" Then
ZZ = ZZ + 1 'we increase count of checkboxes
With Me.Controls
Set chkbox = .Add("Forms.checkbox.1", "chkbox" & i, True)
With chkbox
.Width = 108
.Height = 18
.Top = 30 * ZZ 'we position the chekbox according to its rank (first one, second one, third one, and so on).
.Left = 54
.Caption = PNArray(i)
End With
End With
End If
Next i
With this code, it does not matter how many checkboxes you have. It will add them in the right position, in a "podium" style

Can't change dimensions of dynamically added listbox

I have been looking for hours now and I hope someone can help me here.
I am creating a form in vba where I want to dynamically add Listboxes. The listboxes are added, so that goes as planned. However, I can't seem to change the width and heigth of the listbox. All other things are being changed. This is my code:
Dim lb As MSForms.ListBox
Set lb = Me.controls.add("Forms.Listbox.1")
With lb
.ColumnCount = 4
.Left = 180
.Top = 16
.MultiSelect = 1
.Height = 270
.Width = 665
End with
The other thing that I noticed is that Heigth and Width aren't in the property list of the ListBox. Could it be that I use the wrong ListBox type?
EDIT: It get's stranger. When I go through the code line by line, it functions normally and the ListBox size is as I want it.
Try this may be
Me.Controls("Forms.Listbox.1").IntegralHeight = False
or
lb.IntegralHeight = False

Immediate Box (Debug window) Display Separately

I am really sorry if this is a silly question. I would like to display a message box similar to the Immediate window that will sit "always on top" and scroll a countdown while not interrupting the VBA program.
I am essentially crunching numbers for 40,000 rows and each run takes about 15 minutes. I don't know if it's still running or when the current VBA code will complete.
Does anyone have suggestions?
Use the status bar:
Application.StatusBar = "Row " & rowNum & " of " & rowCount
At the end, to clear the status bar:
Application.StatusBar = False
You can do it by displaying modeless user form. Below is an example how to do this.
In order to make this example working properly you need to add new, empty UserForm to your project and change it name to frmProgress.
Sub test()
Dim form As frmProgress
Dim lblProgress As Object
Dim i As Long
'-------------------------------------------------
'Create an instance of user form and show it modeless on the screen.
Set form = New frmProgress
With form
.Width = 200
.Height = 60
.Caption = "Progress"
'Add label for displaying text...
Set lblProgress = .Controls.Add("Forms.Label.1", "lblProgress")
'... and format it to meet your requirements.
With lblProgress
.Width = 200
.Height = 60
.TextAlign = fmTextAlignCenter
.Font.Size = 12
.Top = 6
End With
Call .Show(vbModeless)
End With
For i = 1 To 100000
'(Some code ...)
DoEvents
'Here the new text is inserted on the message box.
lblProgress.Caption = i
Next i
Call form.Hide
End Sub

Control Caption Text is displayed smaller

I'm working on a Userform in Excel that has to be dynamically generated each time. It can list many (100+) lines which are all exactly the same in format. These are generated by the following code snippet.
' ctextbox
Set ctl = .Controls.Add("Forms.Textbox.1")
With ctl
.Top = 12 + linetop
.Left = 464.9
.Width = 140
.Height = 18
.Name = FieldName & "_ctextbox"
End With
' cshow
Set ctl = .Controls.Add("Forms.CommandButton.1")
With ctl
.Top = 13.1 + linetop
.Left = 611.35
.Width = 41.95
.Height = 18
.Name = FieldName & "_cshow"
.Caption = "Show All"
End With
' confirm
Set ctl = .Controls.Add("Forms.Checkbox.1")
With ctl
.Top = 13.5 + linetop
.Left = 659
.Width = 44.95
.Height = 17.25
.Name = FieldName & "_confirm"
.Caption = "Confirm"
End With
It would fine except for a random occurrence where the Confirm checkbox appears smaller than the rest. The screenshot below shows what I mean.
Has anyone experienced this issue before?
I would recommend using repainting the Userform after you have added the controls dynamically.
The Repaint method completes any pending screen updates for a specified form. When performed on a form, the Repaint method also completes any pending recalculations of the form's controls.
This method is useful if the contents or appearance of an object changes and you don't want to wait until the system automatically repaints the area. Me.Repaint simply updates the display by redrawing the form
I had the same issue in that my repaint did not work. I solved this by setting the CheckBox AutoSize property to True and I have no problems anymore.

There is insufficient memory available to complete this operation

I'm running into an unusual problem. I have an application with a multipage that contains about 10 pages and every page contains another multipage with 3-5 pages. The problem was that the app was too "heavy" and I wanted to break it into multiple forms (a form for every page).
In the initial app the form had as I said about 10 pages, with another 3-5 pages on every one of them and on every page there were about 3-20 comboboxes, 4-40 textboxes. All of them were loaded at initialization by executing a piece of code.
Now... I copied the piece of code for every page and added it in the initializations of the form that replaced it.
The code is something like this:
Private Sub UserForm_Initialize()
Dim i As Integer
Dim ws1 As Worksheet
Dim pagini As range
Set ws1 = Worksheets("Config")
Dim cControl As Control
Set cControl = Me.Controls.Add("Forms.Multipage.1", "oly", True)
With cControl
.Width = 650
.Height = 380
.Top = 0
.Left = 0
End With
Me.Controls("oly").Pages.Remove (Page1)
Me.Controls("oly").Pages.Remove (Page2)
For Each pagini In ws1.range("pagoly")
Me.Controls("oly").Pages.Add (pagini)
Next pagini
i = 0
Do While i < 5
Set cControl = Me!oly.Pages(i).Add("Forms.Frame.1", "iooly" & i, True)
With cControl
.Caption = "IO"
.Width = 210
.Height = 340
.Top = 2
.Left = 5
End With
Set cControl = Me!oly.Pages(i).Add("Forms.Frame.1", "niooly" & i, True)
With cControl
.Caption = "nIO"
.Width = 210
.Height = 340
.Top = 2
.Left = 220
End With
Set cControl = Me!oly.Pages(i).Add("Forms.Frame.1", "descriere" & i, True)
With cControl
.Caption = "Descriere"
.Width = 210
.Height = 340
.Top = 2
.Left = 435
End With
Loop
End Sub
So far it just adds the frames on every of the 5 pages of this form. The problem is that I get the "There is insufficient memory available to complete this operation" when I want to run it and I really don't know why. Yet on the previous version which loaded 50 times more stuff there was no problem. Do you have any idea where's the problem because I really don't understand it.
You have
Do While i < 5
'stuff
Loop
and I don't see where i changes value so that the program will exit the loop. Am I missing something?