Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel VBA编辑器中的UDF仅在需要双精度时返回零_Vba_Excel - Fatal编程技术网

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

Excel VBA编辑器中的UDF仅在需要双精度时返回零,vba,excel,Vba,Excel,此函数用于计算闭合导线的面积。当作为子单元写入并指定给特定单元时,子单元工作正常。但是,当用作函数时(如下所示),它只返回零。为什么? '设计用于容纳任意数量横向侧的功能 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 - Ac

此函数用于计算闭合导线的面积。当作为子单元写入并指定给特定单元时,子单元工作正常。但是,当用作函数时(如下所示),它只返回零。为什么? '设计用于容纳任意数量横向侧的功能

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

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

代码作为子过程工作,因为您有正确的工作表,因为和子过程允许您使用方法和方法。工作表上使用的函数需要知道它在哪个工作表上,并且选择单元格不是一种认可的方法

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
帮助查找函数所在的父工作表。没有选择或激活单元格,但它们通过提供行号、列号和一些操作来使用直接寻址进行循环


有关摆脱依靠选择和激活来实现目标的更多方法,请参阅。

为什么选择单元格并在函数中使用activecell?从我所看到的,你不需要选择那些单元格,你可以不选择就读取单元格内容。我使用activecell的方式是从上到下逐级浏览一个北距和东距列表,直到最后,可以是任意数量的单元格。你完全正确,不需要选择每个单独的单元格,但是,这仍然不能解释为什么函数只返回零而不返回计算区域。停止它,在VBE中逐行遍历F8,并在代码运行时关注区域。我建议在调用函数时删除activecell并传入单元格引用。如果您选择在运行时传入activecell,那么就这样吧,但这比将函数锁定到单元格引用要好得多。另外,我会将While循环更改为for next,循环范围而不是查找空白,这样您就可以在不需要偏移的情况下引用范围。用作UDF的函数运行时有一定的限制,例如,无法更改其运行的Excel环境:这包括选择单元格或更改单元格的值,而不是从中调用单元格的值。感谢大家的快速回复,两种解决方案都进行了一些调整。另外,谢谢你关于避免选择的阅读建议。