How can I transfer the values of a 4D jagged array to a 2D standard array? - vba

I have EuroCPCrap mapped as (j,0)(i,0) and want to put this into an array EuroCPConsol mapped as (j,i). I tried:
For j = 0 to CPIndex 'CPIndex is a global count of variables in matrix j references
For i = 0 to UBound (EuroCPCrap,3) 'i in the (now known to be) jagged
EuroCPConsol(j+1,i+1)= EuroCPCrap(j,0,i,0) 'add one since I'm base 1 but function that produced this matrix outputted base zero
Next i
Next j
I get a subscript error on the UBound statement, and I realised it's because there is no 3rd dimension in the referenced array.

First of all, I don't understand why this EuroCPCrap(j,0,i,0) would work if it's a jagged array as you describe in your first sentence. On the looks of it, it should be EuroCPCrap(j,0)(i,0).
You have a parent two-dimensional array of children two-dimensional arrays. The "third" dimension you're looking for is actually the first dimension of each child array. So something like this should work:
For i = 0 to UBound(EuroCPCrap(j,0),1)
Actually, iterating from LBound to UBound is even better practice to ensure that the entire array is traversed regardless of your Option Base or how the array is "Dimmed":
For i = LBound(EuroCPCrap(j,0),1) to UBound(EuroCPCrap(j,0),1)
Does EuroCPCrap really need to be jagged? Why not make it a 4-dimensional array? EuroCPConsol is not jagged... Is it dimensioned correctly to accept the contents of the largest of the children array? These are things to think about...

Related

Does REDIM PRESERVE for more elements set all new elements to NOTHING?

I have an array with data.
I do REDIM PRESERVE and specify a larger boundlist.
All old elements are preserved.
Will all new elements be NOTHING?
REDIM PRESERVE my_array( my_array.LENGTH + 10 )
Will the new 10 elements all be NOTHING?
Yes, additional elements are Nothing. Be aware, though, ReDim Preserve does not just extend an array in-place. It allocates a completely new array and copies the existing elements, and then leaves the original for the garbage collector.
Almost all cases where you find yourself using ReDim Preserve should be changed to use a generic List(Of T) instead.
It depends on what type your array is. Strings, integers and other 'known' numeric types get initialised with value of 0 ("" for strings).

For loop only way to copy array content to another array?

I have some code that has heavy use of arrays. It all works but there are many for loops where I iterate and copy contents from several arrays to a new array with more dimensions to fit all content.
As I understand it, there is no way to do this without a for loop (to copy array content to another array). Is this correct?
There is the method Array.Copy(arSource,arTarget,length). But it does not work with more dimensions arrays. The new one is that jagged arrays()arrays of arrays are more perfomant than 2D ARRAYS,if you move along the vectors.

Total Nos. of items in array variable

I have an array variable (string type). It contains certain no. of items, that I donot know how many they are.
I need to run a loop for that many nos. that the array contains. I tried LBound and UBound loop but it says my array is not a system array.
How can I know how many items my array contains?
Thanks
Furqan
You can use the Length property of the array object.
From MSDN (Array.Length Property):
Gets a 32-bit integer that represents the total number of elements in all the dimensions of the Array.
Read about arrays in VB.NET and the Array class for better understanding of arrays in VB.NET and the .NET framework.
Update:
However, for looping over an array you should simply use a For Each loop (as an array is treated like any other collection in .NET) - this way you will not make any silly mistakes with array bounds and off by ones:
For Each item As arrayItemType in MyArray
' do stuff with item
Next
See the example on this page.
You look at the length:
To get the number of items in the first dimension: arrayName.GetLength(0)
If you need the index, use GetUpperBound(0)
Some helpful examples here.
Like Oded said, you can use the Length-propery of the Array. This would look something like this:
Dim data As String() = {"one", "two", "three", "four"}
For i = 0 To data.Length - 1
Console.WriteLine(data(i))
Next
If you just want to loop all strings in your array, you can use For Each as well:
For Each s As String In data
Console.WriteLine(s)
Next
If the compiler is telling you that your variable is not a system array, then chances are, it's not an array. If it's not an array, you won't be able to get its bounds through any means.
Inspect the variable in the locals window and verify that your variable is of the type that you think it is. It's probably not an array after all.

Resizing a two dimensional Array

How can I resize the two dimensional array size without affecting its value?
Use ReDim with the Preserve modifier. VB.NET will make sure the original values are untouched. Didn't read the documentation right. ReDim Preserve will only allow you to change the length of the last dimension of the array.
You need to allocate a new array (with the correct size) and manually copy the elements from the first array to the second.
As Adam said, you can't resize 2D arrays dynamically. You can easily copy the existing array into a bigger one like so:
Dim smaller(1, 1) As Byte
Dim bigger(2, 2) As Byte
Array.Copy(smaller, bigger, smaller.length)
Try using array.resize if you are on .net 2 framework or above.
For example:
Dim MyArray() as string
Array.Resize(myarray,12)

Size of array in Visual Basic?

I've tried this code in VB:
Dim a(1) As Byte
Console.WriteLine(a.Length)
The output is "2". Anyone any idea why?
If you are used to C/C++/C# languages you are used that when declaring an array to initialize it with the number of elements in the array.
C# : byte a[] = new byte[1]
will declare a byte array with 1 element (upperBound = 0)
The behavior is different in VB where, when declaring an array the parameter used in initialization represents the UpperBound of the array.
VB.NET: Dim a(1) As Byte
will declare a byte array with 2 elements (upperBound = 1)
In Visual Basic, the size of an array is declared with the array's upper bound, where most languages declare the size of an array by specifying the number of elements in the array. If you aren't aware of this, then your Visual Basic arrays end up being 1 element longer than you expected:
VB.NET:
Dim a(1) as Byte ' under the hood, translated to byte[2]
Console.WriteLine("{0}", a.Length) ' output 2
a(0) = 7 ' No error, element exists
a(1) = 7 ' No error, element exists, array length is 2
a(a.Length) = 7 ' error: Index was outside the bounds of the array.
C#:
byte[] a = new byte[1];
Console.WriteLine("{0}", a.Length); // output 1
a[0] = 7 // No error, element exists
a[1] = 7 // error: Index was outside of bounds of the array. (because array length is 1)
a[a.Length] = 7; // error: Index was outside the bounds of the array.
The reason why Microsoft designed VB.NET to size arrays based on upper bound rather than array length is to make it easier to port code from VB6 to VB.NET. The initial index of a VB6 array is 1, unless you declare Option Base 0. It was common to loop through an array of size N using For i = 1 To N. By designing VB.NET to interpret an array's sizing argument as an upper bound rather than the number of elements in the array, old VB6 code that looped from 1 to N could be ported directly to VB.NET. The array in VB.NET will have one extra element compared to what the array had in VB6 (the element at index 0) but otherwise behaves as it did in VB6.
You'll sometimes see people claim that Visual Basic creates a "wasted" element. This is only true when porting legacy VB6 code which didn't expect an element at index 0. When writing new code, you just have to remember what the sizing parameter means (upper bound, not element count), and declare your arrays accordingly. Just reduce your sizing parameters by one compared to what you'd see in C#. The resulting array will have elements from a(0) to a(a.Length-1), just like a C# array.
Array starts from position 0. You are defining two positions.
If you want only 1 position, then:
Dim a(0) As Byte
and you will get a.Length as 1.
Dimension Length The index of each
dimension is 0-based, which means it
ranges from 0 through its upper bound.
Therefore, the length of a given
dimension is greater by 1 than the
declared upper bound for that
dimension.
Array Size in Visual Basic
The previous answers each have pieces of the correct answer, but not the full correct answer.
When you declare an array (Like with your code: Dim a(1) As Byte) the number you put in the array declaration (in this case, 1) is NOT a declaration of how many entries in the array, it is a declaration of the upper boundary of the array.
So, in your declaration, you're creating an array with 2 entries: a(0) and a(1)