• ベストアンサー

VBAのcountif

ここで質問させていただき、配列に必要なデータを入力する所までは出来ました。 次に各行ごとの"OK"の数をカウントしたいのですが、どのように記述すればよいのでしょうか? Sub count0(a, b, c, d, e)  Dim i1 As Long  Dim i2 As Long  Dim A1 As String  Dim bb As Variant  Dim cc As Variant  Dim dd As Variant  Dim ee As Variant  Dim myLastRow As Long  Sheets(a).Select  myLastRow = Cells(Rows.Count, 1).End(xlUp).Row + 1  bb = Range(b).Resize(myLastRow, 6)  cc = Range(c).Resize(myLastRow, 6)  dd = Range(d).Resize(myLastRow, 6)  ee = Range(e).Resize(myLastRow)  For i1 = 1 To myLastRow   For i2 = 1 To 6    If bb(i1, i2) = "" Then      A1 = "NG"     ElseIf bb(i1, i2) = "A1" Or cc(i1, i2) = "A1" Then      A1 = "-"     ElseIf bb(i1, i2) = cc(i1, i2) Then      A1 = "OK"     Else      A1 = "NG"    End If    dd(i1, i2) = A1   Next i2 '配列をカウントするこの行以降の記述が良く分かりません。   ee(i1) = Application.WorksheetFunction.CountIf(dd(), "OK")  Next i1  Range(e).Resize(myLastRow) = ee End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • ka_na_de
  • ベストアンサー率56% (162/286)
回答No.3

質問のコードをもとに作りました。 Sub count0(a, b, c, d, e)  Dim i1 As Long  Dim i2 As Long  Dim A1 As String  Dim bb As Variant  Dim cc As Variant  Dim dd As Variant  Dim ee As Variant  Dim myLastRow As Long  Dim ctOK As Long    Sheets(a).Select  myLastRow = Cells(Rows.Count, 1).End(xlUp).Row + 1  bb = Range(b).Resize(myLastRow, 6)  cc = Range(c).Resize(myLastRow, 6)  dd = Range(d).Resize(myLastRow, 6)  ee = Range(e).Resize(myLastRow)    For i1 = 1 To myLastRow   ctOK = 0   For i2 = 1 To 6    If bb(i1, i2) = "" Then     A1 = "NG"    ElseIf bb(i1, i2) = "A1" Or cc(i1, i2) = "A1" Then     A1 = "-"    ElseIf bb(i1, i2) = cc(i1, i2) Then     A1 = "OK"     ctOK = ctOK + 1    Else     A1 = "NG"    End If    dd(i1, i2) = A1   Next i2   ee(i1, 1) = ctOK  Next i1  Range(d).Resize(myLastRow, 6) = dd  Range(e).Resize(myLastRow) = ee End Sub 余談ですが、違和感を感じる点を挙げておきます。 1) 最終行という名の変数名に、最終行番号に1を加えた値が代入されている。 2)セルに出現するA1という文字列と同じ名前の変数名A1を使っている。

t_t1112
質問者

お礼

ありがとうございます。 ご指摘頂いた点について修正いたしました。 問題なく期待した結果を得ることが出来ました。

その他の回答 (2)

  • keithin
  • ベストアンサー率66% (5278/7941)
回答No.2

ん? セルに書き込む・セルから読み出すのを避けたくて配列を使っているのではないのですか? あなたが既に書かれたマクロのように 例: For i1 = 1 To myLastRow   For i2 = 1 To 6    If dd(i1, i2) = "OK" Then      Ans = Ans + 1 のようにして,逐一セルを読んだり書いたりをしないで,メモリの中に格納した配列の値の計算だけで高速化を図っているのがあなたが今やっていることです。 >ド素人が どういうのがご希望なんでしょうか。 こちらの掲示板などは「素人です」を前面に免罪符にして実は丸投げ依頼をしてもあんまり怒る人はいないみたいですが,他の掲示板なんかでは,ぼこぼこに叩かれちゃう所も少なくありませんね。 自分に説明力が無くて何でもかんでも貰うばっかりでまかり通るにしても,「VBE画面の開き方」「標準モジュールを挿入します」から教えて貰わないと何も出来ないでは話しも前に進みませんし,それだけサンプルマクロを動かしておいて今さらド素人を自称してもナニ甘えてるんですかみたいにスルーされるのがオチかなといった印象を持たれる方が多いんじゃないでしょうか。 でも大概の場合において, 1.プログラムで判らない言葉が出てきたら,F1キーを押したりオブジェクトブラウザで調べてVBAのヘルプを読む 2.新しいマクロの記録で記録させたマクロを読む 3.書いたプログラムをデバッグできる手順を教わっておく の三点は,どこのサイトで勉強するにも出来てて当たり前,出来てない人は素人の入口にも立ってないと見なされます。

t_t1112
質問者

お礼

ありがとうございました。 サンプルで頂いた内容でクリアできました。 ご気分を害し申し訳ありません。 関数は使えたので、なんとなくサンプルコードは読めましたが、 様々なサイトを拝見しても、VBAの概念が今ひとつ理解できませんでした。 もし基本的な概念を分かりやすいサイトがあればご紹介頂きたかったのです。

  • keithin
  • ベストアンサー率66% (5278/7941)
回答No.1

そこに配列を入れることはできません。 Countifを利用するなら,セル範囲(たとえばdd)のセルに直接A1等を記入し, application.countif(range(d).resize( ),"OK") などのようになります。 メモリの中でfor nextをもう一回2重回しして,配列ddの要素を逐一"OK"と等しいか調べても勿論数えられます。 もっと言うなら,現在の二重のfor nextループの中でOKの回数を数え上げていった方が簡単そうにも思われます。

t_t1112
質問者

補足

早速のご回答ありがとうございます。 >メモリの中でfor nextをもう一回2重回しして,配列ddの要素を逐一"OK"と等しいか調べても勿論数えられます。 何から何までで恐縮ですが、メモリの中で数え上げるにはどのようにしたら良いのでしょうか? また、ど素人が参考にすると良いサイトなどももしあればご紹介頂けないでしょうか?

関連するQ&A

専門家に質問してみよう