First things first:
Say I have a column full of "a", "b", "c", "d" and "N/A", and I want to determine the number of times each appear in the column.
You should just use the CountIf
function :)
But as a learning exercise... Your code is raising an error most likely because of an "Error" value in the sheet/cell being counted.
You could fix it like
If Cstr(MyCell.Value) = "a"...
Make sure to do this for the other conditionals, too, or you could do something like:
For Each myCell In Range("A1:A" & lastRow)
Dim clVal As String
clVal = CStr(myCell)
If clVal = "a" Then
aCount = aCount + 1
ElseIf clVal = "b" Then
bCount = bCount + 1
ElseIf clVal = "c" Then
cCount = cCount + 1
ElseIf clVal = "d" Then
dCount = dCount + 1
ElseIf clVal = "b" Then
bCount = bCount + 1
Else
NACount = NACount + 1
End If
Next
WHY
Because MyCell
is undeclared, it can be an error type. You can't do a string comparison of an error and a string, so that's raising the Type Mismatch error. You can use the CStr
function to cast MyCell.Value
as a string and that can avoid the error.
A note on declaring your variables...
You should declare ALL of your variables and type them appropriately. VBA does not support multiple implicit inline declarations like:
Dim lastRow, aCount, bCount, cCount, dCount, NACount As Long
This is functionaly equivalent to:
Dim lastRow 'As Variant
Dim aCount 'As Variant
Dim bCount 'As Variant
Dim cCount 'As Variant
Dim dCount 'As Variant
Dim naCount As Long
Which is probably not what you were expecting. Instead, do:
Dim lastRow as Long, aCount as Long, bCount as Long, _
cCount as Long, dCount as Long, NACount As Long
You should also declare ALL of your variables, always, including your loop iterators, like MyCell
. One way to enforce this is to always put Option Explicit
at the top of your module. This forces variable declaration, and as such, raises a compile error if you have misspelled variable name somewhere, etc. (this is super-common, actually, so always use Option Explicit!, it will save you a lot of hair-pulling).
Loop iterators can be of type Variant
or they must match a type that is iterable in the collection/array, e.g.:
Dim ws as Worksheet
For each ws in ThisWorkbook.Worksheets
Debug.Print ws.Name
Next
Or they can be a long/integer for an indexed collection
Dim w as Integer
For w = 1 to ThisWorkbook.Worksheets.Count
Debug.Print w
Next
Also, review the documentation:
http://msdn.microsoft.com/en-us/library/office/gg264596(v=office.15).aspx
Ultimately what method you use to iterate depends on what you're trying to accomplish and the structures of the data you're working with.