I have a 2D array - aArray(1,variable) and want to know how I can For Each through the first rank of the array, ie only read aArray(0 , variable)
This is more for self educational purposes as to how if possible it can be done. I can do it with a for loop:
Dim a As Integer: For a = 0 to ?
Range("A1").Value = aArray(0,a)
Next a
But was interested in using the For Each loop. So far I've got
Dim a As Variant: For Each S In aArray
Range("A1").Value = S
Next a
But it iterates through all the array (0,0) (1,0) (0,1) (1,1) Etc...
You can't do that. You'd have to output the first rank into a new array, and then iterate through that.
There's no good reason to use For Each anyway since it's slower - see: https://support.microsoft.com/en-us/kb/129931
Related
I have create an array of integers.
Dim EnemyLevel() as Integer = {1,2,2,3}
Let's say I wanted to get the position of every item that included '2', that'd be EnemyLevel(1) and EnemyLevel(2), what's the function to do that?
I'm supossed to use Array.IndexOf(EnemyLevel(),2) but how do I store the results?
You run the array in a For Loop. And check if any of the indices contain '2'
Array1 = Array(1,2,2,4)
For i=0 to UBound(Array1)
If Array1(i) = 2 Then
msgbox i
End If
Next
I am curious if I can copy multiple columns to a new array from an existing array in one iteration of a loop. Suppose we have the following general example:
Array1 contains 10,000 elements in column1, 10,000 elements in column2, and 10,000 elements in column 3, etc.
Let's say that I want a new array generated off that information, only I want only columns 1 and 2 populated. Can I do this by looping only once with a correctly dimensioned target array? For instance:
'Assume TargetArray has already been ReDimmed to the size of Array1 in the code prior
For i=0 to UBound(Array1)
TargetArray(x,1)= Array1(x,1)
TargetArray(x,2)=Array1(x,2)
Next
So can this be done in one step, or do I have to make a loop for each dimension I want to add to the array. Is there any speed savings by doing two operations per loop as stated above (assuming it works).
Thanks for all of your help!
Have you tried just using Range objects? I just made 100 values in columns A and B, and copy them to F and G. Or are you trying to plug values from the first three columns into an equation to give you values for the new two columns?
Sub CopyRange()
Dim Array1 As Range
Dim Array2 As Range
Set Array1 = Range("A1:B100")
Set Array2 = Range("F1:G100")
Array2.Value = Array1.Value
End Sub
Your example should work as what RubberDuck commented.
It is similar in below example which works at my end.
I can't fit it to comments so I have no choice to post it as answer.
Dim TargetArray ' declared as Variant type, not array of variants
ReDim TargetArray(0 To Ubound(Array1, 0), 0 To 1) ' for 2 columns
For i = 0 To Ubound(Array1, 1)
TargetArray(i, 0) = Array1(i, 0)
TargetArray(i, 1) = Array1(i, 1)
Next
Is this close to what you have? If so, then that should work.
I declared an array in my VBA function that has a dynamic size. As I cannot ReDim the first dimension of a two- or more-dimensional array, can I add a second dimension to a set array?
This is how I dynamically set the size of my array.
Dim nameArray() As String
Dim arrayCount As Long
For i = 1 To 100
ReDim Preserve nameArray(1 to arrayCount)
nameArray(arrayCount) = "Hello World"
arrayCount = arrayCount + 1
Next i
Now I would like to add a second dimension.
ReDim Preserve nameArray(1 To arrayCount, 1 To 5)
doesn't work.
Is there a workaround?
There isn't any built-in way to do this. Just create a new two-dimensional array and transfer the contents of your existing one-dimensional array into the first row of that new array.
This is what this function does:
Function AddDimension(arr() As String, newLBound As Long, NewUBound As Long) As String()
Dim i As Long
Dim arrOut() As String
ReDim arrOut(LBound(arr) To UBound(arr), newLBound To NewUBound)
For i = LBound(arr) To UBound(arr)
arrOut(i, newLBound) = arr(i)
Next i
AddDimension = arrOut
End Function
Example usage:
nameArray = AddDimension(nameArray, 1, 5)
There is one (also works to delete a dimension), but you will have to think in terms of worksheet dimensions...
use transposition
While I highly prefer the previous 'by hand' method from Jean-François Corbett's and I don't like to rely on Excel build-in function (especially this one!), I would just like to clarify another way for future readers coming here:
adding a dimension to a 1d line vector (a row) means transposing it in Excel
Here, nameArray(1 to arrayCount) is a row (index is a column number) and because of it, if you add a dimension it will become a column since 2d arrays are indexed as (row,column). So, you can just do this:
nameArray = Application.Worksheetfunction.Transpose(nameArray) 'transforms the array to nameArray(1 To arrayCount, 1 To 1), so then:
redim preserve nameArray(1 To arrayCount, 1 To 5)
without any other manipulation.
BUT beware of the very confusing Excel's Transpose function (at least it is the case for me!): the advantage here is that it automatically adds a dimension and redimensions the array for you.
It works as expected only because you are using a 'based 1' index '1d array'.
IF this is not the case, all indices will be shifted by 1, (that's how Transpose is build in to be coherent with cells and ranges). That is: if you start with
nameArray(0 to arrayCount)
you will end up with
nameArray(1 to arrayCount + 1, 1 to 5)
with precautions
While I am at it, it may be off-topic and their are many topics about it, but their are other traps in this Transpose function one should never be enough warned about (not to mention it can consume more time and resources than Jean-François Corbett's solution) :
• if you are dealing with '1d column' in an excel 2d array (a column), that is an array:
nameArray(1 to arrayCount, 1 to 1) [*]
and if you make the transpose of it, the column dimension will be "skipped" and the result will be:
nameArray(1 to arrayCount)
It makes sense since you will end up with an Excel row (so why bother with an extra dim?). But I have to say this is not the intuitive behaviour I would expect, which should be more something like nameArray(1 to 1, 1 to arrayCount).
Note that, a contrario, it can be used to delete a dimension and redimension the array automatically from 2d to 1d: redim preserve the last dimension to 1 to 1 and then transpose! This is the resulting array just above.
• But finally all is not lost: suppose you transpose this array of 1 line:
nameArray(0 to 0, 0 to arrayCount)
you correctly get an array of 1 column:
nameArray(1 to arrayCount + 1, 1 to 1)
(well, almost) - and look back at ref [*] now...
Thus, if you are to use this build-in function and if, moreover you need more dimensions or worst, need to compose transpositions, it can become a bit tricky...
For all this or if you simply need to know correct indexing and number of dimensions of your arrays (not only number of columns), I would suggest a very useful function from users John Coleman and Vegard, the post just below.
While all this should appear logical and trivial for people used to work with Excel sheets, it's very not the case when you are more used to matrix manipulations and I think suggesting the use of this Transpose function should come with some precisions.
I've been searching for an example for array of arrays but I couldn't find any. Any link or explanation will be great.
What I'm really trying to do:
I have angles and edges of polygons and I want to insert those informations inside array, It looks like this at the time:
Dim edges() as integer
Dİm angles() as integer
??Dim ArrayOfArray as integer??
Private sub AddPolygonToArray
for i = 0 to x
edges(i) = edge
angles(i) = angle
next
??ArrayOfArray(index) = new Array(edges,angles,NameOfPolygon,QuantityOfPolygon)??
End Sub
Index,nameofpolygon and quantityofpolygon are not necessary, but they're integers if you need to know.
If anything is incomprhensible, don't be afraid to ask.
Thanks in advance
There are two types of multidimensional Arrays
Regular multidimensional array
Dim mdArray(5, 5, 5) as integer
And Jugged Array (Array of Arrays)
Dim jugged()() as integer
Since geometry is all about 3 dimensions, I believe, you can describe any shape using 3-dimentional array such as mdArray(5, 5, 5)
You should do a List(Of Polygon).
But if you can't, you can always do a Multidimensional Array
This means that you can do
Dim MultiArray(X,Y,Z,W)
I am using VB.NET.
I would like have an array called A1 and I will perform for loop inside that array.
In the middle of the for loop, I need to remove an item from that A1 array.
I am aware that if I remove that object from A1 array, the program will crash (out of bounds error message).
Which array variable in VB.NET would allow me to perform the task above?
Code sample is most welcomed!
Thank you.
The easiest way would be to use a list instead of an array (or convert the array you have to a List(of T).
The trick then is to move from the end of the list to the front instead of the other way around.
For example:
Sub Main()
Dim RndGenerator as New Random
Dim a As New List(Of Double)
For i = 0 To 99
a.Add(RndGenerator.NextDouble() * 10) 'Populate the list
Next
For i = a.Count - 1 To 0 Step -1 'This loop performs the deletion.
If a(i) > 5 Then a.RemoveAt(i)
Next
Console.ReadKey() 'Or debugger.Break to look at the result
End Sub
This will populate a list with random numbers from 0 to 10. It then removes all numbers >5 from the list.
Edit:
Good point from Steven Doggart on not using VB6 Relics. Edited the code to use the System.Random class instead.