How can I subtract values from cells while not making them get negative values?
For example.
I have a cell with 100 in a row.
And another with 200 in the next row.
I use a CommandButton to subtract 105 from those rows. However, I want to use the FIFO (First In, First Out) principle and subtract from the cell with 100 first until it reaches 0 and only then, subtract from the one with 200.
This is what I have so far.
Private Sub CommandButton1_Click() 'Guardar Carbonação
Dim LastRow As Long, CR As Long, ws As Worksheet, CR2 As Long, ws2 As Worksheet, ws3 As Worksheet
Set ws = Sheets("Carbonação")
Set ws3 = Sheets("STOCK Sticks")
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row + 1
CR = ws3.Range("A" & Rows.Count).End(xlUp).Row
ws.Range("A" & LastRow).Value = Int((99999999 - 1 + 1) * Rnd + 8) 'ID Carbonação
ws.Range("B" & LastRow).Value = ComboBox1.Text 'Fabricante
ws.Range("C" & LastRow).Value = TextBox25.Text 'Lote Membranas
ws.Range("D" & LastRow).Value = Sheets("STOCK Sticks").Range("A" & CR) 'ID Sticks
ws.Range("E" & LastRow).Value = TextBox2.Text 'Nº Carbonação
ws.Range("F" & LastRow).Value = TextBox3.Text 'Densidade Total / Carbonação
ws.Range("G" & LastRow).Value = TextBox1.Text 'TETRA
ws.Range("H" & LastRow).Value = Format(Now(), "dd/mm/yyyy hh:mm") 'Data / Hora introdução
Set ws2 = Sheets("STOCK Membranas")
CR2 = ws2.Range("A" & Rows.Count).End(xlUp).Row - 1
If ws2.Range("H" & CR2).Value = 0 Then
CR2 = ws2.Range("A" & Rows.Count).End(xlUp).Row
ws2.Range("H" & CR2).Value = ws2.Range("H" & CR2) - 4
ElseIf ws2.Range("H" & CR2).Value > 0 Then
CR2 = ws2.Range("A" & Rows.Count).End(xlUp).Row - 1
ws2.Range("H" & CR2).Value = ws2.Range("H" & CR2) - 4
End If
ComboBox1.Value = Null
TextBox25.Value = Null
TextBox1.Value = Null
TextBox2.Value = Null
TextBox3.Value = Null
End Sub
Whenever you have a problem like this start from the smallest possible example and make it work. E.g., something like this:
Now the idea is to substract a value (let's say 320) from the cell in A1, then the rest from the B1 and etc. At the end you should have something like this:
Now the funny part - work until you do not achieve picture 2 from picture 1. The simplest possible option is with using a variable for substractValue and decrease it with the value of the cell. Once the substractValue becomes 0 exit the for-loop:
Option Explicit
Public Sub SubstractMe()
Dim substractValue As Double
Dim myCell As Range
Range("A1") = 100
Range("A2") = 200
Range("A3") = 300
Range("A4") = 400
substractValue = 320
For Each myCell In Range("A1:A4")
If myCell - substractValue < 0 And substractValue > 0 Then
substractValue = substractValue - myCell
myCell = 0
Else
myCell = myCell - substractValue
Exit For
End If
Next myCell
End Sub
I have three columns, one of them having all the staff list IDs, the second is having Front-Line staff IDs, The third is having the Back-office staff IDs, sometimes we change the task to some of them, to work in the different field, So His Staff ID has to disappear from Front-Line col and appear in Back-Office col instead. and Vice-Versa, and this will be done by selecting some of Column A staff, then it will loop through Col B and remove selection value(If found), then add these selected cells to Col B.
The same when we normalize, we select some staff from Col A, It should remove the staff IDs from Col B and add it to col C
All Staff | Front-line | Back-Office
15348 | 15348 | 15344
15347 | 15347 | 15345
15345 |
15344 |
What I've achieved so far.
Excuse me if my codes looks a little bit complex, that's the only way I know.
Dedicate Button (Dedicating 1st Col staffs to work as Back-office)
Dim found As Boolean
Dim i, j, mycount, dedlist As Integer
Dim firstempty As Long
With Sheets("StaffList")
firstempty = .Range("H" & .Rows.Count).End(xlUp).Row + 1
dedlist = .Range("L" & .Rows.Count).End(xlUp).Row
End With
mycount = firstempty - 1
found = False
Selection.Copy
With Sheets("StaffList")
firstempty = .Range("H" & .Rows.Count).End(xlUp).Row + 1
Cells(firstempty, 8).Select
Cells(firstempty, 8).PasteSpecial Paste:=xlPasteValues
End With
With Sheets("StaffList")
firstempty = .Range("H" & .Rows.Count).End(xlUp).Row + 1
dedlist = .Range("L" & .Rows.Count).End(xlUp).Row
End With
mycount = firstempty - 1
For i = 2 To mycount
For j = 2 To dedlist
With Sheets("StaffList")
If .Range("H" & i).Value = .Range("L" & j).Value Then
found = True
End If
End With
Next j
If found = False Then
dedlist = dedlist + 1
With Sheets("StaffList")
.Range("L" & dedlist).Value = .Range("H" & i).Value
End With
End If
found = False
Next i
' ActiveSheet.Range("$H$1:$H$500").RemoveDuplicates Columns:=1, Header:=xlYes
Range("A1").Select
Normalize Button (Normalizing 2nd Col staffs to get back working as Front-Line)
Dim CompareRange As Variant, x As Variant, y As Variant
Dim rng As Range
Dim found As Boolean
Dim i, j, mycount, dedlist As Integer
Dim firstempty As Long
With Sheets("StaffList")
firstempty = .Range("M" & .Rows.Count).End(xlUp).Row + 1
dedlist = .Range("H" & .Rows.Count).End(xlUp).Row
End With
mycount = firstempty - 1
found = False
Selection.Copy
With Sheets("StaffList")
firstempty = .Range("M" & .Rows.Count).End(xlUp).Row + 1
Cells(firstempty, 13).Select
Cells(firstempty, 13).PasteSpecial Paste:=xlPasteValues
End With
With Sheets("StaffList")
firstempty = .Range("M" & .Rows.Count).End(xlUp).Row + 1
dedlist = .Range("H" & .Rows.Count).End(xlUp).Row
End With
mycount = firstempty - 1
For i = 2 To mycount
For j = 2 To dedlist
With Sheets("StaffList")
If .Range("M" & i).Value = .Range("L" & j).Value Then
.Range("H" & j).Value = ""
End If
End With
Next j
Next i
Range("A1").Select
This is the VBA implementation of the suggestion in comment:
Option Explicit
Public Sub UpdateStaffTasks()
Const FRNT = "Front-line", BACK = "Back-Office"
Dim selRow As Variant, lrSelRow As Long, ws As Worksheet, i As Long, j As Long
Dim usdRng As Variant, lrUsdRng As Long, red As Long, blu As Long
If Selection.Cells.Count = 1 And Selection.Row = 1 Then Exit Sub
Set ws = Selection.Parent
selRow = GetSelRows(Selection): lrSelRow = UBound(selRow): red = RGB(256, 222, 222)
usdRng = ws.UsedRange: lrUsdRng = UBound(usdRng): blu = RGB(222, 222, 256)
For i = 0 To lrSelRow
For j = i + 2 To lrUsdRng
If j = Val(selRow(i)) Then
If Len(usdRng(j, 1)) > 0 And Len(usdRng(j, 2)) > 0 Then
usdRng(j, 2) = IIf(usdRng(j, 2) = FRNT, BACK, FRNT)
With ws.Cells(j, 1).Resize(, 2).Interior
.Color = IIf(usdRng(j, 2) = FRNT, red, blu)
End With
Exit For
End If
End If
Next
Next
Selection.Parent.UsedRange = usdRng
End Sub
Public Function GetSelRows(ByRef selectedRange As Range) As Variant
Dim s As Variant, a As Range, r As Range, result As Variant
If selectedRange.Cells.Count > 1 Then
For Each a In selectedRange.Areas
For Each r In a.Rows
If r.Row > 1 And InStr(s, r.Row) = 0 Then s = s & r.Row & " "
Next
Next
GetSelRows = Split(RTrim$(s)): Exit Function
Else
GetSelRows = Array(selectedRange.Row): Exit Function
End If
End Function
Before and After:
Can anybody please help me figure out my problem?
I have this code that I would like to move to the next column if the condition is not met.I'm stuck and don't know where to proceed.
Dim lrow3, lrow1 as long
dim dDate as Date
dim yrNum, j as Integer
dDate = Format(Now(),"mm/dd/yyyy")
lrow3 = ActiveSheet.Cells(Rows.count, 2).End(xlUp).Row
lrow1 = Sheets("Sample").Cells(Rows.count, 2).End(xlUp).Row
for j = 2 to lrow1
For yrNum = 1 To 100
If DateValue(Format(Range("Q" & j).Value, "mm/dd/yyyy")) >= DateValue(dDate) And _
DateValue(Format(Range("R" & j).Value, "mm/dd/yyyy")) <= DateValue(dDate) Then
ActiveSheet.Range("D" & lrow3 + 1).Value = Range("T" & j).Value
ActiveSheet.Range("E" & lrow3 + 1).Value = Range("U" & j).Value
Exit For
Else
Range("Q" & j) = ActiveCell
Range("Q" & j) = ActiveCell.Offset(0, 9)
'after executing this is I have to set this offsetted cell to be the active one
'on which i will be referring in the next loop
End If
Next yrNum
next j
In the snippet, if the value in Q & j does not met the requirements, then i have to check the 9th letter after Q which is Z and so on.
By the way what I'm comparing on this are date values in the cell.
A few observations
dDate = Format(Now(),"mm/dd/yyyy") is the same as dDate = Date
DateValue(Format(Range("Q" & j).Value, "mm/dd/yyyy")) is the same asDateValue(Range("Q" & j).Value)`
You are starting in column Q and if the conditions are not meet you move over 9 columns and check again. You do this 100 times. The final column is column 917(column letter code AIG)
Sub RefactoredCode()
Dim lrow3, lrow1 As Long
Dim DateRange As Range
Dim wsSample As Worksheet
Dim yrNum, j As Integer, iOffset As Integer
Set wsSample = Worksheets("Sample")
lrow3 = Cells(Rows.Count, 2).End(xlUp).Row
lrow1 = wsSample.Cells(Rows.Count, 2).End(xlUp).Row
For j = 2 To lrow1
For yrNum = 1 To 100
iOffset = (yrNum * 9) - 9
Set DateRange = wsSample.Cells(j, "Q").Offset(0, iOffset)
If DateValue(DateRange.Value) >= Date And _
DateValue(DateRange.Offset(0, 1).Value) <= Date Then
lrow3 = lrow3 + 1
Range("D" & lrow3).Value = wsSample.Cells(j, "T").Offset(0, iOffset).Value
Range("E" & lrow3).Value = wsSample.Cells(j, "U").Offset(0, iOffset).Value
Exit For
End If
Next yrNum
Next j
End Sub
I have a calendar bar in a document that has the same layout as the image. The calendar is copied from Power Pivot, but I want to calculate the quarter, half year and year cells using formulas. I want to create these formulas using VBA. Is there any clever way to do this?
The calendar can start and end on any month and year. The quarters, half years and years are not always complete, meaning the full 3, 6 or 12 months are not always included in the calendar.
My best idea is to loop over all columns three times. The first time, building up a SUM formula month by month until landing on a year column and then writing the formula to that column. The next time, doing in the same for half-year columns. The third time, doing the same for quarter columns. But that seems too complicated to do something this simple.
You only need to run the loop once, as is in the code below. I've had a guess at the functions and variables that you haven't included in the code so here's the whole module:
Option Explicit
Private Enum CellType
Unknown
Month
Quarter
Half
Year
End Enum
Private Const YEAR_ROW As Long = 1
Private Const HALF_ROW As Long = 2
Private Const QUARTER_ROW As Long = 3
Private Const MONTH_ROW As Long = 4
Private Const FIRST_VALUE_ROW As Long = 5
Private mWS As Worksheet
Private mRowCount As Long
Sub RunMe()
Dim ws As Worksheet
Dim lastCol As Long
Dim c As Long
Dim quarterRange As Range
Dim halfRange As Range
Dim yearRange As Range
Set mWS = ThisWorkbook.Worksheets("Sheet1") '~~> amend as necessary
mRowCount = mWS.Cells.Find(What:="*", _
After:=mWS.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row - FIRST_VALUE_ROW
lastCol = mWS.Cells(YEAR_ROW, mWS.Columns.Count).End(xlToLeft).Column
For c = 1 To lastCol
Select Case GetCellType(c)
Case CellType.Month
Set quarterRange = Unionised(quarterRange, c)
Case CellType.Quarter
Set halfRange = Unionised(halfRange, c)
Set quarterRange = FilledAndCleared(quarterRange, c)
Case CellType.Half
Set yearRange = Unionised(yearRange, c)
Set halfRange = FilledAndCleared(halfRange, c)
Case CellType.Year
Set yearRange = FilledAndCleared(yearRange, c)
End Select
Next
End Sub
Private Function GetCellType(c As Long) As CellType
Dim content As String
If Len(CStr(mWS.Cells(MONTH_ROW, c).Value2)) > 0 Then GetCellType = CellType.Month: Exit Function
If InStr(CStr(mWS.Cells(QUARTER_ROW, c).Value2), "Total") > 0 Then GetCellType = CellType.Quarter: Exit Function
If InStr(CStr(mWS.Cells(HALF_ROW, c).Value2), "Total") > 0 Then GetCellType = CellType.Half: Exit Function
If InStr(CStr(mWS.Cells(YEAR_ROW, c).Value2), "Total") > 0 Then GetCellType = CellType.Year: Exit Function
GetCellType = CellType.Unknown
End Function
Private Function Unionised(oldRng As Range, c As Long) As Range
If oldRng Is Nothing Then
Set Unionised = mWS.Cells(FIRST_VALUE_ROW, c)
Else
Set Unionised = Union(oldRng, mWS.Cells(FIRST_VALUE_ROW, c))
End If
End Function
Private Function FilledAndCleared(rng As Range, c As Long) As Range
Dim i As Long
For i = 0 To mRowCount
rng.Worksheet.Cells(FIRST_VALUE_ROW + i, c).Formula = "=SUM(" & rng.Offset(i).Address(False, False) & ")"
Next
Set FilledAndCleared = Nothing
End Function
This is how I solved it. I would welcome a significantly simpler solution.
'Year
sFormula = ""
For c = 6 To LastColumn(wksTarget)
If wksTarget.Cells(lMonthsRow, c) <> "" Then
sFormula = sFormula & "+" & wksTarget.Cells(lFirstItemRow, c).Address(RowAbsolute:=False, ColumnAbsolute:=False)
End If
If wksTarget.Cells(lMonthsRow, c) = "" And InStr(1, wksTarget.Cells(lYearsRow, c), "Total") Then
wksTarget.Range(wksTarget.Cells(lFirstItemRow, c), wksTarget.Cells(LastRow(wksTarget), c)) = "=" & sFormula
Call FormatAsTotal(wksTarget.Range(wksTarget.Cells(lFirstItemRow, c), wksTarget.Cells(LastRow(wksTarget), c)))
sFormula = ""
End If
Next
'Half year
sFormula = ""
For c = 6 To LastColumn(wksTarget)
If wksTarget.Cells(lMonthsRow, c) <> "" Then
sFormula = sFormula & "+" & wksTarget.Cells(lFirstItemRow, c).Address(RowAbsolute:=False, ColumnAbsolute:=False)
End If
If wksTarget.Cells(lMonthsRow, c) = "" And InStr(1, wksTarget.Cells(lHalfYearsRow, c), "Total") Then
wksTarget.Range(wksTarget.Cells(lFirstItemRow, c), wksTarget.Cells(LastRow(wksTarget), c)) = "=" & sFormula
Call FormatAsSubtotal(wksTarget.Range(wksTarget.Cells(lFirstItemRow, c), wksTarget.Cells(LastRow(wksTarget), c)))
sFormula = ""
End If
Next
'Quarter
sFormula = ""
For c = 6 To LastColumn(wksTarget)
If wksTarget.Cells(lMonthsRow, c) <> "" Then
sFormula = sFormula & "+" & wksTarget.Cells(lFirstItemRow, c).Address(RowAbsolute:=False, ColumnAbsolute:=False)
End If
If wksTarget.Cells(lMonthsRow, c) = "" And InStr(1, wksTarget.Cells(lQuartersRow, c), "Total") Then
wksTarget.Range(wksTarget.Cells(lFirstItemRow, c), wksTarget.Cells(LastRow(wksTarget), c)) = "=" & sFormula
Call FormatAsSubtotal(wksTarget.Range(wksTarget.Cells(lFirstItemRow, c), wksTarget.Cells(LastRow(wksTarget), c)))
sFormula = ""
End If
Next
My answer will work if the Months and Sums are set according to the image below (which I got from your image).
Sub SomeSub()
Dim r As Long
Dim LastRow As Long
With ActiveSheet.UsedRange
'Getting the last Row of the used range
LastRow = .Rows(.Rows.Count).Row - 1
End With
'Loop for the rows of data
For r = 5 To LastRow
'Quarter Calculation
'Quarter 1
Range("D" & r).Value = Application.WorksheetFunction.Sum(Range("A" & r), Range("B" & r), Range("C" & r))
'Quarter 2
Range("H" & r).Value = Application.WorksheetFunction.Sum(Range("E" & r), Range("F" & r), Range("G" & r))
'Quarter 3
Range("Q" & r).Value = Application.WorksheetFunction.Sum(Range("J" & r), Range("K" & r), Range("K" & r))
'Quarter 4
Range("M" & r).Value = Application.WorksheetFunction.Sum(Range("N" & r), Range("O" & r), Range("P" & r))
'Bi Annual Calculation
'First 6 Months
Range("I" & r).Value = Application.WorksheetFunction.Sum(Range("A" & r), Range("B" & r), Range("C" & r), _
Range("E" & r), Range("F" & r), Range("G" & r))
'Second 6 Months
Range("R" & r).Value = Application.WorksheetFunction.Sum(Range("J" & r), Range("K" & r), Range("K" & r), _
Range("N" & r), Range("O" & r), Range("P" & r))
'Year Calculation
Range("S" & r).Value = Application.WorksheetFunction.Sum(Range("A" & r), Range("B" & r), Range("C" & r), _
Range("E" & r), Range("F" & r), Range("G" & r), _
Range("J" & r), Range("K" & r), Range("K" & r), _
Range("N" & r), Range("O" & r), Range("P" & r))
Next
End Sub
EDIT
Considering the OP comment that the Quarters may not always have 3 months, first the Quarter Ranges need to be determined.
See new script below:
Sub SomeOtherSub()
Dim YrStart As Long, YrEnd As Long
Dim H1Start As Long, H1End As Long
Dim H2Start As Long, H2End As Long
Dim Q1Start As Long, Q1End As Long, Q1T As Long
Dim Q2Start As Long, Q2End As Long, Q2T As Long
Dim Q3Start As Long, Q3End As Long, Q3T As Long
Dim Q4Start As Long, Q4End As Long, Q4T As Long
Dim LastRow As Long
Dim col As Long
With ActiveSheet.UsedRange
'Getting the last Colunm of the used range
LastColumn = .Columns(.Columns.Count).Column
End With
'InStr() = 0 means that the text is not included in the string
'InStr() > 0 means that the text is included in the string
'Getting the Ranges for each Quarter
For col = 1 To LastColumn
aa = Cells(3, col)
If InStr(aa, "Q1") > 0 And InStr(aa, "Total") = 0 Then Q1Start = col
If InStr(aa, "Q1") > 0 And InStr(aa, "Total") > 0 Then
Q1End = col - 1 ' -1 for the end of the data for the quarter
Q1T = col
End If
If InStr(aa, "Q2") > 0 And InStr(aa, "Total") = 0 Then Q2Start = col
If InStr(aa, "Q2") > 0 And InStr(aa, "Total") > 0 Then
Q2End = col ' -1 for the end of the data for the quarter
Q2T = col
End If
If InStr(aa, "Q3") > 0 And InStr(aa, "Total") = 0 Then Q3Start = col
If InStr(aa, "Q3") > 0 And InStr(aa, "Total") > 0 Then
Q3End = col - 1 ' -1 for the end of the data for the quarter
Q3T = col
End If
If InStr(aa, "Q4") > 0 And InStr(aa, "Total") = 0 Then Q4Start = col
If InStr(aa, "Q4") > 0 And InStr(aa, "Total") > 0 Then
Q4End = col - 1 ' -1 for the end of the data for the quarter
Q4T = col
End If
Next
'Getting the Ranges for each Bi Annual
For col = 1 To LastColumn
aa = Cells(2, col)
If InStr(aa, "H1") > 0 And InStr(aa, "Total") = 0 Then H1Start = col
If InStr(aa, "H1") > 0 And InStr(aa, "Total") > 0 Then H1T = col
If InStr(aa, "H2") > 0 And InStr(aa, "Total") = 0 Then H2Start = col
If InStr(aa, "H2") > 0 And InStr(aa, "Total") > 0 Then H2T = col
Next
'Getting the Ranges for the year
For col = 1 To LastColumn
aa = Cells(1, col)
If Len(aa) > 0 And InStr(aa, "Total") = 0 Then YrStart = col
If Len(aa) > 0 And InStr(aa, "Total") > 0 Then YrT = col
Next
With ActiveSheet.UsedRange
'Getting the last Row of the used range
LastRow = .Rows(.Rows.Count).Row - 1
End With
'Loop for the rows of data
For r = 5 To LastRow
'Quarter Calculation
'Quarter 1
Cells(r, Q1T).Value = Application.WorksheetFunction.Sum(Range(Cells(r, Q1Start), Cells(r, Q1End)))
'Quarter 2
Cells(r, Q2T).Value = Application.WorksheetFunction.Sum(Range(Cells(r, Q2Start), Cells(r, Q2End)))
'Quarter 3
Cells(r, Q3T).Value = Application.WorksheetFunction.Sum(Range(Cells(r, Q3Start), Cells(r, Q3End)))
'Quarter 4
Cells(r, Q4T).Value = Application.WorksheetFunction.Sum(Range(Cells(r, Q4Start), Cells(r, Q4End)))
'Bi Annual Calculation
'First 6 Months
Cells(r, H1T).Value = Application.WorksheetFunction.Sum(Cells(r, Q1T), Cells(r, Q2T))
'Second 6 Months
Cells(r, H2T).Value = Application.WorksheetFunction.Sum(Cells(r, Q3T), Cells(r, Q4T))
'Year Calculation
Cells(r, YrT).Value = Application.WorksheetFunction.Sum(Cells(r, H1T), Cells(r, H2T))
Next
End Sub
I have big data file on excel, the file has 6930 rows and 8 columns,
the 8 column has percents (0%, 4%, 16%, 18%, 19% and etc..)
I tried to do a macro that paint all the rows that the percent in them are bigger then 18%, and it doesn't work.
The file start from row 3, so rows 1 and 2 are empty
The macro:
Sub Test_4
Dim i As Long
Dim countErr As Long
countErr = 0
i = 2
Do While Cells(i, 1) = ""
If Cells(i, 8).Value > 0.18 And IsNumeric(Cells(i, 8)) Then
Range(Cells(i, 1), Cells(i, 8)).Interior.ColorIndex = 3
countErr = countErr + 1
End If
i = i + 1
Loop
If countErr > 0 Then
Sheets("test").Select
Range("E8").Select
Selection.Interior.ColorIndex = 3
Range("D8").Select
Selection.FormulaR1C1 = countErr
Else
Sheets("test").Select
Range("E8").Select
Selection.Interior.ColorIndex = 4
Sheets("test").Range("d8") = "0"
End If
End Sub
A Do While loop might be a bad idea if Column H ever has a blank value part way down, instead you could do this (This will add conditional formatting to each line):
Given this input:
Sub testit()
Dim LastRow As Long, CurRow As Long, countErr As Long
LastRow = Range("H" & Rows.Count).End(xlUp).Row
Cells.FormatConditions.Delete
With Range("A3:H" & LastRow)
.FormatConditions.Add Type:=xlExpression, Formula1:="=$H3>0.18"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
.FormatConditions(1).Interior.ColorIndex = 3
.FormatConditions(1).StopIfTrue = False
End With
countErr = 0
Dim cel As Range
For Each cel In Sheets("NAME OF SHEET").Range("H3:H" & LastRow)
If cel.Value > 0.18 Then
countErr = countErr + 1
End If
Next cel
MsgBox "There are " & countErr & " rows greater than 18%"
End Sub
Running the code gives:
Error Testing:
Sub ErrorTesting()
Dim cel As Range, countErr As Long
countErr = 0
LastRow = Range("H" & Rows.Count).End(xlUp).Row
For Each cel In Range("H3:H" & LastRow)
On Error GoTo ErrHandle
If Not IsNumeric(cel.Value) Then
MsgBox cel.Address & " is the address of the non-numeric Cell"
End If
If cel.Value > 0.18 And IsNumeric(cel.Value) Then
countErr = countErr + 1
End If
Next cel
ErrHandle:
If Not cel Is Nothing Then
MsgBox cel.Address & " is the address and " & cel.Value & " is the value of the Error Cell"
End If
MsgBox countErr
End Sub
Try this (updated for error count):
Sub test()
Count = 0
i = 2
While Not IsEmpty(Cells(i, 8))
If Cells(i, 8).Value > 0.18 Then
Range(Cells(i, 1), Cells(i, 8)).Interior.ColorIndex = 3
Count = Count + 1
End If
i = i + 1
Wend
//rows count bigger than 18% in worksheet "test"
Worksheets("test").Cells(1, 1).Value = "Rows count bigger than 18%"
Worksheets("test").Cells(1, 2).Value = Count
End Sub