• ベストアンサー

エクセルVBAで範囲内での位置取得(行&列)

Sub test() Set Rng = Range("B2:E7") Rng.Cells(2, 2).Select End Sub これで、範囲Rng内では2行/2列目となるC3セルが選択されます。 では、C3セルが、範囲Rng内で何行/何列目であるかを取得するにはどのように記述すればよいのでしょうか? Rng.Cells(2, 2).Rowは、当たり前ですが、3になってしまいます。

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

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

こんばんは。 端的に言うと、絶対参照を相対参照に戻すことですね。 Address メソッドの 「RelativeTo:=」に、入れてあげれば、相対的な位置を出します。 以下は、文字列の取得の仕方には問題があるけれども、左端上を基点として、相対参照に直しています。以下の文字列の取得は、正規表現なんて使うと、いかにも、それらしくはなるけれど、実際には、遅くなってしまいます。実際は、Ref までで取得は出来ています。 Sub TestSample()   Dim rng As Range   Dim Target As Range   Dim Ref As String   Dim i As Long, j As Long, n As Long, rw As Long, col As Long   Set rng = Range("B2:E5")   Set Target = Range("C4")   If Intersect(Target, rng) Is Nothing Then MsgBox "範囲には該当していません。": Exit Sub     Ref = Target.Address(0, 0, xlR1C1, , rng.Cells(1, 1))   '文字列から行数と列数を取得   i = InStr(Ref, "[")   j = InStr(Ref, "]")   n = InStrRev(Ref, "[")   rw = Mid$(Ref, i + 1, j - 1 - i) + 1   col = Mid$(Ref, n + 1, Len(Ref) - n - 1) + 1      MsgBox Target.Address(0, 0) & "は、『" & rng.Address(0, 0) & "』に対して" & vbCrLf _   & rw & "行目" & col & "列目"      Set Target = Nothing   Set rng = Nothing End Sub

merlionXX
質問者

お礼

有難うございます。 Object.Address(RowAbsolute, ColumnAbsolute, ReferenceStyle, External, RelativeTo) という構文だったのですね。 とても勉強になりました。 文字列Refから行数と列数を取得するのはやはり大変ですねえ・・・。

その他の回答 (7)

回答No.8

エキスパートさん、Wendy02さん、こんばんは。 >こうやって見ました。 >Ref = Target.Address(0, 0, xlR1C1, , Rng.Cells(1, 1)) >Ref = Replace(Replace(Replace(Ref, "R", ""), "[", ""), "]", "") >Dim myAdrs >myAdrs = Split(Ref, "C") >MsgBox Val(myAdrs(0)) + 1 & " 行 " & Val(myAdrs(1)) + 1 & " 列" おお、さすがエキスパートさん。 これからも今回のようにひとつの解だけではなく少なくとも2つは考えるようにして 常に頭を柔らかく柔らかくふにゃふにゃにしておきませうねぃ。(^^;;; そうすればきっと遥か遠くに微かではあるけれどWendy02さんの後姿が 目視できるようになる日が来ることでせう。   Wendy02さん、いつも勉強させていただいてます。 これからも実践的なコード、薀蓄のある解説、楽しみにしております。  

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

こんにちは。 kobouzu_su さん、コメントありがとうございました。 前回書いたように、一応、正規表現では、以下のように一回で取得は出来ます。ただ、「いかにも」っていう感じになって、正規表現の自己主張が強くって、自然な流れではないような気がします。(意味不明かな?) Sub TestSample2()   Dim rng As Range   Dim Target As Range   Dim Ref As String   Dim Matches As Object   Set rng = Range("B2:E5")   Set Target = Range("C3")      If Intersect(Target, rng) Is Nothing Then MsgBox "範囲には該当していません。": Exit Sub   Ref = Target.Address(0, 0, xlR1C1, , rng.Cells(1, 1))   With CreateObject("VBScript.RegExp")    .Pattern = "R(\[(\d+)\])*C(\[(\d+)\])*"    Set Matches = .Execute(Ref)    With Matches(0)     MsgBox Target.Address(0, 0) & "は、『" & rng.Address(0, 0) & "』に対して" & vbCrLf _     & Val(.submatches(1)) + 1 & "行目 " & Val(.submatches(3)) + 1 & "列目"    End With   End With   Set Target = Nothing   Set rng = Nothing End Sub

merlionXX
質問者

お礼

「正規表現」ですか・・・・。 まだエクセルVBAでさえおぼつかないのに、わたくしめにはちと難しすぎまするぅ。 有難うございました。

回答No.6

エキスパートMerlionさん、こんにちは。 >文字列Refから行数と列数を取得するのはやはり大変ですねえ・・・。 頭の体操になって楽しいではありませぬか。。(^o^)。。 '------------------------------------------------ Sub TestSample() Dim Rng As Range Dim Target As Range Dim Ref As String Set Rng = Range("B2:E7") Set Target = Range("B4") Ref = Target.Address(0, 0, xlR1C1, , Rng.Cells(1, 1))  Dim myAdrs, myRow, myClm  myAdrs = Split(Ref, "C")  myRow = Replace(Replace(Replace(myAdrs(0), "R", ""), "[", ""), "]", "")  myClm = Replace(Replace(myAdrs(1), "[", ""), "]", "")  MsgBox Val(myRow) + 1 & " 行 " & Val(myClm) + 1 & " 列" End Sub '-------------------------------------------------- それから、こういう類のものをテストするときは、境目を重点的にチェックしなければいけません。 1列目(例えば、B2,B3,B4)だとか 1行目(例えば、C2,D2,E2)などを。 因みに当方は、No3のオーソドックスものしか浮かびませんでした。(^^;;; Wendy02さんは、すごい! 以上です。

merlionXX
質問者

お礼

ありがとうございます。 > 頭の体操になって楽しいではありませぬか。。(^o^)。。 確かに。(*´∇`*) 配列が出てくるとは思いませんでした。 こうやって見ました。 Sub TestSample02() Dim Rng As Range, Target As Range Dim Ref As String Set Rng = Range("B2:E7") Set Target = Range("B2") Ref = Target.Address(0, 0, xlR1C1, , Rng.Cells(1, 1)) Ref = Replace(Replace(Replace(Ref, "R", ""), "[", ""), "]", "") Dim myAdrs myAdrs = Split(Ref, "C") MsgBox Val(myAdrs(0)) + 1 & " 行 " & Val(myAdrs(1)) + 1 & " 列" End Sub

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

こんにちは。 >文字列Refから行数と列数を取得するのはやはり大変ですねえ・・・。 いえ、これが、なんとも言いようがないのでして……。 まだ、見当の余地は残っています。これで終わりではありません。 今回の書いたのは、最近の私のVBAの処理の仕方なのです。 正規表現なら一回で済むのですが、オートメーション・オブジェクトというのは、呼び出すのにタイムラグがあるので、結果的には、内部コマンドでしてしまったほうがよいと考えたのですが、しかし、どうも見栄えが悪いのです。 良いコードは見掛けも良いものだ、といわれますから、どうも、そこらあたりが正解に到達していないのかもしれませんね。最近、どうも雑になっていけませんね。(^^; それに、Excel2003あたりですと、たぶん、List を使えるのではないか、と思いましたが、今回は、それはありませんからね。

merlionXX
質問者

お礼

有難うございます。 とても勉強になりました。 いつもお世話様です。 (o。_。)oペコッ

  • ja7awu
  • ベストアンサー率62% (292/464)
回答No.3

こんな感じで如何でしょうか。 Sub test() Dim Rng As Range Set Rng = Range("C3") With Range("B2:E7")   If Not Intersect(.Cells, Rng) Is Nothing Then     MsgBox Rng.Row - .Cells(1).Row + 1 & "行/" & Rng.Column - .Cells(1).Column + 1 & "列目"   Else     MsgBox "範囲外です。" End If End With Set Rng = Nothing End Sub

merlionXX
質問者

お礼

有難うございます。取得できました。 やはりこのような力技になってしまうのですねえ。 φ(=__=; )

  • aru99
  • ベストアンサー率18% (8/44)
回答No.2

MsgBox (Rng.CurrentRegion.Row & "," & Rng.CurrentRegion.Column) 上記メッセージで2,2が返ってきます。

参考URL:
http://t_shun.at.infoseek.co.jp/My_Page/Excel-VBA/vba_page5.htm
merlionXX
質問者

お礼

Rng.CurrentRegion.RowやRng.CurrentRegion.ColumnではCurrentRegionの一番左上のセルの行と列を返すだけです。

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

期待されている回答はもっとスマートなものだと思いますが  Rng.Cells(2, 2).Row - Rng.Cells(1, 1).Row + 1 で取得はできると思います。

merlionXX
質問者

お礼

zap35さん、早速有難うございます。 Rng.Cells(2, 2).Row - Rng.Cells(1, 1).Row + 1でもちろん取得はできるのですが、これってRng.Cells(2, 2)と書いた時点で既に範囲内で2行2列目ってわかっている計算ですよね。 例えば検索等で特定のセルのアドレスがわかった場合、それが表中の何行/何列目であるかを取得したかったのです。

関連するQ&A

  • For~Next ループ内でUnionメソッドを使うとエラーになります。

    下記の記述で2行おきのセル範囲から0以下のセルを除外したセル範囲を取得しようとすると Set Rng = Application.Union(r, Rng) の行でエラーが発生します。 'Set Rng = Range(Cells(12, 7), Cells(12, 7)) の行のコメントアウトをはずすと動きますが、 cells(12,7)の値が0以下だと本来の目的 である0以下のセル範囲を除外するという目的が果たせません。 Union(r,Rng)のRngがnothingになっているとエラーの原因になるのでしょうか? Private Sub test() Dim r As Range Dim Rng As Range 'Set Rng = Range(Cells(12, 7), Cells(12, 7)) For i = 12 To 27 Step 3 If Cells(i, 7) > 0 Then Set r = Range(Cells(i, 7), Cells(i, 7)) Set Rng = Application.Union(r, Rng) End If Next i Rng.Select End Sub 以上教えてください。 お願いします。

  • 途中に空白行や列があるデータ範囲

    エクセル2003です。 セルA1からセルC50までデータがあり 10行目と20行目は全て空白、 セルC39が空白で セルE55、F57、G55にはデータがある の状態で以下の構文ですと Sub 範囲コピー1() Range("B3").Select Range(Selection, ActiveCell.SpecialCells(xlLastCell)).Select Selection.Copy End Sub 途中に空白行や列、空白セルがあり さらに離れた所E55、F57、G55に データが有るのにもかかわらず セルB3からセルG57までを選択してクリップボードにコピー してくれます。 ですが問題がありまして 上記のシートにて A45~F50を選択してDeleteをし、 さらにセルのF55、G55もDeleteして データ範囲を セルA1~E44とセルE55のみにしてからから 上記構文を実行すると セルB3からセルE55を選択してクリップボードにコピー してほしいのに、 データ削除前と同様の セルB3からセルG57を選択してクリップボードにコピー されてしまいます。 これはエクセルの手操作 Ctrl+Shift+End でも同じようになりますので当然の結果(※1)と思っています。 (※1→なにか別な方法はありますか?) 上記の使用方法はあまりないのですが 構文を使う時点での最大行数や最大列数は常に不明で 途中空白が有る場合無い場合、 上記のようにシート上でデータ操作をした直後であっても データ削除部分は加味しデータのある範囲だけの取得の対応 が可能な構文を1種類で作成したいのですが どういう方法があるでしょうか? ちなみに Sub 範囲コピー2() Range("B3").Select Range(Cells(Rows.Count, 1).End(xlUp).Row).Select Range(Cells(1, Columns.Count).End(xlToLeft).Column).Select Selection.Copy End Sub これですと 実行時エラー1004 Rangeメソッドは失敗しましたGlobalオブジェクト となります。 ヘルプをクリックしても何も表示されません。 WEB検索するとこのエラーの質問は結構多いのですが 事例が相違する為よく理解できません。 もしかしてRangeなのに 取得できる値が一つの番号でセルを指定できないからでしょうか? エラーになる構文だと最初のRangeは行番号、次のRangeは列番号、 ですので。 で、 Sub 範囲コピー3() Dim 最終行 Dim 最終列 Range("B3").Select 最終行 = Cells(Rows.Count, 1).End(xlUp).Row 最終列 = Cells(1, Columns.Count).End(xlToLeft).Column Cells(最終行, 最終列).Select Selection.Copy End Sub これならエラーにはなりませんが 事例だとセルC50だけが単独選択されて範囲として 取得をしてくれません。 また 1, Columns.Count ですので最終列の列番号の取得が1行目の最終列から左に検索し データのある所の列番号を返すので 3→C列 となってしまい D,E,F列を見つけてくれません。 かといって 55, Columns.Count では データが55行まで無い場合には対応が出来ませんのでこれも駄目です。 途中に空白が無い場合や離れたセルが無い場合でも使いたいので UsedRangeは使用したくない(よくわかってない事もあって)です。 よろしくお願いします。

  • VBAで列範囲、行範囲の指定方法の質問です。

    例えば、3行目から5行目を選択する記述、Rows("3:5").Select の記述で行番号を変数で指定することができますか? 要求側で   r1=3   r2=5 と指定してサブルーティンに渡し、 Rows("3:5").Select と同じ効果を期待したいのです。 なお、指定範囲が1行の場合は、次の記述で実現しています。 Sub 列の選択(Sheet as Ojbect, RowNo)   Sheet.Rows(RowNo).Select End Sub アクティブ シートへの処理なので、別にWorkSheet オブジェクトの指定は不要だと思うのですが、次の記述ではエラーで成功しません。 Sub 列の選択(RowNo)   Rows(RowNo).Select End Sub 結論として次のような Subroutine の作成が希望です。 Sub 複数列の選択(Sheet as Object, Row1, Row2) ・・・ End Sub

  • エクセルマクロでA欄に値がある行までのC列の範囲を指定したい。?

    エクセルマクロでA欄に値がある行までのC列の範囲を指定したい。? ●エクセルマクロのVBAで次のように記述しています。 Range("C2").FormulaR1C1 = "=VLOOKUP(LEFT(RC[-2],4),C[-2]:C[-1],2,FALSE)" Range("C2").Select Selection.AutoFill Destination:=Range("C2:C148"), Type:=xlFillDefault A列に文字が入っている最終行は A148なので、C2: C148 の範囲にオートフィルで貼り付けるように しています。 しかし、A列に文字が入っている最終行は、変動します。 なお、貼り付ける範囲はいつでも C2から始まります。 A列に文字が入っている最終行が A200であれば、C2: C200の範囲、 A列に文字が入っている最終行が A321であれば、C2: C321の範囲といったように、 C2の値を貼り付ける範囲を設定したいと思っています。 ●そこで、次のように記入してみました。 With Worksheets(2) Dim lRow As Long, lRow = .Cells(Rows.Count, 1).End(xlUp).Row Range("C1").Formula = "名称" Range("C2").FormulaR1C1 = "=VLOOKUP(LEFT(RC[-2],4),C[-2]:C[-1],2,FALSE)" Range("C2").Select Selection.AutoFill Destination:=Range(Cells(3, 2), Cells(lRow, 3)), Type:=xlFillDefault 変数を使って最終行を指定しても上手くいきませんでした。 (C2:C150)や(C2:C160)といったように「C2」のセルを「C2のセル」から「A列に文字が 入っている行のC列」まで貼り付けたいと思っています。 どのようにVBAを記述したら良いのか教えていただけないでしょうか。

  • VBAコピー範囲について教えてください。

    VBAのコピーペーストの下記プログラムで、 Sub コピー() Dim rng As Range Set rng = Worksheets("2").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) With Range("b2:J10") rng.Resize(.Rows.Count, .Columns.Count).Value = .Value End With End Sub コピー範囲 のJ10の部分(データ入力行)が、その都度変わるため、J10の部分を、 J列のデータが入力されている最終行としたいのですが、どのようなプログラムに すればよいのでしょうか。 どなたかよろしくお願いいたします。

  • Excel VBA 選択した範囲の1行目に色を付けたい

    VBA初心者です。 セルB4~F15に表が作成されています。 プロシージャを実行して、セルB5~F15にブルー。表1行目のセルB4とF4のみに赤の色を付けるというコードを記述したいのです。 以下のように記述しました。 Sub セルに色()    Range("B4").Select    ActiveCell.CurrentRegion.Select    Selection.Interior.ColorIndex = 8    Selection.Range(Cells(1, 1),Cells(1,5)).Interior.ColorIndex = 3 End Sub Rangeでは連続シートになるため、Unionに変更してみましたが、 Unionはオブジェクトがサポートされていない旨のエラーが出ました。 どのように記述すればよいでしょうか? どうぞよろしくお願いいたします。

  • VBAで、セル(Range)のオブジェクトが取得できない

    セルの情報を取得したいのですが、何故か以下のように書くと上手い具合に取得できません(A、B、Cは数値の変数)。 ------ Dim Rng As Range 'セル範囲を格納 Set Rng = Worksheets(1).Range(Cells(A, B), Cells(A, C)) ------ 以下のようにしてやると、何とか取得できます。 Worksheets(lngASNo + 1).Select Set Rng = Range(Cells(A, B), Cells(A, C)) どこが悪いのでしょうか? もし、判る方がいらっしゃいましたら、よろしくお願いいたします。

  • 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 と書いてみたのですが、エラーになってしまいました。 正しい指定の仕方を教えて下さい。よろしくお願いします。

  • エクセルVBAで表から行の削除

    添付画像のような表があります。 表はB列の名前でソートされています。 D列の比率をみて、100でないものは、必ず同じ名前で複数行にわかれ合計で100になります。この例では名前CとEとHがそうです。 同じ名前が複数行にわかれている場合、最大の比率の行を残し、他の行(例では、埼玉、栃木、長野、新潟の行)を削除したいのです。 複数行にわかれるのが名前CやEのように2行なら、以下のコードで出来ました。 しかし、めったにはありませんが名前Hのような3行以上に分かれるものには対応できません。 どうすればよいでしょうか? Sub test01()   Dim c As Range   Dim Rng As Range   Set Rng = Range(Cells(2, "D"), Cells(Rows.Count, "D").End(xlUp))   For Each c In Rng '2地区の分担の場合、分担比率高い方を残す。(3地区以上は未対応)2012/08/29     If c.Value <> 100 And c.Offset(1).Value <> 100 Then       If c.Offset(, -2).Value = c.Offset(1, -2).Value Then         If c.Value >= c.Offset(1).Value Then           c.Offset(1).Value = False         Else           c.Value = False         End If       End If     End If   Next   If Application.WorksheetFunction.CountIf(Rng, False) > 0 Then     Rng.SpecialCells(xlCellTypeConstants, xlLogical).EntireRow.Delete   End If End Sub

  • セルが何行なのかをVBAで取得したい

    セルが何行なのかをVBAで取得したいのですが どういうコードにすればいいですか? 例えば、A1セルに a b c と入ってる場合、3行ですが それをVBAで取得するにはどうすればいいですか? Sub test() Dim r As Range Set r = Cells(1, 1) If r.Value Like "*" & Chr(10) & "*" Then MsgBox "改行があります" End If End Sub というコードで改行が有ることは取得できたのですが 何行かまでは取得する方法がわかりません。

専門家に質問してみよう