'Find Range Based on Interior.ColorIndex - Improve Performance
I've written this code to find squared Range spoted with a back ground color.
My problem is that it thakes 4 or 5 seconds to execute on a large range of 36000 row x 8 columns.
Do you have suggestions to improve and speed the code quoted below ?
Function RegionColoree(cel As Range)
i = 0
ii = 0
j = 0
jj = 0
Set cel = cel.Resize(1, 1)
If Not cel.Interior.ColorIndex = xlNone Then
Do While cel.Offset(i).Interior.ColorIndex <> xlNone 'vers le bas
i = i + 1
Loop
Do While cel.Offset(ii).Interior.ColorIndex <> xlNone 'vers le haut
ii = ii - 1
Loop
Do While cel.Offset(, j).Interior.ColorIndex <> xlNone 'vers la droite
j = j + 1
Loop
Do While cel.Offset(, jj).Interior.ColorIndex <> xlNone 'vers la gauche
jj = jj - 1
Loop
ii = ii + 1
jj = jj + 1
RegionColoree = cel.Offset(ii, jj).Resize(i - ii, j - jj).Address
End If
End Function
Solution 1:[1]
You don't mention whether there could be more than one square range of coloured cells. Assuming there is, and the cell passed into your function is within your desired coloured square range, then you might find the FindFormat function is quicker. The trick would be to find the clear cell limits of your square.
Code would look something like this:
Public Function ColouredCellRange(rng As Range) As Range
Dim r(1) As Long, c(1) As Long
On Error GoTo EH
'Exit if cell isn't coloured.
If rng.Interior.Color = xlNone Then Exit Function
'Set the find format parameters.
With Application.FindFormat
.Clear
.Interior.ColorIndex = xlNone
End With
'Find the left and right columns and top and bottom rows.
With Sheet1.Cells
c(0) = .Find(What:="", After:=rng, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:= _
False, SearchFormat:=True).Column
r(0) = .Find(What:="", After:=rng, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:= _
False, SearchFormat:=True).Row
c(1) = .Find(What:="", After:=rng, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=True).Column
r(1) = .Find(What:="", After:=rng, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=True).Row
End With
With Sheet1
'Test if square is on the edge of the sheet.
If c(0) > rng.Column Then c(0) = 1 Else c(0) = c(0) + 1
If r(0) > rng.Row Then r(0) = 1 Else r(0) = r(0) + 1
If c(1) < rng.Column Then c(1) = .Columns.Count Else c(1) = c(1) - 1
If r(1) < rng.Row Then r(1) = .Rows.Count Else r(1) = r(1) - 1
'Return the square range.
Set ColouredCellRange = .Range(.Cells(r(0), c(0)), .Cells(r(1), c(1)))
End With
Exit Function
EH:
End Function
Solution 2:[2]
Read: Optimize VBA Code for performance improvement. Turning off Application.ScreenUpdating and setting Application.Calculation will greatly improve he speed.
Function RegionColoree(cel As Range)
Dim CalculationMode As XlCalculation
Application.ScreenUpdating = False
CalculationMode = Application.Calculation
Application.Calculation = xlCalculationManual
i = 0
ii = 0
j = 0
jj = 0
Set cel = cel.Resize(1, 1)
If Not cel.Interior.ColorIndex = xlNone Then
Do While cel.Offset(i).Interior.ColorIndex <> xlNone 'vers le bas
i = i + 1
Loop
Do While cel.Offset(ii).Interior.ColorIndex <> xlNone 'vers le haut
ii = ii - 1
Loop
Do While cel.Offset(, j).Interior.ColorIndex <> xlNone 'vers la droite
j = j + 1
Loop
Do While cel.Offset(, jj).Interior.ColorIndex <> xlNone 'vers la gauche
jj = jj - 1
Loop
ii = ii + 1
jj = jj + 1
RegionColoree = cel.Offset(ii, jj).Resize(i - ii, j - jj).Address
End If
Application.Calculation = CalculationMode
End Function
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ambie |
| Solution 2 | TinMan |
