【问题标题】:Excel VBA - Storing Find result in a range variableExcel VBA - 将查找结果存储在范围变量中
【发布时间】:2020-02-10 17:21:09
【问题描述】:

我正在尝试将范围存储在范围变量 startID、endID 和 endDest 中,但我不断收到运行时错误 1004“对象 _Global 的方法范围失败”。

我的工作簿的控制页面上有一个贷款列表,它们都有多行(从 2 到 6 行),如下所示:

  • 一个 |乙| C
  • 贷款1 |东西| 1.0
  • 贷款1 |东西| 1.1
  • 贷款2 |东西| 2.0
  • 贷款2 |东西| 2.1
  • 贷款2 |东西| 2.2

整个目的是将活动单元格所在的贷款向下移动到列表的底部。这是我遇到的问题(到目前为止):假设在上面的小项目符号列表临时工作表中的活动单元格是 B2 - 活动单元格的行以及固定的列索引 3 表示我在第 1.1 行。然后我将 1.1 “修复”为 1 并将该整数存储在 currentID 中。现在我可以在 C 列中找到 currentID 的第一次出现,然后将 currentID 出现的范围的地址存储在范围变量 startID 中。在这种情况下,我应该将 C1 存储在 startID 中。

我读过 Find 返回一个范围。所以我尝试了Set startID = .Range("C:C").Find(what:=currentID),但这只是将currentID 1 存储在startID 中。所以然后我尝试了Set startID = Range(.Range("C:C").Find(what:=currentID))(这是我的代码块下面出现的内容),但这会导致运行时错误。我还尝试添加和删除句点,以防我弄乱了 With 语句,但这没有帮助。有什么想法吗?

如果我遗漏了一些明显的东西,我深表歉意。我已经使用 VBA 大约三周了,所以我通常必须在谷歌上搜索我需要的每一件事,直到我开始记住重复出现的主题。

Sub ExpireLoan()
With Workbooks("1908 AUS IC Loans Recon.xlsm").Worksheets("Control Page")
Dim currentID As Integer
Dim startID As Range
Dim endID As Range
Dim endDest As Range
Dim rowCount As Integer

'find the current loan range
    currentID = Fix(.Cells(ActiveCell.Row, 3).Value)
    Set startID = Range(.Range("C:C").Find(what:=currentID))
    Set endID = Range(.Range("C:C").Find(what:=currentID + 1))
    Set endID = Range(endID.Offset(-1, 0))

'find the last row
    Set endDest = .Range("A7").End(xlDown)
    Set endDest = endDest.Offset(-1, 0)

'copy the current loan and paste into the end of the table
    rowCount = .Range(startID, endID).Count
    .Range(startID, endID).EntireRow.Copy
    .endDest.EntireRow.PasteSpecial

'set bottom border at new end of the table
    endDest.Select
    ActiveCell.Offset(0, 0).Range("A1:AF1").Borders(xlEdgeBottom).LineStyle = xlDouble

'delete rows from loan's original position above
    .Range(startID, endID).EntireRow.Delete

'set sort ID
    ActiveCell.Offset(0, 2).Value = Fix(ActiveCell.Offset(-1, 2).Value) + 1
    For i = 0 To rowCount - 2
        ActiveCell.Offset(i + 1, 2).Value = ActiveCell.Offset(i, 2).Value + 0.1
    Next

'delete loanTypeCode
    ActiveCell.Offset(0, 1).ClearContents
    For i = 1 To rowCount - 1
        ActiveCell.Offset(i, 1).ClearContents
    Next

'fix sortID
    Set sortIdRange = Range(startID, startID.End(xlDown))
    Call subtractOneFromCells

'make it red
    ActiveCell.Offset(0, 0).Range("A1:AF1").Interior.TintAndShade = 0.399975585192419
    For i = 1 To rowCount - 1
        ActiveCell.Offset(i, 17).Range("A1:P1").Interior.TintAndShade = 0.399975585192419
    Next

End With
End Sub

【问题讨论】:

  • 可能是函数找不到搜索条件。
  • Set startID = Range(.Range("C:C").Find(what:=currentID))更改为Set startID = .Range("C:C").Find(what:=currentID),然后使用If Not startID is Nothing检查它是否返回了一些东西,也尝试使用完整的参数。 This 将帮助您了解如何使用 .Find
  • 如果上述建议没有帮助,请查看this问答。使用带有大数值(超过 8 个字符)的 .Find 将开始变得错误。查看xlFormulas 确实有帮助!
  • @walter kloosterboer,该函数肯定能够找到搜索条件,因为我首先从该列获取搜索条件。
  • @Siddharth Rout,当我尝试您的建议时,该函数返回 currentID(在上面的示例中为 1。我真正想要的是第一次出现 1 的地址,即 C1.

标签: excel vba find range runtime-error


【解决方案1】:

根据我的经验,.Find 在查找数字时可能会表现得有些奇怪。使用xlWhole 通常会为我修复它,当我在您的示例数据上尝试它时也可以修复它。否则,例如,如果您正在寻找 currentID = 3.Find 将返回第一个包含 3 的单元格作为子字符串。这意味着值 1.3 的单元格可以作为 3 的第一次出现返回。试试这行:

Set startID = .Range("C:C").Find(What:=currentID, LookAt:=xlWhole)

要对此进行调试,您可以使用F8 逐行遍历代码,并使用Debug.Print currentIDDebug.Print startID.Address 通过即时窗口查看发生了什么。

关于更短代码(不一定总是更易读)的提示如下:您可以像这样合并两行:

Set endDest = .Range("A7").End(xlDown)
Set endDest = endDest.Offset(-1, 0)

变成这样的一行:

Set endDest = .Range("A7").End(xlDown).Offset(-1, 0)

由于您的第一行返回一个 Range 对象,因此无需在步骤之间将其存储在变量中。

另一方面,关于这两行:

endDest.Select
ActiveCell.Offset(0, 0).Range("A1:AF1").Borders(xlEdgeBottom).LineStyle = xlDouble

首先,建议尽可能避免使用.Select,如下所述:How to avoid using Select in Excel VBA。其次,第二行很难理解。尝试像这样使用Resize

ActiveCell.Resize(1, 32).Borders(xlEdgeBottom).LineStyle = xlDouble

【讨论】:

  • 感谢您的周到回答!不幸的是,xlWhole 没有用。但是,您确实通过在即时窗口中建议调试内容帮助我解决了这个问题。 startID.Address 确实返回了正确的地址。所以我最终恢复到Set startID = .Range("C:C").Find(what:=currentID, lookat:=xlWhole, LookIn:=xlFormulas),它返回单元格值而不是地址。但是后来当我提到startID时,我不得不在.Range(startID.Address, endID.Address).EntireRow.Copy中添加.Address。并感谢您的其他提示!
猜你喜欢
  • 2018-03-29
  • 2023-03-19
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多