VBA:矩阵求和

7

为什么这个函数不起作用?

在Excel中键入=funtest(2.1),它会给我一个#VALUE!

Public Function funtest(a As Double) As Double

Dim z, j, i As Integer
Dim matrix(3, 3, 3) As Double

For z = 0 To 3 Step 1
For j = 0 To 3 Step 1
For i = 0 To 3 Step 1

matrix(z, j, i) = a

Next i, j, z

funtest = Application.WorksheetFunction.Sum(matrix)

End Function

1
我相信Sum函数是以范围为输入,而不是VBA双精度数组。 - RBarryYoung
你想通过这个函数实现什么目标? - brettdj
@brettdj 我创建的对象名为matrix,是一个三维数组,具有(3,3,3)的维度。我想要对这个矩阵中的每个元素进行求和。将函数命名为funtest(2.1)2.1无关,我只是想测试它是否适用于任何double类型。我的实际问题更加复杂,但我正在尝试解决每个元素都等于某个双精度浮点数a(3,3,3)矩阵的简单情况,然后再进一步处理。 - user1125946
7
我从没想到你可以把Next i、j和z都放在一行上!因此要加分+1。 - Doug Glancy
@Harokitty,您不需要第一步。仅当增量大于1或者您在递减时使用Step -1时才使用Step。 - Jeremy Thompson
3个回答

3

WorksheetFunction.Sum 可以用于范围或二维数组。由于您传递了一个三维数组,因此会出现错误。

因此,以下内容是有效的:

Public Function funtest(a As Double) As Double
    Dim z As Long, j As Long, i As Long
    Dim matrix() As Double

    ReDim matrix(0 To 3, 0 To 4)
    For j = LBound(matrix, 1) To UBound(matrix, 1)
    For i = LBound(matrix, 2) To UBound(matrix, 2)
        matrix(j, i) = a
    Next i, j

    funtest = Application.WorksheetFunction.Sum(matrix)
End Function

请注意,我稍微修改了您的声明,详见答案结尾的注释。

如果要对高维数组求和,您需要进行一些循环操作。

其中一种选项(可能适合您的整体要求)是稍微不同地声明您的数组,称为所谓的“锯齿形数组”。

Public Function funtest2(a As Double) As Double
    Dim z As Long, j As Long, i As Long
    Dim matrix() As Variant
    Dim InnerMatrix(0 To 4, 0 To 4) As Double

    ' Dimension Jagged Array
    ReDim matrix(0 To 4)
    For i = LBound(matrix, 1) To UBound(matrix, 1)
        matrix(i) = InnerMatrix
    Next

    'Load Data into matrix
    For z = LBound(matrix) To UBound(matrix)
    For j = LBound(matrix(z), 1) To UBound(matrix(z), 1)
    For i = LBound(matrix(z), 2) To UBound(matrix(z), 2)
        matrix(z)(j, i) = a
    Next i, j, z

    ' Sum matrix
    For z = LBound(matrix) To UBound(matrix)
        funtest2 = funtest2 + Application.WorksheetFunction.Sum(matrix(z))
    Next
End Function

这是一个二维数组的数组。接着对每个内部数组分别应用Sum函数。这样,你至少只需要循环一维而不是所有三维。

DimInteger 的注意事项
必须指定所有的As Type,否则变量默认为Variant
在你的代码中,zj会成为Variants

此外,在32位操作系统上使用Integer而不是Long实际上是适得其反的:Long会稍微更快。


而“变量”会更慢。在VBA中,可以通过在模块开头添加“Option Explicit”来打开静态类型,这并不会有任何损失。 - airstrike

0

当你说“我正在尝试解决一个简单的情况,即一个(3,3,3)矩阵,每个元素都等于某个双精度浮点数a”时,我会字面理解你的意思。下面的代码可以实现这个目标:

Public Function funtest(a As Double) As Double
   funtest = 4*4*4*a
End Function

-1

首先,当你看到#VALUE!时,这意味着出现了错误,可能是因为使用了无效的矩阵。

回答你的问题,你的代码不起作用是因为语法不正确。下面的函数可以从数值创建一个矩阵。

Function FQ_matrix_create(StartValue As Double, Interval As Double,
nrow As Long, ncol As Long) As Double()
Dim M() As Double
' Creates matrix with sequential element values with given row and
' column sizes. Fills matrix row-wise with numbers.
' - set Interval = 0 for constant element values
' - error input arguments nrow and ncol are not positive integers

要对值进行求和,请使用以下代码:

Function FQ_matrix_element_sum(M() As Double, SumOption As
MatrixDirection) As Double()
' Returns the sum of elements of matrix M, either row or column wise
' - Rowwise sum returns a horizontal 1xNcol matrix
' - Columnwise sum returns a vertical 1 xNrow matrix
' - Element sum (all elements) returns a 1x1 matrix
' - error if M is not a matrix
' - error if SumOption is not 1 (nRowWiseSum) or 2 (nColWiseSum) or
3 (nElementSum)

为了帮助您理解Excel VBA中的矩阵,这里有一个很好的资源:http://finaquant.com/download/matrixvectorvba
具体来说,请查看该网站上的PDF下载。

那么矩阵没有本地功能吗?它们与我尝试创建的多维数组有什么不同? - user1125946
矩阵函数语法应为 [{1,2,3; 4,5,6}],而非 (1,2,3)。 - Todd Moses
1
我不明白声明一个二维常量数组与所问的问题有什么关系。 - Charles Williams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接