- ベストアンサー
EXCELマクロのこの記述の意味を教えてください。
こんにちは。 以前、教えてもらったマクロですが もう少し深く勉強したいので、記述の 意味(翻訳?)を教えてください。 Sub Test5() Dim FR1 As Range, FR2 As Range With ActiveSheet Set FR1 = .Cells.Find( _ "*", , xlValues, xlWhole, xlByRows, xlPrevious) Set FR2 = .Cells.Find( _ "*", , xlValues, xlWhole, xlByColumns, xlPrevious) End With Range("A1", Cells(FR1.Row, FR2.Column)).Select Set FR1 = Nothing: Set FR2 = Nothing End Sub また、この範囲をA列だけを見る場合、つまりA列の最終行を範囲とする場合は、どう記述すればよいのでしょうか? ぜひ、教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 どうも元の質問がわかりませんので、こちらの想像で書かせていただきます。FR1 もFR2 もおそらく、初回検索だけでは、同じ場所を検索しているはずですし、戻り値もRangeオブジェクトですから、そのまま、Range("A1",...)の範囲に入れればよいはずです。 ほとんど解説のしようがありませんが、 Find メソッドは、ヘルプを見ていただくしかありません。 また、見つからなかった場合を想定して、エラー解除をしなくてはなりません。 私は、1列目というので、.Columns(1) を考えましたが、 A列の最終行を範囲 なら、 このように書き換えることも可能です。 .Range("A1", .Range("A65536").End(xlUp)).Find( _ '------------------------------------------------- Sub TestSample1() Dim rng As Range With ActiveSheet Set rng = .Columns(1).Find( _ What:="*", _ LookIn:=xlValue, _ LookAt:=xlWhole) If Not rng Is Nothing Then .Range("A1", rng).Select End If End With End Sub // なお、私は、名前付き引数の場合は、このような縦並びに書きます。 With ステートメントは、書くときは、「.(ピリオド)」を忘れやすいのですが、環境の変化に対してエラーが少ないです。
その他の回答 (3)
- Wendy02
- ベストアンサー率57% (3570/6232)
#2 のWendy02 です。 #3 の KenKen_Sp さんの書き込みの後、もう一度、試してみたら、横と縦とは違う検索をしていることに気が付きました。元のコードを書き直してみました。どうも、コードから、そのコードの目的を見出すのは、ちょっとむつかしいです。 Sub TestSample2() Dim rng As Range, cnt As Long Dim r As Long, c As Long With ActiveSheet 'エラーチェック cnt = .UsedRange.Count If cnt = 1 Then Exit Sub 'データの最初の行数 r = .Cells.Find("*", , xlValue, 1, 1, 2).Row 'データの最初の列数 c = .Cells.Find("*", , xlValue, 1, 2, 1).Column '範囲選択 .Range("A1", .Cells(r, c)).Select End With End Sub 同じ範囲選択の方法を、他のコードで考えてみたのですが、このようなものになるのでしょうか? Sub TestSample3() Dim cnt As Long With ActiveSheet cnt = .UsedRange.Count If cnt = 1 Then Exit Sub 'A1からUsedRangeの最初の列範囲 .Range("A1", .UsedRange.Columns(1)).Select End With End Sub >この範囲をA列だけを見る場合、つまりA列の最終行を範囲とする場合は、どう記述すればよいのでしょうか? その範囲に対するA列の最終行と解釈しました。単独の「A列の最終行を範囲」とは違うということでしょうか?具体例があればはっきりします。つまり、A列にはデータがないこともありうる、と考えれば、以下のようになります。 Sub TestSample4() Dim cnt As Long With ActiveSheet cnt = .UsedRange.Count If cnt = 1 Then Exit Sub 'UsedRange の最終行を取り、それを範囲とする .Range("A1").Resize(.UsedRange.Cells(cnt).Row).Select End With End Sub
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんにちは。KenKen_SP です。 簡単に言えば、セル全体から 1. データのある行方向で最終のセル 2. データのある列方向で最終のセル をそれぞれ見つけて、A1からその最終行と最終列の番号で表される セルを選択、、、つまりA1から最後のセルまでを範囲選択する、、 ということでしょうね。 Sub Test5() 'オブジェクト変数の宣言 As句の後が変数の型を表す Dim FR1 As Range, FR2 As Range 'ピリオドで始まる句はActiveSheetの省略である With ActiveSheet 'アクティブシートのセル全体からワイルドカード「*」 'つまり空以外の値をもつ行方向の最後のセルを探し、 '見つかったセルを変数 FR1 にセット '--> 一番最終行のセルを探してます。 Set FR1 = .Cells.Find( _ "*", , xlValues, xlWhole, xlByRows, xlPrevious) 'アクティブシートのセル全体からワイルドカード「*」 'つまり空以外の値をもつ列方向の最後のセルを探し、 '見つかったセルを変数 FR2 にセット '--> 一番最終列のセルを探してます。 Set FR2 = .Cells.Find( _ "*", , xlValues, xlWhole, xlByColumns, xlPrevious) End With 'A1~最終行番号・最終列番号で表されるセルを範囲選択 Range("A1", Cells(FR1.Row, FR2.Column)).Select 'オブジェクト変数をクリア Set FR1 = Nothing: Set FR2 = Nothing End Sub 余談ですが、同様の処理を次のように書くことができます。 Sub Test6() With ActiveSheet .Range("A1", .UsedRange).Select End With End Sub で、A 列だけなら様々な書き方がありますがこんな感じ。 Sub Test7() With ActiveSheet .Range(.Range("A1"), .Range("A65536").End(xlUp)).Select End With End Sub ちなみに、見つからない場合のエラー処理はしてません。
お礼
KenKen_SPさん、こんにちは。 甘えてすみませんでした。 解説をしかと頭に叩き込みます。 ありがとうございました。
- finneganswake
- ベストアンサー率23% (194/809)
With ActiveSheet を With Range("A:A") でいいと思うけど。 FR1とFR2はrange(範囲)です。 今のシートすべてを対象とします。 FR1は行において最後の*が見つかるところまでです。 FR2は列において最後の*が見つかるところまでです。 A1からFR1の行番号、FR2の列番号のセルまでを選択しなさい。 FR1とFR2を忘れなさい。 そんなとこかな。無理な翻訳ですまん。 つまり、最初のシート全部見ろから、Aだけにしろにすればいいのでは。(この場合、いらないところが発生しますが、まあいいでしょ。)
お礼
finneganswakeさん、みなさん、ありがとうございます。 平易にわかりやすい翻訳ありがとうございました。 また、何かわからないことがあったら教えてください.
お礼
Wendy02さん、こんにちは。 質問の意図、明確でなくて申し訳ありませんでした。 今度からもう少し丁寧な質問の仕方を心がけます。