Excel VBA:#Value!使用Range时出错,即使计算在调试模式下运行正常,也要查找

2q5ifsrm  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(191)

我是VBA新手,我正试图计算过去一个月的一些数据的总和。下面是我的代码:

Function Monthly_volume_given_velocity() As Double
Dim velocity As Double
Dim ind_vit As Integer
Dim ind_today As Integer
velocity= ActiveCell.Offset(0, -1).Value

With Sheets("2022")
ind_vel = .Range("A5:A13").Find(What:=velocity).Row
Dim rng As Range
rng = .Rows("1").Find(What:=Date, LookIn:=xlFormulas)
If Not rng Is Nothing Then ind_today = rng.Column: Debug.Print ind_today 

Monthly_volume_given_velocity = Application.WorksheetFunction.Sum(.Range(.Cells(ind_vel , ind_today - 30), .Cells(ind_vel , ind_today )))
End With
End Function

使用这段代码时,我得到了一个#Value!错误,尽管在调试模式下运行它时,我得到了Monthly_volume_given_velocity的正确值。
用预期值替换代码中的ind_today不会出错,所以我猜它来自Range.Find过程。我从另一个线程获得了If Not rng...过程,但它似乎没有解决这个问题。
有人知道我哪里做错了吗?

xdnvmnnf

xdnvmnnf1#

当UDF在遇到任何错误时运行,它将返回一个错误,该错误在页面中显示为#VALUE
现在很难说函数中到底是什么失败了,但我看到了一些问题:

  • 自定义项不应依赖于ActiveCell(或ActiveSheet)。Excel处理重新计算,如果包含公式的单元格不活动,则可以触发重新计算。将单元格作为参数传递。
  • 日期的Find可能很棘手,请参见Range.Find on a Date That is a Formula。我建议您手动搜索日期。
  • 指定“第二次查找”的结果时丢失了Set
  • 检查rng是否不是Nothing(所以Find返回了一些东西),但是,如果没有找到任何东西,int_today将为0,并且下面的Sum将获得一个无效的范围作为参数。

我修改了你的函数。当然,Debug.Print-语句可以在函数工作后删除。正如前面所说,你必须在公式中将单元格作为参数传递,例如=Monthly_volume_given_velocity(B1)

Function Monthly_volume_given_velocity(cell As Range) As Double
    Dim velocity As Double
    Dim ind_vel As Long
    Dim ind_today As Long
    velocity = cell.Offset(0, -1).Value
    Debug.Print "Vel: " & velocity
        
    With Sheets("2022")
        ' Find Velocity Row
        On Error Resume Next
        ind_vel = .Range("A5:A13").Find(What:=velocity).row
        On Error GoTo 0
        If ind_vel = 0 Then Exit Function
        Debug.Print "ind_vel: " & ind_vel
        
        ' Find Date column
        Dim dates As Variant, lastCol As Long
        lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
        Debug.Print "lastcol: " & lastCol
        dates = .Cells(1, 1).Resize(1, lastCol)
        For ind_today = 1 To lastCol
            Debug.Print ind_today, dates(1, ind_today)
            If dates(1, ind_today) = Date Then Exit For
        Next
        If ind_today > lastCol Then
            Debug.Print "today not found"
            Exit Function ' date not found
        End If
        Debug.Print ind_today
        
        ' Calculate value
        Dim rng As Range
        Set rng = Range(.Cells(ind_vel, ind_today - 5), .Cells(ind_vel, ind_today))
        Debug.Print rng.Address
        Monthly_volume_given_velocity = Application.WorksheetFunction.Sum(rng)
    End With
End Function
vjrehmav

vjrehmav2#

范围是一个对象,因此必须使用Set进行定义,因此必须

Set rng = [...]

加上一条关于.Find方法的注解,以防您不知道:参数(LookIn、LookAt等)是静态的,也就是说,如果没有在新调用中定义,则会从上一次调用中记住它们。这也包括使用用户界面中的“查找”对话框。为了安全起见,每次调用时都应提供所有参数。

相关问题