• ベストアンサー

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

  • VBA EXCEL セルのコピーについて

    Range(Cells(PRow + SERVICE_ROW, 2), Cells(SRow, 40)).Select Selection.Copy Destination:=Range(Cells(PRow, 2), Cells(A, 40)) このような形で変数を使いセルの値のコピーし、貼り付けたいと思っています。 貼り付ける場所にも変数を使いたいのですが、 Aの部分が可変で値を設定できません。 Range("B2")みたいな意味でRange(Cells(Prow,2))みたいな感じでスタートだけ設定して貼り付けることはできないのでしょうか?

  • VBA (Row とRowsの違いについて)

    いつもお世話になっております。 VBA初心者ですが、RowとRowsの違いについて今一つ分かりません。 添付ファイルのように、A2:A25まで数字を入れた表を作って、今ある知識で行数をカウントするコードをいくつか書いてみました。 test1:A2から始まる表を構成するトータル行数を返す。 test2:?? test3:A2から始まる表の最終行番号を返す。 test4:test1と同じ test5:??? (1)test2、5は同じ内容のコードになると思いますが・・結果の『2』は何を意味しているのか分かりません。 (2)RowとRowsの違いは簡単に言うとどういう事でしょうか? まとまりの無い文章で申し訳ありませんが、よろしくお願いいたします。 Sub test1() Cells(2, 2).Value = Cells(2, 1).CurrentRegion.Rows.Count End Sub Sub test2() Cells(2, 3).Value = Cells(2, 1).CurrentRegion.Row End Sub Sub test3() Cells(2, 4).Value = Cells(2, 1).End(xlDown).Row End Sub Sub test4() Cells(2, 5).Value = Range(Cells(2, 1), Cells(2, 1).End(xlDown)).Rows.Count End Sub Sub test5() Cells(2, 6).Value = Range(Cells(2, 1), Cells(2, 1).End(xlDown)).Row End Sub

  • 関数の中で参照するセル範囲(変動する)の記述方法

    セルJ5に下記の数式を入力するマクロを組みたいのですが、記述方法が分かりません。   =SUMIF(セル範囲(1),B5,セル範囲(2))  ・セル範囲(1)にはB5:C列の最終データまで  ・セル範囲(2)にはC5:C列の最終データまで 自分なりに   ActiveCell.Formula = "=SUMIF(Range(Cells(5, 2), Cells(Range("b5").End(xlDown).Row, 3)),b5,Range(Cells(5, 2), Cells(Range("C5").End(xlDown).Row, 3)))" と書いてみたのですがダメでした。 どうかご教授お願い致します。

  • EXCEL VBA----離れたセル範囲の指定

    こんにちは。初歩的なことで困っています。 Range("A3:A19,F3:F19").Select のように、離れたセル範囲を選択したいのですが 上の例の19行目が不定であるため、変数を使ったCellsプロパティを使用し i=Range("A3").End(xldown).Row Range("Cells(3, 1).Cells(i, 1), Cells(3, 6).Cells(i, 6)").Select と書いてみたのですが、エラーになってしまいました。 正しい指定の仕方を教えて下さい。よろしくお願いします。

  • Excel2007で困ってます2

    Sub test4() Worksheets("sheet2").Select Dim n As Byte, t As Byte n = Cells(Rows.Count, "O").End(xlup).Row + 1 t = Cells(Rows.Count, "ML").End(xlup).Row + 1 Range ("O" & n, "ML" & t).Select Selection = Worksheets("sheet1").Range("Y7:MV7").Value End Sub [test3でC3から始まる値をX5に入れる度に("Y:MV")に計算結果の値が出来上がります。その結果の値を、sheet2の("O3:ML3")には1から336の数字が振られていて、その下にその下にと次々と計算結果をコピーします。] test1からtest4を繋げたソースが私の力では無理でした。誰か教えてください。

  • VBA AutoFilter 範囲指定

    いつもお世話になっております 過去に https://okwave.jp/qa/q9707059.html にてワークシートのデータをオートフィルターをかけて別なワークシートにデータを取り出す方法を教えて頂きました 送られてくる元データが変更になって、A3セルの上のA2セルの上にテキスト文字が入るようになったので、範囲指定を正しく出来るようにする方法を https://okwave.jp/qa/q9708868.html にて教えて頂きました 今回、https://okwave.jp/qa/q9707059.htmlで教えて頂いたワークシートのコードを実行させると元データが変更になったデータを利用すると、A1セルまで含まれた範囲がAutoFilter の領域と判断される為正しい結果となりません 添付画像のワークシートで Sub test9() Worksheets("Sheet1").Range(Cells(3, "A"), Cells(Range("A3").CurrentRegion.Rows.Count, Range("A3").CurrentRegion.Columns.Count)) _ .AutoFilter Field:=2, Criteria1:=Cells(5, "G").Value End Sub を実行させれば、"秋田”でフィルターがきちんとかけれらた状態になります そこで教えて頂いたコードを下記に変更して実行させてみたのですが Dim i As Long With Worksheets("Sheet1") .Range("B4", .Range("B4").End(xlDown)).Copy .Range("G4").PasteSpecial (xlPasteAll) .Range("G4", .Range("G4").End(xlDown)).RemoveDuplicates Columns:=Array(1), Header:=xlNo For i = 4 To .Cells(Rows.Count, "G").End(xlUp).Row Worksheets.Add After:=Worksheets(Worksheets.Count) ActiveSheet.Name = .Cells(i, "G").Value .Range(Cells(3, "A"), Cells(Range("A3").CurrentRegion.Rows.Count, Range("A3").CurrentRegion.Columns.Count)) _ .AutoFilter Field:=2, Criteria1:=.Cells(i, "G").Value .Cells(3, 1).CurrentRegion.Copy Destination:=Worksheets(.Cells(i, "G").Value).Cells(3, 1) .AutoFilterMode = False Next .Range(Cells(3, "A"), Cells(Range("A3").CurrentRegion.Rows.Count, Range("A3").CurrentRegion.Columns.Count)) _ .AutoFilter Field:=2, Criteria1:=.Cells(i, "G").Value 部分で 実行時エラー'1004' アプリケーション定義またはオブジェクト定義のエラーです になってしまいます 元データがA2セルにテキスト文字が入った状態でも正常にコード動作させるにはどのようにしたらいいのでしょうか よろしくお願い致します

  • Excel007大量データのコピーが

    (1)、Sheet1の("Y7:MV7")の各セルに値A、B、C、の何れかが配置形の中央揃えで入ってます。 (2)、Sheet2の("O3:ML3")の各セルには1~336の数字が順に振られています。 そして(1)の形でデータが入るたびに(2)の最下に(1)の値だけがコピーされるようにVBAで次の様に書いてみました。 Sub test() Worksheets("Sheet2").Select Dim n As Byte, t As Byte n = Cells(Rows.Count, "O").E nd(xlup).Row + 1 t = Cells(Rows.Count, "ML"). End(xlup).Row + 1 Range("O" & n:"ML" & t).Sele ct Selection = Worksheets("Shee t1").Range("Y7:MV7").Value End Sub が、オーバーフローのエラーになります。 間違いの原因やお奨めなど頂けたらありがたいです。

  • VBAでi行j列ずれたセルの値

    VBAでセルA1にTESTという名前を定義しているとします。 セルA1はRange("TEST")で値を取得できますが、 セルA1からi行j列ずれたセルの値はどうやって取得できるのでしょうか? 今までは、Cells(1+i,1+j)で取得していましたが、 行や列を挿入することもあるので、セルに名前を付けたいと思います。

  • 【VBA】特定の範囲で同じ値を含むセルの色を変える

    Excelのマクロに関して質問です。 特定の範囲(複数行と複数列)内で重複した値(セル内の最初の4文字が同じもの)を含むセルの色を変えたいです。 さらに、重複した値ごとに色分けをしたいです。例えば重複した値[1111]と重複した値[1112]の時では、前者が赤色で後者は青色、更に他の重複する値はまた別の色でというように、 要は、どのセルとセルが重複しているか色分けをして一目瞭然にしたいです。 ※なお特定の範囲は以下の変数を利用します。 dataRow = Workbooks(booksName).Worksheets(sheetsName).Range("A2").End(xlDown).Row 'データの入っている最終行を取得 dataColum = Workbooks(booksName).Worksheets(sheetsName).Range("A1").End(xlToRight).Column 'データの入っている最終列を取得 どなたか知恵をお貸し下さい。よろしくお願いします。

  • 【VBA】特定の範囲で同じ値を含むセルの色を変える

    Excelのマクロに関して質問です。 特定の範囲(複数行と複数列)内で重複した値(セル内の最初の4文字が同じもの)を含むセルの色を変えたいです。 さらに、重複した値ごとに色分けをしたいです。例えば重複した値[1111]と重複した値[1112]の時では、前者が赤色で後者は青色、更に他の重複する値はまた別の色でというように、 要は、どのセルとセルが重複しているか色分けをして一目瞭然にしたいです。 ※なお特定の範囲は以下の変数を利用します。 dataRow = Workbooks(booksName).Worksheets(sheetsName).Range("A2").End(xlDown).Row 'データの入っている最終行を取得 dataColum = Workbooks(booksName).Worksheets(sheetsName).Range("A1").End(xlToRight).Column 'データの入っている最終列を取得 どなたか知恵をお貸し下さい。よろしくお願いします。.

専門家に質問してみよう