2014-05-12 82 views
0

我目前正在學習VBA,並試圖理解For Each ... Next語句的語法。如果語法是:Excel VBA - 如何使用For Each ...下一條語句

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

什麼樣的變量可以用於「元素」和「組」,您是否定義它們?我問,因爲我發現的大多數例子都沒有定義「元素」。假設我有一列填滿了「a」,「b」,「c」,「d」和「N/A」,我想確定每個列出現的次數。

到目前爲止,我有以下幾點:

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 

這給「類型不匹配」的錯誤爲If MyCell.Value = "a" Then,雖然我已經知道我必須使用錯誤的組或陣列。

對於這樣一個初學者問題的任何幫助非常感謝。

+0

你確定錯誤不是「變量未定義?」 (假設你在代碼模塊的頂部使用'Option Explicit',你應該*)你確實需要聲明循環變量(在你的情況下爲'MyCell') –

+0

如果'MyCell'包含代碼會引起不匹配錯誤值。 –

+0

你有沒有試過F1的幫助?因爲它在那裏說什麼* element *和* group *可以。 –

回答

10

首先:

說我有一個完整的 「a」 列中, 「b」, 「C」, 「d」 和 「N/A」,我想判定數的時間每個出現在列中。

應該只使用CountIf功能:)

但作爲一個學習鍛鍊...您的代碼提高,因爲在片/單元的「錯誤」值是一個錯誤很可能計數。

您可以修復它像

If Cstr(MyCell.Value) = "a"... 

確保爲其他條件語句做到這一點,也或者你可以這樣做:

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 

爲什麼

因爲MyCell未申報,可能是錯誤類型。您無法對錯誤和字符串進行字符串比較,因此會引發類型不匹配錯誤。您可以使用CStr函數將MyCell.Value作爲字符串進行投射,並且可以避免該錯誤。

有關聲明的變量筆記...

你應該聲明所有的變量,並適當輸入。 VBA不支持多個隱行內聲明,如:

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

這是functionaly等同於:

Dim lastRow 'As Variant 
Dim aCount 'As Variant 
Dim bCount 'As Variant 
Dim cCount 'As Variant 
Dim dCount 'As Variant 
Dim naCount As Long 

這可能不是你期待什麼。相反,這樣做:

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

你也應該聲明所有的變量,總是,包括你的循環迭代器,像MyCell。執行此操作的一種方法是始終將Option Explicit放在模塊的頂部。這會強制變量聲明,因此,如果您在某處存在拼寫錯誤的變量名稱等,則會引發編譯錯誤(這實際上非常常見,所以始終使用Option Explicit!,這將爲您節省大量的頭髮拉動) 。

循環迭代器可以是Variant型的,或者它們必須一個類型,它是迭代的收集/陣列中,例如,匹配:

Dim ws as Worksheet 
For each ws in ThisWorkbook.Worksheets 
    Debug.Print ws.Name 
Next 

或者它們可以是一個長/整數爲索引的集合

Dim w as Integer 
For w = 1 to ThisWorkbook.Worksheets.Count 
    Debug.Print w 
Next 

此外,文檔審覈:

http://msdn.microsoft.com/en-us/library/office/gg264596(v=office.15).aspx

最終你用什麼方法來迭代取決於你想要完成什麼以及你正在使用的數據的結構。

+0

在'For'循環中放置'Dim clVal ...'會引起誤解,因爲它可能暗示它只在循環內部有效。雖然_some_語言會將'clVal'的範圍限制爲'For'循環,但對於VBA,情況並非如此。一旦該行執行一次,該變量將保持有效並可用,直到例程完成。 –

+0

@chrisneilsen一個變量通常可以在VBA子程序中的任意位置聲明,並且這個變量甚至可以在該行的「執行」之前提供,這個簡單的事實是該行不「執行」使用F8確認...)。爲了簡潔起見,我把它放在循環中,但實際上我會把所有的聲明放在模塊的頂部。我只是不想重寫整個事情,並試圖將它解釋爲一個甚至不瞭解VBA基礎知識的人 - 僅僅解釋一個小塊就容易多了。 –

+0

我沒有說你的代碼是_wrong_(不會工作)我說這是因爲給出的原因_missleading_,我堅持這一點。你聲稱一個'Dim'可以去_anywhere_是不正確的。當聲明爲Sub/Function的作用域變量時,它必須在變量被引用之前進行。而且你沒有將_all_變量聲明爲_module_ scope,是嗎? –