Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
  • ベストアンサー

Excel VBA Rangeについて

下記のコードは、あるテキストに掲載されていたコードです。 D5に番号を入力すると、F5に文字が表示されるというようなコードです。 下記コードのRange("顧客コード")とは何を意味するのでしょうか? Worksheets("顧客")の意味は分かりますが、私の知識ではRange(" ")の中に入るのは、A1などしか分かりません。 よろしくお願いします。 Private Sub Worksheet_Change(ByVal Target As Excel.Range) Dim r As Integer, myRange As Range Set myRange = Worksheets("顧客").Range("顧客コード") With Target '変更されたセルがD5だったら If .Row = 5 And .Column = 4 Then '顧客コードの位置を取得 r = Application.WorksheetFunction _ .Match(Target.Value, myRange, 0) 'セルに顧客名を表示 Range("F5") = Worksheets("顧客").Range("B1").Offset(r - 1).Value End If End With End Sub

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

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

こんにちは。 >テキストに掲載されていたコード うーん、参考にしなくて良いと思います。あまり、きちんと書かれた内容ではありません。 まずい点がいくつもあります。 >私の知識ではRange(" ")の中に入るのは、A1などしか分かりません。 その考え方で良いと思います。私は、ここの掲示板で、[名前-定義]を使った書き方はいけない、と力説しています。Rangeの引数には、[名前-定義]が入りますが、可読性が落ちますし、[名前-定義]を絶対参照にしても、条件によって、移動してしまいますから、明示的、つまり、Range("A1:A20") などと書いたほうがよいです。 厳密に、オブジェクトブラウザで、Names オブジェクトを調べてもらえば分かりますが、Application から、Sheet まで、その親オブジェクトが複数あります。そうすると、どう登録されたかは、コードをみても分かりません。意外にも、エラーが出て、初めて気が付くものがあります。 >With Target Change イベントですと、Target は、必ずしも、1つとは限りません。貼り付けもあります。また、空白値もあります。その対策が処理されていません。そうしたら、そのようなコードでは確実に、実行時エラーが発生します。 >Range("F5") = Worksheets("顧客").Range("B1").Offset(r - 1).Value Range("F5") にプロパティを入れていないのは、大目にみても、  Worksheets("顧客").Range("B1").Offset(r - 1).Value ここで、イベントを発生させています。二重にイベントを発生していることには間違いありません。 もちろん、If .Row = 5 And .Column = 4 Then で、解除しているものの、本来は、 Application.EnableEvents =False で解除すべきです。 最大の問題点は、 >r = Application.WorksheetFunction.Match(Target.Value, myRange, 0) Match の第三引数、0 =False ですから、確実に同じ値を求められます。しかし、Excel 2000 以上の書き方の Application.WorksheetFunction では、見つからない場合は、実行時エラーが発生してしまいます。 >Dim r As Integer, また、r --> row ですから、Long 型になります。 しかし、ワークシート関数を、エラートラップをおかず、Excel 97方式で使うというと、Variant 型になり、そこに、エラー値も入れられます。したがって、r のデータ型は、Variant 型になります。 なお、 >Set myRange = Worksheets("顧客").Range("顧客コード") と、変数に入れる必要性があるのか、疑問です。イベントが終了すれば、myRange は、一般的には、オブジェクトは残っていませんが、100% 残らないという保証はありません。もちろん、それは、一般的ではない使い方をすればということですが、今は、もう、旧VB 系の Developer を使っていた時代ではありませんから、オブジェクトの処理は、念には念を入れたほうが無難です。 そういうことを踏まえて、書き直してみました。 'シートモジュール Private Sub Worksheet_Change(ByVal Target As Excel.Range)   Dim i As Variant   With Target.Cells(1)     '変更されたセルがD5だったら     If .Address(0, 0) = "D5" And .Value <> "" Then       '顧客コードの位置を取得       i = Application.Match(Target.Value, Worksheets("顧客").Range("A1:A20"), 0)       If Not IsError(i) Then       Application.EnableEvents = False       'セルに顧客名を表示       Range("F5").Value = Worksheets("顧客").Cells(i, 2).Value       Application.EnableEvents = True       End If     End If   End With End Sub

taka1012
質問者

お礼

ご回答ありがとうございます。 詳しいご解説に感謝します。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • marbin
  • ベストアンサー率27% (636/2290)
回答No.2

↓のマクロをtest1、test2の順に実行してみてください。 test1では選択セル範囲に"名前"という名前を定義し、 test2では、"名前"で定義したセル範囲のアドレスを 取得します。 Sub test1() Dim r As Range Set r = Selection r.Name = "名前" End Sub Sub test2() MsgBox Range("名前").Address End Sub もちろん 手作業でセル範囲に名前を定義した場合でも Range("名前") という風に使えます。

taka1012
質問者

お礼

ご回答ありがとうございます。 よくわかりました。

すると、全ての回答が全文表示されます。
  • marbin
  • ベストアンサー率27% (636/2290)
回答No.1

セル範囲に名前を定義したものは Range("定義した名前") というように使えます。

taka1012
質問者

お礼

ご回答ありがとうございます。

すると、全ての回答が全文表示されます。

関連するQ&A