【问题标题】:Return last value in table column返回表列中的最后一个值
【发布时间】:2019-07-08 08:54:44
【问题描述】:

VBA 新手。这两天一直在寻找答案,但没有找到真正问我想要答案的问题。

我正在使用在我的一张工作表中填充表格的用户窗体。

我的问题在 Sub UserForm_Initialize() 内。我要做的第一件事就是找出我在我的 DataBodyRange 中的最后一行(顺便说一下,第一列)是否包含一个 ID 号。

如果是这样,那么我就取那个值,加一个,然后在我的用户窗体中填充一个文本框。

但是,如果表格包含标题和一个空行,我想用数字 1 填充 TextBox(通过另一个子将添加到该空行),但我的代码停止工作并出现错误。

使用以下代码我得到错误

运行时错误“91”:对象变量或未设置块变量

Private Sub UserForm_Initialize()
Dim tbl As ListObject, rng As Range

Set tbl = Worksheets("Sheet1").ListObjects("table1")
Set rng = tbl.ListColumns("ID").DataBodyRange

If IsEmpty(rng.Cells.Find("*", LookIn:=xlValues,_
           SearchOrder:=xlByRows,_
           SearchDirection:=xlPrevious).Value) Then
    Me.textBox.Value = 1
Else
    Me.textBox.Value = rng.Cells.Find("*", LookIn:=xlValues,_
           SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Value + 1
End If

End Sub

我不明白我找到的关于错误代码或如何修复它的解释。我认为错误与rng.Cells.Find... 有关,因为那是在单步执行代码时出现错误的时候,但我可能一辈子都不明白为什么。

【问题讨论】:

  • 我相信这将是nothing 不为空。 :也看.end(xlUp).row
  • 添加到@Nathan_Sav 评论,您将执行两次相同的搜索:一次用于您的IF 条件,然后更新您的文本框。我会声明一个range 变量并将其设置为您的搜索结果。然后在您的 IF 条件和分配中使用它

标签: excel vba find listobject


【解决方案1】:

Find() 返回一个 Range,如果没有找到,则 Range 是 Nothing。因此,应该检查 Is Nothing。

在下面的代码中,引入了一个新的范围变量result。检查它是否为空:

Private Sub UserForm_Initialize()
    Dim tbl As ListObject, rng As Range

    Set tbl = Worksheets("Sheet1").ListObjects("table1")
    Set rng = tbl.ListColumns("ID").DataBodyRange

    Dim result As Range
    Set result = rng.Cells.Find("*", LookIn:=xlValues, _ 
                  SearchOrder:=xlByRows, SearchDirection:=xlPrevious)

    If Not result Is Nothing Then
        Debug.Print result.Address
    Else
        Debug.Print "result is nothing"
    End If

End Sub

【讨论】:

  • 这成功了!我刚刚在上面的If 语句中添加了Me.textBox = result + 1Me.textBox = result,以便在用户窗体中填充我的文本框。
【解决方案2】:

失败是因为

rng.Cells.Find("*", LookIn:=xlValues, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Value

如果Range.Find method 没有找到任何东西,它会返回Nothing,然后您尝试获取Nothing.Value 失败。

在使用Nothing 之前,始终测试Find 的结果:

Dim FoundAt As Range
Set FoundAt = rng.Cells.Find("*", LookIn:=xlValues, SearchOrder:=xlByRows, SearchDirection:=xlPrevious)

If Not FoundAt Is Nothing Then
    Debug.Print FoundAt.Value 'now you can safely use .Value
Else
    MsgBox "Nothing found"
End If 

【讨论】:

  • 正是我的建议.. 虽然 'savely' 可能有点不合适(在第 5 行的评论中):)
  • :) 你的答案会奏效,这正是我会做的。我的评论不是关于你的答案,而是第 5 行的评论。我怀疑你的意思是 "safely" 而不是 "savely" 在你的评论中?
【解决方案3】:

仅供参考,您实际上并不需要Find,因为您可以直接获取最后一个单元格:

Private Sub UserForm_Initialize()
    Dim tbl As ListObject, rng As Range, lastCell As Range

    Set tbl = Worksheets("Sheet1").ListObjects("table1")
    Set rng = tbl.ListColumns("ID").DataBodyRange
    With rng
        Set lastCell = .Cells(.Cells.Count)
    End With
    If IsEmpty(lastCell) Then
        Me.TextBox.Value = 1
    Else
        Me.TextBox.Value = lastCell.Value + 1
    End If

End Sub

【讨论】:

  • 与使用Find相比,这种方法需要更少的CPU工作吗?
  • 可能虽然我认为差异可以忽略不计。结果不一定相同,因为此方法将始终获取表的最后一行,而 Find 将获取第一列中包含数据的最后一行。
猜你喜欢
  • 1970-01-01
  • 2013-12-22
  • 2022-11-19
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 2016-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多