我写了一个UDF,它把范围作为可选参数。然后,它计算所使用范围的最后一行。如果未将范围作为参数传递,则UDF应该默认为调用单元格的完整工作表。不知何故,直截了当的方法不起作用-UDF返回0。
var inputString = $('body').html();
inputString = inputString.replace(/(\r\n|\r|\n){2,}/g, '$1\n');
$('body').html(inputString);
正如我所说,如果我在单元格“ = hrLastRow()”中调用此方法,尽管到处都有值,但结果为零:)-因此结果肯定是肯定的。
也许我没有正确使用Application.Caller ...?任何帮助将非常感激。还是VBA不允许以某种方式进行递归调用?那为什么是零?
PS:在射程上工作正常。
PPS:我刚刚注意到,Excel警告调用单元格中有循环引用。也许这是潜在的问题-但是,如何解决呢?
更新: 因此,目标是要使该工作无副作用,例如迭代计算。有人建议只是在UDF调用者下面进行搜索以避免循环引用,这对我来说似乎是一个聪明的主意,既简单又针对性。不知何故,我的代码似乎很笨拙,但是结果刚刚关闭...这是UDF的当前状态。只要看一下r是否无关紧要:
var inputString = document.getElementsByTagName('body')[0].innerHTML;
inputString = inputString.replace(/(\r\n|\r|\n){2,}/g, '$1\n');
document.getElementsByTagName('body')[0].innerHTML.html(inputString);
外部if语句的else部分工作正常。
答案 0 :(得分:0)
感谢所有贡献者。
特别感谢BrakNicku提出的简单但聪明的想法,即仅在调用单元格下方进行搜索以避免循环引用。
随时使用以下代码。 这是最终功能,可以按需工作:
Public Function hrLastRow(Optional r As Range = Nothing) As Long
Application.Volatile True
If r Is Nothing Then
Dim callerRow As Long
Dim callerWS As Worksheet
Dim searchRange As Range
Set callerWS = Application.Caller.Parent
callerRow = Range(Application.Caller.Address).row
With callerWS
Set searchRange = .Range(.Cells(callerRow + 1, 1), .Cells(callerRow + .UsedRange.Rows.Count, .UsedRange.Columns.Count))
If Application.WorksheetFunction.CountA(searchRange) <> 0 Then
hrLastRow = searchRange.Find(What:="*", _
After:=searchRange.Cells(1, 1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).row
Else
hrLastRow = callerRow
End If
End With
Else
If Application.WorksheetFunction.CountA(r) <> 0 Then
hrLastRow = 1 - r.Rows(1).row + _
r.Find(What:="*", _
After:=r.Cells(1, 1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).row
hrLastRow = Application.WorksheetFunction.Max(hrLastRow, 0)
Else
hrLastRow = 0
End If
End If
End Function
答案 1 :(得分:-1)
在您的工作簿模块上写入:
Option Explicit
Private Sub Workbook_Activate()
With Application
.Iteration = True
.MaxIterations = 1000
.MaxChange = 0.001
End With
End Sub
Private Sub Workbook_Deactivate()
Application.Iteration = False
End Sub
并将其添加到您的函数中:
Option Explicit
Public Function hrLastRow(Optional r As Range = Nothing) As Long
If Application.Iteration = False Then End
If r Is Nothing Then
hrLastRow = hrLastRow(ThisWorkbook.Worksheets(Application.Caller.Parent.Name).Cells())
Else
If Application.WorksheetFunction.CountA(r) <> 0 Then
hrLastRow = 1 - r.Rows(1).Row + _
r.Find(What:="*", _
After:=r.Cells(1, 1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
hrLastRow = Application.WorksheetFunction.Max(hrLastRow, 0)
Else
hrLastRow = 0
End If
End If
End Function
这样,迭代计算将仅在此工作簿上被激活,如果未激活,则不会重新计算您的函数。