how to get listbox selected item name? - vba

How do I get the item name on listbox?
I have this code:
Dim x2 As Long
Dim OriginalCount2 As Long
'Store original ListBox count
OriginalCount2 = ListBox1.ListCount
'Temporarily hide ListBox (runs faster)
ListBox1.Visible = False
'Delete selected line items
For x2 = OriginalCount2 - 1 To 0 Step -1
If ListBox1.Selected(x2) = True Then MsgBox x2
Next x2
'Unhide ListBox
ListBox1.Visible = True
But it only gets the item index.

Would help to know what is event or action is triggering the code but this should get you started in the right direction:
Private Sub ListBox1_Click()
Dim LBItem As Long
For LBItem = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(LBItem) = True Then
MsgBox (ListBox1.List(LBItem))
End If
Next
End Sub

Related

Item transfer between Listboxes Last Row Issue

I have a listbox with values that I want to move to another listbox so the user can sort the items. When the last item is selected, it only moves that item and erases the values above it. How can I have it function like the other items in the list?
FYI, it is a single item selection, if that changes anything
Option Explicit
Option Base 1
Private Sub Add_Click()
Dim x As Integer, count As Integer
count = Me.Unsorted.ListCount
For x = 0 To count
If Me.Unsorted.Selected(x) = True Then
Me.Sorted.AddItem Me.Unsorted.List(x)
End If
Next x
For x = count To 0 Step -1
If Me.Unsorted.Selected(x) = True Then
Me.Unsorted.RemoveItem x
End If
Next x
End Sub
you could use this
Private Sub Add_Click()
Dim x As Integer
Dim nSelecteds As Long
With Me
With .Unsorted
ReDim selecteds(1 To .ListCount) As Long
For x = .ListCount - 1 To 0 Step -1
If .Selected(x) Then
nSelecteds = nSelecteds + 1
selecteds(nSelecteds) = x
Me.Sorted.AddItem .List(x)
End If
Next x
If nSelecteds > 0 Then
For x = 1 To nSelecteds
.RemoveItem selecteds(x)
Next x
End If
End With
End With
End Sub

How to check if userform checkboxes were checked or not; which were dynamically created?

I have a userform with dynamic checkboxes(programmed)
Below is my code
Dim Rows As Integer
Dim toppart As Integer
Dim Opt As Variant
Dim x As Integer
On Error Resume Next
toppart = 20
UpdateRow = Application.WorksheetFunction.CountA(ActiveSheet.Range("C3:CU3"))
For x = 3 To UpdateRow
Set Opt = Te.Controls.Add("Forms.CheckBox.1", "CheckBox" & x, True)
Opt.Caption = ActiveSheet.Cells(x, "C").Value
Opt.Width = 70
Opt.Height = 18
Opt.Left = 18
Opt.Top = toppart
toppart = toppart + 20
Next
I know if the checkboxes were set via the controls my code will look something like this:
If (CheckBox1.Value = False) Or (CheckBox2.Value = False) Then
MsgBox "You must select alteast 2 checkboxes", vbCritical
But when the checkboxes are dynamically created I can't think of a efficient way to do it. Please any suggestions or Help is very much appreciated, thanks.
Untested, but you can probably loop the controls on your form, check if each is a checkbox, if it is, query it's .Value and tally the total number of checkboxes which are "checked. If that number is LTE 1, then you raise your warning/MsgBox:
Dim checked as Long
Dim ctrl as Object
For Each ctrl in Me.Controls
If TypeName(ctrl) = "CheckBox" Then
If ctrl.Value = True Then
checked = checked + 1
End If
End If
Next
If checked <= 1 Then
MsgBox "You must select alteast 2 checkboxes", vbCritical
Exit Sub
End If

How do I prevent ListBox - Multiselect Change Event from firing twice on the first selection?

I have created a UserForm that has two ListBoxes, one populated from a dictionary that contains excess items from a company report, and the other from a dictionary that contains excess items from a bank report. The first ListBox is a fmMultiSelectMulti, allowing the user to select multiple items to get the sum of the selected items (which change the value of a TextBox).
My issue is when I select the first item in the ListBox, the ListBox_Change() event fires twice. The sum variable is public since it is referenced in other methods, but upon the double-fire, it doubles the real value.
Here's the code for the change event:
Private Sub GPListBox_Change()
For lItem = 0 To GPListBox.ListCount - 1
If GPListBox.Selected(lItem) = True Then
gpTotal = gpTotal + GPListBox.List(lItem, 1)
Debug.Print GPListBox.List(lItem, 1)
End If
Next
GPTotalTextBox.Value = Format(gpTotal, "$#,##0.00")
End Sub
The other method that removes the (multiple) selected variables, and references the sum variable:
Private Sub RemoveButton1_Click()
For lItem = GPListBox.ListCount - 1 To 0 Step -1
If GPListBox.Selected(lItem) Then
gpTotal = gpTotal - GPListBox.List(lItem, 1)
'GPListBox.RemoveItem GPListBox.ListIndex
GPListBox.RemoveItem lItem
GPTotalTextBox.Value = gpTotal
End If
Next
End Sub
This is the UserForm after I selected the first item, which automatically deselected and left the sum present:
.
My Question: How do I prevent this from double-firing every time the first selection occurs?
I have got around it like this in the past. Something like this.
Use a global boolean at the top of you code. Above all subs and functions.
Dim bFire as Boolean
A boolean is false by default so you will have to set the boolean to true somewhere outside of you subs such as form UserForm_Initialize event or something. If you don't have a place to do that, switch the true/false usage in the subs (Benno Grimm Elaborated on this below in comments).
Private Sub UserForm_Initialize()
bFire = True
End Sub
Then use the boolean in the subs.
Private Sub GPListBox_Change()
'Check the status and get out if you have set it to not fire.
If bFire = false then
Exit Sub
End If
For lItem = 0 To GPListBox.ListCount - 1
If GPListBox.Selected(lItem) = True Then
gpTotal = gpTotal + GPListBox.List(lItem, 1)
Debug.Print GPListBox.List(lItem, 1)
End If
Next
GPTotalTextBox.Value = Format(gpTotal, "$#,##0.00")
End Sub
In the button that modifies it, set the boolean false at the start and true at the end.
Private Sub RemoveButton1_Click()
'Set it false
bFire = false
For lItem = GPListBox.ListCount - 1 To 0 Step -1
If GPListBox.Selected(lItem) Then
gpTotal = gpTotal - GPListBox.List(lItem, 1)
'GPListBox.RemoveItem GPListBox.ListIndex
GPListBox.RemoveItem lItem
GPTotalTextBox.Value = gpTotal
End If
Next
'After you have modified the control set it to true
bFire = True
End Sub

How to search in listview

I am trying to create a Loop that will read through the information on my ListView through the SubItem to find the text that matches the text in my Textbox whenever I hit the search button and Focuses the listbox onto the matched text. Below is what I have but it keeps telling me that the value of string cannot be converted. I am also pretty sure that my numbers wont loop correctly but I am not really sure how to cause them to loop endlessly till end of statement.
Dim T As String
T = Lines.Text
For r As Integer = 0 to -1
For C As Integer = 0 to -1
If List.Items(r).SubItems(C).Text = Lines.Text Then
List.FocusedItem = T
End If
Next
Next
End Sub
I don't understand your code, but I do understand the question. Below is example code to search all rows and columns of a listview. Search is case insensitive and supports a "find next match" scenario. If a match or partial match is found in any column the row is selected. TextBox1 gets the text to find. FindBtn starts a new search.
Private SrchParameter As String = ""
Private NxtStrtRow As Integer = 0
Private Sub FindBtn_Click(sender As Object, e As EventArgs) Handles FindBtn.Click
If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then
SrchParameter = TextBox1.Text
NxtStrtRow = 0
SearchListView()
End If
End Sub
Private Sub ListView1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListView1.KeyDown
If e.KeyCode = Keys.F3 Then
SearchListView()
End If
End Sub
Private Sub SearchListView()
' selects the row containing data matching the text parameter
' sets NxtStrtRow (a form level variable) value for a "find next match" scenario (press F3 key)
If ListView1.Items.Count > 0 Then
If SrchParameter <> "" Then
Dim thisRow As Integer = -1
For x As Integer = NxtStrtRow To ListView1.Items.Count - 1 ' each row
For y As Integer = 0 To ListView1.Columns.Count - 1 ' each column
If InStr(1, ListView1.Items(x).SubItems(y).Text.ToLower, SrchParameter.ToLower) > 0 Then
thisRow = x
NxtStrtRow = x + 1
Exit For
End If
Next
If thisRow > -1 Then Exit For
Next
If thisRow = -1 Then
MsgBox("Not found.")
NxtStrtRow = 0
TextBox1.SelectAll()
TextBox1.Select()
Else
' select the row, ensure its visible and set focus into the listview
ListView1.Items(thisRow).Selected = True
ListView1.Items(thisRow).EnsureVisible()
ListView1.Select()
End If
End If
End If
End Sub
Instead of looping like that through the ListView, try using a For Each instead:
searchstring as String = "test1b"
ListView1.SelectedIndices.Clear()
For Each lvi As ListViewItem In ListView1.Items
For Each lvisub As ListViewItem.ListViewSubItem In lvi.SubItems
If lvisub.Text = searchstring Then
ListView1.SelectedIndices.Add(lvi.Index)
Exit For
End If
Next
Next
ListView1.Focus()
This will select every item which has a text match in a subitem.
Don't put this code in a form load handler, it won't give the focus to the listview and the selected items won't show. Use a Button click handler instead.
This is the easiest way to search in listview and combobox controls in vb net
dim i as integer = cb_name.findstring(tb_name.text) 'findstring will return index
if i = -1 then
msgbox("Not found")
else
msgbox("Item found")
end if

Error ending For/Next loop through CheckBoxes

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