如何定义 DIAG 函数?
Posted
技术标签:
【中文标题】如何定义 DIAG 函数?【英文标题】:How to define a DIAG function? 【发布时间】:2022-01-23 12:52:28 【问题描述】:我想定义一个 VBA 函数:
-
返回矩阵主对角线元素的列向量;
返回一个正方形对角矩阵,其中向量的元素在主对角线上;
自动返回矩阵/向量,无需按Ctrl Shift Enter;
我正在处理这段代码:
Public Function DIAG(matrix As Variant) As Variant
Dim i As Long
Dim j As Long
Dim nRows As Long
Dim nCols As Long
Dim tempArray As Variant
nRows = matrix.Rows.Count
nCols = matrix.Columns.Count
For i = 1 To nRows
For j = 1 To nCols
If i = j Then
tempArray(i) = matrix(i, j)
End If
Next j
Next i
DIAG = tempArray
End Function
这仅用于该功能的第一个目的,但它不起作用。我明白了:
#VALUE
【问题讨论】:
哪行代码给出了这个错误?为什么使用Variant
而不是Range
? ...?
@Dominique 我在输入公式的单元格中得到#VALUE
,代码没有错误
你的意思是nRows = matrix.Count
和nRows = matrix.Rows.Count
一样吗?
该错误意味着函数在以 UDF 形式调用时出现错误
【参考方案1】:
我认为您的应用程序结构有问题:您确定您的函数所在的模块可以从您的 Excel 工作簿中访问吗?
作为一个例子,我做了一个类似的函数,我在我的 Excel 工作簿中使用了它(在一个单元格中,我输入了公式 =DIAG(J5:Q25)
)并且一切正常,特此截图:
糟糕,我刚刚尝试了其他方法,但出现了相同的错误消息:
Public Function DIAG(matrix As Variant) As Variant
Dim tempArray As Variant
tempArray(1) = 1
tempArray(2) = 2
DIAG = tempArray
End Function
您确定可以将整个矩阵甚至一维数组作为函数的返回值返回,并这么容易地调用它吗?
为了您的信息,我尝试了这个,在一个单元格中使用=DIAG(J5:Q25)
,在两个单元格中,并作为一个数组公式。
【讨论】:
刚刚检查了一下,看起来一切正常,就像你的截图一样 我相信返回一个数组是问题所在:我相应地编辑了我的答案。 恐怕已经构建的函数无法返回任何数组,这就是错误的原因,如果调用为 UDF。如果从测试Sub
中调用,它将返回更多 elocvent 错误。如果没有声明维度,或者是ReDim
,tempArray
就不能这样加载...如果加载了,可以返回数组!
@FaneDuru:所以你对作者的声明是“如果你创建一个用户定义的函数,称为UDF,那么首先通过在宏中调用它来测试它,并且只有当这个工作正常,您可以直接从 Excel 中使用它。"。感谢您的建议!
您可以以这种方式“翻译”该声明,我同意... :) 最好将 translation
放在我的答案末尾,改进它,我思考。感谢您的建议!【参考方案2】:
当调用 UDF 时,您的函数会返回这样的错误,如果我正确理解了您想要什么,请使用下一个改编函数:
Public Function DIAG(matrix As Range) As Variant
Dim i As Long, j As Long, k As Long, nRows As Long, nCols As Long
Dim tempArray As Variant
nRows = matrix.Count: nCols = matrix.Columns.Count
ReDim tempArray(nRows * nCols) 'without this step it will return an error when try loading
For i = 1 To nRows
For j = 1 To nCols
If i = j Then
tempArray(k) = matrix(i, j): k = k + 1
End If
Next j
Next i
ReDim Preserve tempArray(k - 1) 'preserving only the elements keeping data
DIAG = tempArray
End Function
中间数组应该是 ReDim,然后只保留保存数据的元素...
结束语句(@Dominique 建议):如果您创建了一个用户定义的函数,称为 UDF,则首先通过在宏中调用它来测试它,并且仅当它返回您的需要,没有任何错误,您可以直接从单元格中调用它。
【讨论】:
【参考方案3】:@FaneDuru 的代码确实帮助了我,但我成功地以这种方式编写了我的 UDF:
Public Function DIAG(matrix As Range) As Variant
Dim i As Long, j As Long, nRows As Long, nCols As Long
Dim tempArray As Variant
nRows = matrix.Rows.Count
nCols = matrix.Columns.Count
If nCols = 1 Then
ReDim tempArray(nRows - 1, nRows - 1)
For i = 1 To nRows
tempArray(i - 1, i - 1) = matrix(i)
Next i
Else
If nCols = nRows Then
ReDim tempArray(nRows - 1, 0)
For i = 1 To nRows
For j = 1 To nCols
If i = j Then
tempArray(i - 1, 0) = matrix(i, j)
End If
Next j
Next i
Else
tempArray = CVErr(xlErrValue)
End If
End If
DIAG = tempArray
End Function
【讨论】:
以上是关于如何定义 DIAG 函数?的主要内容,如果未能解决你的问题,请参考以下文章