I have made a userform. It contains around about 19 combo boxes. Combo boxes have 2 options YES and NO. then comes a text box infront of each combo box, where comments are typed. What I want is that if user selects no from combo box I want to copy paste the comments of that combo box from userform onto another excel sheet. Right now I am copy pasting all comments. So I want to add this feature as well. Below is the code I am currently using. Can anybody help me in upgrading this code, to add above mentioned feature as well.
Private Sub ()
Dim ws As Worksheet
Set ws = Worksheets("PQCILDMS")
Dim newRow2 As Long
newRow2 = Application.WorksheetFunction.CountA(ws.Range("A:A")) + 1
ws.Cells(newRow2, 1).Value = cmbDMS.Value
Dim newRow3 As Long
newRow3 = Application.WorksheetFunction.CountA(ws.Range("A:A")) + 1
ws.Cells(newRow3, 1).Value = cmbYesNo.Value
Dim newRow4 As Long
newRow4 = Application.WorksheetFunction.CountA(ws.Range("A:A")) + 1
ws.Cells(newRow4, 1).Value = Me.txtComments.Value
ws.Cells(newRow4, 1).Columns.AutoFit
End Sub
I want to copy paste the comments of that combo box from userform
I think you mean copy TextBox comments?
The best way to handle this is name your ComboBoxes as ComboBox1, ComboBox2..ComboBox19. Similarly for the TextBoxes, name them as TextBox1, textBox2... TextBox19. Ensure that TextBox1 is in front of ComboBox1 and so on.
The reason we do this is so that it become easier to loop. See this example
Private Sub CommandButton1_Click()
Dim ws As Worksheet
Dim lRow As Long, i As Long
'~~> Change this to the relevant sheet
Set ws = Sheet1
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
For i = 1 To 19
If Me.Controls("ComboBox" & i).Value = "No" Then
.Cells(lRow, 1).Value = Me.Controls("TextBox" & i).Value
lRow = lRow + 1
End If
Next i
End With
End Sub
as an alternative to appropriately renaming texboxes and comboboxes facing each other (suggested approach), you could get the textbox facing a given combobox by checking whether textbox horizontal axis (e.g.: its medium ordinate in the Userfom layout) crosses the combobox
so you could put the following code into your userfom code pane:
Option Explicit
Dim Cbs As Collection '<--| set this collection as Userform scoped variable
Dim Tbs As Collection '<--| set this collection as Userform scoped variable
Private Sub CommandButton1_Click()
Dim cb As MSForms.ComboBox, tb As MSForms.TextBox
Dim el As Variant
With Worksheets("PQCILDMS") '<--| reference sheet
For Each el In Cbs '<--|loop through all userform comboboxes
Set cb = el '<--|set the current combobox control
If cb.value = "NO" Then '<--|if its value is "NO" ...
Set tb = GetTbNextToCb(cb, Tbs) '<--|... look for the textbox whose horizontal axis is inbetween the current combobox
If Not tb Is Nothing Then .Cells(.Rows.Count, 1).End(xlUp).Offset(1).value = tb.value '<--|... if found it then write its content in referenced sheet column "A" next available cell
End If
Next el
End With
End Sub
Function GetTbNextToCb(cb As MSForms.ComboBox, Tbs As Collection) As MSForms.TextBox
Dim tb As MSForms.TextBox
Dim cbYMin As Long, cbYMax As Long, tbYMin As Long, tbYMax As Long
Dim el As Variant
GetYMinMax cb, cbYMin, cbYMax '<--| get minimum and maximum ordinate of passed combobox
For Each el In Tbs '<--|loop through all userform textboxes
Set tb = el '<--|set the current textbox control
If IsAxisInBetween(tb, cbYMin, cbYMax) Then '<--|if current textbox horizontal axis inbetween passed combobox minimum and maximum ordinates...
Set GetTbNextToCb = tb '...return the found textbox...
Exit Function '<--|... and exit function (no need to iterate over remaining textboxes)
End If
Next el
End Function
Function IsAxisInBetween(ctrl As Control, yMinRef As Long, yMaxRef As Long) As Boolean
Dim yMin As Long, yMax As Long
GetYMinMax ctrl, yMin, yMax '<--| get minimum and maximum ordinates of the control in the userform
IsAxisInBetween = (yMax + yMin) / 2 <= yMaxRef And (yMax + yMin) / 2 >= yMinRef '<--| check if the control orizontal axis is in between the reference ordinates
End Function
Sub GetYMinMax(ctrl As Control, yMin As Long, yMax As Long)
With ctrl
yMin = .Top '<--| get the minimum ordinate of the control in the Userform
yMax = .Top + .Height '<--| get the maximum ordinate of the control in the Userform
End With
End Sub
'this sub will run at Userfom loading
Private Sub UserForm_Initialize()
Set Cbs = GetCtrls("ComboBox") '<--| gather all Userform comboboxes in this collection
Set Tbs = GetCtrls("TextBox") '<--| gather all Userform texboxes in this collection
End Sub
Function GetCtrls(ctrlTypeName As String) As Collection
Dim coll As New Collection '<--| declare and set a new Collection object
Dim ctrl As Control
For Each ctrl In Me.Controls '<--| loop through all Userform controls
If TypeName(ctrl) = ctrlTypeName Then '<--| if it matches the passed Type name...
coll.Add ctrl, ctrl.Name '<--| ... then add it to the collection
End If
Next ctrl
Set GetCtrls = coll '<--| return the collection
End Function
Related
I have looked through numerous posts on looping through UserForm Controls but cant seem to adjust the code i have found for my needs and need some help.
Scenario I am trying to figure out:
I have 44 text boxes on a userform whose names all start with "ch" example "chTextBox1"
When the userform activates I need to loop through all of the text boxes that start with "ch" and change the background color of those textboxes to a color based on the interior color of a cell
Below is the code that I have been messing around with and I either end up in an infinite loop or I get
Error 424
Private Sub UserForm_Activate()
Dim wb As Workbook
Dim wsRR As Worksheet
Dim bColor As Range
Dim c As Control
Dim y As String
Set wb = Application.ThisWorkbook
Set wsRR = wb.Sheets("RiskRating")
Set bColor = wsRR.Range("C3")
For Each c In JHKey.Controls
If TypeName(c) = "TextBox" Then
y = Left(c, 2)
End If
If y = "ch" Then
c.BackColor = bColor.Interior.Color
End If
Next c
End Sub
Try placing the If statement testing for "ch" within the If statement testing for "TextBox". Also, you should specify the Name property for the control when checking for its name, otherwise it defaults to its Value property. Also, as an aside, I would suggest replacing JHKey with the keyword Me, which refers to the userform itself regardless of its name.
Private Sub UserForm_Activate()
Dim wb As Workbook
Dim wsRR As Worksheet
Dim bColor As Range
Dim c As Control
Dim y As String
Set wb = Application.ThisWorkbook
Set wsRR = wb.Sheets("RiskRating")
Set bColor = wsRR.Range("C3")
For Each c In Me.Controls
If TypeName(c) = "TextBox" Then
y = Left(c.Name, 2)
If y = "ch" Then
c.BackColor = bColor.Interior.Color
End If
End If
Next c
End Sub
I am looping through few rows and I need to know if the CheckBox in each row is "Checked" or not, but I don't know the name of the CheckBox. The below code is just to illustrate the problem:
Sub Checkboxes()
Dim ws As Worksheet
Set ws = Sheets("Input Data")
Dim Switch As Boolean
For i = 4 To 8
Switch = ws.Cells(i, 11).CheckboxValue
MsgBox Switch
Next i
End Sub
To create the checkboxes I did the following:
Create a CheckBox
Place it in a cell
Copy below in the same column
I assume the code should be the exact opposite of:
CheckBox1.LinkedCell
This is a good workaround. The code links all CheckBoxes to the cell that they're in and gives them Boolean value (TRUE/FALSE). For visual appearance, I have used "Number Formating" that makes the text "TRUE/FALSE" invisible. All you need to do is call the function with the Worksheet (where the CheckBoxes are) as input. The idea came from Aeneas
Public Function Link_Checkboxes_To_Cells(ws As Worksheet)
'This function is linking the checkboxes to the cells that they are in, so that the value of the cell becomes TRUE/FALSE when using the checkbox within.
'Meanwhile, I have manually made the text invisible in the cells with checkboxes, using the following method:
' https://support.office.com/en-us/article/Hide-or-display-cell-values-c94b3493-7762-4a53-8461-fb5cd9f05c33#bm1
' Number Type ---> Custom --> Then type ";;;" (without the quotes) and OK
Dim chk As CheckBox
For Each chk In ws.Checkboxes
With chk
.LinkedCell = _
.TopLeftCell.Offset(0, 0).Address
End With
Next chk
End Function
Try....
Sub Checkboxes()
Dim ws As Worksheet
Set ws = Sheets("Input Data")
Dim Switch As Boolean
For Each cb In ws.Checkboxes
If cb.Value = 1 Then
Switch = True
Else
Switch = False
End If
MsgBox cb.Name & " Value= " & Switch
Next cb
End Sub
I was playing around with a userform where I have a TextBox and ComboBox.
Now my aim is to start writing a Name in the TextBox while in the meantime have list of suggestions of Names (stored in a database) which filter out with every letter I type in the text box.
An example would be writing "N..." in the TextBox and having a ComboBox with suggestions "Nick, Nathan, etc."
Does anyone have any ideas, I was banging my head around this for a while.
Thank you!
You may try something like this...
Place the following code on UserForm Module.
The code assumes you have a sheet called Data in the workbook and two controls named TextBox1 and ComboBox1 on the UserForm.
Private Sub TextBox1_Change()
Dim wsData As Worksheet
Dim x, dict
Dim i As Long
Set wsData = Sheets("Data") 'Sheet with data
Set dict = CreateObject("Scripting.Dictionary")
'Clearing the combobox
Me.ComboBox1.Clear
If TextBox1.Value <> "" Then
x = wsData.Range("A1").CurrentRegion.Value
'Assuming the ComboBox will have items from column A of data sheet
'Assuming Row1 is the header row
For i = 2 To UBound(x, 1)
If LCase(Left(x(i, 1), 1)) = LCase(Left(TextBox1.Value, 1)) Then
dict.Item(x(i, 1)) = ""
End If
Next i
Me.ComboBox1.List = dict.keys
End If
End Sub
I am creating a userform that I want to be able to populate values in a data tab as well as default to certain values.
I think I have text boxes and combo boxes down, but cannot find info on using multiple optional buttons to generate data to one cell depending on the selection.
from the example, my criteria would be "secondary insurance" how do I go about linking them all so that, lets say cell b1 is populated with the selected option?
I'm completely guessing but I think checkboxes are a little more simple, true if checked and false if unchecked.
What I have so far is just a code I came across to fill in a cell with the value of the designated text/combo box and was just going to repeat for each column I need to set a criteria for.
Private Sub CommandButton1_Click()
Dim LastRow As Long, ws As Worksheet
Set ws = Sheets("Sheet1")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row + 1 'Finds the last blank row
ws.Range("A" & LastRow).Value = TextBox1.Text 'Adds the TextBox1 into Col A & Last Blank Row
Me.Hide
End Sub
combobox list
Private Sub UserForm_Initialize()
ComboBox1.Value = ("N/A")
ComboBox1.List = Split("N/A Yes No")
End Sub
Please let me know if I lack information and or how to attach my test worksheet, hopefully you can see the picture (I can't on my work server).
Thanks in advance for any and all education.
If the caption of the option button is the same as you want as cell text, then something like this may be what you want to store it:
Private Sub CommandButton1_Click()
Dim LastRow As Range
With Sheets("Sheet1")
Set LastRow = .Rows(.Cells(Rows.Count, 1).End(xlUp).Row + 1).Cells
If OptionButton1 Then
LastRow(2).Value2 = Me.OptionButton1.Caption
ElseIf Me.OptionButton2 Then
LastRow(2).Value2 = Me.OptionButton2.Caption
Else
LastRow(2).Value2 = Me.OptionButton3.Caption
End If
End With
End Sub
This will set the desired cell to the value of the caption of the option button you have selected.
To load the data back in the userform, you could use something like this:
Sub Load_in(Row_To_Load As Long)
Dim MyRow As Range
With Sheets("Sheet1")
Set MyRow = .Rows(Row_To_Load).Cells
If MyRow(2).Value2 = OptionButton1.Caption Then
OptionButton1.Value = True
ElseIf MyRow(2).Value2 = OptionButton2.Caption Then
OptionButton2.Value = True
Else
OptionButton3.Value = True
End If
End With
End Sub
For this, I assumed that the names hasn't been changed. Also if nothing is selected, the third option (N/A) will be used. The same goes for loading it back. If you do not want that, simply change the Else part to ElseIf so it looks like the first 2 options.
I currently run a macro to compare the most recent sheet of data to the report immediately prior and highlight changes. It works fine on its own. Now, however, we would like to be able to compare selected sheets from any time period. My idea was to pop up a simple userform with two textboxes that the user can use to specify which two reports he wants to compare. I am quite lost though with the idea of trying to declare public variables; what I've got atm is:
Option Explicit
Public shtNew As String, shtOld As String, _
TextBox1 As TextBox, TextBox2 As TextBox
Sub SComparison()
Const ID_COL As Integer = 31 'ID is in this column
Const NUM_COLS As Integer = 31 'how many columns are being compared?
Dim rwNew As Range, rwOld As Range, f As Range
Dim X As Integer, Id
shtNew = CSManager.TextBox1
shtOld = CSManager.TextBox2
'Row location of the first employee on "CurrentMaster" sheet
Set rwNew = shtNew.Rows(5)
Do While rwNew.Cells(ID_COL).Value <> ""
Id = rwNew.Cells(ID_COL).Value
Set f = shtOld.UsedRange.Columns(ID_COL).Find(Id, , xlValues, xlWhole)
If Not f Is Nothing Then
Set rwOld = f.EntireRow
For X = 1 To NUM_COLS
If rwNew.Cells(X).Value <> rwOld.Cells(X).Value Then
rwNew.Cells(X).Interior.Color = vbYellow
rwNew.Cells(33) = "UPDATE"
Else
rwNew.Cells(X).Interior.ColorIndex = xlNone
End If
Next X
End If
Set rwNew = rwNew.Offset(1, 0) 'next row to compare
Loop
Call SUpdates
End Sub
My Suggestion would be to use Comboboxes instead of TextBoxes. Create a userform with two command buttons and two comboboxes and populate the comboboxes in the UserForm_Initialize() event using this code.
Private Sub UserForm_Initialize()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Sheets
ComboBox1.AddItem ws.Name: ComboBox2.AddItem ws.Name
Next
End Sub
And then use this code in the OK button to do the comparison.
Private Sub CommandButton1_Click()
Dim shtNew As Worksheet, shtOld As Worksheet
If ComboBox1.ListIndex = -1 Then
MsgBox "Please select the first sheet"
Exit Sub
End If
If ComboBox2.ListIndex = -1 Then
MsgBox "Please select the Second sheet"
Exit Sub
End If
Set shtNew = Sheets(ComboBox1.Value)
Set shtOld = Sheets(ComboBox2.Value)
'~~> REST OF THE CODE HERE NOW TO WORK WITH THE ABOVE SHEETS
End Sub
Private Sub CommandButton2_Click()
Unload Me
End Sub
HTH
Sid
For an easy fix, couldn't you just colour (sorry, I'm English!) the worksheets that you want to refer to, then do something like:
Sub ListSheets()
'lists only non-coloured sheets in immediate window
'(could amend to add to combo boxes)
Dim w As Worksheet
'loop over worksheets in active workbook
For Each w In Worksheets
If w.Tab.Color Then
'if tab color is set, print
Debug.Print w.Name
End If
Next w
Let me know if this solves your problem.