I am trying to Redim an array with multiple columns like:
Dim f() as Variant
ReDim f(0 To 0, 0 To 0) As Variant
ReDim Preserve f(0 To UBound(f), 0 To UBound(f))
To obtain something like this:
[15 34 70]
When I try to store into the array, I am doing as:
f(0,i) = ...
f(1,i) = ...
f(2,i) = ...
What's wrong with the code?
I wanted to create an array with 1 row and 3 columns where the number of columns could increase. First, I needed to re-dimension the empty array (Dim f() As Variant) as follows (ReDim f(0 To a, 0 To 3)). The above code was not working since I was trying to Redim the array that was already dimensioned.
Second, I wanted the array to return:
f(0,i) = "Bring the value from, for instance, cells A9"
f(0,i+1) = "Bring the value from, for instance, cells A16"
f(0,i+2) = "Bring the value from, for instance, cells G16"
Related
I am loading an array from a table.
aryNonE = ActiveSheet.Range("AA1:AA" & lRowNonE - 1)
test = Array("Bob Smith", "John Davies"...)
Want to use Filter but get type mismatch on aryNonE.
test works fine
[Debug shows1
How do I get aryNonE to look like test??
Thanks
Try this way, please:
Sub test2DTo1DArray()
Dim aryNonE, lRowNonE As Long
lRowNonE = 10
aryNonE = ActiveSheet.Range("AA1:AA" & lRowNonE - 1) '2D array
aryNonE = Application.Transpose(Application.Index(aryNonE, 0, 1)) '1D array
'You can test it in this way:
Debug.Print Join(aryNonE, ",")
End Sub
In this way, it can be used to filter using an array like Criteria1...
But, if the values in the 2D array are numbers, since the Criteria array must keep only strings, the range where the array is extracted from, must preliminarily be formatted as text.
Hey everyone: I'm trying to make a function that digs through an array and adds values from range2 when the corresponding value from range1 equals criteria1.
I'm relatively new to VBA, so it's not the most elegant function in the world, but here's my code:
Function SingleArray(range1 As Range, range2 As Range, criteria1 As String)
Dim newrange() As Double
Dim d As Integer
Dim g As Integer
Dim i As Integer
g = Application.WorksheetFunction.CountIf(range1, criteria1)
ReDim newrange(g)
d = 1
For i = 0 To (range1.Count)
If range1(i) = criteria1 Then
newrange(d) = range2.Item(i).Value
d = d + 1
End If
Next i
SingleArray = newrange
End Function
Here is my data sample:
range2 range1
-5000 Bob
-5000 Jim
200 Bob
500 Jim
5000 Bob
200 Bob
300 Bob
1000 Bob
When I set the criteria as "Bob," the array that is returned is as follows:
{0,-5000,200,5000,200,300,1000}
I'm genuinely at a loss for how that zero is making it in there. Any thoughts you can provide would be most welcome!
1-D arrays default to a zero-based index structure (e.g. 0, 1, 2, 3, ....). You are looping through the ranges with a one based index (e.g. 1, 2, 3, 4, ...).
When you declare ReDim newrange(5) you are actually creating an array with six elements, not five (e.g. 0, 1, 2, 3, 4, 5)
You can make all arrays on that code sheet default to a one based index by putting this compiler directive at the top of the code sheet.
Option Base 1
You can also change the way the array is declared on the fly by specifying the Lower Boundary and the Upper Boundary.
ReDim newrange(1 to g)
I'm using secondarray as range of cells in a worksheet (Ex. "1", "2") to exclude them as autofilter list that I'm defining in the below function in "filtercriteria".
I get "type mismatch" error in the filter (secondarray) line for some reason, but I works flawlessly when I define an array using a list of items instead. For example, if I use below line to define secondarray instead.
secondarray = ("1", "2")
I've researched similar postings and wasn't lucky, can someone help with this instance?
Thanks,
Dim secondArray As Variant
secondArray = Range("L76:M76").Value
c = 0
k = 0
count = 0
rowNumb = Worksheets("List").Range(Worksheets("List").Range("L5"), Worksheets("List").Range("L5").End(xlDown)).Rows.count
For L = 1 To rowNumb
c = Worksheets("List").Range("L5").Offset(L)
If c <> k Then
'check the current activity type against the array of types we don’t want. If it isn’t in the array we add it to an array that will be used as the filter criteria
If UBound(Filter(secondArray, c)) = -1 Then
ReDim Preserve filterCriteria(0 To count)
filterCriteria(count) = c
count = count + 1
End If
k = c
End If
Next
It isn't working because filter function takes a One-dimensional array of strings to be searched for its sourcearray argument.
When you read in a range from the sheet you automatically get a 2d array as opposed to the 1D you have when assigning from a list.
Find a way to use a 1D array to pass in
For example, as your data is coming from 1 row then slice the array by row
UBound(Filter(Application.WorksheetFunction.Index(secondArray, 1, 0), c)) = -1
You may need to find the right method for you.
Another method is given here.
I have a couple of college assignments I am having trouble with. Really I am just confused about one thing regarding an array. I need to declare a three column, 5 row array. The first two columns are integers and the third column is the letter grade. So I am very confused about declaring the data type since they are different. This is my first go-around with arrays, so please excuse my ignorance. Here is an what my array is supposed to look like.
Column 1 {0,300,350,400,450}
Column 2 {299,349,399,449,500}
Column 3 {F,D,C,B,A}
(It's a grading app)
I can solve the rest of the problem myself, I am just confused about this array portion. So my question is strictly about how to declare such an array. It say's to use a two-dimensional array which only confuses me more since there are three columns. Thank you!
2-dimensional array is correct. First index is column, second index is row.
Dim strData(,) As String 'Use String variable type, even for the numbers
Dim intRowCount As Integer = 5
Dim intColumnCount As Integer = 3
ReDim strData(intColumnCount - 1, intRowCount - 1) 'subtract 1 because array indices are 0-based. Column 0 = Range start, Column 1 = Range End, Column 2 = Grade
'first row
strData(0, 0) = "0" 'Range start
strData(1, 0) = "299" 'Range end
strData(2, 0) = "F" 'Grade
'second row
strData(0, 1) = "300"
strData(1, 1) = "349"
strData(2, 1) = "D"
'third row
strData(0, 2) = "350"
strData(1, 2) = "399"
strData(2, 2) = "C"
'fourth row
strData(0, 3) = "400"
strData(1, 3) = "449"
strData(2, 3) = "B"
'fifth row
strData(0, 4) = "450"
strData(1, 4) = "500"
strData(2, 4) = "A"
'Add a row
intRowCount = intRowCount + 1
ReDim Preserve strData(intColumnCount - 1, intRowCount - 1)
'sixth row
strData(0, 5) = "501"
strData(1, 5) = "600"
strData(2, 5) = "A+"
Note that Redim Preserve can only change the last index in the array, which is why we store in (column, row) order rather than the more traditional (row, column) order.
There are a couple of ways to approach this. One is to declare the array as Object type, and they assign integers or strings to the appropriate element. Some don't consider this socially acceptable, though, because it can lead to code that's difficult to debug.
You could also use a String type for a two dimensional array and save the integers in string variables. This is also not normally done because of the conversion necessary for numeric comparisons and computation.
Another approach is to use a structure or class that contains the three values, and make an array of that.
For example,
Structure Item
Dim col1 as integer
Dim col2 as integer
Dim col3 as string
End Structure
Dim itemList(20) as Item
itemList(4).col1 = 23
itemList(4).col2 = 45
itemList(4).col3 = "somestring"
I have 6 arrays of data as longs. I want to find a way to graph all six arrays as separate lines on a Chart Control.
I have created the Chart object, in my Series Collection Editor I have 6 members, but I cannot find a function that does something along the lines of chart1.series1.setData(myArray).
I know I can go through and call .add() on every point, but I am wondering if there is a direct way to assign an array to a Series.
There is no built in way to add a whole range apart from databinding. You can call, as you said, the AddXY method of the Points property (or one of the related methods in the type DataPointCollection) of the Series, like so:
'Add data from Array1 to the first series of the chart
Chart.Series(0).Points.Clear() 'Clear all points
For i = 0 to Array1.Count - 1
Chart.Series(0).Points.AddXY(i, Array1(i)) 'Adds the data from the array to the first series
Next
If you have the data in a multidimensional (e.g. Dim Data()() As Long) you can do something like
For a = 0 to Data.Count - 1
Chart.Series(a).Points.Clear() 'Clear all points from the ath series
For i = 0 to Data(a).Count - 1
Chart.Series(a).Points.AddXY(i, Data(a)(i)) 'Adds the data from the ath array to the ath series
Next
Next
Note the X values will be just an index (0 to the array's count - 1) since you provided no further information.
Or you could write an extension method in a new Module
Public Module Extensions
<System.Runtime.CompilerServices.Extension>
Public Sub AddRange(d As System.Windows.Forms.DataVisualization.Charting.DataPointCollection, data() As Long)
Dim meCount As Integer = d.Count
For i = 0 To data.Count - 1
d.AddXY(meCount + i, data(i))
Next
End Sub
End Module
Now you can just call the AddRange method for the Points property of the series:
Chart.Series(0).Points.AddRange(Array1)
You can do it by adding point by point as Jens mentions, and this works find. Another way which should work fine is:
For a as integer = 0 to AmountOfSeries.count - 1 step 1
Chart1.Series(a).Points.DataBindXY(ArrayX1, ArrayY1)
Next
This may be closer to what you were looking for - a way to set two arrays to a series.
Here's what it would look like with only one series:
Dim xs As Double() = {0, 1, 2, 3, 4}
Dim ys As Double() = {0, 1, 2, 3, 4}
Chart1.Series(0).Points.DataBindXY(xs, ys)