Pregunta

I'm currently learning VBA by doing, and I'm trying to understand the syntax of the For Each...Next statement. If the syntax is:

For Each element In group
[statements]
[Exit For]
[statements]
Next [element]

What sort of variables can you use for "element" and "group", and do you define them? I ask because most of the examples I've found for the function don't define "element".

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.

So far I have the following:

Sub Count()

Dim lastRow, aCount, bCount, cCount, dCount, NACount As Long

lastRow = Range("A" & Rows.Count).End(xlUp).Row
aCount = 0
bCount = 0
cCount = 0
dCount = 0
NACount = 0

For Each MyCell In Range("A1:A" & lastRow)
    If MyCell.Value = "a" Then
        aCount = aCount + 1
    ElseIf MyCell.Value = "b" Then
        bCount = bCount + 1
    ElseIf MyCell.Value = "c" Then
        cCount = cCount + 1
    ElseIf MyCell.Value = "d" Then
        dCount = dCount + 1
    ElseIf MyCell.Value = "b" Then
        bCount = bCount + 1
    Else
        NACount = NACount + 1
    End If
Next

End Sub

This give a "Type mismatch" error for If MyCell.Value = "a" Then, though I already know that I must be using a wrong group or array.

Any help for such a beginner issue is greatly appreciated.

¿Fue útil?

Solución

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top