Excel VBA函数可以';t集范围

Excel VBA函数可以';t集范围,excel,vba,range,Excel,Vba,Range,我编写了一个VBA函数,它接受两个参数,第一个是字符串,第二个是范围,在工作表中指定为: =strPack(B1,G3) 在代码中,此例程声明为: Public Function strPack(ByVal strHex As String, ByRef rngCnt As Range) As String On Error Goto ErrHandler If False Then ErrHandler: MsgBox Err.Description

我编写了一个VBA函数,它接受两个参数,第一个是字符串,第二个是范围,在工作表中指定为:

=strPack(B1,G3)
在代码中,此例程声明为:

Public Function strPack(ByVal strHex As String, ByRef rngCnt As Range) As String
    On Error Goto ErrHandler
    If False Then
ErrHandler:
        MsgBox Err.Description
        Exit Function
    End If
    Dim intCnt As Integer
    intCnt = 0
    '...do something with strHex and increment intCnt whilst we go
    rngCnt.Value = CStr(intCnt)
    'strPack is populated by the body of the function
    strPack = "Hello World"
End Function
我尝试了.Value、.Value2和.Text,所有这些都会导致错误:

Application-defined or object-defined error
当我查看调试器时,strHex和rngCnt都是有效和正确的。为什么我不能分配给该范围以及如何修复它

错误处理程序不是问题所在,请尝试一下,它工作得非常好,是在发生错误时提取错误并中止函数的标准方法

[编辑]我刚刚尝试了以下方法:

Public Sub updateCount()
    Worksheets("Sheet1").Range("G3").Value = CStr(intProcessed)
End Sub
intProcessed是模块的全局值,是一个整数,结果相同,错误完全相同

[Edit2]我想删除这篇文章,因为我现在改变了调用另一个子程序的方法,该子程序返回一个被放入单元格的值。我不能删除它!谢谢大家的帮助。

请参阅代码注释:

Public Function strPack(ByVal strHex As String, ByVal rngCnt As Range) As String

   Dim lRes     As Long

   On Error GoTo errHandler

     lRes = 1000 '==> Your business logic goes here

     '/ This is the gymnastics you do to update range from an UDF
     Application.Evaluate ("UpdateRange(" & rngCnt.Address & "," & lRes & ")")
     strPack = "SUCCESSFULL"

errHandler:
   If Err.Number <> 0 Then
    strPack = "FAILED"
   End If

End Function

'/ Helper to allow range update from UDF
Private Function UpdateRange(rngDest As Range, val As Variant)
    rngDest.Value = val
End Function
公共函数strPack(ByVal strHex作为字符串,ByVal rngCnt作为范围)作为字符串
暗淡的lRes和长的一样
关于错误转到错误处理程序
lRes=1000'=>您的业务逻辑在这里
“/这是您从UDF更新范围所做的练习
Application.Evaluate(“UpdateRange”(&rngCnt.Address&“,&lRes&”))
strPack=“成功”
错误处理程序:
如果错误号为0,则
strPack=“失败”
如果结束
端函数
“/Helper允许从UDF更新范围
私有函数UpdateRange(rngDest作为范围,val作为变量)
rngDest.Value=val
端函数
请参见代码注释:

Public Function strPack(ByVal strHex As String, ByVal rngCnt As Range) As String

   Dim lRes     As Long

   On Error GoTo errHandler

     lRes = 1000 '==> Your business logic goes here

     '/ This is the gymnastics you do to update range from an UDF
     Application.Evaluate ("UpdateRange(" & rngCnt.Address & "," & lRes & ")")
     strPack = "SUCCESSFULL"

errHandler:
   If Err.Number <> 0 Then
    strPack = "FAILED"
   End If

End Function

'/ Helper to allow range update from UDF
Private Function UpdateRange(rngDest As Range, val As Variant)
    rngDest.Value = val
End Function
公共函数strPack(ByVal strHex作为字符串,ByVal rngCnt作为范围)作为字符串
暗淡的lRes和长的一样
关于错误转到错误处理程序
lRes=1000'=>您的业务逻辑在这里
“/这是您从UDF更新范围所做的练习
Application.Evaluate(“UpdateRange”(&rngCnt.Address&“,&lRes&”))
strPack=“成功”
错误处理程序:
如果错误号为0,则
strPack=“失败”
如果结束
端函数
“/Helper允许从UDF更新范围
私有函数UpdateRange(rngDest作为范围,val作为变量)
rngDest.Value=val
端函数


除了其他错误之外,工作表上的自定义项不能更改其他单元格的值。它只能向它所在的单元格返回一个值。@Zac,是的,您可以,错误处理程序不是问题,我从2005年起就这样做了。我想看看您在哪里发现从工作表调用的UDF可以影响与调用UDF的单元格不同的单元格。我所读到和学到的一切都是,这是不可能做到的,而且有很好的理由。@splaten你是在问我为什么微软会制定一项政策?我只能猜测这是一种帮助维护数据完整性的方法。目前,您知道每个值的来源。如果数据发生意外更改,则可以将其追溯到源,但如果允许单元格更改其他单元格的值,则知道什么以及为什么会变得复杂。您必须找到正在执行此操作的单元格,这可能是一项艰巨的任务。当我将intprocessed设置为10时,您编辑的sub没有错误。当您得到错误时,该变量的值是多少?除了所有其他错误之外,工作表上的自定义项不能更改另一个单元格的值。它只能向它所在的单元格返回一个值。@Zac,是的,您可以,错误处理程序不是问题,我从2005年起就这样做了。我想看看您在哪里发现从工作表调用的UDF可以影响与调用UDF的单元格不同的单元格。我所读到和学到的一切都是,这是不可能做到的,而且有很好的理由。@splaten你是在问我为什么微软会制定一项政策?我只能猜测这是一种帮助维护数据完整性的方法。目前,您知道每个值的来源。如果数据发生意外更改,则可以将其追溯到源,但如果允许单元格更改其他单元格的值,则知道什么以及为什么会变得复杂。您必须找到正在执行此操作的单元格,这可能是一项艰巨的任务。当我将intprocessed设置为10时,您编辑的sub没有错误。当您得到错误时,该变量的值是多少?这与我自己的示例有什么不同?rngDest通过引用传递,并以相同的方式分配…它不会工作。请冷静。阅读此文件,可能是我使用的Excel 2010版本。@Splaten我以前在Excel 2003、Excel 2007、Excel 2010和Excel 2013中使用过此方法-但是,与所有自定义项一样,您需要确保代码在模块中,而不是在工作表对象中。@Chronocidal,代码在模块中,而不是在工作表中。谢谢。这和我自己的例子有什么不同?rngDest通过引用传递,并以相同的方式分配…它不会工作。请冷静。阅读此文件,可能是我使用的Excel 2010版本。@Splaten我以前在Excel 2003、Excel 2007、Excel 2010和Excel 2013中使用过此方法-但是,与所有自定义项一样,您需要确保代码在模块中,而不是在工作表对象中。@Chronocidal,代码在模块中,而不是在工作表中。非常感谢。