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)
Related
I am working at rewriting C code to Visual Basic now. And I got some problems with this syntaxes:
C code:
typedef uint8_t state_t[4][4];
static state_t* state;
void myFunc (uint8_t* output)
{
state = (state_t*)output;
// some actions
}
My Visual Basic code:
Dim state(3, 3) As Byte
Sub myVBFunc(ByRef output() As Byte)
state = output ' does not work: Cannot convert Byte() to Byte(*,*)'
'state = CType(output, Byte(,)) ''also does not work'
' some actions'
End Sub
I can do it in C, because array name is a pointer to the first element. And C can automatically converts this types. So VB cannot. I'm stacked here.
How to convert this array to matrix?
Or how to avoid using of this in VB?
P.S. Actually I work in Visual Basic 6.0. (try to modify old project).
If the question is about VB6, then you have three options:
a. Change everything to use dynamic arrays:
Dim state() As Byte
Sub myVBFunc(ByRef output() As Byte)
state = output
End Sub
You can set up the array to call myVBFunc by redimensioning e.g.:
Dim myarray() as Byte
ReDim myarray(3,3)
myVBFunc(myarray)
b. Embed the fixed size array in a user defined type and pass that around instead:
Type type_state
state(3, 3) As Byte
End Type
Dim state As type_state
Sub test()
Dim something As type_state
myVBFunc something
End Sub
Sub myVBFunc(ByRef output As type_state)
state = output
End Sub
c. Use objects. Set up a class to hold your fixed sized array and set up getters and setters to access it. A short answer would be to long for me to show in this post.
(You will need extra code to set up the array itself)
I used simple way: just assign it trough the loop using index multiplication.
For k = 0 To 3
For j = 0 To 3
state(k, j) = temp(4 * k + j)
Next j
Next k
Why I didn't use Guillermo Phillips's answer:
a. I can't replace state(3,3) from my question just as
Dim state() As Byte
because there is some specific math here which is really simple for matrices.
I found useful ReDim option. Especially when use it in this way:
ReDim Preserve input(15)
It saves previous values of input array or put zeros in new positions!
But we can convert array to matrix using ReDim:
ReDim cannot change the number of dimensions
b. Idea of using of user defined type is really interesting but I stall can't figure out how to assign then Byte() to my
Type type_state
state(3, 3) As Byte
End Type
c. Agree! This way is useful. I just avoid it because of it's complicity (much easier to create function with inbuilt loop). But maybe using object is more safety?..
I have a set of data where each item has a 2D array of information corresponding to it. I'd like to create a 3D array where the first dimension is the item name and the second and third dimensions are taken up by the info corresponding to the item.
I can read the data for each item into a 2D array, but I can't figure out how to get the 2D array read into the 3D array.
I know the sizes of all the dimensions so I can create an array of fixed size before I begin the reading and writing process.
I'd like to do this by looping only through the names of the items and not looping through every cell of every 2D array.
It is easy to get the 2D arrays read in to an ArrayList but I want to be able to name the items and be able to read these back in to excel and it seems difficult to do with an ArrayList.
The question is: how do I read a 2D selection from excel into a 3D fixed sized array in VBA?
Here is an example of each approach: array of arrays or Dictionary of arrays. The Dictionary approach is considerably easier than the array of arrays if what you want is keyed lookup of values. There might be merits to the array of arrays in other cases.
This is dummy code with no real purpose but to show a couple things: grabbing a single value and an array of values. I am building a 2D array of values by grabbing some Range data which is easy and 2D. From there I build up the arrays of these values and then put them into the relevant data structure. Then I poke at the data structure to get some values out of it.
Array of Arrays approach is shown first (and outputs on the left of the picture).
Sub ArraysOfArrays()
Dim arrA() As Variant
Dim arrB() As Variant
'wire up a 2-D array
arrA = Range("B2:D4").Value
arrB = Range("F2:H4").Value
Dim arrCombo() As Variant
ReDim arrCombo(2, 1) As Variant
'name and give data
arrCombo(0, 0) = "arrA"
arrCombo(1, 0) = arrA
'add more elements
ReDim Preserve arrCombo(2, 2)
arrCombo(0, 1) = "arrB"
arrCombo(1, 1) = arrB
'output a single result
'cell(2,2) of arrA
Range("B6") = arrCombo(1, 0)(2, 2)
Dim str_search As String
str_search = "arrB"
'iterate through and output arrB to cells
Dim i As Integer
For i = LBound(arrCombo, 1) To UBound(arrCombo, 1)
If arrCombo(0, i) = str_search Then
Range("B8").Resize(3, 3).Value = arrCombo(1, i)
End If
Next i
End Sub
Couple key points here:
You can only expand the array using ReDim. ReDim is very particular that you only change the last dimension of the array when used with Preserve. Since I need one of them to track the number of entries, I do that in the second index which is... unnatural. If you know the size in advance, this painful step is skipped.
My final array is a 2xN array where the 2 contains a name and a YxZ array of data.
In order to find a given array in the mix, you have to iterate through them all.
Dictionary of Arrays is far less code and more elegant. Be sure to add the reference Tools->References in the VBA editor to Microsoft Scripting Runtime.
Sub DictionaryOfArrays()
Dim dict As New Scripting.Dictionary
'wire up a 2-D array
arrA = Range("B2:D4").Value
arrB = Range("F2:H4").Value
dict.Add "arrA", arrA
dict.Add "arrB", arrB
'get a single value
Range("F6") = dict("arrB")(2, 2)
'get a array of values
Range("F8").Resize(3, 3) = dict("arrA")
End Sub
Picture of input data and results
Data to copy if you want it (paste in B1)
a b
1 2 3 10 11 12
4 5 6 13 14 15
7 8 9 16 17 18
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
I want to know how to pass a single dimension of a four-dimensional array to an XY Scatter Chart using VBA.
[I know that I could do it by laboriously typing out separate arrays for everything, but I was hoping to make my code more compact. The compactness is particularly useful for populating the array, which I have not included below as I have that done already. I also know that if I were using 2D arrays, then I could use Application.Index, but my understanding is that that will not work for a three dimensional array or four dimensional array - if I'm wrong about that, then please let me know. I have looked at numerous queries on several websites, and I can only find answers about 2D arrays using Application.Index - if there is a page I've missed, then please let me know.]
I have an array variable that I have populated:
Dim arrData() As Single
arrData(1 To 2, 1 To 4, 1 To 3, 1 To 56)
arrData contains Single-type data for variables 1 to 56, within a 2x4x3 layout, so 1,344 data points.
I have a chart:
Dim bIOpt As Byte
Dim bPOpt As Byte
For bIOpt = 1 To 4
For bPOpt = 1 To 4
Worksheets("Data").Activate
Range(Cells(1, 1), Cells(2, 2)).Select
Charts.Add
With ActiveChart
.Type = xlXYScatter
.ChartTitle.Delete
With .SeriesCollection(1)
.XValues = ?
.Values = ?
End With
.SeriesCollection.NewSeries
With .SeriesCollection(2)
.XValues = ?
.Values = ?
End With
.SeriesCollection.NewSeries
With .SeriesCollection(3)
.XValues = ?
.Values = ?
End With
End With
Next bPOpt
Next bIOpt
I want each SeriesCollection to contain 56 points from arrData: the XValues will come from the bPOpt version of arrData(2, bPOpt, n, ); the (Y) Values will come from the bIOpt version of arrData(1, bIOpt, n, ).
I do not know how to write the ".XValues = ?" and ".Values = ?" lines so as to achieve my aim.
Thank you for your help.
Chris
You could use whatever looping algorithm you want to generate 1-D arrays for XValues and YValues, then pass these arrays to the chart series:
Dim XVals(1 to 56) As Double, YVals(1 to 56) As Double
' loop to populate XVals, YVals from arrData
' blah blah
' end of loop
With .SeriesCollection(1)
.Values = YVals
.XValues = XVals
End With
Note that there's no advantage in VBA to using Singles in place of Doubles, or Ints in place of Longs.
Note also that Excel's charts are much more reliable when working with data from worksheet cells than with arrays. If you experience problems, you might first dump XVals and YVals into a couple columns, then use this data range as the chart series data.
I am trying to write a couple lines of code in VBA for excel, here is what the VB.Net version of the code looks like.
ThisVariable <<= 8
Variable.Add(ThisVariable)
How do I write these lines of code in VBA? VBA does not have the "<<=" operator and does not have the .Add property of an array. Any help would be greatly appreciated.
For the first question, VBA doesn't have built in bit shifting, but you can add a function that does it for you. Try this one.
For the second question, to increase an array size, you have to use the ReDim command. Here's the info on that.
Also, you could use a collection instead of an array. With a collection, you can add & delete item within it at will.
Good luck
<<= left-shifts the number by 8 binary digits, i.e. multiplies the number by 256. For adding something to an array you can re-dim the array:
ThisVariable = ThisVariable * 256
Dim U As Long
Dim L As Long
L = LBound (Variable)
U = UBound (Variable)
ReDim Preserve Variable (L To U+1)
Variable (U+1) = ThisVariable
Note that redim'ing the array just to add an element is not very efficient. You should try to find another approach (e.g. use a larger array and store the number of "valid" elements in a counter variable -- or even create a class module for that).