perform operations on columns or row of VBA array - arrays

In VBA is it possible to loop through, for example, every column of a 2 dimensional array and perform and operation on each column? I would like to pass each column or row of an array sequentially to a function.
Thanks.

Normally I'd not answer this because you haven't shown any effort in trying.. But I've had my own difficulty with this (with my own question currently posted looking for a better solution) and I'm bored so:
if you have a 2D array named myArr like this:
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
defined by: dim myArr(2,4) as variant
then you could loop through it with a double loop like this:
For i = LBound(myArr) To UBound(myArr)
For j = LBound(myArr, 2) To UBound(myArr, 2)
temp(j) = myArr(i, j)
Next
Next
where temp is defined and reDim'd like this:
dim temp() as variant
redim temp(lbound(myArr,2), ubound(myArr,2)) 'note the ",2" gets the bounds of the 2nd dimention
and then pass temp to a function: FunctionName(Temp)
So put that together by sticking thue function call after the inner loop and it would loop through and pass temp to the function for each row

Related

VB.net How to access row in 2 dimensional array?

I want to read all elements of the first row from a 2-D array in VB.NET. Is there a simple way to do it rather than running a loop. I know that in MATLAB there is possibilty to say: A(1,:) and its done.
Thank you.
There is nothing built into the array itself to read without a loop but you could use a LINQ query, e.g.
Dim firstRow = Enumerable.Range(0, myArray.GetUpperBound(1) + 1).
Select(Function(i) myArray(0, i))
Note that what is a "row" and what is a "column" is not defined for a 2D array so it's really up to you whether you want to use that or this:
Dim firstRow = Enumerable.Range(0, myArray.GetUpperBound(0) + 1).
Select(Function(i) myArray(i, 0))
That gives you an enumerable list of the specified elements so the question is, what do you want to do with it? You haven't actually specified. As it is, all you can really do is enumerate it, which means running a For Each loop over it. That kinda defeats the purpose of avoiding a loop in the first place. If you're saying, without actually saying, that you want those elements in a 1D array then you can call ToArray:
Dim firstRow = Enumerable.Range(0, myArray.GetUpperBound(1) + 1).
Select(Function(i) myArray(0, i)).
ToArray()
EDIT:
Here is an extension method that you could use to do the job:
Imports System.Runtime.CompilerServices
Public Module ArrayExtensions
<Extension>
Public Function GetRow(Of T)(source As T(,), rowIndex As Integer) As T()
Return Enumerable.Range(0, source.GetUpperBound(1) + 1).
Select(Function(i) source(rowIndex, i)).
ToArray()
End Function
End Module
It then makes the calling code much cleaner, especially if you need to do it multiple times, e.g.
Dim firstRow = myArray.GetRow(0)
If you don't know size of your array u can use nested loop For Each like this:
For each row in array
For each col in row
''something here like Debug.Write(col.ToString)
Next
Next
If you know your size and you want specific item in the array you simply do that like in any other loop "for" like this:
For index As Integer = 5 To 5
For index2 As Integer = 3 To 3
Debug.Write(index2.ToString)
Next
Next

How to reference an array and write to another array with more than one column per iteration

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.

Excel VBA: Replace first row by an array

I have a first row with 100 cells and I created an Array of Strings, which represent the new row content.
I would like to replace the content of all the first row with the content of my Array in VBA, how can I do that?
Say your array is called myArray, it's enough to do this:
For j = LBound(myArray) To UBound(myArray)
Sheets("your sheet").Cells(1,j+1).Value = myArray(j)
Next j
The functions LBound() and UBound() are respectively returning the first and the last index of your array.
Please note that when writing Cells(1,j+1) I'm assuming two important things:
1) Your start index starts with 0, so I want to start the insertion of the values from the column 1 (j+1 = 0+1 = 1).
2) You want to override the first row (because the row index is equal to 1).
You might want to customize this, for example creating independent indexes - when I say "independent", I mean "not depending on the lower and the upper bound of your array, nor being hard-coded like I did for the "row 1".
You can read and write between a Range and an Array in one line. It is more efficient than using a loop.
Note: The array must be 2 Dimensional to write to a range.
Public Sub ReadToArray()
' Create dynamic array
Dim StudentMarks() As Variant
' Read values into array from 100 cells in row 1
StudentMarks = Sheets("Sheet1").Range("A1:CV1").Value
' Do something with array
' Write the values back to sheet
Sheets("Sheet1").Range("A1:CV1").Value = StudentMarks
End Sub

passing arrays or ranges to VBA udf

I am trying to pass an array to a UDF to avoid massive duplication of code. As a simple example:
function USERFUNC1(inp as variant)
Dim array_size As Integer
dim i as integer
dim values as double
array_size = WorksheetFunction.CountA(inp)
for i = 1 to array_size
values = values + inp(i)
Next i
USERFUNC1 = values
End function
function USERFUNC2(input1 as variant, input2 as variant)
Dim array_size As Integer
dim i as integer
dim values as double
array_size = WorksheetFunction.CountA(input1)
redim nested_array(array_size)
for i = 1 to array_size
nested_array(i) = input1(i)+input2(i)
Next i
USERFUNC2= USERFUNC1(nested_array)
End function
In the example I have create I have the nested array that I am passing internally to the UDF. However when run this results in a by ref error. I am sure that this can be done but I appear to be missing something
EDIT
It seems what I wrote caused confusion, essentially I have a number of functions, the above is just to demonstrate the idea.
On some of the cells I am calculating a value using a function (call it fugacity) that picks up values into an array a range from the worksheet. In another function (phase equilibrium) I need to perform the same calculation (fugacity) within the second function (phase equilibrium) using values calculated within the second function. This requires me to pass the array from the second function into the first or write out the entire first function again within the second.
I could do that however it make the 2nd function much more difficult to debug as I can no longer be certain that the nested calculation is performing the right calculation, rather I need to check the whole thing. So far I have about 250 lines of code in the first and 300 line the second and within the second (phase equilibrium) I need to perform the first (fugacity) 4 times.
If you want USERFUNC1 to return an array of the values in the inp range, then merely:
function USERFUNC1(inp as Range) as Variant
USERFUNC1 = inp
End function
This will be a 1-based two dimensional array where the first dimension represents the rows, and the second dimension the columns in the original range inp.
I'm not sure what your end goal is, but you may not even need USERFUNC1

Any Shortcut method to reinitialize Arrays in vb.net

I have a dynamic array ,where the array size changes according to the no.of rows in database
code goes like this :
Dim pgm_act_arr(0) As Double
Dim pgm_act_count As Integer = no.of rows retuned from database
ReDim pgm_act_arr(pgm_act_count)
for each rows in database1
'i want to reinitialize the array here
'now am using for loop to reinitialize array to zero
For i As double to pgm_act_arr.Length
pgm_act_arr(i) = 0.0
Next
for each rows in database2
pgm_act_arr(index)+=somevalue 'inserting values to array elements
next
next
Is there any single line code or any short hand operations to reinitialise the array
Not entirely sure i have understood the Q but....
Not sure if it is the right way but i always redim as i go so code would look like this:
Dim pgm_act_arr(0) As Double
for each rows in database2
pgm_act_arr(index)+=somevalue 'inserting values to array elements
ReDim preserve pgm_act_arr(ubound(pgm_act_arr)+1)
next
'remove blank entry at bottom
ReDim preserve pgm_act_arr(ubound(pgm_act_arr)-1)
To reset the array to as it started
ReDim pgm_act_arr(0)
So consider array size as 3
i.e.
pgm_act_arr(0)=1
pgm_act_arr(1)=2
pgm_act_arr(2)=3
so what i want to do is
pgm_act_arr(0)=0
pgm_act_arr(1)=0
pgm_act_arr(2)=0
But as far as i know this is the simplest way
for i=0 to 2
pgm_act_arr(i)=0.0
next

Resources