- ベストアンサー
VBAコードでセルのデータ数を取得する方法
- VBAコードを使用して、指定した条件に基づいてセルのデータ数を取得する方法について教えてください。
- 具体的には、A列のデータから1を探し、その1つ前と2つ前のB列の値をC列とD列に出力する方法です。
- また、出力されるデータの数を知りたい場合、どのようにすればいいのかも教えていただきたいです。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
先ほどのNo.2の回答、間違えてしまいました。 (D列のデータを行番号にしてテストしていたので・・・) 申し訳ありませんがNo.2は無視してこちらをご覧ください。 では以下回答を書き直します。 「A1から最初の1の2つ前(A?)のデータ数もカウントにいれる」というところですが、申し訳ありませんがよくわかりません。 まず、最初の1というのは、 ElseIf Cells(i, 2) = 1 And flg = True Then の条件式が最初に成り立つこととなった1のことでしょうか? (ここまで同じです) 次に、カウントに入れるというのは、Cells(j - 1, 7)に加算するのでしょうか? もしそうであれば、たとえば以下のようになります。 (こなれていないコードで申し訳ありません) しかしこれでは質問者様の意図を理解できていないような気がするのです。 Sub test2() Dim i As Long, j As Long, flg As Boolean Dim i1 As Long, i2 As Long j = 1 For i = 2 To Cells(Rows.Count, 2).End(xlUp).Row If Cells(i, 2) = 0 Then flg = True ElseIf Cells(i, 2) = 1 And flg = True Then i1 = i i2 = i - 2 Cells(j, 5) = Cells(i - 1, 4) Cells(j, 6) = Cells(i - 2, 4) flg = False Exit For Else: flg = False End If Next For i = i To Cells(Rows.Count, 2).End(xlUp).Row If Cells(i, 2) = 0 Then flg = True ElseIf Cells(i, 2) = 1 And flg = True Then j = j + 1 Cells(j - 1, 7) = i - i1 - 2 + i2 i1 = i Cells(j, 5) = Cells(i - 1, 4) Cells(j, 6) = Cells(i - 2, 4) flg = False Else: flg = False End If Next End Sub
その他の回答 (4)
- queuerev2
- ベストアンサー率78% (96/122)
Cells(1,7)にしてもうまく実行されない理由は、ここでいったんA1からのデータ数がG1に出力されるものの、あとでE1とF2の間のデータ数で上書きされてしまうからです。 A1からのデータ数をG1に入れるということで、これまでG列に出力していたものを1行ずつ下にずらしてみました。 そのための変更は、No.4の3)のところで、 Cells(j - 1, 7) = i - i1 - 2 (修正前 Cells(j - 1, 7) = i - i1 - 2 + i2) を Cells(j, 7) = i - i1 - 2 にするだけです。 もちろんNo.4の2)のところはCells(1, 8)ではなくCells(1, 7)にしておきます。 いかがでしょうか。
お礼
なるほど、ありがとうございます。
- queuerev2
- ベストアンサー率78% (96/122)
A1から最初の1の2つ前までのデータ数は、加算してはいけなかったのですね。 ならば値を別途セルに入れます。場所はとりあえずセルH1(Cells(1 ,8))にします。 その結果、No.3のコードからの変更点は3か所だけだったので変更点のみ示します。 1) 変数i2は使用しない Dim i1 As Long, i2 As Long を Dim i1 As Long ' に。 2) A1からB列の最初の有効な1の行の2つ前までのデータ個数をセルH1に i2 = i - 2 を Cells(1, 8) = i - 2 ' に 3) 上記2)の値は加えない Cells(j - 1, 7) = i - i1 - 2 + i2 を Cells(j - 1, 7) = i - i1 - 2 ' に ところで、変更後のコードを実行して気づいたのですが、F1に出力されるデータは、最初の1の2行前のD列のデータです。つまり、A1から最初の1の2行前のデータは、出力されたデータと同じ行を含んだ個数になっています。 一方、G列に出力される個数は、その行のE列に出力されたデータと、次の行のF列に出力されたデータの間のデータの個数になっており、つまり出力されたデータは含まない個数になっています。 もしも出力されたデータの行を含むかどうかを統一する場合は、コードを適宜変更して1を加えるなり引くなりしてください。 これも質問者様の意図と違っていたり、あるいは何か質問事項等ありましたら補足いただければと思います。
お礼
回答ありがとうございます。これでやりたいことの実行できます! ただ1つだけなんですが、セルH1でなくてG1に出力することはできますか?Cells(1,7)にしてみたのですがうまく実行されないようで、、、
- queuerev2
- ベストアンサー率78% (96/122)
「A1から最初の1の2つ前(A?)のデータ数もカウントにいれる」というところですが、申し訳ありませんがよくわかりません。 まず、最初の1というのは、 ElseIf Cells(i, 2) = 1 And flg = True Then の条件式が最初に成り立つこととなった1のことでしょうか? そうであるならA1から2つ前までのデータの個数はF1の値、つまりCells(1,6)になると思いますがいかがでしょうか。 (B2つまりCells(2,2)が1の場合は出力されないので無効と考えています) 次に、カウントに入れるというのは、Cells(j - 1, 7)に加算するのでしょうか? もしそうであれば、 Cells(j - 1, 7) = i - i1 - 2 を Cells(j - 1, 7) = i - i1 - 2 + Cells(1,6) にするだけです。 でもこれでは質問者様の意図を理解できていないような気がするのです。
- queuerev2
- ベストアンサー率78% (96/122)
ちょっと推定を交えて書いてみましたがこんな感じでしょうか? Sub sample() Dim i As Long, j As Long, flg As Boolean Dim i1 As Long For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row If Cells(i, 1) = 0 Then flg = True ElseIf Cells(i, 1) = 1 And flg = True Then j = j + 1 If j >= 2 Then Cells(j - 1, "BV") = i - i1 - 2 End If i1 = i Cells(j, "BT") = Cells(i - 1, "BS") Cells(j, "BU") = Cells(i - 2, "BS") flg = False Else: flg = False End If Next End Sub
お礼
回答ありがとうございます。返事遅くなってすいません。表記を以下のように変えたのですがA1から最初の1の2つ前(A?)のデータ数もカウントにいれるにはどうしたらいいですか? Dim i As Long, j As Long, flg As Boolean Dim i1 As Long For i = 2 To Cells(Rows.count, 2).End(xlUp).Row If Cells(i, 2) = 0 Then flg = True ElseIf Cells(i, 2) = 1 And flg = True Then j = j + 1 If j >= 2 Then Cells(j - 1, 7) = i - i1 - 2 End If i1 = i Cells(j, 5) = Cells(i - 1, 4) Cells(j, 6) = Cells(i - 2, 4) flg = False Else: flg = False End If Next
お礼
なんか色々丁寧にお答えしていただいてるのに申し訳ないです。 確かにこれだと私のやりたいこととはちょっと違います・・・ 要は、条件に対応する1のところでデータの数をしりたいだけなんですが、No1で回答していただいたコードだと条件の1同士のデータ数はカウントできるんですが最初のデータ(A1)から最初の条件の1の間のデータ数がカウントされないんでそこをカウントできるコードがしりたいんです。