Type casting Strings - arrays

I am using an array list to store my strings. However when I run the program it throws an error : Conversion from type 'String()' to type 'String" is not valid. I am sure I am missing something simple. I thought an ArrayList was a list of objects and that it could be anything that I was sent to the array. e.g. Strings in, Strings out. Here is the code that I am working with.
Dim tempString As New ArrayList()
For Each s As String In tempString
Dim sAry As String() = bufString.Split(New Char() {ChrW(2)})
For i As Int16 = 1 To sAry.Length
xlCells(CurrentRow, i).Value = sAry(i - 1).ToString()
Next
Next
I also have come to understand that ArrayList has depreciated, should I be using something else?

Before jumping into your case quickly please give a look into other great answers
What's Wrong with an ArrayList?
.NET: ArrayList vs List
and you can google to know more in this regard...
For known typed collection it is not good to use ArrayLists.
For your case I would suggest generic List collection(List is much more efficient in terms of memory usage)
You can see my below test case for you:
Sub Main()
Dim tempList As New List(Of String) 'Consider List Rather ArrayList as you knw your requirement for Strings collection
tempList.Add("string1string2string3string4") 'for testing purpose I've joined "string1, string2, string3 & string4" with ChrW(2) unicode character
For Each s As String In tempList
Dim sAry As String() = s.Split(New Char() {ChrW(2)})
For i As Int16 = 1 To sAry.Length
'xlCells(CurrentRow, i).Value = sAry(i - 1).ToString()
Console.WriteLine(sAry(i - 1).ToString())
Next
Next
Console.ReadLine()
End Sub

Related

Populating two one-dimensional arrays with text file

For my Visual Basic final, my program is required to read data from a text file into two different arrays, each being one-dimensional. The following is my code for doing so:
Option Explicit On
Option Infer Off
Option Strict On
Public Class frmMain
'Constant for filename and a dirty flag variable
Const INVENTORY_FILENAME As String = "inventory.txt"
Dim noFile As Boolean = False
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Populates DVD listbox with text file data upon load
'Variable for reading the file
Dim myFile As IO.StreamReader
'Declaring arrays for DVD names and prices
Dim arrayDVD() As String
Dim arrayPrice() As Double
'Variables for populating arrays with respective data
Dim dvdName As String
Dim dvdPrice As Double
Dim i As Integer = 0
'Checking that file exists then reading data to each array
If IO.File.Exists(INVENTORY_FILENAME) Then
myFile = IO.File.OpenText(INVENTORY_FILENAME)
'Read data to arrays
Do Until myFile.Peek = -1
dvdName = myFile.ReadLine()
dvdPrice = Double.Parse(myFile.ReadLine())
arrayDVD = dvdName
arrayPrice = dvdPrice
'Using arrays to populate multicolumn listbox
lstDVD.Items.Add(arrayDVD(i) & arrayPrice(i))
i += 1
Loop
'Closing the file
myFile.Close()
End If
End Sub
End Class
The text file alternates names and prices of DVDs to be read as individual lines, making the arrays parallel:
Pulp Fiction
9.99
Jumanji
13.99
And so on...
I'm receiving a value type error code stating that I cannot convert 'String' to 'String()' or convert 'Double' to 'Double()' when setting the arrays' values equal to their respective variables. Is there a way to correct this? Thanks in advance!
These lines are wrong:
arrayDVD = dvdName
arrayPrice = dvdPrice
arrayDVD and arrayPrice are arrays. You need to assign to a specific element in each of those arrays:
arrayDVD(i) = dvdName
arrayPrice(i) = dvdPrice
Don't forget to make sure the arrays actually have enough elements for this.
Hint: ReDim Preserve is pretty much the least efficient way possible to make sure an array is big enough. Each use will allocate a brand new array, copy the elements one at a time, assign the new array to the old reference, and then release the old array. It does not preserve in-place. Nevertheless, if this is a 100-level course it might be what you are expected to do at this point.
Finally, you should never use Double when working with money (use Decimal instead).
Separate from the question, here is how I might approach this without the weird array limitation:
Private Iterator Function ReadInventoryFile(filePath As String) As IEnumerable(Of (String, Decimal))
Using rdr As New StreamReader(filePath)
Dim DVDName As String = Nothing
While (DVDName = rdr.ReadLine()) IsNot Nothing
Yield (DVDName, Decimal.Parse(rdr.ReadLine()))
End While
End Using
End Function
Const INVENTORY_FILENAME As String = "inventory.txt"
Private data As List(Of (String, Decimal))
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try 'Replaces the File.Exists() check
data = ReadInventoryFile(INVENTORY_FILENAME).ToList()
For Each item As (String, Decimal) In data
lstDVD.Items.Add($"{item.Item1}{vbTab}{item.Item2:C}")
Next
Catch
' Actually do something here. Empty catch blocks are rarely correct.
' Note I catch at this level, rather than in the ReadFile() method.
End Try
End Sub

How to trim values in an array in VBA?

I got a problem I just cant fix. I have a string, want to split it at ";" (that is working) and then trim the values.
Dim cell As String
Dim objects() As String
cell = Range("X74").Text
objects= Trim(Split(cell, ";"))
I get my error on the Trim-function. I then tried the following approach:
For Each object In objects
object = Trim(object)
Debug.Print object
Next
This works, but doesnt save the trimmed value to my objects-array.
Despite naming your variables objects and object, they are an array of simple Strings resp. a simple String, and in VBA a string is not an object.
In your For Each-Loop, you are copying a string to the variable object, and no matter what you do with it, it doesn't change the content of the objects-array.
If you really need to change the content of the objects-array, use a loop like that:
Dim i As Long
For i = LBound(objects) To UBound(objects)
objects(i) = Trim(objects(i))
Debug.Print objects(i)
Next
And you should think about changing the name of your variables...
I would try to avoid vba names as variables:
Sub tst()
Dim yourcell As String, i As Long
Dim yourobjects() As String
yourcell = Range("X74").Text
yourobjects = Split(yourcell, ";")
For i = LBound(yourobjects) To UBound(yourobjects)
yourobjects(i) = Trim(yourobjects(i))
Debug.Print yourobjects(i)
Next i
End Sub

How Do You Return True If A String Contains Any Item In An Array Of String With LINQ in VB.NET

I could not find this question on stack overflow but if it is here, please let me know and I will take it down.
Using LINQ in VB.NET, how do you return True if a string contains one of the items in an array of strings?
This is this is the code in multiple lines. How do you do this in one line with LINQ in VB.NET?
Sub Main
Dim endPointTimeoutText As Array = {"endpoint timeout", "endpoint is not available"}
Dim strResult As String = "endpoint is not available sample text."
Dim booleanResult As Boolean = False
For Each item As String In endPointTimeoutText
If strResult.Contains(item) Then
booleanResult = True
Exit For
End If
Next
Console.WriteLine(booleanResult) 'Only included this for the example
End Sub
The expected result would be 'True' or 'False' depending on if the string (strResult) contained one of the values in the Array Of Strings (endPointTimeoutText)
You turn it around, mentally - don't ask "for this string X, which of these things in this array are in that string", you ask "for this array of strings, which of them are in this one string X":
Dim whichStringsArePresent = endPointTimeoutText.Where(Function(ett) strResult.Contains(ett))
Dim firstImeoutStringFound = endPointTimeoutText.FirstOrDefault(Function(ett) strResult.Contains(ett))
Dim wasATimeout = endPointTimeoutText.Any(Function(ett) strResult.Contains(ett))
etc
By the way it would make your code read more nicely if you make it so that Collections of things have plural names. Consider something more like this:
Dim wasATimeout = endPointTimeoutTexts.Any(Function(ett) strResult.Contains(ett))
It's subtle, but significant in terms of readability
Thank you Caius Jard for your help on this. I am going to post the complete program for what I'm going to use as the answer below.
I needed to use a List instead of an Array so that I could use the 'Any()' method. Thanks again Caius, I really appreciate it!
Sub Main
Dim endPointTimeoutText As String = "endpoint timeout,endpoint is not available"
Dim endPointTimeoutList As New List(Of String)
Dim strResult As String = "endpoint is not available sample text."
endPointTimeoutList = endPointTimeoutText.Split(",").ToList()
Dim areAnyStringsPresent As Boolean
areAnyStringsPresent = endPointTimeoutList.Any(Function(itemInEndPointTimeoutList) strResult.Contains(itemInEndPointTimeoutList))
Console.WriteLine(areAnyStringsPresent)
'This code produces the following output:
'True
End Sub

Why Won't My Array Sort? (Visual Basic)

I'm working on a project, for school, that reads text from a .txt file to an array. After doing that, I'm supposed to sort the array, alphabetically, and then list the contents in a listbox. Here is my code:
Imports System.IO
Public Class Form1
'Allow array to be accessed by the entire program
Public books(1) As String
Private Sub btnView_Click(sender As Object, e As EventArgs) Handles btnView.Click
'Declare variables
Dim sr As New StreamReader("C:\Users\Bryson\Desktop\BooksinStock.txt")
Dim book As String
Dim i As Integer = 0
'Establish loop to read contents of the text file into the array and list the array in the listbox
'the sr.Peek = -1 simply means that the reader has reached the end of the file and there is nothing more to be read
Do Until sr.Peek = -1
book = sr.ReadLine()
'ReDim allows the array to grow with the set amount of books in text file
ReDim books(books.Length + 1)
books(i) = book
i += 1
Loop
Array.Sort(books)
lstBoxInventory.Items.Add(books(i))
End Sub
End Class
However, when I run the program, I receive an error on the lstBoxInventory.Items.Add(books(i)) line that says "an unhandled exception of the type 'System.ArgumentNullException' occurred in System.Windows.Forms.Dll
I've tried to lay the code out in various ways to get the sort to work but keep coming up short. Does anyone know how to get rid of this null error?
The problem happening because "i" is larger than the highest index
Do Until sr.Peek = -1
book = sr.ReadLine()
ReDim books(books.Length + 1)
books(i) = book
i += 1 'This is adding 1 to the very end
Loop
Array.Sort(books)
lstBoxInventory.Items.Add(books(i)) 'When the items are being added it is trying to add an extra i that does not exist
edit
Honestly I would change the format to use ReadAllLines and list(of String)
Something like (Im writing code from memory)
Dim bookList as new List(of String)
Dim bookTextFile as String() = File.ReadAllLines("C:\booklist.txt")
for each book as String in bookTextFile
bookList.add(book)
next
bookList.Sort
Edit Again
Just using this
Dim bookList As String() = System.IO.File.ReadAllLines("C:\Users\Bryson\Desktop\BooksinStock.txt")
creates a single dimension array ..
Strings() are single Arrays String(,) are two dimensional Arrays
Honestly your whole homework could be
Dim bookList As String() = System.IO.File.ReadAllLines("C:\Users\Bryson\Desktop\BooksinStock.txt")
Array.Sort(BookList)
boom - done.
Test it using
for each book as String in BookList
Msgbox(book)
next
You could do
Dim bookList As String() = System.IO.File.ReadAllLines("C:\Users\Bryson\Desktop\BooksinStock.txt")
Dim books(bookList.Length - 1) As String 'This is the same as ReDim
For x As Integer = 0 To bookList.Length - 1
books(x) = bookList(x)
Next
Array.Sort(books)
but you would literally be saying bookList = books
But.... if you just want to get your code working, just try this
lstBoxInventory.Items.Add(books(i -1)) 'This takes away the extra i that you added

Getting full Split array into a VBA variable

Say I have a path in Range("A1") that looks like this:
/data/apps/server/
I would like to get the three elements into a variable. I've thought doing a Split() by the separator / I would get the full array:
Dim myElements()
myElements = Split(Range("A1").Value,"/")
'>>> EXPECTED: myElements is [data, apps, servers]
but I actually get a Type mismatch error on the line myElements = Split(Range("A1").Value,"/"). What does the Split function return? Does it actually return the array or it rather gives read-only access?
I would just like to get the array of the Split method without having to loop through them and build my own array, if possible of course.
Change Dim elements() to Dim elements As Variant
You need to declare it as a Variant.
Explanation:
The data in Excel cell can be anything. So use a Variant. In cases like below, you know it is a String so declare it like a String
Sub Sample()
Dim myElements() As String
Dim myString As String
myString = "aaa/bbb/ccc"
myElements = Split(myString, "/")
Debug.Print myElements(0)
Debug.Print myElements(1)
Debug.Print myElements(2)
End Sub
Split returns a String Array. You may want to see This
Edit: I have a feeling that I may confuse someone with my explanation so let me explain it a bit more.
Dim myElements() means "Declare myElements as array of Variants".
Split returns an array of Strings. Hence, the mismatch.
You can do either Dim myElements or Dim myElements as Variant or Dim myElements() as String to resolve the problem.
Here is why each one of these works:
Dim myElements and Dim myElements as Variant
Both of these means that you declare myElements as Variant. Variants are special types, which can accept anything. As such, they can accept array of strings easily. However, variants have large memory overheads and should be avoided wherever possible.
Dim myElements() as String
This means that you declare myElements as array of strings. Since this is the same type as what is returned by the Split function, it is accepted.
Ideally, if you know the return type of a function, you should specify the correct type for your variables.
So in this case, Dim myElements() as String which is the same type returned from the Split funcition.

Resources