Let's say I have the following Array, arr that contains a maximum of 20 substrings. In this example, the array will have 4 substrings:
arr = {"AAAA: 1234567" , "BBBB: 2345678" , "CCCC: 98765432" , "DDDD: 87654321"}
Note: Capitalization is not important.
I am needing assistance with finding a substring inside an array (again, up to 20 strings possible), that Starts With CCCC:, and then assigning that entire string to it's own variable, let's call it Var1.
I understand I could assign Var1 = arr(2), but I need to figure out how to determine the index number in the array that meets my criteria.
What I would really appreciate (although any method I will be happy with), is making a stand alone function such as:
Function ArrayIndex(ArrayInput as Variant, StartsWith as String) as Byte
'Arguments Here
End Function
Then I could just use this in my Subroutine:
Var1 = arr(ArrayIndex(arr, "CCCC:"))
Update 1
Here is a snippet of my current code
Sub T_Report
'<Shortcut = Shift+Ctrl+T>
Dim Data as String, DataArray as Variant
With ActiveSession
.Copy 0, 2, 80, 21 'Just a big block of text with multiple lines, copied to clipboard
Data = Clipboard 'Set Data to the clipboard value
DataArray = Split(Data,vbCrLf) 'This is "Data" in an Array, separated by line breaks
'Just checking to see if the Array was successful (it is)
Debug.Print DataArray(0) & vbNL & DataArray(1) & vbNL & DataArray(2) & _
vbNL & DataArray(3) & vbNL & DataArray(4) & vbNL & vbNL
'Misc code here
Dim sF1 as String, sF2 as String, sF3 as String
Dim Rslt1 as String, Rslt2 as String, Rslt3 as String
sF1 = "Field1:"
sF2 = "Field2:"
sF3 = "Field3:"
MsgBox DataArray(0) ' This works fine, giving me first substring
Rslt1 = FindMyString(sF1, DataArray)
' Misc Code
End With
End Sub
However, when I use the following function, I get Type Mismatch error on the MsgBox arr(0) line, although it should be giving me the very first substring of DataArray in the above sub (should be an exact match, the array has not been modified).. However, when I do MsgBox DataArray(0) above, I do get the first substring.
Private Function FindMyString(strToFind As String, ParamArray arr() As Variant) As String
Dim i As Integer
Dim iLen As Integer
Dim strArr As String
FindMyString = "" ' Returns Blank String if not found
' I get type mismatch here (Doesn't appear Array from sub loaded into this function)
MsgBox arr(0)
iLen = Len(strToFind)
For i = 0 To UBound(arr)
strArr = CStr(arr(i))
If strToFind = Left$(strArr, iLen) Then
FindMyString = strArr
Exit Function
End If
Next i
End Function
EDIT - FIX YOUR ARRAY LOAD
Change this (it MUST give you an error!):
arr = {"AAAA: 1234567" , "BBBB: 2345678" , "CCCC: 98765432" , "DDDD: 87654321"}
To This:
Dim arr As Variant
arr = Split("AAAA: 1234567,BBBB: 2345678,CCCC: 98765432,DDDD: 87654321", ",")
If you want to use a function to do your bidding you can pass an array of data using the ParamArray type. It has to be the last parameter in your function
This should do what you want:
Private Function FindMyString(strToFind as string, ParamArray arr() As Variant) As String
Dim i As Integer
Dim iLen as Integer
Dim strArr as String
FindMyString = "" ' Returns Blank String if not found '
Debug.Print arr(0)(0) ' Print first element of array
iLen = Len(strToFind)
For i = 0 To UBound(arr(0))
strArr = CStr(arr(0)(i))
If strToFind = Left$(strArr, iLen) Then
FindMyString = strArr
Exit Function
End If
Next i
End Function
In your example you can test it by:
Var1 = FindMyString("CCCC:", arr)
Related
I have a sub that takes a variant array generated in a userform and I would like to extract all of the values and return them as a single comma delimited string. This is probably pretty basic, but I'm having trouble getting the values from the array into a string. I'm getting a type mismatch when I try to cast the variant as a string. Any idea what I'm doing wrong?
Sub formSearch(ParamArray search() As Variant)
Dim returnString As String
returnString = ""
For i = LBound(search) To UBound(search)
returnString = returnString + CStr(search(i)) + ","
Next
MsgBox returnString
End Sub
I had the same problem because the input array was the contents of a NamedRange on a WorkSheet.
Even though the NamedRange was a single column of cells, the array returned by VBA was a 2-dimensional array of values and thus the code needed the i,1 adjustment in the CStr function to work :
Function getCellArrayAsString(RangeName As String) As String
Dim arr() As Variant
getCellArrayAsString = ""
arr = ThisWorkbook.Names(RangeName).RefersToRange.value
For i = LBound(arr) + 1 To UBound(arr)
getCellArrayAsString = getCellArrayAsString & CStr(arr(i, 1)) & ","
Next
End Function
or as it would be applied to the OP's code :
Sub formSearch(ParamArray search() As Variant)
Dim returnString As String
returnString = ""
For i = LBound(search) To UBound(search)
returnString = returnString + CStr(search(i,1)) + ","
Next
MsgBox returnString
End Sub
I suspect that your code suffered from the same problem in that your input was actually a 2-dimensional array.
I'm trying to loop through a listbox and add the contents to an array....
My code is this:
Private Sub exportfolders_Click()
Dim list As String
Dim folderlist As String
Dim folderarray() As String
'Dim i As Interger
For i = 0 To Me.selectedfolders.ListCount - 1
'folderlist = (Me.selectedfolders.Column(0, i))
'folderarray() = Join(Me.selectedfolders.Column(0, i), ",")
list = (Me.selectedfolders.Column(0, i))
folderarray() = Join(list, ",")
ReDim Preserve folderarray(i)
Next i
folderlist = folderarray
'folderarray() = Join(folderlist, ",")
MsgBox (folderlist)
End Sub
You can see the bits I have commented out, trying all sorts to get it to work. But I keep getting the message "Can't assign to array" at folderarray(i) = Join(list, ","). Any pointers as to where I am failing?
You can concatenate the list box items into a string, and then use Split() to load your array. That way, the array is sized automagically without you needing to ReDim.
I tested this code in Access 2010:
Dim folderarray() As String
Dim i As Long
Dim strList As String
For i = 0 To Me!selectedfolders.ListCount - 1
strList = strList & "," & Me!selectedfolders.Column(0, i)
Next
' use Mid() to exclude the first comma ...
folderarray = Split(Mid(strList, 2), ",")
Note I don't know what you want to do with the array after loading it. MsgBox folderarray would throw Type mismatch error. MsgBox Mid(strList, 2) would be valid, but if that's what you want, you wouldn't need the array.
1) declare the array. Take a look at https://msdn.microsoft.com/en-us/library/wak0wfyt.aspx
2) No need of support variable
3) Assign the values to your array with the correct syntax
Private Sub exportfolders_Click()
Dim folderarray() As String
Dim i As Interger
Redim folderarray (Me.selectedfolders.ListCount-1)
For i = 0 To Me.selectedfolders.ListCount - 1
folderarray(i) = Me.selectedfolders.Column(0, i)
Next i
' Write here what you want to do with your array
End Sub
You could try something like this:
Private Sub ListToArray()
Dim folderArray() As Variant
Dim currentValue As String
Dim currentIndex As Integer
Dim topIndex As Integer
topIndex = Me.selectedfolders.ListCount - 1
ReDim folderArray(0 To topIndex, 0 To 1)
For i = 0 To topIndex
currentValue = Me.selectedfolders.Column(0, i)
folderArray(i, 0) = i
folderArray(i, 1) = currentValue
Next i
End Sub
Note my example is a multi-dimensional array which will give you the ability to add more than one item should you chose to do so. In this example I added the value of "i" as a placeholder/ index.
I reviewed this question/answer here before writing this: Declare and Initialize String Array in VBA
I am trying to understand the proper way to declare and initialize an array WITHOUT resorting to data type VARIANT.
This is my code, and it does work as it is:
Function MakeLegalFilename(legalname As String) As String
Dim MyArray() As Variant
Dim x As Integer
MyArray = Array("<",">","?","#","%")
For x = LBound(MyArray) To UBound(MyArray)
legalname = Replace(legalname, MyArray(x), "", 1)
Next x
MakeLegalFilename = legalname
End Function
If I change "Variant" to "String," the code fails at MyArray = Array(... with a runtime error 13 type mismatch.
If I define the array size to match the number of characters in the string (5 total, but array starts at 0):
Dim MyArray(4) As String
MyArray = Array("<",">","?","#","%")
Now I get a compile error at MyArray = Array(... that says "Can't assign to array."
I know that I could declare the array this way and make it work (I tested it this way):
MyArray(0) = "<"
MyArray(1) = ">"
MyArray(2) = "?"
...
MyArray(4) = "%"
But if I am coding in a whole list of characters (say 20), then doing this is cumbersome, and plus, I would like to know why the other way doesn't work, since it suggests I have a fundamental misunderstanding. In it's most basic form, my question really is, why doesn't this:
Dim MyArray(4) As String
MyArray = Array("<",">","?","#","%")
work?
Thank you.
Array returns a Variant.
So you can't use it if you don't what a variant.
Split can split a string.
Split Function
Description
Returns a zero-based, one-dimensional array containing a specified number of substrings.
Syntax
Split(expression[, delimiter[, limit[, compare]]])
Put comma delimited string into split containing your characters.
Use a helper function:
Dim MyArray() As String
MyArray = StrArray("<", ">", "?", "#", "%")
...
Public Function StrArray(ParamArray args() As Variant) As String()
Dim i As Long
ReDim temp(UBound(args)) As String
For i = 0 To UBound(args)
temp(i) = args(i)
Next
StrArray = temp
End Function
To initialize static-size string array, use:
Dim MyArray(4) As String
MyArray(0) = "<"
MyArray(1) = ">"
MyArray(2) = "?"
MyArray(3) = "#"
MyArray(4) = "%"
To initialize dynamic-size string array, use:
Dim MyArray() As String
For i = 0 to 10
Redim Preserve MyArray(i) 'increase the size
MyArray(i) = Char(64 + i)
Next
For further information, please see: http://msdn.microsoft.com/en-us/library/wak0wfyt.aspx
I need to know how can I add an item to an existing array using a user input.
I tried something like this:
Dim MyArray(100) as String
UBound(MyArray) = Inputbox("What's the name of your new array item?")
Ubound(myArray) returns a Long datatype, it literally return the length/size of the array.
If you want to read or assign a value then you must fully qualify the array ie.
MyArray(ubound(myArray)) = "new Value" or MyArray(100) = "new Value"
Sub Main()
Dim MyArray(100) As String
MyArray(UBound(MyArray)) = InputBox("What's the name of your new array item?")
MsgBox MyArray(UBound(MyArray))
End Sub
You could use a dynamic array instead:
Dim MyArray() As String
' Then to add a new element:
Redim Preserve MyArray(1 to SafeUBound(MyArray) + 1)
MyArray(SafeUBound(MyArray)) = InputBox("Who's yer daddy?")
Function SafeUBound(vArray As Variant) As Long
Dim x As Long
On Error Resume Next
x = UBound(vArray)
If Err.Number = 0 Then
SafeUBound = x
Else
SafeUBound = 0
End If
End Function
The call to SafeUbound is necessary because calling UBound or LBound on an uninitialized array will throw an error.
I don't get what's false in my code. I searched the error the whole morning! So I hope you can help me.
First, here's the problem code (the names of the variables aren't their real names):
Sheets(sheet).Range(nameOfTheRange).FormulaR1C1 = _
functionReturningString(functionReturningStrArr( _
Range(nameOfAnotherRange).Value, AnInputWorkSheet, "colNameInInputSheet"))
So my description on that:
All functions work fine standing alone, but in combination there is always this error (Language: German):
Fehler beim Kompilieren:
Unverträglicher Typ: Datenfeld oder benutzerdefinierter Typ erwartet
functionReturningString is a function with the following parameters(strArr() as Variant) --> it returns a String like a bulletlist.
functionReturningStrArr(nameWhichISearchInSheet as String, dataSheet as Worksheet, dataColumn, as String) --> it returns a Variant() for the bulletListing
I'm not sure if the second method really works so here's the code of it.
Function functionReturningStrArr(ByVal nameWhichISearchInSheet As String, ByVal datasheet As Worksheet, ByVal datacolumn As String) As String()
Dim returnArray() As String
Dim rowindex As Integer
Dim ID As String
Sheets(rawdataOverall).Cells(1, getColNumFromColName("Project")).EntireColumn.Select
'search correct dataset
For Each cell In Selection
If cell.Value = nameWhichISearchInSheet Then
rowindex = cell.row
Exit For
End If
Next cell
'get ID
ID = Sheets(rawdataOverall).Cells(rowindex, getColNumFromColName("ID")).Value
'search data from file with this ID
datasheet.Cells(1, getColNumFromColName(datacolumn)).EntireColumn.Select
Selection.UsedRange.Select
For Each cell In Selection
rowindex = cell.row
'check if row contains to this project
If Cells(rowindex, getColNumFromColName("ID")) = ID Then
ReDim Preserve returnArray(UBound(returnArray) + 1)
returnArray(UBound(returnArray)) = cell.Value
End If
Next cell
functionReturningStrArr = returnArray()
If you are asking yourselves what is getColNumFromColName, it is a method which works really fine, I used it in other projects too.
You really have to start declaring everything explicitly using Dim -- and force yourself to do this by writing Option Explicit at the top of your module. That way you will identify errors much more quickly.
Here
'get ID
ID = Sheets(rawdataOverall).Cells(rowindex, getcolnumformcolname("ID")).Value
you call a function called getcolnumformcolname; presumably form is a typo and you meant From as in getColNumFromColName. Had you had Option Explicit, you would have detected that error immediately.
The following three variables/arrays are not declared: rawdataOverall, cell, getDataFromThisProject. You should declare them and assign them a type explicitly.
Try fixing those things and see where that brings you.
Is seems a small portion of the function code snippet is wrong. on the very last line, you should assign the value of returnArray() to your function name like so:
functionReturningStrArr = returnArray()
Otherwise, you would need to extract the array from a variable named "getDataFromActualProject", as is shown in the example.
EDIT:
Alter your function "functionReturningStrArr As Variant" to return "As String()" instead of Variant. It seems you cant cast a Variant to a string array as you would expect.
EDIT:
I created a function to test this. This compile error shows up when you try to cast Variant as Array of string. This also includes a fix, your function that returns Variant MUST return array of string instead.
Sub RunTest()
Debug.Print getStringFromArray(getArray())
Debug.Print getStringFromArray(getVariant()) ' compile error! you cannot cast variant to array of string
End Sub
Function getArray() As String()
Dim returnArray(2) As String
returnArray(0) = "A"
returnArray(1) = "B"
returnArray(2) = "C"
getArray = returnArray()
End Function
Function getVariant() As Variant()
Dim returnArray(2) As String
returnArray(0) = "A"
returnArray(1) = "B"
returnArray(2) = "C"
getArray = returnArray() ' Not a compile error, you can cast string array to variant
End Function
Function getStringFromArray(inputArray() As String) As String
Dim returnString As String
For i = LBound(inputArray()) To UBound(inputArray())
If returnString = "" Then
returnString = inputArray(i)
Else
returnString = returnString & "," & inputArray(i)
End If
Next i
getStringFromArray = returnString
End Function