I had the idea of creating an array of empty strings:
Dim elements as String = {"%", "&", "#"}
Then creating the dictionary as such:
Dim dictionary = New Dictionary(Of String, elements)
Finally looping through the range of the excel sheet from bottom up (lastindex specified as lenExcel from a function I have to get the last row in a sheet).
for lenExcel To 0 step -1:
Dim faa = cDec(sheet.Range((lenExcel & num).ToString)
If faa = 10.2 Then
elements[0] = sheet.Range(lenExcel & value1).toString
elements[1] = sheet.Range(lenExcel & value2).toString
elements[2] = sheet.Range(lenExcel & value3).toString
With Dictionary
.Add Key:=faa, Item:=elements
End With
Rows(lenExcel).Delete
Next
However, I think this will not work because the dictionary will hold a reference to the elements array. Hence, all of the array values contained within the dictionary for all keys would be the last values given to the elements array.
A possible solution would be to initialize a new array within the dictionary's parameters. That being said, I do not know VB and would appreciate some insight.
Thank you.
Related
I am trying to create arrays of specific length dynamically, so that I can use them in a bigger procedure.
Sample Data:
The below code using the Dictionary Gives me the Count and Unique File Extensions in the Data.
Code:
Dim dict As New Scripting.Dictionary
For Each cel In Range("B1:B8")
I = 1
If Not dict.Exists(cel.Text) Then
dict.Add cel.Text, I
Else
temp = dict(cel.Text) + 1
dict.Remove cel.Text
dict.Add cel.Text, temp
End If
Next cel
For Each varKey In dict.Keys
Debug.Print varKey & ":" & dict.Item(varKey)
Next
Result:
What I am trying to do is create 3 (in this sample) arrays pdf(4),xlsx(3),docm(1)
Using the results from Dictionary.
But the line Dim varkey(dict.Item(varKey)) As Variant gives me Compile Error.
Constant Expression Required
Is there a way to do it ? I searched google for ways to achieve this, but with no luck.
Basically what I want is to use these different extension names to declare Arrays. But these extension names will vary so I need to declare them dynamically. Array should have same name as the Extension.
So pick the name from sheet or from Dictionary and declare that as Array of a specified Length. Length can be Redim'ed afterwards also, but the main problem is declaring them from a variable.
As BrakNicku commented a Dictionary of Dictionaries will get you the answer that you want.
Sub PrintExtensionCount()
Dim Cell As Range
Dim Map As New Scripting.Dictionary, subMap As New Scripting.Dictionary
For Each Cell In Range("B1:B8")
If Not Map.Exists(Cell.Value) Then Map.Add Cell.Text, New Dictionary
Set subMap = Map(Cell.Value)
subMap.Add Cell.Offset(0, -1).Value, vbNullString
Next
Dim Key As Variant
For Each Key In Map
Set subMap = Map(Key)
Debug.Print Key; ":"; subMap.Count
Next
End Sub
Result
Not to confuse things but I like to use a Dictionary of ArrayList.
Sub PrintExtensionCount()
Dim Cell As Range
Dim Map As New Scripting.Dictionary, list As Object
For Each Cell In Range("B1:B8")
If Not Map.Exists(Cell.Value) Then Map.Add Cell.Text, CreateObject("System.Collections.ArrayList")
Set list = Map(Cell.Value)
list.Add Cell.Offset(0, -1).Value
Next
Dim Key As Variant
For Each Key In Map
Set list = Map(Key)
Debug.Print Key; ":"; list.Count
Next
End Sub
I'm not sure exactly what the task at hand is, but this is an X-Y problem, if I understand your comments.
Dim statements - declarative statements - are not executable. This is regardless of the type (String, Long, Variant array, whatever.) Your question title might have been bit misleading in that regard, since it seems like essentially you're trying to dynamically declare variables - the fact they are arrays is coincidental.
You can avoid the compile error by ReDimming an array based on the count from your dictionary, but you can't come up with a dynamic list of variables.
I have a list of arrays. I am looping through to write the data in the arrays into a text file. When I loop through each time, I would like to use a different array to access the data.
I am thinking of storing the names of these arrays in an different array and as I loop through, I can access this array using the current loop index. But I am not sure how to do this in VBA.
Need some guidance on this. I am welcome to other suggestions as well.
You could also store them in a collection. This will also allow you to add a key to each array that you store in the collection. You can than even call a specific array using this key. Just a short example to get you started:
Sub CreateCollection()
Dim col As Collection
Dim arr As Variant
Dim MyArray1(1) As String
Dim MyArray2(1) As String
MyArray1(0) = "FirstItemArr1"
MyArray1(1) = "SecondItemArr1"
MyArray2(0) = "FirstItemArr2"
MyArray2(1) = "SecondItemArr2"
Set col = New Collection
col.Add MyArray1, "ArrayName1"
col.Add MyArray2, "ArrayName2"
For Each arr In col
Debug.Print arr(1)
Next
Debug.Print col("ArrayName2")(1)
Set col = Nothing
End Sub
I have a spreadsheet of data that I want to put into a VBA array which then outputs unique values to a new sheet. I have got that to work so far. However, some of the cells in the original data have text separated by commas, and I want to add those to the array as well. I can't quite get that bit to work.
After the various 'dims', my code is
'Grabs the data to work with
Set rTable = Worksheets("Data Entry").Range("N1:N100", "P1:P100")
'Puts it into an array
MyArray = rTable.Value
'Sets where the data will end up
Set rCell = Worksheets("TestSheet").Range("A1:A100")
'Each unique entry gets added to the new array
On Error Resume Next
For Each a In MyArray
UnqArray.Add a, a
Next
'Add unique data to new location
For i = 1 To UnqArray.Count
rCell(i, 1) = UnqArray(i)
Next
I have tried doing a new variant to store the split data
SpArray = split(MyArray,", ")
and then have that here
MyArray = rTable.Value
SpArray = split(MyArray,", ")
and then refer to SpArray for the rest of the code
I've also tried to have as part of
For Each a in SpArray
but it doesn't work for me.
Do I need to do a separate loop on each cell of the array before I filter out the unique ones?
Yes, you need another loop. But if you set a reference to Microsoft Scripting Runtime and use a Dictionary object, you can eliminate the loop that writes to the range because Dictionary.Keys returns an array.
In this example, it attempts to split every entry on a comma and treats each of those as a unique. If there is no comma, Split returns the one value so it works in both cases. There's probably a small cost to splitting things that don't need to be split, but you won't notice until your range is much larger. And it makes the code cleaner, I think.
Sub WriteUniques()
Dim dcUnique As Scripting.Dictionary
Dim vaData As Variant
Dim vaSplit As Variant
Dim i As Long, j As Long
vaData = Sheet1.Range("$I$12:$I$62").Value
Set dcUnique = New Scripting.Dictionary
For i = LBound(vaData, 1) To UBound(vaData, 1)
vaSplit = Split(vaData(i, 1), ",")
For j = LBound(vaSplit) To UBound(vaSplit)
If Not dcUnique.Exists(vaSplit(j)) Then
dcUnique.Add vaSplit(j), vaSplit(j)
End If
Next j
Next i
Sheet1.Range("J12").Resize(dcUnique.Count, 1).Value = Application.Transpose(dcUnique.Keys)
End Sub
The code tweak that worked for me was to put the Split at the end.
'Add unique data to new location
For i = 1 To UnqArray.Count
rCell(i, 1) = Split(UnqArray(i), ",")
Next
This then built up an array using data from different ranges and splitting up comma separated ones before outputting only the unique ones.
I have a string array A where I store some values for instance A(1) = "a,b,c" A(2)="1,2" etc. From that array I am creating subarrays using A(1).split(",") and I have
dim subArr1() as string = {"a","b","c"}
dim subArr2() as string = {"1","2"}
etc
Now, I want to create a new two-dimensional array
dim all()() as string = {subArr1, subArr2, ...}
The initial array is created dynamically and could be have 2, 5, or whatever number of items. So I could have any number of subArrays (subArrX)
Any idea how to deal with that? I am writing in vb.net 2013
Thank you
You could use this little LINQ query:
Dim A As String() = {"a,b,c", "1,2"}
Dim parts As IEnumerable(Of String()) = From str In A Select str.Split(","c)
Dim all()() As String = parts.ToArray()
Now the array contains two arrays, the first contains "a","b" and "c" and the second contains "1" and "2".
In vb.net I want to split a string into an array, I also want to be able to know how many indices are in the array.
In vb6
I would write it like this
dim v1, arrIN(), idcCount
v1 = "1,2,3,4,5"
arrin() = split(v1,",")
idcCount = ubound(arrin))
I can get this to actually put those values into an array using:
Dim arrIN() = Split(v1, ",")
But I cannot figure out how to get the count of indices
When I try to test this in the immediate window I get the message below
?UBound(arrIN())
Number of indices is less than the number of dimensions of the indexed array.
You may use arrVar.GetUpperBound(0) and arrVar.GetLowerBound(0) methods.
Have look at MSDN reference : Array.GetUpperBound(dimension)
Dim v1 As String = "1,2,3,4,5"
Dim arrIN() As String = Split(v1, ",")
'Gets the total number of elements in the array
Dim a As Integer = arrIN.Length
'Gets the index of the last element
Dim b As Integer = arrIN.GetUpperBound(0)
In this instance:
arrIN.Length = 5
arrIN.GetUpperBound(0)=4
The zero in GetUpperBound(0) is the dimension that you want the upper index for.
AVD gave you the right answer. I just added arrIN.Length just in case you needed it.