在我的wooksheet中我有单元格:A1 = 1和A2 = 2
此公式当然适用于工作表的单元格:
=SUM(A1:A2) [correctly giving *3*]
但是我确实有这样的值:A1:1½和A2 =2½ 但是此数组(CSE)公式不起作用:
{=SUM(myUserDefinedFkt(A1:A2))} [giving *#VALUE*, should have been *4*]
其中myUserDefinedFkt可以像(仅示例)一样简单:
public function myUserDefinedFkt(value) as double
if instr(1, value, "½" , 1)>0 then value = replace(value, "½", ".5")
myUserDefinedFkt = value
end function
我认为使用数组公式是正确的,但是如何?
EDIT。我改变了我的功能,两个单元格值更加精确!
答案 0 :(得分:0)
使用以下用户定义函数= UDFSumstring(A1:B10)
不需要数组公式输入
这个UDF
Function UDFSumstring(ByVal cell_range As Range) As Double
> Dim i As Long, j As Long, total As Double
> Dim varray As Variant, sv As Double
> varray = cell_range.Value>
> For i = 1 To UBound(varray, 1)
> For j = 1 To UBound(varray, 2)
> If InStr(1, varray(i, j), "½") > 0 Then
> sv = Val(WorksheetFunction.Substitute(varray(i, j), "½", ".5"))
> Else
> sv = Val(varray(i, j))
> End If
> total = total + sv
> Next
> Next
>
> UDFSumstring = total
>
> End Function
答案 1 :(得分:0)
您可以这样做,以便在公式中调用函数两次(或每次需要多次)。
让你的函数返回一个值:
Public Function myUserDefinedFkt(value) As Double
If InStr(1, value, "1/2") > 0 Then
myUserDefinedFkt = CDbl(Left(value, Len(value) - 4) & ".5")
Else
myUserDefinedFkt = CDbl(value)
End If
End Function
然后在工作表中写下这样的公式:
=myuserdefinedfkt(A1)+myuserdefinedfkt(B1)
答案 2 :(得分:0)
UDF
是否可以返回数组,因此可以用作数组公式取决于UDF
。即使Excels
本机函数 所有也可用于数组上下文。
所以首先我们必须有一个可以返回数组的UDF
。在User defined function in VBA not "array-firendly"中,我为arrayFriendlyUDF
的原型提供了一种方法。
使用这个我们也可以解决这个问题的问题:
UDF:
Public Function arrayFriendlyUDF(vParam As Variant) As Variant
'function which can get variant parameter vParam
'either a single value or a range or an array literal
'will return a single value or an array of results
'it will only accept double values or strings as single value, in range or in array literal
Dim adParam As Variant, dParam As Double, aParam() As Variant
Dim aResult() As Double
Dim i As Integer
adParam = vParam
'if vParam is a single value, then adParam also is a single value
'if vParam is a range, then adParam is a variant array from this range's values
'if vParam is a array literal, then adParam is a variant array from this array literal
If TypeName(adParam) = "Variant()" Then 'we have a variant array
'it could be one dimensional (row vector) or two dimensional (column vector)
'we will only process one dimensional array, so we must transform if needed
i = 0
For Each vParam In adParam
ReDim Preserve aParam(i)
aParam(i) = vParam
i = i + 1
Next
ElseIf TypeName(adParam) = "Double" Or TypeName(adParam) = "String" Then 'we have a single value, either a double or a string
ReDim aParam(0)
aParam(0) = adParam
End If
'now we have an array (one dimensional) in any case
For i = LBound(aParam) To UBound(aParam)
ReDim Preserve aResult(i)
aResult(i) = Val(Replace(aParam(i), "½", ".5")) 'this is the function's main operation.
Next
If UBound(aResult) = 0 Then
'if only one result
arrayFriendlyUDF = aResult(0)
Else
'return the array of results
arrayFriendlyUDF = aResult
End If
End Function
表:
我的语言环境是德语。所以十进制分隔符是逗号。
公式:
<{1}}中的:B1:B9
:=arrayFriendlyUDF(A1)
:D2:L2
:=arrayFriendlyUDF(D2)
在这种情况下,数组上下文不是必需的。但该公式也可用于数组上下文中。
答案 3 :(得分:0)
有点晚了,但有些方法可以在没有循环的情况下返回数组:
Public Function f(v)
v = Application.Transpose(v) ' 2D to 1D because Join needs 1D array
v = Join(v, ";") ' "1½;2½"
v = Replace(v, "½", ".5") ' "1.5;2.5"
f = Evaluate("{" & v & "}") ' {1.5;2.5}
End Function
如果它还需要适用于行或单个单元格,那就有点复杂了:
Public Function f(v)
Let v = v ' Range to 2D Array or value
If IsArray(v) Then
If UBound(v, 1) = 1 Then
v = Application.Index(v, 1, 0) ' 2D row array to 1D
v = "{" & Join(v, ",") & "}" ' Join needs 1D array
Else
v = Application.Transpose(v) ' 2D column array to 1D
v = "{" & Join(v, ";") & "}" ' ; is row separator
End If
End If
v = Replace(v, "½", ".5") ' "{1.5;2.5}"
f = Evaluate(v) ' {1.5;2.5}
End Function
但最好和最快的选择很可能是For循环:
Public Function f(v)
Let v = v ' Range to 2D Array or value
If Not IsArray(v) Then f = Val(Replace(v, "½", ".5")): Exit Function
Dim r As Long, c As Long
For r = 1 To UBound(v, 1)
For c = 1 To UBound(v, 2)
v(r, c) = Val(Replace(v(r, c), "½", ".5"))
Next c
Next r
f = v
End Function
在Excel 2016中,TEXTJOIN
函数可用于将任何范围展平为数组(未测试):
Public Function f(r As Range)
f = r.Worksheet.Evaluate("TEXTJOIN(("","",1," & r.Address & ")") ' "1½,2½"
f = Replace(f, "½", ".5") ' "1.5,2.5"
f = Evaluate("{" & f & "}") ' {1.5,2.5}
End Function