此功能用于计算闭合导线的面积。当作为子编写并分配给特定单元格时,子工作完美。但是,当用作函数时 - 如下所示 - 它仅返回零。为什么? '功能旨在容纳任意数量的导线侧
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
答案 0 :(得分:2)
我没有您的数据或工作表结构,所以这一切都不在我的脑海中,但这可以让您了解如何在没有专门使用硬编码范围的情况下使用您的功能。
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
这很可能需要一些调试,但应该足以让你知道我在之前关于使用单元格引用而不选择它们的评论中想说的内容。
答案 1 :(得分:1)
代码作为子程序工作,因为您可以看到正确的工作表,因为ActiveSheet property和subs允许您使用Range .Select方法和Range .Activate方法¹。工作表上使用的函数需要知道它所处的工作表,并且选择单元格不是批准的方法。
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 property的一些操作,使用直接寻址循环它们。
¹有关远离依赖选择和激活以实现目标的更多方法,请参阅How to avoid using Select in Excel VBA macros。