簡體   English   中英

如何計算Excel中的連續值?

[英]How to count consecutive values in Excel?

此時我有這個計算連續值的公式:

=IF(AB5=0;0;IF(OR(AND(AB4>=100;AB5>=100);AND(AB4<=-100;AB5<=-100));AC4+1;1))

基本上這樣做:

0           0
0           0
-110        1
-110        2
-110        3
-100        4
0           0
0           0
0           0
130         1
150         2
0           0
0           0
-100        1
0           0
0           0
0           0
0           0
-110        1
0           0
0           0
0           0
-220        1
-150        2
0           0
0           0

但我希望它能做到這一點:

0           0
0           0
-110        0
-110        0
-110        0
-100        4
0           0
0           0
0           0
130         0
150         2
0           0
0           0
-100        1
0           0
0           0
0           0
0           0
-110        1
0           0
0           0
0           0
-220        0
-150        2
0           0
0           0

或這個:

0           0
0           0
-110        4
-110        0
-110        0
-100        0
0           0
0           0
0           0
130         2
150         0
0           0
0           0
-100        1
0           0
0           0
0           0
0           0
-110        1
0           0
0           0
0           0
-220        2
-150        0
0           0
0           0

使這成為可能的公式是什么?

我不想添加更多列,因為文件已經很大...

僅使用公式來做這件事是最好的事情。

謝謝。

您可以嘗試這樣的匹配公式:

=IF(AND(ABS(AB5)>=100,AB4=0),MATCH(0,AB6:AB$1048576,0),0)

編輯

顯然,1,000,000個細胞的速度很慢。 不精確的匹配更快:

=IF(AND(AB5>=100,AB4=0),MATCH(0,AB6:AB$1048576,-1),IF(AND(AB5<=-100,AB4=0),MATCH(-100,AB5:AB$1048576,1),0))

在此輸入圖像描述

討論

為什么Match在表面上這么慢,它應該只搜索前面幾個單元格來匹配? 我想知道是否因為Match將要搜索的整個范圍復制到臨時數組? 通常這可能是一個很好的策略,但在特定情況下,當匹配值接近范圍的開頭並且范圍非常大時,它是一個糟糕的策略。

另一種可能的方法是使用頻率確定最長的序列(這很快),然后使用索引來限制要搜索的范圍,例如:

=MAX(FREQUENCY(IF(ABS(A:A)>=100,ROW(A:A)),IF(A:A=0,ROW(A:A))))

然后在B1

...MATCH(0,AB6:INDEX(A:A,ROW()+B$1),0)

連續計數版本1

我不知道如何用excel解決你的問題,它可能是用一些數組公式來完成的,這會大大減慢你現在速度很慢的工作簿。 因此我寫了一個VBA版本。
在使用它之前,您應該仔細更改前三個變量的值以滿足您的需要。
將以下代碼放入模塊中

Option Explicit
'-- Customize BEGIN --------------------

  'Read data from this column, and write to the next, e.g.
  'The AB column is column 28: Read from 28 and write to 29
  Public Const ciCol As Integer = 6

  'The first row of data
  Public Const cLoFirstRow As Long = 5

  'cLoRow is an approximate value e.g. you have 200 rows of data and you
  'estimate that you won't have more than a 1000 in a year, than 1000 is enough,
  'if you have a million then put in a million. The smaller this number the
  'faster the code.
  Public Const cLoRow As Long = 1000
'-- Customize END ----------------------

Sub ConsecutiveCounting1()
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'-- Customize BEGIN --------------------
  'The Abs function eliminates the need for a negative value variable.
  Const cLoLimit As Long = 100
'-- Customize END ----------------------
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  Dim oRng As Range
  Dim loLastRow As Long
  Dim loTemp As Long
  Dim loF1 As Long 'Row Counter
  loLastRow = Cells(Rows.Count, ciCol).End(xlUp).Row
  Set oRng = Range(Cells(cLoFirstRow, ciCol), Cells(loLastRow, ciCol))
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  loTemp = 0
  For loF1 = 1 To oRng.Rows.Count
    If loF1 <> oRng.Rows.Count Then
      If Abs(oRng(loF1, 1)) >= cLoLimit Then
        loTemp = loTemp + 1
        If Abs(oRng(loF1 + 1, 1)) >= cLoLimit Then
          oRng(loF1, 2) = 0
         Else
          oRng(loF1, 2) = loTemp
          loTemp = 0
        End If
       Else
        oRng(loF1, 2) = 0
      End If
     Else 'Last Value
      If Abs(oRng(loF1, 1)) >= cLoLimit Then
        loTemp = loTemp + 1
        oRng(loF1, 2) = loTemp
       Else
        oRng(loF1, 2) = 0
      End If
    End If
  Next
End Sub

然后將以下代碼放在工作表的代碼窗口中

Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
  Dim ColumnNumber As Long
  Dim RowNumber As Long
    ColumnNumber = Target.Column
    RowNumber = Target.Row
    If ColumnNumber <> ciCol Then Exit Sub
    If RowNumber > cLoRow Then Exit Sub
  ConsecutiveCounting1
End Sub

代碼會自動更改目標列中單元格的值,而在結果單元格中沒有任何公式應該使它非常快。 如果不是這種情況,可以編寫一個數組版本,這將使代碼速度提高幾十倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM