【问题标题】:Excel VBA: Find first value in row larger than 0 and sum over following 4 cellsExcel VBA:在大于0的行中查找第一个值并对以下4个单元格求和
【发布时间】:2016-01-16 01:30:34
【问题描述】:

作为 VBA Excel 的初学者,我希望能够做到以下几点:

我想在一行中找到第一个大于 0 的值,然后对同一行中的以下 4 个单元格求和。所以

Animal1    0    0    1    2    3    0    1
Animal2    3    3    0    1    4    2    0
Animal3    0    0    0    0    0    1    0

结果

Animal1    7
Animal2    11
Animal3    1

这可能吗?

【问题讨论】:

  • 是的,这是可能的。向我们展示您迄今为止编写的代码,并提供有关应将结果写入何处的更多信息(新工作表/同一张工作表,...) - 这样我们可能会提供帮助
  • 也可以只用公式来完成 - 你不需要 VBA
  • 您的示例与您的描述不符。为什么不是第一行 6 个,第二行 7 个?另外——“之后”是指严格地在之后还是之后并包括在内?

标签: vba excel


【解决方案1】:

(您的问题描述与您的示例不匹配。我将问题解释为对以大于 0 的第一个数字开头的连续 4 个元素求和。如果我的解释错误 - 以下代码需要调整。)

您可以使用用户定义的函数(即 UDF -- 一种设计用作电子表格函数的 VBA 函数)来实现:

Function SumAfter(R As Range, n As Long) As Variant
    'Sums the (at most) n elements beginning with the first occurence of
    'a strictly positive number in the range R,
    'which is assumed to be 1-dimensional.
    'If all numbers are zero or negative -- returns a #VALUE! error

    Dim i As Long, j As Long, m As Long
    Dim total As Variant

    m = R.Cells.Count
    For i = 1 To m
        If R.Cells(i).Value > 0 Then
            For j = i To Application.Min(m, i + n - 1)
                total = total + R.Cells(j)
            Next j
            SumAfter = total
            Exit Function
        End If
    Next i
    'error condition if you reach here
     SumAfter = CVErr(xlErrValue)
End Function

如果您的示例数据位于 A1:H3 中,则将公式 =SumAfter(B1:H1,4) 放入 I1 并复制下来将按预期工作。请注意,代码比您的问题描述更一般。如果你打算使用 VBA,你最好让你的 subs/functions 尽可能灵活。另请注意,如果您正在编写 UDF,最好考虑一下如果输入违反预期,您希望返回哪种类型的错误。请参阅 this 以获得精彩的讨论(来自 Chip Pearson 的网站 - 这是 Excel VBA 程序员的绝佳资源)。

编辑:如果您希望将大于 0 的第一个单元格添加到接下来的 4 个单元格(总计 5 个单元格),那么我给出的函数按原样工作,但使用 =SumAfter(B1:H1,5) 而不是 =SumAfter(B1:H1,4) .

【讨论】:

  • 修复它的好方法 - 我不知道 UDF,但我肯定会在未来更多地研究它。谢谢。
【解决方案2】:

这是实现所需结果的变体之一:

 Sub test()
        Dim cl As Range, cl2 As Range, k, Dic As Object, i%: i = 1
        Set Dic = CreateObject("Scripting.Dictionary")
        For Each cl In ActiveSheet.UsedRange.Columns(1).Cells
            For Each cl2 In Range(Cells(cl.Row, 2), Cells(cl.Row, 8))
                If cl2.Value2 > 0 Then
                    Dic.Add i, cl.Value2 & "|" & Application.Sum(Range(cl2, cl2.Offset(, 4)))
                    i = i + 1
                    Exit For
                End If
        Next cl2, cl
        Workbooks.Add: i = 1
        For Each k In Dic
            Cells(i, "A").Value2 = Split(Dic(k), "|")(0)
            Cells(i, "b").Value2 = CDec(Split(Dic(k), "|")(1))
            i = i + 1
        Next k
    End Sub

【讨论】:

  • 您似乎在对整行求和,如果总和超过 0,则保留总和。它似乎与问题描述不匹配(例如 - 它不涉及数字 4)。另一方面——目前还不清楚 OP 到底在想什么。
  • @JohnColeman,是的,你是对的,直到你发表评论,我才意识到真正的 OP 需求,谢谢,帖子已更新
  • 您的输出与 OP 的示例匹配,但与 OP 的描述不匹配。似乎 OP 想要添加第一个非零值 + 下一个 4,总共 5 个单元格。无论如何,您的解决方案很好,并且在 OP 澄清后可以轻松调整 4 与 5 的问题。
【解决方案3】:

这是我要使用的,我不知道您使用的任何单元格位置,因此您需要自己更改。

未来参考这不是一个适合你的代码编写网站,如果你是 VBA 新手,我建议先做一些简单的事情,出现一个消息框,使用代码移动到不同的单元格,尝试一些 if 语句和/或循环.当你开始使用变量(布尔值、字符串、整数等)时,你会看到你能走多远。正如我喜欢说的,“如果你能在 excel 中做到这一点,代码就能做得更好”

如果代码不起作用或不适合您的需求,请更改它,这样它就可以了,当我使用它时它对我有用,但我不是你,我也没有你的电子表格

将其粘贴到您的 vba 中并使用 F8 逐步查看它的工作原理以及是否要使用它。

Sub test()

[A1].Select ' assuming it starts in column A1

'loops till it reachs the end of the cells or till it hits a blank cell
Do Until ActiveCell.Value = ""

ActiveCell.Offset(0, 1).Select

'adds up the value of the cells going right and removes the previous cell to clean up
Do Until ActiveCell.Value = ""
x = x + ActiveCell.Value
ActiveCell.Offset(0, 1).Select
ActiveCell.Offset(0, -1).ClearContents
Loop

'goes back to the begining and ends tallyed up value
Selection.End(xlToLeft).Select
ActiveCell.Offset(0, 1).Value = x

'moves down one to next row
ActiveCell.Offset(1, 0).Select

Loop

End Sub

【讨论】:

  • .select 方法的使用是一种不好的做法,vba 中的所有任务都可以在不使用它的情况下完成,并且代码更短更易读。 stackoverflow.com/questions/10714251/…
  • 我会查看您发送给我的内容,但是我将保持我的代码与以前没有使用过该方法相同,如果我能够使我的代码更高效,那么我将使用此方法然后更新我发布的代码。
  • 对不起,如果听起来我冒犯了你的话,我不是故意的,如果你批评它,我会把它当作建设性的批评(我知道拼写不对)这意味着我有更多的改进空间,这是我喜欢用 VBA 做的事情。另外,我希望您不要删除您的评论,因为它有一个有用的链接,说明如何不使用 .select,如果他们偶然发现这篇文章,它可能对其他人有用,也可能没有用。希望这能消除任何误解。
猜你喜欢
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多