Excel VBA 编辑器中的 UDF 仅在需要双精度时返回零



此函数旨在计算闭合导线的面积。当写为 sub 并分配给特定单元格时,sub 可以完美运行。但是,当用作函数时(如下所示(,它仅返回零。为什么?'功能设计用于容纳任意数量的横移边

Public Function TraverseArea() As Double
Dim Area As Double
Area = 0
Range("N2").Select
Area = (ActiveCell.Value * (Range("M2").End(xlDown).Offset(-1, 0).Value - ActiveCell.Offset(1, -1).Value))
ActiveCell.Offset(1, 0).Select
While ActiveCell.Offset(1, -1) <> ""
    Area = Area + (ActiveCell.Value * (ActiveCell.Offset(-1, -1).Value   -  ActiveCell.Offset(1, -1).Value))
    ActiveCell.Offset(1, 0).Select
Wend
If Area < 0 Then
    Area = Area * -1
End If
Area = Area / 2
TraverseArea = Area
End Function
我没有

您的数据或工作表结构,所以这一切都超出了我的脑海,但这应该让您了解如何在不专门使用硬编码范围的情况下拥有您的函数。

Sub TestFunction()
    MsgBox TraverseArea(Range("N2"), Range("M2").End(xlDown).Offset(-1, -1))
End Sub
Public Function TraverseArea(MyRange As Range, MySecondRange As Range) As Double
Dim Area As Double, lr As Long, X as long
lr = Cells(Rows.Count, MyRange.Column).End(xlUp).Row
Area = (MyRange.Value * (MySecondRange.Value - MyRange.Offset(1, -1).Value))
For X = MyRange.Row To lr
    If Cells(X, MyRange.Column - 1) = "" Then Exit For
    Area = Area + (ActiveCell.Value * (ActiveCell.Offset(-1, -1).Value - ActiveCell.Offset(1, -1).Value))
Next
If Area < 0 Then Area = Area * -1
Area = Area / 2
TraverseArea = Area
End Function

这很可能需要一些调试,但应该足以让您了解我在之前的评论中关于使用单元格引用而不选择它们的说法。

该代码用作子过程,因为您具有正确的工作表,可显示为 ActiveSheet 属性,并且 sub 允许您使用 范围 。选择方法和范围。激活方法¹。工作表上使用的函数需要知道它在哪个工作表上,选择单元格不是批准的方法。

Public Function TraverseArea(Optional aRNG As Variant) As Double
    Dim dAREA As Double, r As Long, rng As Range
    dAREA = 0
    With Application.Caller.Parent
        If IsMissing(aRNG) Then Set aRNG = .Range("N2")
        For Each rng In .Range(aRNG, aRNG.End(xlDown))
            If IsEmpty(rng) Or Not IsNumeric(rng) Or Not CBool(Len(rng.Offset(1, -1))) Then _
                Exit For
            With rng
                'Area = Area + (ActiveCell.Value * (ActiveCell.Offset(-1, -1).Value - ActiveCell.Offset(1, -1).Value))
                dAREA = dAREA + .Value2 * (.Offset(0, -1).End(xlDown).Offset(-1, 0).Value2 - .Offset(1, -1).Value2)
            End With
        Next rng
    End With
    If dAREA < 0 Then
        dAREA = dAREA * -1
    End If
    dAREA = dAREA / 2
    TraverseArea = dAREA
End Function

Application.Caller 帮助查找函数所在的父工作表。不会选择或激活任何单元格,但通过提供行号、列号和对 Range.Offset 属性的一些操作,使用直接寻址循环访问这些单元格。


¹ 请参阅如何避免在 Excel VBA 宏中使用选择,了解有关摆脱依赖选择和激活来实现目标的更多方法。

最新更新