• ベストアンサー

excel2000で特定セルから空セルの前までの行数を数えたい

セルA7から下へ向かってデータが入っています。その数をセルA1に入れたいと思い、   「 Cells(1, 1) = Range("a7", Range("a7").End(xlDown)).Rows.Count 」 こんなマクロを書きました。出展は  「 http://park7.wakwak.com/~efc21/cgi-bin/exqalounge.cgi?print+200611/06110262.txt 」です。 ここで、下記のようなデータを入れて試してみました。()内が期待する値で、[]内が実際の値です。        <テスト1> <テスト2> <テスト3> <テスト4> <テスト5> セルA7           あああ    あああ           あああ  セルA8                  いいい    いいい    いいい  セルA9                         ううう         セルA10                                    セルA11                               おおお ----------------------------------------- 期待する値     0      1      2      0      2 実際の値  65530  65530      2      2      2 と、このように期待する値が得られません。何が間違っているのでしょうか。 丸1日考えているのですが原因が分かりません。よろしくお願いします。 (文字幅がおかしくて見にくいと思いますがよろしくお願いします)

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんにちは。 正しいとか間違っているというよりも、「期待する値」に、特別な法則を持っている、と思います。 Cells(1, 1) = Range("a7", Range("a7").End(xlDown)).Rows.Count End プロパティは、値のあるセルを下に向かって探せ、ということです。だから、A7 から、その下を最後まで探して、その行数を出せ、ということでは、意味が違いますね。 質問者さんの直感なのでしょうか、「期待する値」の求め方は、関数タイプですね。「最初の空白行を探せ」ということですね。 関数なら、こうなります。 =MATCH(TRUE,INDEX(ISBLANK(A7:A100),,),0)-1 7行目より手前か、引数の範囲の外に数式を置いてください。循環参照になります。 もちろん、この数式をマクロに代入しても構いませんが、少し工夫が必要です。 以下のマクロと比較すると、上記の数式に軍配が上がりそうですね。Excelのワークシートはマクロよりも難しいですね。 '------------------------------------ Sub Test1()   Dim i As Integer   Dim ret As Long   Const col As Integer = 5   '書き出す行...15 行目   Cells(15, col).Resize(, 5).ClearContents   For i = 1 To col     ret = spBlankRow(Cells(7, i)) '7行目から     Cells(15, i).Value = ret - 7   Next End Sub Function spBlankRow(rng As Range) As Long Dim r As Range   On Error Resume Next   Set r = Range(rng, Cells(Rows.Count, rng.Column)).SpecialCells(xlCellTypeBlanks)   On Error GoTo 0   spBlankRow = r.Cells.Cells(1).Row End Function ちょっと言い訳: 最初、ユーザー定義関数だけで作ろうと思いましたが、SpecialCells で範囲を認識させるには、コマンドに命令を与える信号が必要ですが、ユーザー定義だけでは、そのコマンドに命令が与えられないので、プロシージャ型になっています。

その他の回答 (3)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

#3の回答者です。 「#1 のお礼」に対するレス Range("A7").End(xlDown) というのは、 A7にカーソルを置いて、Ctrl + ↓ という結果と変わらないということです。 次の下のセルから、値の入っているセルを探しているわけです。 バグではないのですが、VBAをいつも使っている者からすると、ワークシートの仕様を映しているだけだとしか言いようがありません。VBA全体を体系的に、Office, Excel, VBAという三つに分かれます。その中で、Excel の仕様だけ、とって付けたような感じがしますし、その分、難しい問題が表れてきます。 しかし、そっくり同じだとは言えない部分も持っています。例えば、JIS関数やCODE関数が、VBAでは、そのまま使えません。 他にもいくつかありますが、今回の #3 の 範囲.SpecialCells(xlCellTypeBlanks) も、この範囲を、同じ列の最後の行まで指定しても、 範囲.SpecialCells(xlCellTypeBlanks).Select Select される範囲は、認識できる最後の行までなので、数行しかないことが分かるはずです。

k-family
質問者

お礼

解説ありがとうございます。 「Ctrl + ↓ という結果と変わらない」と言うことで、いろいろやってみました。 「値のあるセルを下に向かって探せ」というより、「値のないセルから値のあるセルに変わるセルを下に向かって探せ」という感じですね。電気回路で言うところの立ち上がりエッジを探すようなイメージですね。 解説を読んで意味がわかってきました。 私がバグではないかと思ったのは、いろいろ方法を探す中で、 「指定行から空白セルまでの行数を数えるには?」という質問に対する回答が「Range("A7", Range("A7").End(xlDown)).Rows.Count」だったり、 「xldownで探すと空白行で止まってしまうから、一番下からxlupで上に向かって探せ」 などの説明を読んでそれなりに納得していたからでした。 おかげさまですっきりしました。 また、「=MATCH(TRUE,INDEX(ISBLANK(A7:A100),,),0)-1」もすばらしいです。似たような所まで行ったのですができませんでした。

  • hige_082
  • ベストアンサー率50% (379/747)
回答No.2

Sub test() Dim i, ii As Integer i = 0 Do While Cells(i + 7, "a").Value <> "" i = i + 1 Loop Cells(1, "a").Value = i End Sub do ~ loop を使用しました

k-family
質問者

お礼

マクロまで書いて頂いてありがとうございます。 でも、下の方でも書きましたが、一番知りたいのは原因なんです。 マクロを書けば簡単なんですが、できれば関数だけで何とかなりませんでしょうか。

  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.1

とりあえずベタに Sub Macro2() Dim idx As Long  For idx = 7 To 65536   If Cells(idx, "A").Value = "" Then    Cells(1, 1).Value = idx - 7    Exit For   End If  Next idx End Sub Range("A7").End(xlDown)では  7行目 ああああ  8行目 (空白)  9行目 いいいい のときは9行目を示しますから使いにくいのではないでしょうか

k-family
質問者

お礼

回答ありがとうございます。 >のときは9行目を示しますから使いにくいのではないでしょうか これですが、  7行目 ああああ  8行目 (空白)  9行目 いいいい のときは「3」になります。この場合はご指摘の通り「Range("A7").End(xlDown)」が9行目を示しているのかもしれません。しかし、  7行目 ああああ  8行目 (空白)  9行目 いいいい  10行目 うううう の時は10行目を示し、値は4になるような気がしますが、実際には値は3です。 さらに不思議なのは、  7行目 ああああ  8行目 いいいい  9行目 (空白)  10行目 うううう とすると、値は2になります。 エクセルのバグのような気がしますがどうでしょう。 もしかするとエクセル2000だけの現象でしょうか。

関連するQ&A