vba select values in listview and show in textbox - vba

I want to display the value of 3rd column instead of 1st column. Pleae advise as to whan changed is required.
Dim blnFoundFirstItem As Boolean
blnFoundFirstItem = False
Dim i As Integer
For i = 1 To ListView16.ListItems.Count
If (ListView16.ListItems(i).Selected) Then
If (Not blnFoundFirstItem) Then
TextBox118.Text = ListView16.ListItems(i).Text
blnFoundFirstItem = True
Else
TextBox118.Text = ListView16.ListItems(i).Text
End If
End If
Next i

Use ListSubItems() :
Dim blnFoundFirstItem As Boolean
blnFoundFirstItem = False
Dim i As Integer
For i = 1 To ListView16.ListItems.Count
If (ListView16.ListItems(i).Selected) Then
If (Not blnFoundFirstItem) Then
TextBox118.Text = ListView16.ListItems(i).ListSubItems(3).Text
blnFoundFirstItem = True
Else
TextBox118.Text = ListView16.ListItems(i).ListSubItems(3).Text
End If
End If
Next i

Related

Linq vb.net simple query returning bad results (no yielding results)

Hello I'm trying to develop a Linq query to find the Lowest Unique Value or else Lowest Value which is also sorted by Row and Column Value.
First it does the Lowest Unique Value Exact match using BinarySearch (unique value)
If nothing is found then it does a Partial Match (lowest value then lowest row then column)
Whichever has the smallest Value is the output (unique (smallest first)) or (not found (smallest second or first if unique not found)).
Console returns this value
2,0,0
When it should be
2,1,1
Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click
Dim UniqueValuesFound As New List(Of Short)
Dim ValuesFoundInPath As New List(Of FoundValue)
UniqueValuesFound.Add(1)
'UniqueValuesFound.Add(0)
'UniqueValuesFound.Add(2)
'UniqueValuesFound.Add(3)
UniqueValuesFound = UniqueValuesFound.Distinct().ToList()
UniqueValuesFound.Sort()
Dim foundValue As New FoundValue
foundValue.Value = 2
foundValue.Row = 1
foundValue.Column = 1
ValuesFoundInPath.Add(foundValue)
'foundValue = New FoundValue
'foundValue.Value = 3
'foundValue.Row = 0
'foundValue.Column = 2
'ValuesFoundInPath.Add(foundValue)
'foundValue = New FoundValue
'foundValue.Value = 2
'foundValue.Row = 0
'foundValue.Column = 2
'ValuesFoundInPath.Add(foundValue)
'foundValue = New FoundValue
'foundValue.Value = 0
'foundValue.Row = 2
'foundValue.Column = 0
'ValuesFoundInPath.Add(foundValue)
Dim alreadyFound As Boolean = False
Dim matching = ValuesFoundInPath.Where(Function(s)
Dim index As Integer = UniqueValuesFound.BinarySearch(s.Value)
If alreadyFound = False AndAlso index >= 0 Then
alreadyFound = True
Return True 'UniqueValuesFound(index) 'exact match
ElseIf alreadyFound = False AndAlso index < 0 Then
alreadyFound = True
Return True 's.Value
Else
Return False
End If
End Function).OrderBy(Function(p) p.Value).ThenBy(Function(p) p.Row).ThenBy(Function(p) p.Column)
Console.WriteLine(matching(0).Value.ToString & "," & matching(0).Row.ToString & "," & matching(0).Column.ToString)
End Sub
Solved it, needed to use Find instead of Where and problem disappeared!.
The answer now reqires 2 linq queries instead of one cannot do chaining on Find
ValuesFoundInPath = ValuesFoundInPath.OrderBy(Function(p) p.Row).ThenBy(Function(p) p.Column).ThenBy(Function(p) p.Value).ToList()
Dim alreadyFound As Boolean = False
Dim matching = ValuesFoundInPath.Find(Function(s)
Dim index As Integer = UniqueValuesFound.BinarySearch(s.Value)
If alreadyFound = False AndAlso index >= 0 Then
alreadyFound = True
Return True 'UniqueValuesFound(index) 'exact match
ElseIf alreadyFound = False AndAlso index < 0 Then
alreadyFound = True
Return True 's.Value
Else
Return False
End If
End Function)
Dim result As New Result
result.Answer = matching.Value
result.CurrentRow = matching.Row
result.CurrentColumn = matching.Column
You may have problems since Find(...) pre-sorts the list of values always. So you need to use FindIndex(...) this avoids the sorting issue.
Dim matchingIndex = ValuesFoundInPath.FindIndex(Function(s)
Dim index As Integer = UniqueValuesFound.BinarySearch(s.Value)
If alreadyFound = False AndAlso index >= 0 Then
alreadyFound = True
Return True 'UniqueValuesFound(index) 'exact match
ElseIf alreadyFound = False AndAlso index < 0 Then
alreadyFound = True
Return True 's.Value
End If
Return False 'No match.
End Function)
If matchingIndex < 0 Then MessageBox.Show("Wtf!")
Dim result As New Result
result.Answer = ValuesFoundInPath(matchingIndex).Value
result.CurrentRow = ValuesFoundInPath(matchingIndex).Row
result.CurrentColumn = ValuesFoundInPath(matchingIndex).Column
It makes the OrderBy(...) useless because Find(...) pre-sorts the lists by incrementing values.

ListView.BackColor not working for current row, after next search item it works

I have a weird issue. I'm using ListView item in VB.NET Forms. During my search for partial text (SearchText can be abc), when found for the first instance I try to change the BackColor for a list item it's not changing the BackColor for the current row.
Whereas when I search for a new matched item it shows previous searched item BackColor as blue. Any suggestion to resolve the issue? My goal is to color the current matched row.
Public Function SearchGridFindNext(ByRef Grid As ListView, ByVal SearchText As String, Optional ByVal FromBeginning As Boolean = False) As Boolean
Dim StartRowIndex As Integer = 0
Dim StartNextRowIndex As Integer = 0
Dim RowIndex As Integer = 0
Dim IncrementIndex As Integer = 0
Dim Found As Boolean = False
If Grid.Items.Count > 0 Then
If Grid.SelectedItems.Count > 0 Then
StartRowIndex = Grid.SelectedItems(0).Index
If FromBeginning Then StartNextRowIndex = 0 Else StartNextRowIndex = Grid.SelectedItems(0).Index + 1
Grid.SelectedItems.Clear()
End If
For RowIndex = StartRowIndex To Grid.Items.Count - 1
If RowIndex > StartRowIndex Then
StartNextRowIndex = 0
End If
For IncrementIndex = 1 To StartNextRowIndex - 1
Grid.Items(IncrementIndex).BackColor = Color.White
Next
For IncrementIndex = StartNextRowIndex To Grid.Items.Count - 1
If (Grid.Items(IncrementIndex).SubItems(0).Text.ToUpper.Contains(SearchText)) Then
Grid.Items(IncrementIndex).Selected = True
Grid.Items(IncrementIndex).EnsureVisible()
Grid.Items(IncrementIndex).BackColor = Color.Blue
Found = True
Exit For
End If
Next
If Found Then Exit For
Next
End If
Return Found
End Function

Having problems with counter if i add an else in a nested if statement

if I try to put an else after exit while my counter doesn't work, I can find the first name but not the rest. I want to put the else to show a message box if the user has inputted a wrong name. i have tried putting else but if i search for eg the last name it doesn't work because the counter doesn't increments. please can you'll help me with the code without changing the loops.
Dim name(5) As String
Dim found As Boolean
Dim search As String
name(0) = "John"
name(1) = "Ken"
name(2) = "Jen"
name(3) = "Fam"
name(4) = "Denny"
search = InputBox("search name")
found = False
Dim counter As Integer = -1
While found = False
counter = counter + 1
If search = name(counter) Then
MsgBox("hello")
Exit While
End If
End While
End Sub
End Class
In this case I would recommend to use the For Each statement, since you are looping through a collection where you need the identifier. So instead of creating a seperate counter, just use the For Each identifier.
Dim name(4) As String
name(0) = "John"
name(1) = "Ken"
name(2) = "Jen"
name(3) = "Fam"
name(4) = "Denny"
Dim search = InputBox("search name")
Dim index As Integer = -1
For i = 0 To name.Length - 1
If name(i) = search Then
index = i
Exit For
End If
Next
If index > -1 Then
MsgBox("Name '" + name(index) + "' was found.")
Else
MsgBox("Name '" + search + "' was not found.")
End If
Just to give you an example I've removed the found boolean and used the found index (or object) instead. In case you want to lookup the object instead of just detecting if the name exists.
An alternative would be to use Linq (Imports System.Linq):
Dim found = name.Any(Function(n) n.Equals(search, StringComparison.InvariantCultureIgnoreCase))
You need to use th found boolean flag to tell you whether or not the name was found.You set it to true within the if statement and then check for its value after the loop ends. You also would need to exit the while loop after the counter reaches the last element in the list.
Dim name(5) As String
Dim found As Boolean
Dim search As String
name(0) = "John"
name(1) = "Ken"
name(2) = "Jen"
name(3) = "Fam"
name(4) = "Denny"
search = InputBox("search name")
found = False
Dim counter As Integer = -1
While found = False
counter = counter + 1
If search = name(counter) Then
MsgBox("hello")
found = True
Exit While
End If
If Counter = name.Length - 1
Exit While
End If
End While
If found = True Then
MsgBox("Name was found")
Else
MsgBox("Name was not found")
End If

Filter ListView data with CheckBox inputs

I'm trying to provide a way to filter data within a ListView using CheckBox controls. Checking a box will add or remove the selected attribute from the ListView.
The current code:
For i = 0 To RecCount
Filter = True
'RecordDat array populated here
'filter the record by checkbox selection
If ckbComplete.Checked = True And Len(RecordDat(7)) = 0 Then
Filter = False
ElseIf ckbOpen.Checked = True And Len(RecordDat(7)) > 0 Then
Filter = false
ElseIf ckbApps.Checked = True And strings.Left(RecordDat(0).ToString, 4) <> "APPS" Then
Filter = False
ElseIf ckbContract.Checked = True And Strings.Left(RecordDat(0), 3) <> "SOP" Then
Filter = false
End If
If Filter = False Then GoTo SkipItem
' More code adding the item to the list view and formatting
SkipItem:
Next
At the moment I can filter only once per array index, i.e. I can filter ckbComplete and ckbApps but not ckbcomplete, ckbApps and ckbContract.
I managed to figure out a solution by trial and error and wish to share what I found.
In order to filter the data, each variable (in this case, the column value) required its own filter statements, each which must be encased in an If ELSE statement.
The resulting code was as follows:
Dim Filter As Boolean = True
For i = 0 To RecCount
Filter = False
'RecordDat initialisation
Filter = FilterPass(RecordDat)
If Filter = False Then Continue For
Dim itm As ListViewItem
itm = New ListViewItem(RecordDat)
Healthchart.ListView1.Items.Add(itm)
'Continue formatting and input of data into listview
Next
The FilterPass functions then follow:
Private Function FilterPass(ByVal RecordDat() As String)
Dim filter As Boolean = False
If Healthchart.ckbComplete.Checked = True Then
If Len(RecordDat(7)) > 0 Then
filter = FilterPass2(RecordDat)
If filter = True Then
filter = FilterPass3(RecordDat)
End If
End If
End If
If Healthchart.ckbOpen.Checked = True Then
If Len(RecordDat(7)) = 0 Then
filter = FilterPass2(RecordDat)
If filter = True Then
filter = FilterPass3(RecordDat)
End If
End If
End If
Return filter
End Function
Private Function FilterPass2(ByVal RecordDat() As String)
Dim filter As Boolean = False
If Healthchart.ckbApps.Checked = True Then
If Strings.Left(RecordDat(0).ToString, 4) = "APPS" Then
filter = True
End If
End If
If Healthchart.ckbContract.Checked = True Then
If Strings.Left(RecordDat(0), 3) = "SOP" Then
filter = True
End If
End If
If Healthchart.ckbTech.Checked = True Then
If Strings.Left(RecordDat(0), 3) = "ATS" Then
filter = True
End If
End If
If Healthchart.ckbDes.Checked = True Then
If Strings.Left(RecordDat(0), 3) = "DES" Then
filter = True
End If
End If
Return filter
End Function
Private Function FilterPass3(ByVal RecordDat() As String)
Dim filter As Boolean = True
Dim SubDate As Date = Date.ParseExact(RecordDat(1).ToString, "dd/MM/yy", System.Globalization.DateTimeFormatInfo.InvariantInfo)
If Healthchart.ckbLast30.Checked = True Then
If DateAdd(DateInterval.Day, -30, Now) > SubDate Then
filter = False
End If
End If
If Healthchart.ckb7Days.Checked = True Then
If DateAdd(DateInterval.Day, -7, Now) > SubDate Then
filter = False
End If
End If
Return filter
End Function
One can then add as many 'filters' as required by adding an additional If Filter = true then into the FilterPass function.

IIF-Else statement Never Reachs Else Condition

Im using this custom Code in SQL Reporting Services. The problem is it NEVER reachs the false condition. If the condition is NOT true, the function won't return "false". It works fine when the value is True (prints "X") , otherwise I get an #Error .
I'm calling the function from a textbox :
= IIF(Code.CodeExist(Variables!MyCode.Value) = true, "X", "")
function CodeExist( ByVal Codigo As String) as Boolean
dim i as integer
dim Centinela as integer
i = 0
Centinela = 0
for i = 0 To Report.Parameters!CodeList.Count()
if Report.Parameters!CodeList.Value(i) = Codigo Then
Centinela = 1
Exit For
End If
Next
If Centinela = 1 Then
Return true
Else
Return false // IT NEVERS RETURN FALSE even if Centinela = 0
End If
End function
I don't know what's happening. Thanks in advance.
VBA has no "Return" statement. To return a value you'd use (eg)
....
If Centinela = 1 Then
CodeExist = True
Else
CodeExist = False
End If
End Function
or (much tidier):
....
CodeExist = (Centinela = 1)
End Function