I have two string arrays that I want to compare to each other. The one array (sProdList) will always be a set size (16 values), the other (sProd) might be 16, but it might be more or less values. I want to see if sProd contains any of the values in sProdList.
I'm using the below LINQ to try this out:
If Array.Exists(sProd, Function(x As String) sProdList.Contains(x)) Then
The idea being that if the current value of sProd is in sProdList it goes into the If statement, otherwise it skips over it.
When debugging my code I see that the value of x is 24, I'm not sure where it's getting this value from as neither of my arrays have 24 items.
Code is below, any help would be appreciated:
'Separate out Product Names
Dim sProd() As String = {}
Dim sInst() As String = {}
Dim sProdList() As String = {"Auto", "Chequing", "GIC", "Mutual Funds", "Real Estate", "RIF", "RSP", "Savings", "Shares", "Stock", "TFSA", "CCard", "Guar", "Loan", "Loc", "Mortgage"}
sProd = objNode.InnerText.Split(",")
objNode = Nothing
objNode = objXMl.SelectSingleNode("//Inst")
sInst = objNode.InnerText.Split(",")
Dim instPos As Integer = 0
For Each st As String In sProdList
If Array.Exists(sProd, Function(x As String) sProdList.Contains(x)) Then
If sInst(instPos) = "PCCU" Then
img = My.Resources.check
ElseIf sInst(instPos) <> "PCCU" OrElse sInst(instPos) = "" Then
img = My.Resources.exclamation
Else
img = My.Resources.redX
End If
dt.Rows.Add(New Object() {st, imageToByteArray(img)})
instPos += 1
End If
Next
dgProduct.DataSource = dt
You are iterating over sProdList but checking the whole list each time.
You can just use the Linq Contains method to see if sProd contains the string:
For Each st As String In sProdList
If sProd.Contains(st) Then
....
You are iterating sProdList, so you don't want to compare all of them within the loop, but you can use .Intersect to change to loop to just loop over the ones that are in both like this:
For Each st As String In sProdList.Intersect(sProd)
If sInst(instPos) = "PCCU" Then
img = My.Resources.check
ElseIf sInst(instPos) <> "PCCU" OrElse sInst(instPos) = "" Then
img = My.Resources.exclamation
Else
img = My.Resources.redX
End If
dt.Rows.Add(New Object() {st, imageToByteArray(img)})
instPos += 1
Next If
Also, you can further use LINQ to do create your query and feed that directly to dgProduct.DataSource rather than using DataTable as a wrapper like this:
Dim imgs = sInst.Select(Function(i) imageToByteArray(If(i = "PCCU", My.Resources.check, If((i <> "PCCU" OrElse i = ""), My.Resources.exclamation, My.Resources.redX))))
dgProduct.DataSource = sProdList.Intersect(sProd).Zip(imgs, Function(product, image) New From { product, image })
Related
eg A "Label" the value is stored in "Caption" whilst a Textboxes uses "Value" Please...
...but elegantly
I know I could use and "if then" statement ... but I see it getting messy pretty quick.
Dim propValue(2, 2) As String
propValue(0, 1) = "SomeInfo"
propValue(1, 1) = "lblReference"
propValue(2, 1) = "Caption"
propValue(0, 2) = "MoreInfo"
propValue(1, 2) = "tboxReference"
propValue(2, 2) = "Value"
Dim element As Integer
For element = 1 To 2
UserForm1.Controls(propValue(1, element)).propValue(2, element) = propValue(0, element)
Next element
Many thanks.
As I tried saying in my comment, it is not possible to use a string (extracted from an array or not) as an Object Property. The next code store a string defining the control type and use it in the following way:
Sub testModifFormControlsProperties()
Dim propValue(2, 2) As String
propValue(0, 1) = "SomeInfo": propValue(1, 1) = "lblReference"
propValue(2, 1) = "Label" 'store the control type as String
propValue(0, 2) = "MoreInfo": propValue(1, 2) = "tboxReference"
propValue(2, 2) = "TextBox" 'store the control type as String
Dim element As Integer, ctrl As MSForms.Control
For element = 1 To 2
Set ctrl = UserForm1.Controls(propValue(1, element)) 'to make a compact code
Select Case propValue(2, element)
Case "TextBox": ctrl.Text = propValue(0, element)
Case "Label": ctrl.Caption = propValue(0, element)
End Select
Next element
UserForm1.Show
End Sub
For the additional price of a very simple data object, the following is an approach that avoids using a 2-d Array. You could use a Collection or an Array with this implementation.
Option Explicit
Private Sub InitTextBoxesAndLabels()
Dim propValue(1) As Variant
Set propValue(0) = CreateTextBoxOrLabel("Label1", "MoreInfo", True)
Set propValue(1) = CreateTextBoxOrLabel("TextBox1", "SomeInfo", False)
Dim dElement As TextBoxOrLabel
Dim element As Long
For element = 0 To 1
Set dElement = propValue(element)
If dElement.IsLabel Then
UserForm1.Controls(dElement.ControlName).Caption = dElement.Content
Else
UserForm1.Controls(dElement.ControlName).Value = dElement.Content
End If
Next
End Sub
Private Function CreateTextBoxOrLabel(ByVal pControlName As String, _
pContent As String, pIsLabel As Boolean) As TextBoxOrLabel
Set CreateTextBoxOrLabel = New TextBoxOrLabel
With CreateTextBoxOrLabel
.ControlName = pControlName
.Content = pContent
.IsLabel = pIsLabel
End With
End Function
TextBoxOrLabel data object
Option Explicit
Public IsLabel As Boolean
Public Content As String
Public ControlName As String
hi I have a code that can transform the lower case letters of each element of a String array using for loop. the problem is only the last element is appearing on the output(label) but shows fine on the debug output
Dim lst() = {"apple", "banana", "cherry"}
For Each item As String In lst
Dim array() As Char = item.ToCharArray
array(0) = Char.ToUpper(array(0))
Dim newS = New String(array)
Dim value As String = String.Join("/", newS)
TextBox1.Text = value
Debug.Write(value)
Output.Text = value
Next
Debug.WriteLine("")
this is the problem that occurs, it changes the label into an into the last element with the uppercase letter as it it is meant to be, but
i want the output to be the same as the debug output which is
AppleBananaCherry
You don't need to explicitly define a Char array. A String has a Char(index) property which is the Default property. We can use this directly on the String. MyString(index)
We assign the new String that is returned by the Replace method to an element of the array. index starts at 0, the default value of an Integer, and is incremented on each iteration of the For Each loop.
Finally, after the For Each, we assign the Join to the label.
Your code and where it went wrong.
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim lst() = {"apple", "banana", "cherry"}
For Each item As String In lst
Dim array() As Char = item.ToCharArray
array(0) = Char.ToUpper(array(0))
Dim newS = New String(array)
Dim value As String = String.Join("/", newS)
TextBox1.Text = value 'Overwrites the last value you assigned to the Text property
Debug.Write(value) 'Adds on to the last value it wrote in the debug window.
Label1.Text = value 'Overwrites the last value you assigned to the Text property
Next
Debug.WriteLine("")
End Sub
Corrected code.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim lst = {"apple", "banana", "cherry"}
Dim index As Integer
For Each item As String In lst
lst(index) = item.Replace(item(0), Char.ToUpper(item(0)))
index += 1
Next
Label1.Text = String.Join("", lst)
End Sub
This is WinForms but the code you care about shouldn't be any different, just the Event procedure format.
You can even make it in a single line without an explicit loop.
Dim lst = {"apple", "banana", "cherry"}
Output.Text = String.Join("", lst.Select(Function(x) CultureInfo.CurrentCulture.TextInfo.ToTitleCase(x))))
While it seems very "smart" there are a couple of things to consider.
If the original list is very big (meaning thousands of strings) this
is less efficient because the Linq Select and the subsequent Join
will create a new list doubling the memory used.
If you want to change more than the first character, the ToTitleCase
method cannot work
I have an array like below
(0) = "apple"
(1) = "orange"
How can I add some string to all item in array? like apple become 'apple', orange become 'orange'
Edited
Private Sub test()
Dim txtReader As TextReader = New StreamReader("data.csv")
Dim parser = New CsvParser(txtReader)
Dim str As String = ""
'Ignore first line
parser.Read()
While True
Dim row = parser.Read()
If row Is Nothing Then
Exit While
End If
str &= $"({String.Join(",", row)}),"
End While
str_record = str.TrimEnd(",")
End Sub
Private Sub Model_Insert()
Dim data As String = ""
Dim query As String = "INSERT INTO main_item(item_code,item_name,item_desc,item_unitprice,item_barcode,dept_id,cat_id,gst_id,set_item,active)" &
"VALUES " & str_record & ""
Using cmd = New MySqlCommand(query, conn)
cmd.ExecuteNonQuery()
End Using
End Sub
Im trying to create a string and use it in INSERT INTO
Use a For-loop:
Dim array = {"apple", "orange"}
For i As Int32 = 0 To array.Length - 1
array(i) = $"'{array(i)}'"
Next
If you can't use string interpolation yet, use String.Format (or string concatenation):
For i As Int32 = 0 To array.Length - 1
array(i) = String.Format("'{0}'", array(i))
Next
If you don't mind recreating the array, you could use Linq Select:
Dim testarray As String() = New String() {"orange", "apple"}
testarray = testarray.Select(Function(x) String.Format("'{0}'", x)).ToArray()
I have and array and i want to check if my Dim value is contains in array but i need to check if it appears twice.
Example:
Dim value as String = "AST"
Dim zone_check_list() As String = {"AMST","AST","AST","EET","EDT"}
'if "AST" appeared twice then i will show message box
How about using LINQ :
Imports System.Linq
Dim value as String = "AST"
Dim zone_check_list() As String = {"AMST","AST","AST","EET","EDT"}
Dim isAppearTwice As Boolean = (zone_check_list.Count(Function(x) x = value) = 2)
Console.WriteLine(isAppearTwice)
I have a text file like:
[edit] the number of line is unknown, it could be hundreds of lines.
How would I store them in a multidimensional array? I want my array to look like:
sample(0)(0) = "--------"
sample(0)(1) = "Line1"
..and so on
sample(1)(0) = "--------"
sample(1)(3) = "Sample 123"
..and so on
What I have done so far was to open the file and store in a 1-dimentional array:
logs = File.ReadAllLines("D:\LOGS.TXT")
I have tried creating an Array of string like:
Dim stringArray as String()()
stringArray = New String(varNumber0)(varNumber1)
But it returns and error.
You can use File.ReadLines/File.ReadAllLines to get the lines and a simple For Each-loop to fill a List(Of List(Of String)). Then you can use
list.Select(Function(l) l.ToArray()).ToArray()
to get the String()() (jagged array):
Dim lines = File.ReadLines("D:\LOGS.TXT")
Dim list As New List(Of List(Of String))
Dim current As List(Of String)
For Each line As String In lines.SkipWhile(Function(l) Not l.TrimStart.StartsWith("----------"))
If line.TrimStart.StartsWith("----------") Then
current = New List(Of String)
list.Add(current)
Else
current.Add(line)
End If
Next
Dim last = list.LastOrDefault()
If last IsNot Nothing Then
If Not current Is last AndAlso current.Any() Then
list.Add(current)
ElseIf Not last.Any() Then
list.Remove(last) ' last line was ("----------")'
End If
End If
Dim stringArray As String()() = list.Select(Function(l) l.ToArray()).ToArray()
If you want to include the --------- in the array at the first position:
For Each line As String In lines.SkipWhile(Function(l) Not l.TrimStart.StartsWith("----------"))
If line.TrimStart.StartsWith("----------") Then
current = New List(Of String)
current.Add(line)
list.Add(current)
Else
current.Add(line)
End If
Next
Try like this but you need to customize according to you
Dim mArray(10,10) As String
Dim i As Integer = 0
For I=0 to 10
For J=0 to 10
For Each line As String In System.IO.File.ReadAllLines("file.txt")
mArray(i,j) = cmdReader.Item(line)
Next
Next
Next
Use declaration like this (this is just a generic)
Dim dim1 As Integer = 0
Dim dim2 As Integer = 0
Dim strings(,) As String
Do
dim1 = NewDimensionNumberFromFile
dim2 = NewSecondDimensionNumberFromFile
ReDim Preserve strings(dim1, dim2)
strings(dim1, dim2) = ValueFromfile
Loop While (Not EOF()) 'this will determine