【问题标题】:How would I get the first non-empty cell in a column?如何获得列中的第一个非空单元格?
【发布时间】:2012-07-12 06:24:29
【问题描述】:

如果一个单元格是空的,我希望它在上面的单元格中查找。如果那个是空的,它将在上面的单元格中查找,直到找到一个非空单元格。当它发生时,它应该返回它。这将是一个名为loopUp 的UDF。然后,当我在这样的单元格公式中使用它时:=loopUp(D24),并且范围 D18:D24 为空,它将显示 D17 中的内容。

这里有一些伪:

Function loopUp(Cell)
    while Cell is empty
        Cell becomes cell above
    return cell

我是 VBA 新手。我坚持的事情是如何传递一个单元格的地址而不是它的值。

【问题讨论】:

  • 你能告诉我们你尝试了什么以及你卡在哪里了吗?
  • 您是否尝试过自己编写函数?如果是这样,请发布您尝试过的内容,我们可以帮助您解决无效的问题。
  • 这就是你添加的逻辑。您能否展示您实际编写的代码并提及哪个部分不起作用...
  • I am stuck on is how to pass in the address of a cell rather than its value 试试这个Function loopUp(cl as range)

标签: vba excel


【解决方案1】:

根据 Siddharth 的最后建议,这里有一个解决方法。

Function LoopUp(rng As Range) As Variant

Dim intCnt As Long

LoopUp = "Nothing found"

For intCnt = rng.Row To 1 Step -1
    If Not IsEmpty(Cells(intCnt, rng.Column)) Then
        LoopUp = Cells(intCnt, rng.Column)
        Exit For
    End If
Next


End Function

更新

这可能是一个更好、更简洁、更易于理解的解决方案。我测试了一下,但有人可能会破坏它!

Function LoopUp(rng As Range) As Variant

If Not IsEmpty(rng) Then LoopUp = rng
Else
    If rng.End(xlUp).Row = 1 Then LoopUp = "Nothing found" Else LoopUp = rng.End(xlUp)
End If 

End Function

【讨论】:

  • + 1 这行得通。但是不需要循环:) @TimWilliams 删除了他的答案,因为你和我都在要求 OP 表现出一些努力。他的回答真的很好。希望他取消删除它。
  • 我没有看到他的回答,但看到我的更新。我认为找到了一种更简单、更清洁的方法。除非有人能打破它!
  • 我认为在函数应该返回错误时返回一个有意义的值是非常非常错误的,并不是我希望该范围在某个单元格中包含“未找到”,而是作为一般原则.当然,如果单元格本身包含一个值,那么您的第二个变体将不起作用,这不是 OP 想要的。
  • @panda-34。总的来说,我同意你的第一句话,但这就是 VBA 的美妙之处(以及 IFERROR、ISERROR 公式)。我们可以拿#VALUE!并很容易变成对眼睛有意义的东西!关于第二个变体的好点!我已编辑帖子以解决此问题。
【解决方案2】:
Function LoopUp(rng as Range)
    With rng.Cells(1)
        If Len(.Value) > 0 Then
            Lookup = .Value
        Else
            LoopUp = .End(xlUp).Value
        End If
    End With
End Function

编辑:关于如果在传递的 Range 参数上方没有“非空”单元格会发生什么的讨论。由于 OP 没有指定在这种情况下应该发生什么,这只会返回一个空响应。

【讨论】:

  • + 1 我喜欢它的简单性:)
  • 这值得吗? If Len(Trim(rng.Cells(1).Value)) <> 0 Then LoopUp = rng.Value _ Else LoopUp = rng.Cells(1).End(xlUp).Value
  • 是的! - 我错过了问题的“如果单元格为空”部分
  • Len(.Value) 如果单元格包含错误值将是一个运行时错误,如果单元格故意包含一个空字符串,它将中断,因此这不是测试空虚的好方法.如果隐藏行的值在该范围内,它也将不起作用。结束函数用于交互移动。
【解决方案3】:

UDF 将如下所示:

Function loopUp(Cell)
  Do While IsEmpty(Cell)
    Set Cell = Cell.Offset(-1)
  Loop
  loopUp = Cell
End Function

请注意,只有当 Cell 本身发生变化时才会重新计算该函数,而不是当您更改 Cell 上方的范围(函数扫描)时,为了解决这个问题,添加第二个虚拟参数,该参数应设置为您的范围希望重新计算要监视的函数(为简单起见,可能是整个列)。

【讨论】:

  • Set Cell = Cell.Offset(-1) 如果到达第一行并且为空,则会中断。为此需要一个错误陷阱。
  • @Scott 你是什么意思,'会打破'?调用此类函数的结果将是一个错误,这正是您在没有返回值时所期望的。 OP 没有要求特殊的错误处理,因此留作练习。
  • 从你的角度来看,这点很公平,但我只是在发表我认为值得注意的评论作为良好的编程实践。
  • @Scott 我认为这是一种很好的编程习惯,不要默默地抑制异常,而是让用户知道在他可以做某事的级别上出现了问题。在这种情况下,必须在具有 ISERR 函数的 Excel 工作表上出现错误陷阱。当您可以使用 Excel 提供的实际错误值(甚至无需编写任何代码)时,我真的认为没有必要发明一些表示错误并引入可能的歧义的“神奇值”
  • 好点。昨晚离开办公室后,我也想过这个问题。有趣的是,这些似乎是编程的更好点,并且它们的实现方式通常受到项目范围和谁在使用它的影响!不过,了解可用的选项总是好的。
猜你喜欢
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多