At this moment I have this formula that counts consecutive values:
=IF(AB5=0;0;IF(OR(AND(AB4>=100;AB5>=100);AND(AB4<=-100;AB5<=-100));AC4+1;1))
Basically it does this:
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
But I want it to do this:
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
Or this:
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
What is the formula to make this possible ?
I prefer not to have to add more columns since the file is already big...
Using only a formula to do this would be the best thing to do.
Thanks.
You could try a match formula like this:
=IF(AND(ABS(AB5)>=100,AB4=0),MATCH(0,AB6:AB$1048576,0),0)
EDIT
Clearly this is slow for 1,000,000 cells. The inexact match is faster:
=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))
Discussion
Why is Match so slow when on the face of it, it should be only searching a few cells ahead for a match? I am wondering if it is because Match copies the whole range to be searched to a temporary array? Generally this might be a good strategy, but in the particular case when the matching value is near the beginning of the range and the range is very large, it is a bad one.
One more possible approach would be to determine the longest sequence using Frequency (this is fast), then limit the range to be searched using Index, something like:
=MAX(FREQUENCY(IF(ABS(A:A)>=100,ROW(A:A)),IF(A:A=0,ROW(A:A))))
in B1 then
...MATCH(0,AB6:INDEX(A:A,ROW()+B$1),0)
I don't know how to solve your problem with excel, it could be probably done with some array formula which would drastically slow down your even now slow workbook. Therefore I have written a VBA version.
Before you use it you should carefully change the values of the first three variables to fit your needs.
Put the following code into a module :
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
And then put the following code in the sheet's code window :
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
The code automatically changes the value of the cell in the target column without any formula in the resulting cells what should make it very fast. If this isn't the case, an array version could be written, which would make the code dozens of times faster.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.