Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel自定义项将被评估子项的值加倍_Excel_User Defined Functions_Vba - Fatal编程技术网

Excel自定义项将被评估子项的值加倍

Excel自定义项将被评估子项的值加倍,excel,user-defined-functions,vba,Excel,User Defined Functions,Vba,1。我试图回答,但在计算我的UDF时得到了一个不愉快的结果 Public Function mytest(src, dest) dest.Parent.Evaluate "test(" & src.Address(False, False) & ", " & dest.Address(False, False) & ")" mytest = "wut" End Function Sub test(src As Range, dest As Ran

1。我试图回答,但在计算我的UDF时得到了一个不愉快的结果

Public Function mytest(src, dest)
    dest.Parent.Evaluate "test(" & src.Address(False, False) & ", " & dest.Address(False, False) & ")"
    mytest = "wut"
End Function

Sub test(src As Range, dest As Range)
    Dim chr, rows, cols
    rows = 0
    cols = 0
    For chr = 1 To Len(src.Value)
        Select Case Mid(src.Value, chr, 1)
            Case ","
            rows = rows + 1
            Case ";"
            cols = cols + 1
            rows = 0
            Case Else
            Cells(dest.Row + rows, dest.Column + cols).Value = Cells(dest.Row + rows, dest.Column + cols).Value & Mid(src.Value, chr, 1) '
        End Select
    Next chr
End Sub
预期结果: 公式结果: 有人能解释为什么它使单元格的值加倍吗?
当我调试测试时使用

Sub ffs()
    Call test(Cells(1, 1), Cells(3, 1))
End Sub
我得到了预期的结果,所以我猜问题不在测试中

2.每当我尝试向函数添加更多参数时,Sub(例如分隔符)函数根本不计算Sub

Public Function CellToRange(src, dest, DelimL, DelimC)
    dest.Parent.Evaluate "test(" & src.Address(False, False) & ", " & dest.Address(False, False) & ", " & DelimL & ", " & DelimC & ")"
    CellToRange = "wut"
End Function

Sub CTR(src As Range, dest As Range, Delim1, Delim2)
    Dim chr, rows, cols
    rows = 0
    cols = 0
    For chr = 1 To Len(src.Value)
        Select Case Mid(src.Value, chr, 1)
            Case Delim1
            rows = rows + 1
            Case Delim2
            cols = cols + 1
            rows = 0
            Case Else
            Cells(dest.Row + rows, dest.Column + cols).Value = Cells(dest.Row + rows, dest.Column + cols).Value & Mid(src.Value, chr, 1) '
        End Select
    Next chr
End Sub
请帮忙。并提前表示感谢。
解决方案:
谢谢比利和查尔斯·威廉姆斯。
改变

谢谢大家

1)当公式被触发时,它计算一次,当函数更新单元格A3时,它再次计算一次(因为它是公式所依赖的单元格之一)

2a)调用了错误的子例程(
test
,而不是
CTR

2b)您需要使用以下方法调用第二个函数

=CellToRange(A1;A3;""",""";""";""")
或者将代码中调用CTR的行更改为

dest.Parent.Evaluate "CTR(" & src.Address(False, False) & ", " & dest.Address(False, False) & ", """ & DelimL & """, """ & DelimC & """)"
3) 我强烈建议您不要使用这种方法获取UDF来更新包含函数的单元格以外的单元格。

1)当触发公式时,它会计算一次,当函数更新单元格A3时,它会计算一次(因为它是公式所依赖的单元格之一)

2a)调用了错误的子例程(
test
,而不是
CTR

2b)您需要使用以下方法调用第二个函数

=CellToRange(A1;A3;""",""";""";""")
或者将代码中调用CTR的行更改为

dest.Parent.Evaluate "CTR(" & src.Address(False, False) & ", " & dest.Address(False, False) & ", """ & DelimL & """, """ & DelimC & """)"

3) 我强烈建议您不要使用这种方法获取UDF来更新包含函数的单元格以外的单元格。

问题在于
工作表。请评估
方法,该方法用于绕过不允许UDF修改工作表结构的限制

考虑一下这个代码

Option Explicit

Public Function dummyudf() As String
    Debug.Print "Calling Evaluate method"
    ActiveSheet.Evaluate "testsub()"
    Debug.Print "Returning From Evaluate method"
    dummyudf = "done"
End Function

Sub testsub()
    Debug.Print "testsub running"
End Sub

Sub testmacro()
    Dim s As String
    Debug.Print "testmacro running"
    s = dummyudf
End Sub
UDF
dummyudf()
使用
Evaluate
方法
调用
testsub()
Sub
。这些是对第一部分中的
mytest
test
的分析。第2部分中的OP和to
CellToRange
CTR
,但被剥离至最低限度

testsub()
也可以作为宏直接调用。第二个宏
testmacro
作为VBA中的函数调用
dummyudf

从即时窗口获得以下输出:

可以看出

  • 作为宏调用时:
    testsub()
    的行为符合预期

  • dummyudf()
    作为工作表上的自定义项调用时(例如,通过将公式
    =dummyudf()
    添加到单元格
    A1
    中,
    Evaluate
    方法将调用
    testsub()
    两次

  • 当通过以宏的形式运行
    testmacro()
    调用VBA中的函数
    dummyudf()
    时,
    Evaluate
    方法将调用
    testsub()
    两次

文档建议
工作表.Evaluate
方法的Name参数应该是一个对象的名称,因此可能会提供
Sub
的名称,这有点令人惊讶。它似乎也会调用任何这样的
Sub
两次,这更令人惊讶,但确实强调了YowE3K的建议回答关于在UDF中不使用此黑客的问题。我会更进一步:不要使用
工作表。使用任何
评估

问题在于
工作表。评估
方法用于绕过不允许UDF修改工作表结构的限制

考虑一下这个代码

Option Explicit

Public Function dummyudf() As String
    Debug.Print "Calling Evaluate method"
    ActiveSheet.Evaluate "testsub()"
    Debug.Print "Returning From Evaluate method"
    dummyudf = "done"
End Function

Sub testsub()
    Debug.Print "testsub running"
End Sub

Sub testmacro()
    Dim s As String
    Debug.Print "testmacro running"
    s = dummyudf
End Sub
UDF
dummyudf()
使用
Evaluate
方法调用
Sub
被称为
testsub()
。这与OP的第1部分中的
mytest
test
以及第2部分中的
celltrange
CTR
非常相似,但都被精简到了最低限度

testsub()
也可以作为宏直接调用。第二个宏
testmacro
作为VBA中的函数调用
dummyudf

从即时窗口获得以下输出:

可以看出

  • 作为宏调用时:
    testsub()
    的行为符合预期

  • dummyudf()
    作为工作表上的自定义项调用时(例如,通过将公式
    =dummyudf()
    添加到单元格
    A1
    中,
    Evaluate
    方法将调用
    testsub()
    两次

  • 当通过以宏的形式运行
    testmacro()
    调用VBA中的函数
    dummyudf()
    时,
    Evaluate
    方法将调用
    testsub()
    两次
文档建议
工作表.Evaluate
方法的Name参数应该是一个对象的名称,因此可能会提供
Sub
的名称,这有点令人惊讶。它似乎也会调用任何这样的
Sub
两次,这更令人惊讶,但确实强调了YowE3K的建议回答关于在UDF中不使用此黑客的问题。我会更进一步:不要使用
工作表。使用任何
子项评估

@YowE3k 1)该函数不应该被调用两次以计算两次吗?当我在函数的开头切换断点并在工作表上进行计算时,我看到它只运行了一次。对不起,如果我理解不正确。2a)Ops!^2b)做了吗3)我只是为了改进@YowE3K 2a)Hm,它没有解决2b)更改了行,现在它将src
cell
复制到dest
cell
(hmmm)同样,当我计算celltorrange时,它的计算值也没有我的两倍test@AntiDrondert是的,看来我弄错了。