VBA:如何创建一个新数组来显示另一个数组中每一列的计算平均值?
VBA: how to create a new array showing the calculated averages for each column in another array?
我是 VBA 和 Stack Overflow 的新手,对于任何笨拙之处深表歉意。
根据下面的代码,我生成了 Array1 的随机值,其大小由用户通过输入框指定。然后将 Array1 输出到工作表以进行测试。出于速度原因,我尽量减少与工作表的交互。
问题:如何计算 Array1 的每一列的平均值(这些平均值馈入待创建的 Array2,测量 1 行且宽度与 Array1 中的列数相同)?计算严格在内存中完成,而不是在工作表中完成。分别为每列取平均值。然后将这些 Array2 结果粘贴到工作表中 Array1 粘贴位置下方的第二个空行中? (您会看到 Array1 粘贴从单元格 A1 开始并从那里传播 down/right)。
我研究并尝试过,但没有成功。 运行 下面的代码(对我来说工作正常)的简单输入是 10 行,2 列,alpha = 1,beta = 1
Sub MC()
' Clear contents of active worksheet
Cells.Clear
' Moves cursor to starting point
Range("A1").Select
' Declarations of variables and arrays
Dim CellsDown As Long, CellsAcross As Long
Dim Alpha As Double, Beta As Double
Dim i As Long, j As Integer
Dim StartTime As Double
Dim Array1() As Double
Dim OutputSim As Range
' Set array dimensions and other inputs for running Monte Carlo
CellsDown = InputBox("How many rows?")
If CellsDown = 0 Then Exit Sub
CellsAcross = InputBox("How many columns?")
If CellsAcross = 0 Then Exit Sub
Alpha = InputBox("Distribution shape alpha value?")
If Alpha <= 0 Then Exit Sub
Beta = InputBox("Distribution shape beta value?")
If Beta <= 0 Then Exit Sub
' Record starting time
StartTime = Timer
' Redimension array
ReDim Array1(1 To CellsDown, 1 To CellsAcross)
' Set worksheet range
Set OutputSim = ActiveCell.Range(Cells(1, 1), Cells(CellsDown, CellsAcross))
' Fill array1 with random values generated from inverse of cumulative beta probability density function
Application.ScreenUpdating = False
For i = 1 To CellsDown
For j = 1 To CellsAcross
Randomize
Array1(i, j) = Application.Beta_Inv(Application.RandBetween(0.0000001, 100 - 0.0000001) / 100, Alpha, Beta, 0, 1)
Next j
Next i
' Transfer array1 to worksheet
OutputSim.Value = Array1
' Display elapsed time
Application.ScreenUpdating = True
MsgBox Format(Timer - StartTime, "00.00") & " seconds"
End Sub
请在 Array1
加载循环后插入下一段代码:
'Fill the average array:____________________________________________________________________
Dim arrAv, arrCol
ReDim arrAv(CellsAcross - 1) '1D array to keep the columns average
For i = 0 To UBound(Array1, 2) - 1 'iterate between the array columns
arrCol = Application.index(Array1, 0, i + 1) 'obtain a column slice from Array1
arrAv(i) = WorksheetFunction.Average(arrCol) 'fill the array element with the Average
Next i
'drop the array content at two columns to the right of OutputSim:
OutputSim.Offset(0, 2 + OutputSim.Columns.count).Resize(1, UBound(arrAv) + 1).Value = arrAv
'____________________________________________________________________________________________
我是 VBA 和 Stack Overflow 的新手,对于任何笨拙之处深表歉意。
根据下面的代码,我生成了 Array1 的随机值,其大小由用户通过输入框指定。然后将 Array1 输出到工作表以进行测试。出于速度原因,我尽量减少与工作表的交互。
问题:如何计算 Array1 的每一列的平均值(这些平均值馈入待创建的 Array2,测量 1 行且宽度与 Array1 中的列数相同)?计算严格在内存中完成,而不是在工作表中完成。分别为每列取平均值。然后将这些 Array2 结果粘贴到工作表中 Array1 粘贴位置下方的第二个空行中? (您会看到 Array1 粘贴从单元格 A1 开始并从那里传播 down/right)。
我研究并尝试过,但没有成功。 运行 下面的代码(对我来说工作正常)的简单输入是 10 行,2 列,alpha = 1,beta = 1
Sub MC()
' Clear contents of active worksheet
Cells.Clear
' Moves cursor to starting point
Range("A1").Select
' Declarations of variables and arrays
Dim CellsDown As Long, CellsAcross As Long
Dim Alpha As Double, Beta As Double
Dim i As Long, j As Integer
Dim StartTime As Double
Dim Array1() As Double
Dim OutputSim As Range
' Set array dimensions and other inputs for running Monte Carlo
CellsDown = InputBox("How many rows?")
If CellsDown = 0 Then Exit Sub
CellsAcross = InputBox("How many columns?")
If CellsAcross = 0 Then Exit Sub
Alpha = InputBox("Distribution shape alpha value?")
If Alpha <= 0 Then Exit Sub
Beta = InputBox("Distribution shape beta value?")
If Beta <= 0 Then Exit Sub
' Record starting time
StartTime = Timer
' Redimension array
ReDim Array1(1 To CellsDown, 1 To CellsAcross)
' Set worksheet range
Set OutputSim = ActiveCell.Range(Cells(1, 1), Cells(CellsDown, CellsAcross))
' Fill array1 with random values generated from inverse of cumulative beta probability density function
Application.ScreenUpdating = False
For i = 1 To CellsDown
For j = 1 To CellsAcross
Randomize
Array1(i, j) = Application.Beta_Inv(Application.RandBetween(0.0000001, 100 - 0.0000001) / 100, Alpha, Beta, 0, 1)
Next j
Next i
' Transfer array1 to worksheet
OutputSim.Value = Array1
' Display elapsed time
Application.ScreenUpdating = True
MsgBox Format(Timer - StartTime, "00.00") & " seconds"
End Sub
请在 Array1
加载循环后插入下一段代码:
'Fill the average array:____________________________________________________________________
Dim arrAv, arrCol
ReDim arrAv(CellsAcross - 1) '1D array to keep the columns average
For i = 0 To UBound(Array1, 2) - 1 'iterate between the array columns
arrCol = Application.index(Array1, 0, i + 1) 'obtain a column slice from Array1
arrAv(i) = WorksheetFunction.Average(arrCol) 'fill the array element with the Average
Next i
'drop the array content at two columns to the right of OutputSim:
OutputSim.Offset(0, 2 + OutputSim.Columns.count).Resize(1, UBound(arrAv) + 1).Value = arrAv
'____________________________________________________________________________________________