Excel UDF 将评估的 SUB 的值加倍
Excel UDF doubles value of the evaluated SUB
1. 我试图回答 VBA UDF to split string array,但在计算我的 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
预期结果:
公式结果:
有人可以解释为什么它会使单元格的值加倍吗?
当我使用
调试 test 时
Sub ffs()
Call test(Cells(1, 1), Cells(3, 1))
End Sub
我得到了预期的结果,所以我想问题不在 test Sub?..
2. 每当我尝试向 Function 和 Sub 添加更多参数(例如定界符)时,Function 根本不计算 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
请帮助._。并提前致谢。
解决方案:
谢谢比利和查尔斯威廉姆斯。
变化
dest.Parent.Evaluate "CTR(" & src.Address(False, False) & ", " & dest.Address(False, False) & ", " & DelimL & ", " & DelimC & ")"
到
dest.Parent.Evaluate "0+CTR(" & src.Address(False, False) & ", " & dest.Address(False, False) & ", " & DelimL & ", " & DelimC & ")"
谢谢大家!
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) 我强烈建议您不要使用这种 hack 来获取 UDF 来更新包含该函数的单元格以外的单元格。
问题在于 Worksheet.Evaluate
方法,该方法用于绕过不允许 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
方法 invoke
Sub
调用 testsub()
。这些与 OP 第 1 部分中的 mytest
和 test
以及第 2 部分中的 CellToRange
和 CTR
类似,但被剥离到最低限度。
testsub()
也可以作为宏直接调用。第二个宏 testmacro
调用 dummyudf
作为 VBA.
中的函数
从立即 Window 获得以下输出:
可以看出
当作为宏调用时:testsub()
表现如预期
当 dummyudf()
在工作表上作为 UDF 调用时(例如,通过将公式 =dummyudf()
添加到单元格 A1
Evaluate
方法似乎调用 testsub()
两次
- 当
dummyudf()
作为函数在 VBA 中被 运行 调用时 testmacro()
作为宏调用 Evaluate
方法似乎调用 testsub()
两次
文档here建议Name方法的Worksheet.Evaluate
参数应该是一个对象的名称,所以有点奇怪可以提供 Sub
的名称。它似乎还调用了任何此类 Sub
两次,这更令人惊讶,但确实强调了 YowE3K 的回答中关于不在 UDF 中使用此 hack 的建议。我会更进一步:不要将 Worksheet.Evaluate
与任何 Sub
一起使用。
1. 我试图回答 VBA UDF to split string array,但在计算我的 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
我得到了预期的结果,所以我想问题不在 test Sub?..
2. 每当我尝试向 Function 和 Sub 添加更多参数(例如定界符)时,Function 根本不计算 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
请帮助._。并提前致谢。
解决方案:
谢谢比利和查尔斯威廉姆斯。
变化
dest.Parent.Evaluate "CTR(" & src.Address(False, False) & ", " & dest.Address(False, False) & ", " & DelimL & ", " & DelimC & ")"
到
dest.Parent.Evaluate "0+CTR(" & src.Address(False, False) & ", " & dest.Address(False, False) & ", " & DelimL & ", " & DelimC & ")"
谢谢大家!
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) 我强烈建议您不要使用这种 hack 来获取 UDF 来更新包含该函数的单元格以外的单元格。
问题在于 Worksheet.Evaluate
方法,该方法用于绕过不允许 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
方法 invoke
Sub
调用 testsub()
。这些与 OP 第 1 部分中的 mytest
和 test
以及第 2 部分中的 CellToRange
和 CTR
类似,但被剥离到最低限度。
testsub()
也可以作为宏直接调用。第二个宏 testmacro
调用 dummyudf
作为 VBA.
从立即 Window 获得以下输出:
可以看出
当作为宏调用时:
testsub()
表现如预期当
dummyudf()
在工作表上作为 UDF 调用时(例如,通过将公式=dummyudf()
添加到单元格A1
Evaluate
方法似乎调用testsub()
两次- 当
dummyudf()
作为函数在 VBA 中被 运行 调用时testmacro()
作为宏调用Evaluate
方法似乎调用testsub()
两次
文档here建议Name方法的Worksheet.Evaluate
参数应该是一个对象的名称,所以有点奇怪可以提供 Sub
的名称。它似乎还调用了任何此类 Sub
两次,这更令人惊讶,但确实强调了 YowE3K 的回答中关于不在 UDF 中使用此 hack 的建议。我会更进一步:不要将 Worksheet.Evaluate
与任何 Sub
一起使用。