VBA Excel - looping through ListView Controls - excel

I have 4 ListViews on the UserForm. Is it possible to check which ListView is active/selected as on the code below?
Private Sub CommandButton8_Click()
For i = 1 To 4
If me."ListView" & i) is selected Then
MsgBox me("ListView" & i ).Name
End If
Next i
End Sub
It is not working with ListView.SelectedItem. I don't actually understand why? Even if ListView is not selected, MsgBox pops up first ListView item as SelectedItem.
For i = 1 To 4
If Me("ListView" & i).SelectedItem > 0 Then
MsgBox "listview" & i & " selected item is " & Me("ListView" & i).SelectedItem
End If
Next i

First, when the data is loaded onto a listview control, the first item is automatically selected. So, to avoid this from happening, set the Selected property for the first item to False after you've added the data. For example...
Me.ListView1.ListItems(1).Selected = False
or
Me.Controls("ListView" & i).ListItems(1).Selected = False
Then you can use the following code to loop through each listview control, and then for each one loop through each item to check which one is selected...
Private Sub CommandButton1_Click()
Dim i As Long
For i = 1 To 4
Dim lv As ListView
Set lv = Me.Controls("ListView" & i)
With lv
Dim j As Long
For j = 1 To .ListItems.Count
If .ListItems(j).Selected Then
MsgBox lv.Name & " - " & .ListItems(j).Text
Exit Sub 'optional
End If
Next j
End With
Next i
End Sub
If you can have more than one item selected, and you want to display the name of each one, remove Exit Sub from the code.

Related

Trying to update an excel table using a multiselect form

I'm creating a simple log that will update a table of devices to show when the last firmware update was and who updated it. I have a form that will update a single device entry correctly, but I can't get it to work with multiselect. It will only update the last item in the list.
How can I get it so that a that someone can update multiple entries with their name and date in a single use of the form? I think I need to loop through the selected index values (for loop?), but I'm just not seeing it.
Private Sub UpdateButton_Click()
EditIndex = Me.UpdateDevice.ListIndex
If EditIndex = -1 Then
MsgBox "No device was selected", vbExclamation, "Update Log"
Else
EditIndex = EditIndex + 2
Devices.Range("F" & EditIndex) = Me.DateUpdated
Devices.Range("G" & EditIndex) = Me.UpdatedBy
Unload Me
End If
MsgBox "Log has been successfully updated", vbExclamation, "Update Log"
End Sub
EditIndex is a public variable I have saved in a module to use across various forms in this file.
Private Sub UpdateButton_Click()
EditIndex = Me.UpdateDevice.ListIndex
Dim i As Integer
Dim rmaster As Long
If EditIndex = -1 Then
MsgBox "No device was selected", vbExclamation, "Update Log"
Exit Sub
Else
For i = 0 To Me.UpdateDevice.ListCount - 1
If Me.UpdateDevice.Selected(i) Then
rmaster = i + 2
Devices.Range("F" & rmaster) = Me.DateUpdated.Value
Devices.Range("G" & rmaster) = Me.UpdatedBy.Value
Debug.Print (Me.UpdateDevice.List(i))
Debug.Print rmaster
Else
End If
Next i
Unload Me
End If
MsgBox "Log has been successfully updated", vbExclamation, "Update Log"
End Sub
I kept the debug.print to see if it was returning correctly. Only returns the first selected item if I try to update the columns.
ListBox to Update Worksheet
ListIndex will return -1 only if the list box is empty (not populated).
Objects
Command Button - UpdateButton
List Box - UpdateDevice
Text Box - DateUpdated
Text Box - UpdatedBy
Worksheet - Devices
All controls are on a user form.
Devices is the code name of the worksheet.
The Code
Option Explicit
Private Sub UpdateButton_Click()
Dim ItemsCount As Long
Dim i As Long
With Me.UpdateDevice
For i = 0 To .ListCount - 1
If .Selected(i) Then
ItemsCount = ItemsCount + 1
EditIndex = i + 2 ' EditIndex is maybe not needed!?
Devices.Range("F" & EditIndex) = Me.DateUpdated
Devices.Range("G" & EditIndex) = Me.UpdatedBy
End If
Next i
End With
' I don't know why, but I needed the following line to see the complete
' change in worksheet 'Devices' (CodeName) before the MsgBox:
'Application.ScreenUpdating = True
Select Case ItemsCount
Case 0
MsgBox "No device was selected", vbExclamation, "Update Log"
Case 1
MsgBox "Log has been successfully updated with 1" _
& " entry.", vbInformation, "Update Log"
Case Else
MsgBox "Log has been successfully updated with " & ItemsCount _
& " entries.", vbInformation, "Update Log"
End Select
Unload Me
End Sub
The .ListIndex property only returns the index of the last selected item from a multiselect enabled listbox control. You'll have to iterate though all the items in the list and check to see if they have been selected. Note that .ListCount returns the number of items in the listbox control starting with 1 while the .Selected(i) references the list index values which start at 0. (i.e. if the listbox has one item in it, .ListCount returns 1 while .ListIndex returns 0 because there is 1 item in the list, but it is the item at the 0th index).
For i = 0 To Me.lsBox.ListCount - 1
If Me.lsBox.Selected(i) Then
'record was selected
'do something
Debug.Print (Me.lsBox.List(i))
Else
'record was not selected
'do nothing
End If
Next i
Edit 1 - In action
Edit 2 - OPs updated code exactly

Reset count of buttons so it starts from Button 1 again after all Buttons are deleted

I have inserted the following three buttons into my Excel spreadsheet:
I am using a German Excel version: Schaltfläche = Button
As you can see the buttons are counted by 1,2,3 and each additional button will get the next higher count number.
Now, I run the following VBA to delete all buttons:
Sub Delete_Buttons()
Sheet1.Select
Sheet1.Buttons.Delete
End Sub
After I run this VBA I insert the buttons again:
As you can see the buttons are counted starting from 3.
How can I reset the count of the buttons and make the count starting from 1 again?
or you could use a sub that "orders" the buttons text by their Left property
this example uses a SortedList object
Sub Rename_Buttons()
With CreateObject("System.Collections.SortedList")
Dim btn As Button
For Each btn In Sheet1.Buttons
.Add btn.Left, btn
Next
Dim j As Long
For j = 0 To .Count - 1
.GetValueList()(j).Text = "Button" & j + 1
Next
End With
End Sub
You could also use:
Sub create_new()
Dim counter As Long, MaxValue As Long, i As Long
Dim btn As Button, btnNew As Button
Dim FullBtnName As String
counter = 3
MaxValue = 0
'You could change sheet name
With ThisWorkbook.Worksheets("Sheet1")
'Loop all butons in the sheet
For Each btn In .Buttons
'Split the name to get its number
FullBtnName = btn.Name
If CInt(Split(FullBtnName, " ")(1)) > MaxValue Then
'Get the max number
MaxValue = CInt(Split(FullBtnName, " ")(1))
End If
Next btn
'Loop 3 times to create 3 shhets
For i = 1 To 3
Set btnNew = .Buttons.Add(.Range("A" & i + 5).Left, .Range("A" & i + 5).Top, .Range("A" & i + 5).Width, .Range("A" & i + 5).Height)
'Change button name & caption
With btnNew
.Caption = "Button " & MaxValue + i
.Name = "Button" & MaxValue + i
End With
Next i
End With
End Sub
The best way to solve this issue is:
Run the VBA to delete all buttons:
Sub Delete_Buttons()
Sheet1.Select
Sheet1.Buttons.Delete
End Sub
Save the file and close it.
Re-open the file and then insert the buttons again.
(Now it starts counting from Button 1 again)

vba trouble working with cutomizable multiple Listbox with multiple macro

So here's my objective: I need to execute different macros deppending on a multiple choice ListBox. I am a begginner with vba and some tasks get a bit harder for me at the moment.
there's a multiple choice ListBox with 9 options. If you choose the option "Exfoliación", it executes the macro called "macro4". This is fully customizable, so if I choose from the ListBox the option "Exfoliación" and "Estanqueidad", it will execute the macros 4 and 3 (the ones related to them).
I've seen some example surfinf the Internet, but they're about ListBox's working with columns, sheets, and so on. But there weren't much explanations working with macros.
The user selects the options and presses a Submit button in the worksheet called "Botón". the choices from the Listbox are marked with vector(i)=1. With a for loop the choices are read and executes the corresponding macros to those choices with the array a(i) that contains the names of those macros.
Sub Submit()
'Getting selected items in ListBox1
Dim vector(1 To 11) As Integer
Dim i As Integer
Dim a(1 To 9) As String
'Private Sub CommandButton1_Click()
For i = LBound(a) To UBound(a)
vector(i) = 0
Next i
With Sheets("Botón").ListBox1
Select Case (ListBox1.Text)
Case "Tornillo Resorte": vector(1) = 1
Case "Categoría Manguito": vector(2) = 1
Case "Estanqueidad": vector(3) = 1
Case "Exfoliación": vector(4) = 1
Case "Material vaina": vector(5) = 1
Case "Diseño EC": vector(6) = 1
Case "Curva Q vs Enriquecimiento": vector(7) = 1
Case "Curva Criticidad": vector(8) = 1
Case "Curva de carga t. enfriamiento": vector(9) = 1
Case "Condicioón de transporte": vector(10) = 1
Case "ATI": vector(11) = 1
Case ""
MsgBox "nothing selected"
Case Else
MsgBox Me.ListBox1.Text
End Select
Dim MN As String
For i = 1 To N 'Fill the array
a(i) = "macro" & i
Next
MN = "Módulo5" 'Module where i have the worksheet I'm working with
Dim N As Integer
N = 11
For i = LBound(a) To UBound(a)
If vector(i) = 1 Then
Application.Run MN & "." & a(i)
End If
Next i
End Sub
I find trouble with the Select Case (ListBox1.Text) statement.
It doesn't compile and don't know how to call the listBox with Select Case.
thank you in advance for your help :)
Edit: with a new code. Method with selection:
`Private Sub Command Button1_Click() 'This is a button that opens the multilist with the different options. It works correctly
Worksheets("Botón").ListBox1.Clear
ListBox1.Height=200
ListBox1.Width=250
Dim mylist As Variant
mylist=Array("Tornillo Resorte",...,"Condicioón de transporte")
ListBox1.List=mylist
End Sub
Sub Submit() ''here's the macro with the button assigned to execute the selection. This is where I get the problem.
With Sheets("Botón").ListBox1
MN = "Módulo5" 'Module where i have the worksheet I'm working with
For X = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(X) = True Then
Application.Run MN & "." & .ListIndex + 1
Else
MsgBox "No se ha seleccionado ningún filtro"
End If
Next X
End With
End Sub
If you only wanted to select one macro - and assuming the macros are named sequentially macro1 to macrox, then you can just do this:
Sub Submit()
With Sheets("Botón").ListBox1
if .listindex = -1 then
MsgBox "nothing selected"
Else
MN = "Módulo5" 'Module where i have the worksheet I'm working with
Application.Run MN & "." & .listindex +1
End If
End With
End Sub
If you want to do more than one then you need to loop through the .selected array calling the macros sequentially

How to list all the names of the controls in a command bar in vba

Is there a way to list all the control's names pertaining to a command bar and the corresponding index?
I was playing around with this but I have clearly have the wrong syntax.
Sub test3()
i = 0
For Each ctl In CommandBars(1).Controls
i = i + 1
Debug.Print ctl.Properties.Name & " " & i
Next ctl
End Sub
Thanks!
They are arranged in two levels. Try this:
Sub test3()
i = 0
For Each ctl In CommandBars(1).Controls
For Each ctl2 In ctl.Controls
i = i + 1
Debug.Print ctl2.Caption & " " & i
Next ctl2
Next ctl
End Sub

How can I find the shape that is selected in group box in Excel?

I have a group box with option buttons in it and I need to find out which one of them is selected in VBA. I have been browsing MSDN for hours now and I can't find a solution.
There has to be a way to find the selected option button. Possibly find the group by name and for-each through each option button?
Here's what seems to be a working solution.
(Nod to KazJaw for Dim ... As OptionButton. this seems to be the key to get .GroupBox to work)
Function WhichOption(shpGroupBox As Shape) As OptionButton
Dim shp As OptionButton
Dim shpOptionGB As GroupBox
Dim gb As GroupBox
If shpGroupBox.FormControlType <> xlGroupBox Then Exit Function
Set gb = shpGroupBox.DrawingObject
For Each shp In shpGroupBox.Parent.OptionButtons
Set shpOptionGB = shp.GroupBox
If Not shpOptionGB Is Nothing Then
If shpOptionGB.Name = gb.Name Then
If shp.Value = 1 Then
Set WhichOption = shp
Exit Function
End If
End If
End If
Next
End Function
Use it like this
Sub test()
Dim shpOpt As OptionButton
Set shpOpt = WhichOption(Worksheets("Sheet1").Shapes("Group Box 1"))
Debug.Print shpOpt.Name
End Sub
If you really need to check OptionButton which are grouped (Grouped in the way we group any type of shape) you could go with this code:
Sub Grouped_into_UnitType()
Dim i!
'grouped into 'UnitType' Shape
For i = 1 To ActiveSheet.Shapes("UnitType").GroupItems.Count
With ActiveSheet.Shapes("UnitType").GroupItems(i).ControlFormat
If .Value = 1 Then
MsgBox "Chosen item: " & i
End If
End With
Next i
End Sub
Edit having in mind the following picture the code above will solve the problem if we have Option Buttons which are group in the way we group any Shapes placed in the sheet.
The code under the picture will find which option button is selected if they are located within GroupBox. Code check the name of the group in which OptionButton is located.
Important Note! the code below didn't work until I switched Excel off and run it again.
Sub Grouped_into_GroupBox_UnitType()
Dim OB As OptionButton
For Each OB In ActiveSheet.OptionButtons
'check if grouped into 'UnitType' Shape
If OB.GroupBox.Name = "UnitType" Then
If OB.Value = 1 Then
MsgBox "Chosen item: " & OB.Name & _
vbNewLine & _
"Alt text: " & OB.ShapeRange.AlternativeText
End If
End If
Next
End Sub
Lets say you have two standard option buttons:
To check if its "on" use:
Dim opt As Shape
Set opt = Worksheets("Sheet1").Shapes("Option Button 1")
If opt.ControlFormat.Value = xlOn Then
Debug.Print "option is ""on"" value of 1"
Else
Debug.Print "option is ""off"" value of -4146"
End If
To get its alternat text use:
Debug.Print "Alternate Text is: " & opt.AlternativeText
For a large amount of options the "FormControlType" property can be used:
Dim s as Shape
For Each s In Worksheets("Sheet1").Shapes
If s.FormControlType = xlOptionButton Then
If s.ControlFormat.Value = xlOn Then
Debug.Print "option is ""on"" value of 1"
Else
Debug.Print "option is ""off"" value of -4146"
End If
Debug.Print "Alternate Text is: " & s.AlternativeText
End If
Next
If you wanted a particular group:
Dim s As Shape, o
For Each s In Worksheets("Sheet1").Shapes
If s.FormControlType = xlOptionButton Then
Set o = s.OLEFormat.Object
If o.GroupBox.Name = "Group Box 3" Then
If s.ControlFormat.Value = xlOn Then
Debug.Print "Option is ""on"" value of 1"
Else
Debug.Print "Option is ""off"" value of -4146"
End If
Debug.Print "Alternate Text is: " & s.AlternativeText
Debug.Print "Group: " & o.GroupBox.Name
End If
Set o = Nothing
End If
Next

Resources