I am using a form to show outstanding work. the code creates a number of textboxes based on the number of rows used on a sheet call "Jobcardslive"
I can get it to create the right number of textboxes on the form but i would also like to populate the textboxes with a value stored in Row A
e.g If I have 4 rows populated on the sheet it will create 4 textboxes named vehicle1 - 4 etc
I would also like it to populate vehicle1 with A1 from the sheet and vehicle2 with A2 etc
The boxes are created fine
the code i am using at the moment is
Dim txtB1 As Control
Dim TextBox_Name As String
Dim f As String
f = ThisWorkbook.Sheets("Jobcardslive").Range("A" & Rows.Count).End(xlUp).Row - 1
Dim i
For i = 0 To f
Set txtB1 = Controls.Add("Forms.TextBox.1")
With txtB1
.Name = "vehicle" & i
.Height = 20
.Width = 200
.Left = 10
.Top = 10 * i * 2
End With
Next i
Any help would be greatly appreciated
you could go like follows:
Dim txtB1 As MSForms.TextBox '<--| declare it as a TextBox instead of Control, to have Intellisense show you real `Textbox` object specific members
Dim i As Long
With ThisWorkbook.Sheets("Jobcardslive")
For i = 1 To .Range("A" & .Rows.Count).End(xlUp).Row
Set txtB1 = Me.Controls.Add("Forms.TextBox.1")
SetTextBox txtB1, i, Range("A" & i).value
Next i
End With
thus also demanding to the following specific Sub SetTextBox the task of properly initializing the textbox:
Sub SetTextBox(txtB As MSForms.TextBox, i As Long, v As Variant)
With txtB
.name = "vehicle" & i
.height = 20
.Width = 200
.Left = 10
.Top = 10 * i * 2
.value = v
End With
End Sub
Related
I'm trying to make a grid of Option Buttons from about 10x60 and would like to do so with VBA, but I can't get the attribute changing to work.
So far I got this:
Sub Buttons()
Dim i As Integer
Dim j As Integer
Dim k As Integer
k = 48
For i = 8 To 9
For j = 5 To 15
ActiveSheet.Shapes.Range(Array("OptionButton" & k)).Select
k = k + 1
Selection.Copy
With Sheets("Weekreview")
.Cells(i, j).Select
.Paste
.Shapes.Range(Array("OptionButton" & k)).Select
.OptionButtons(k).GroupName = i - 1
.OptionButtons(k).LinkedCell = Range(j, i)
End With
Next
Next
End Sub
The problem with this is that the program errors at .OptionButtons(k).GroupName with the message "Unable to get the OptionButtons property of the Worksheet class".
Anyone who can help me?
Edit 1: My first try (before I tried pretty much all the ways I could find googling the issue) was to use Selection.GroupName, this didn't work either. It looks like it can't access the attributes. So either the attribute changing is wrong, or the selection is wrong.
Edit 2: I got the entire program working except the changing of the GroupName of an existing OptionButton. Even though Selection.LinkedCell works, Selection.GroupName doesnt.
Your code copy and paste OptionButton & k then refers to OptionButton & k+1 (object doesn't exist).
Look at line were k is incremented:
k = k + 1
Please change all the words
ActiveSheet.Shapes.Range(Array("OptionButton" & k))
to
ActiveSheet.Shapes.Range("Option Button " & k)
Please try this code:
Sub Buttons()
Dim i As Integer
Dim j As Integer
Dim k As Integer
k = 48
For i = 8 To 9
For j = 5 To 15
ActiveSheet.Shapes.Range(Array("OptionButton" & k)).Select
k = k + 1
Selection.Copy
ActiveSheet.Paste
With Selection
.Name = "OptionButton" & k
.Top = Worksheets("Weekreview").Cells(i, j).Top
.Left = Worksheets("Weekreview").Cells(i, j).Left
.GroupName = i - 1
.LinkedCell = Range(j, i)
End With
Next
Next
End Sub
Controls with a naming convention of TypeName# are ActiveX controls (e.g. "OptionButton1","TextBox1"). The object itself is wrapped in an OLEObject. ActiveX controls on a Worksheet should be references using the Worksheet's OLEObjects collection.
Properties not available directly from the OLEObject can be access by the OLEObject.Object.
Sub Buttons()
Application.ScreenUpdating = False
Dim opt As OLEObject
Dim cell As Range
With Sheets("Weekreview")
For Each cell In Range(Cells(8, 5), Cells(9, 15))
Set opt = .OLEObjects.Add(ClassType:="Forms.OptionButton.1", Link:=False, DisplayAsIcon:=False, Width:=108, Height:=21)
With opt
.Left = cell.Left
.Top = cell.Top
.Width = cell.Width
.LinkedCell = cell
.Name = cell.Address(False, False)
With opt.Object
.GroupName = cell.Row
.Caption = cell.Address(False, False)
End With
End With
Next
End With
Application.ScreenUpdating = True
End Sub
I'm trying to create an array of option buttons (or check boxes if you find that works better) where only one option can be selected in each row and column.
I'm trying to do this so that a user can choose an order in which a certain list goes.
The following code takes the column headers in an excel sheet, and creates bunch of option buttons x columns across and x rows down.
Sub Option_Buttons()
Dim str As String
lCol = Sheets("Headers").UsedRange.Columns.Count
Dim OpBtn() As OptionButton
ReDim OpBtn(lCol, lCol) As OptionButton
Dim GrBx() As GroupBox
ReDim GrBx(lCol) As GroupBox
Dim i
Dim j
'
For i = 1 To lCol
Set GrBx(i) = Sheets("OPBTN").GroupBoxes.Add(Cells(i, 1).Left, _
Cells(i, 1).Top, lCol * 50, 17.25)
With GrBx(i)
.Caption = ""
'.Visible = False
End With
For j = 1 To lCol
Set OpBtn(i, j) = Sheets("OPBTN").OptionButtons.Add _
(Cells(i,j).Left, Cells(i, j).Top, 72, 17.25)
str = Sheets("Turf").Cells(1, j)
check = OpBtn(i, j).Value
With OpBtn(i, j)
.Caption = str
.Value = xlOff '
.LinkedCell = "'OData'!" & Sheets("OData").Cells(i, 1).Address
.Display3DShading = False
End With
Next
Next
End Sub
Is there any way I can make it so that only one option can exist in each row AND column? (so if there are 5 column headers, there are 25 option buttons of which only 5 can be selected).
Is there any way to deal with the option that a user doesn't want a header selected?
I'm trying to avoid all possible uses of the controls tab because this is part of a macro that needs to be used by completely excel illiterate people and needs to be applied to highly variable
I was able to accomplish this using checkboxes. The key was to name the checkboxes using R1C1 notation and assigning a macro (ManageCheckBoxes) to all the checkboxes. After identifying what checkbox was clicked using Application.Caller I iterate over all the checkboxes parsing their names to identify which rows and columns they are in.
Sub Option_Buttons()
Dim str As String
Dim r As Integer, c As Integer
Dim check As CheckBox
lCol = Sheets("Headers").UsedRange.Columns.Count
With Sheets("OPBTN")
For r = 1 To lCol
For c = 1 To lCol
Set check = .CheckBoxes.Add(.Cells(r, c).Left, .Cells(r, c).Top, 72, 17.25)
str = Sheets("Turf").Cells(r, c)
With check
.Caption = str
.Value = xlOff '
.Name = "R" & r & "C" & c
.Display3DShading = False
.OnAction = "ManageCheckBoxes"
End With
Next
Next
End With
End Sub
Sub ManageCheckBoxes()
Dim arrCaller As Variant, arrCheck As Variant
Dim check As CheckBox, ckCaller As CheckBox
arrCaller = getRC(Application.Caller)
With Sheets("OPBTN")
Set ckCaller = .CheckBoxes(Application.Caller)
For Each check In .CheckBoxes
If ckCaller.Name <> check.Name Then
If check.Name Like "R#*C#*" Then
arrCheck = getRC(check.Name)
If arrCheck(0) = arrCaller(0) Or arrCheck(1) = arrCaller(1) Then
check.Value = False
End If
End If
End If
Next
End With
End Sub
Function getRC(sName As String)
Dim a(1) As Long
Dim arr As Variant
arr = Split(sName, "C")
a(0) = Right(arr(0), Len(arr(0)) - 1)
a(1) = arr(1)
getRC = a
End Function
use GroupName property of option buttons. GroupName property determines the group of option button. user will be able to select only one option button from the group.
Set same groupname for your five option buttons and same for other five.
For Example :
Option1 GroupName: grp1
Option2 GroupName: grp1
Option3 GroupName: grp2
Option4 GroupName: grp2
in the above case user will be able to select one from option1 and option2. one button from option3 and option4.
I could really use some help on this. I've read through about 60+ websites and it's either not clicking (pun intended), or it's incorrect for my application. Here's the rundown:
Goal: Use a "Submit" button that was dynamically created in a Userform to copy the Caption from an OptionButton to a dynamic cell on the worksheet, and then clear/close the Userform.
Background: The userform is called from a change in a column in the worksheet.
Here's a snippet of the code used to call the userform:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
Dim lastRow As Long
With Worksheets("Test")
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
With Target
If .Count > 1 Then Exit Sub
If Not Intersect(Range("B1:B" & lastRow), .Cells) Is Nothing Then
Application.EnableEvents = False
If IsEmpty(.Value) Then
.Offset(0, 1).ClearContents
Else
With .Offset(0, 1)
.NumberFormat = "mmm dd yyyy hh:mm:ss"
.Value = Now
UserForm1.Show
End With
End If
Application.EnableEvents = True
End If
End With
End Sub
After the Userform is shown, it initializes. It pulls from a list on the spreadsheet to populate how many option buttons there are, their captions, and the dimensions of each item on the Userform. The code for that is this:
Sub UserForm_Initialize()
Dim HLastRow As Integer
Dim NoOfExplanations As Integer
Dim TopPixels As Integer
Dim UserFormHeight As Integer
Dim UserFormWidth As Integer
Dim Opt As Variant
Dim i As Integer
Dim ExplanationRow As Integer
Dim lbl As MSForms.Label
Dim LabelCap As String
Dim btn As CommandButton
Dim OtherInput As MSForms.TextBox
Dim Margins As Integer
With Worksheets("Test")
HLastRow = .Cells(.Rows.Count, "H").End(xlUp).Row
End With
NoOfExplanations = Application.WorksheetFunction.CountA(Worksheets("Test").Range("H2:H" & HLastRow))
Margins = 20
LabelCap = "You have chosen a non sequential row for your team/subteam. Please select an explanation below before you are able to proceed"
UserFormWidth = Len(LabelCap) * 2
TopPixels = (18 * 2)
UserFormHeight = TopPixels + 80 + (20 * NoOfExplanations)
With UserForm1
.Width = UserFormWidth + 40
.Height = UserFormHeight
End With
Set lbl = UserForm1.Controls.Add("Forms.Label.1")
With lbl
.Top = 10
.Left = 20
.Height = 20
.Width = UserFormWidth - 20
.Caption = LabelCap
End With
ExplanationRow = 2
For i = 1 To NoOfExplanations
Set Opt = UserForm1.Controls.Add("Forms.OptionButton.1", "OptionButton" & i, True)
Opt.Caption = Worksheets("Test").Cells(ExplanationRow, 8).Value
If Worksheets("Test").Cells(ExplanationRow, 8).Value = "Other" Then
Set OtherInput = UserForm1.Controls.Add("Forms.TextBox.1")
With OtherInput
.Top = TopPixels
.Width = UserFormWidth - (Len(Worksheets("Test").Cells(ExplanationRow, 8).Value) * 11)
.Left = UserFormWidth - (UserFormWidth - (Len(Worksheets("Test").Cells(ExplanationRow, 8).Value) * 11))
.Height = 18
End With
End If
If Len(Worksheets("Test").Cells(ExplanationRow, 8).Value) > 45 Then
Opt.Width = UserFormWidth - 10
Opt.Height = 36
Opt.Left = 18
Opt.Top = TopPixels
TopPixels = TopPixels + 38
End If
If Len(Worksheets("Test").Cells(ExplanationRow, 8).Value) <= 45 Then
Opt.Width = UserFormWidth - 10
Opt.Height = 18
Opt.Left = 18
Opt.Top = TopPixels
TopPixels = TopPixels + 20
End If
ExplanationRow = ExplanationRow + 1
Next i
Set btn = UserForm1.Controls.Add("Forms.CommandButton.1")
With btn
.Top = TopPixels
.Width = 40
.Left = ((UserFormWidth + 40) / 2) - 20
.Height = 20
.Caption = "Submit"
.Name = btn
End With
End Sub
Question: So, how do I get the btn created here in the Userform to both copy the selected OptionButton caption to the dynamic cell, and then clear/close the Userform?
I know it's a stretch, but I'm trying to fill in the cell that is two columns over from the "Target" cell that triggers the Userform to open. The code fills in the current date/time in the .Offset(0, 1) in the Worksheet_Change snipped, but is there a way to place the OptionButton caption in the cell at .Offset(0, 2)?
I'm still pretty new to VBA and this one thing is really sticking a thorn in me.
I'll be incredibly grateful for any help on this.
Thanks!
Joe
Changing your btn variable to a class level variable and using WithEvents will allow you to access the dynamic buttons events.
Private WithEvents btn As CommandButton
Private Sub btn_Click()
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeName(ctrl) = "OptionButton" Then
If ctrl.Object.Value Then
MsgBox ctrl.Object.Caption
End If
End If
Next
End Sub
Read all the rows for one column & display on textbox(s) which are created at run time.I am turning over to seek you assistance for below after several attempts which didn't help.
Name
ABC
AB
ABCEF
GHFD
I want all the rows from excel sheet to be shown in textbox just as they appear in sheet for a particular column.I am creating 4 textbox(s) that represent columns & 11 textbox(s) that represent rows. For the first column, I want the data to be displayed as it is in sheet. I am successful in creating text box as per my requirement but not able to display data as per needs. Thanks a ton for help
Public Sub UserForm_Initialize()
Set sh = ThisWorkbook.Sheets("Testing")
sh.Range("F21").Activate
With sh
fatalcount = WorksheetFunction.CountIf(Range("F:F"), "Fatal")
Majorcount = WorksheetFunction.CountIf(Range("F:F"), "Major")
Minorcount = WorksheetFunction.CountIf(Range("F:F"), "Minor")
End With
For jrow = 1 To 11
For i = 0 To 4
Set txtB1 = WtmsFrm.Controls.Add("Forms.TextBox.1")
With txtB1
.Name = "chkDemo" & i
.Height = 20
.Width = 5 + 50 + 5
.Left = 10 + 50 * i + 2
.Top = 15 * jrow + 10
.ControlTipText = "Type of Bug"
End With
Next i
Next jrow
For Each tbox In Frm.Controls
' For counter = 2 To 11
If tbox.Name = "chkDemo" Then
tbox.Value = Sheets("sheet1").Cells(counter, 2).Value ' failing code
tbox.ControlTipText = "Name"
ElseIf tbox.Name = "chkDemo1" Then
tbox.Value = 1
ElseIf tbox.Name = "chkDemo2" Then
tbox.Value = 2
ElseIf tbox.Name = "chkDemo3" Then
tbox.Value = 3
ElseIf tbox.Name = "chkDemo4" Then
tbox.Value = 4
End If
' Next counter
Next
' Initialise the followings
Frm.txtFatal.Value = fatalcount
Frm.txtMajor.Value = Majorcount
Frm.txtMinor.Value = Minorcount
Frm.txtTotoal.Value = fatalcount + Majorcount + Minorcount
End Sub
I don't see you create a textbox named "chkDemo". They all have a number appended. As you take tbox from all controls, there might be a control on your sheet somewhere named "chkDemo" but which is not a textbox. Neither do I see counter declared or initialized. That might also let the code fail.
Note also that with .Name = "chkDemo" & i you give the same name to textboxes because you are also in a For jrow loop.
Could any one direct me in right direction for the following code? I want to create a text box at run time by row & column.The following creates only a row & not multiple rows. I want the columns to remain same & just keep increasing rows. Thanks in advance :)
Dim txtB1 As Control
Dim i
For i = 0 To 4
Set txtB1 = UserForm.Controls.Add("Forms.TextBox.1")
With txtB1
.Name = "chkDemo" & i
.Height = 20
.Width = 50
.Left = 30 * i * 2
.Top = 15
.ControlTipText = "Type of Bug"
End With
Next i
You need a For loop for each dimension (rows and columns).
Dim txtB1 As Control
Dim i, jrow
For jrow = 1 To 5
For i = 0 To 4
Set txtB1 = UserForm.Controls.Add("Forms.TextBox.1")
With txtB1
.Name = "chkDemo" & i
.Height = 20
.Width = 50
.Left = 50 * i + 2
.Top = 20 * jrow + 15
.ControlTipText = "Type of Bug"
End With
Next i
Next jrow
Result: