How to trim values in an array in VBA? - arrays

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

Related

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

Adding Regex matches to an array

I'm struggling to solve a small bit of code. What the code does is to first load a CSV file, line by line (starting by line 3), and add it to an array. Then run a regex match and I want to insert the value in an array.
This is my working code, it shows a msgbox with the actual matches:
Dim file = "C:\Users\David\Desktop\mycsv.csv"
Dim basestatisticspath = Path.GetDirectoryName(file)
Dim statistics() As String = IO.File.ReadAllLines(file)
'Dim x As Integer = statistics.Length
'ReDim Preserve statistics(x)
Dim regexlang As Regex = New Regex("(?<=^"")\[.*\]")
Dim regexlinefilename As Regex = New Regex("(?<=^""\[.*?\]\s).*(?="")")
Dim linefilename As Match = Nothing
Dim langmatch As Match = Nothing
Dim filename() As String
Dim lang() As String
For i = 2 To UBound(statistics)
langmatch = regexlang.Match(statistics(i))
linefilename = regexlinefilename.Match(statistics(i))
MsgBox(langmatch.Value & linefilename.Value)
Next
That works well and the actual matches is what I want. So my next step was to add each match to an array to then use it to generate other files.
Therefore I ended up with this:
Dim file = "C:\Users\David\Desktop\myscv.csv"
Dim basestatisticspath = Path.GetDirectoryName(file)
Dim statistics() As String = IO.File.ReadAllLines(file)
'Dim x As Integer = statistics.Length
'ReDim Preserve statistics(x)
Dim regexlang As Regex = New Regex("(?<=^"")\[.*\]")
Dim regexlinefilename As Regex = New Regex("(?<=^""\[.*?\]\s).*(?="")")
Dim linefilename As Match = Nothing
Dim langmatch As Match = Nothing
Dim filename() As String
Dim lang() As String
' Set all value line by line
For i = 2 To UBound(statistics)
langmatch = regexlang.Match(statistics(i))
linefilename = regexlinefilename.Match(statistics(i))
lang(i) = langmatch.Value.ToString
filename(i) = linefilename.Value.ToString
MsgBox(langmatch.Value & linefilename.Value)
Next
After adding the below the program crashes on that line
lang(i) = langmatch.Value.ToString
filename(i) = linefilename.Value.ToString
I am assuming you can add the value of a regex match to a certain position of a string, but it seems I am wrong.
I´ve been searching for an answer with no results (at least to my poor understanding).
How could I convert each of the matches to a string and add it to the i position of the array?
Thanks in advance!
UPDATE:
As #Tval explained, I solved it by including the size of the array when declaring it. Thanks!
Dim filename(UBound(statistics)) As String
Dim lang(UBound(statistics)) As String
you need to initialize the array before you can reference it or you'll get a null reference error, also you can't reference an index that doesn't exist yet or you'll get an index out of range exception.
right now your using an array with a fixed length, so if you want to add a value to it you'll have to re-declare it one index larger every time.
If you want an array of a variable length id suggest using a list, so you can just append values to it without any issues
Dim myList = New List(Of String)
For Each foo As String In bar
myList.Add(bar)
Next

Accessing Object Properties in Array VBA

I cannot figure out how to access object properties in an array using VBA. I have created an array like:
Dim objectArray(10) as Variant
Dim counter as Integer 'used to move to next element in array
Next, I declared an object and store it in the array:
Dim object as Variant
objectArray(0) = object 'object stored in array[0]
counter = counter + 1 'increment counter
I want to pass the array to a function.
Call function(objectArray())
That function receives the array of objects like:
Public function(objectArray() as Variant)
So far, it seems to have worked when I have debugged it. My objectArray() seems to contain the object. When I store one object in the array, the debuger shows
objectArray(0)(1,1) .... 'this is in the Watch section of the debugger
I want to access the properties of that object in the first position of the array. That object will contain a name, several values, and a date. I've been trying to access the properties on that object like
Dim separateVar as Variant 'declare new var to hold "name"
separateVar = objectArray(0)(1,1).Value
However, when I run the macro, I get "Some Error Occured, 13, Type Mismatch". Am I accessing the object property values incorrectly?
Any help would be appreciated. Finding articles about accessing objects is easy, but finding ones about accessing their individual properties has been very difficult.
Try this.
Sub T()
Dim objInner1(1) As String
objInner1(0) = "Hello"
objInner1(1) = "World 1"
Dim objInner2(1) As String
objInner2(0) = "Hello"
objInner2(1) = "World 2"
Dim objInner3(1) As String
objInner3(0) = "Hello"
objInner3(1) = "World 3"
Dim objOuter(2) As Variant
objOuter(0) = objInner1
objOuter(1) = objInner2
objOuter(2) = objInner3
PrintArray objOuter
End Sub
Sub PrintArray(objArray As Variant)
Dim idx As Long
For idx = LBound(objArray) To UBound(objArray)
Debug.Print objArray(idx)(0) & " " & objArray(idx)(1)
Next idx
End Sub
'Hello World 1
'Hello World 2
'Hello World 3

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.

How to create find/replace add in with two multiline textboxes

I'm trying to create a find and replace macro for use as an add-in. I'd like to do so with a userform containing two multiline textboxes where users can enter the strings they would like to find and replace. I've figured out how to put these strings into arrays, but cannot figure out how to match the 'find' array with the 'replace' array and run a Replace command.
Is there some way to give each entry in each array a value, and match them up? I.e. the first string in the 'find' textbox gets a value of 1, the second gets a value of 2, and the same for the 'replace' textbox. Then the macro replaces any instances of 'find' string value 1 with 'replace' string value 1, and so on.
Here's the code I've figured out so far, thanks in advance for the help.
Private Sub CommandButton1_Click()
Dim Find_text As String
Dim Replace_text As String
Dim Find_lines As Variant
Dim x As Integer
Dim Replace_Lines As Variant
Dim y As Integer
Dim find As String
Dim Replace2 As String
Find_text = Find1.Text
Replace_text = Replace1.Text
Find_lines = Split(FindReplace2.Find1, vbCrLf)
Replace_Lines = Split(FindReplace2.Replace1, vbCrLf)
For x = LBound(Find_lines) To UBound(Find_lines)
find = Find_lines(x)
For y = LBound(Replace_Lines) To UBound(Replace_Lines)
Replace2 = Replace_Lines(y)
Next y
Next x
End Sub

Resources