【问题标题】:EXCEL VBA: how to count scenarios?EXCEL VBA:如何计算场景?
【发布时间】:2014-10-16 18:09:42
【问题描述】:

我正在完成一个项目,似乎最后一部分是最困难的。

我有 7 个(6 + 1 个可选)列具有这种排序数据(其中一些只有早/晚/na,其中一些只有早/晚/等于/na)。例如三行:

OK OK       No  Yes Earlier Earlier N/A
OK OK       No  Yes Earlier Earlier Earlier
OK Missed   Yes Yes Later   Later   Earlier

这些可以在 13 种不同的情况下结束(如果它是“ok ok no yes early n/a”,例如“a = a + 1”)。我需要的是实际计算每种情况发生了多少(从“a”到“m”)。另外例如,如果前三列是“OK OK OK”,我不需要考虑以下条件并将其直接添加到 f.e. b = b + 1 并转到下一行。

我的问题是,考虑到我将拥有超过 50,000 行,我能做到这一点的效率如何?我知道我可以用 IF 做到这一点,但我会迷失在所有的 if 中,而且我相信这需要很长时间才能让宏运行所有场景。

感谢您的所有帮助和支持。

【问题讨论】:

  • 起初您似乎只想计算所有唯一组合,但后来您说OK OK OK 应该被区别对待。这是唯一得到特殊待遇的场景吗?似乎您可以通过连接 7 列中的值来使用公式来执行此操作(检查 OK OK OK 以筛选出这些值)
  • 你好蒂姆,正如我提到的,有 13 个不同的结局,例如“OK OK NO OK Early Later Later”给出了第 5 个场景(我需要将此场景计为 + 1)所以毕竟 50,000行将运行,我将有多少次每个场景发生的次数。我所说的“OK OK OK”是什么意思——如果前三列都OK,则无需检查其他字段,因为这将被视为第一种情况(a = a +1)。例如,第一种情况是“a - 工作按时完成”
  • 在这种情况下,您可以使用公式创建一个新的连接列并计算该列中的不同条目。
  • 您的意思是一列并将所有OK视为1,不视为2,更早视为3等等?并且有像 1312123 一样的,后来数数所有需要的数?没有其他快速简单的方法吗?
  • 我认为他的意思是创建一个参考列,将同一行的其他列的值结合起来,这样更容易计算出现次数。

标签: excel vba scenarios


【解决方案1】:

好的,这是在 VBA 中使用 Excel SubTotal 函数的初学者

它具有您可能想要更改的代码内置的假设,包括“解决方案”当前与数据位于同一工作表中(当前位于名为“场景”的工作表中,从 col A 和 row 开始7)。这适用于有限数量的数据,但价值 50k 行!您可以根据需要添加代码来汇总统计数据并删除小计。它使原始数据保持不变。

Sub scenarios()
Dim ws As Worksheet
Dim strow As Long, endrow As Long, stcol As Long, endcol As Long
Dim r As Long, c As Long
Dim newstr As String
Dim cl As Range, rng As Range, drng As Range
Dim strArr() As String

strow = 7
stcol = 1  'Col A
endcol = 7 '7 variables

Set ws = Sheets("Scenarios")

    With ws
        'find last data row
        endrow = Cells(Rows.Count, stcol).End(xlUp).Row
            'for each data row
            For r = strow To endrow
                newstr = ""
                'produce concatenated string of that row
                For c = stcol To endcol
                    newstr = newstr & .Cells(r, c)
                Next c
                'put string into array
                ReDim Preserve strArr(r - strow)
                strArr(r - strow) = newstr
            Next r
        'put array to worksheet
        Set drng = .Range(.Cells(strow, endcol + 4), .Cells(endrow, endcol + 4))
        drng = Application.Transpose(strArr)
        'sort newly copied range
        drng.Sort Key1:=.Cells(strow, endcol + 4), Order1:=xlAscending, Header:=xlNo

        'provide a header row for SubTotal
        .Cells(strow - 1, endcol + 4) = "Header"
        'resize range to include header
        drng.Offset(-1, 0).Resize(drng.Rows.Count + 1, drng.Columns.Count).Select
        'apply Excel SubTotal function
        Selection.Subtotal GroupBy:=1, Function:=xlCount, Totallist:=Array(1)

    End With

End Sub

【讨论】:

  • 你好,我以前从未见过这个。它在哪里计算场景?谢谢!
  • 运行代码,它将生成一个与您的数据相邻的排序列表,并在每次更改时应用小计。向下滚动此列表,您将在每个组或场景更改下找到小计计数。目前您需要滚动整个列表,但正如我在回答中指出的那样,如果它适合您,我们可以添加代码以将这些小计提取到某个地方的整洁摘要中并删除小计。你有没有运行它,如果有,需要多长时间?
  • 实际上,使用屏幕左侧生成的 +/1 按钮可能更容易折叠小计列表。单击第二级列中的每个“-”按钮。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 2010-10-25
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多