Option Explicit
Sub Locals_New_Array()
Dim rngCrit As Range
Dim strOp As String
Dim lngRow As Long
Dim lastrow As Long
Dim lasttrue_row As Long
Dim t As Single, start_row As Long
Dim g_array(), m_array(), o_array(), qrs_array()
Dim index1 As Long, index2 As Long
Set rngCrit = Application.InputBox("Select Cell", "Select", , Type:=8)
If rngCrit.Cells.Count > 1 Or rngCrit.Row - 2 < 2 Or rngCrit.Column <> 7 Then ' Column "G" is "7"
MsgBox "No Valid Single Cell Selected - Routine Terminated", vbCritical, "Error"
Exit Sub
End If
Application.ScreenUpdating = False
t = Timer
With Worksheets("Random")
lastrow = .Cells(.Rows.Count, "G").End(xlUp).Row
start_row = rngCrit.Row
' ERASE WORKSHEET VALUES
' This command erases values in column Q,R & S
Range(.Cells(2, "Q"), .Cells(lastrow, "S")).ClearContents
' This command erases values in column M
Range(.Cells(2, "M"), .Cells(lastrow, "M")).ClearContents
' This command erases values in column O
Range(.Cells(2, "O"), .Cells(lastrow, "O")).ClearContents
' INITIALISE INPUT ARRAY AND QRS_ARRAY
g_array = Range(rngCrit, .Cells(lastrow, "G"))
ReDim qrs_array(1 To lastrow - start_row + 1, 1 To 3)
For index1 = 1 To UBound(g_array)
' This command erases values in M & O
ReDim m_array(1 To (lastrow - rngCrit.Row) + 1, 1 To 1): ReDim o_array(1 To (lastrow - rngCrit.Row) + 1, 1 To 1)
' This command sets the initial value of strOp to < or > based on
' the comparison of the starting cell and the next cell
If index1 = UBound(g_array) Then
strOp = ">"
Else
strOp = IIf(g_array(index1 + 1, 1) > g_array(index1, 1), "<", ">")
End If
' This Loops from the Selected Row to the Last Row.
' It extracts the Break point to "M" and
' the Time Differences between break points to "O"
lasttrue_row = index1
index2 = index1 + 2
' Loop through the data
For index2 = index2 To UBound(g_array)
' Find a True, (or run out of data)
Do Until index2 > UBound(g_array)
If Evaluate(g_array(index2, 1) & strOp & g_array(index1, 1)) Then Exit Do
index2 = index2 + 1
Loop
If index2 <= UBound(g_array) Then
' We have a 'TRUE'
' Copy the value to M
m_array(index2, 1) = g_array(index2, 1)
' Time difference to O
o_array(index2, 1) = .Cells(start_row + index2 - 1, "A").Value - .Cells(start_row + lasttrue_row - 1, "A").Value
' We have a value in M, so toggle comparison
strOp = IIf(strOp = ">", "<", ">")
' Record this row as the last 'true row' for timings
lasttrue_row = index2
Else
' ran out of data
Exit For
End If
' Uncomment block below for 3 minute time check
' If Timer - t >= 180 Then
' MsgBox "3 minutes are up, done " & index1 & " rows"
' Exit Sub
' End If
Next
' For each set of Break points for which the Time Difference has been calculated
' in column "O" the Average, STDEV and the Max values are calculated in
' columns "Q", "R" and "S"
' In some instances there will not be enough data to run the functions
On Error Resume Next
Application.DisplayAlerts = False
qrs_array(index1, 1) = Application.WorksheetFunction.Average(Application.Index(o_array, 0, 1))
qrs_array(index1, 2) = Application.WorksheetFunction.StDev(Application.Index(o_array, 0, 1))
qrs_array(index1, 3) = Application.WorksheetFunction.Max(Application.Index(o_array, 0, 1))
Application.DisplayAlerts = False
On Error GoTo 0
Next
' Copy the data to the sheet
Range(.Cells(start_row, "Q"), .Cells(lastrow, "S")) = qrs_array
End With
MsgBox "Duration: " & Format(Timer - t, "00.00") & " seconds"
Application.ScreenUpdating = True
End Sub
Bookmarks