• ベストアンサー
  • 暇なときにでも

エクセルvba  (ByVal Target As Range)について

シートのイベントプロシージャーが Private Sub Worksheet_SelectionChange(ByVal Target As Range) End Sub となりますが (ByVal Target As Range)部分は何なのでしょうか? 何のためにあるのかわかりません。 Private Sub Worksheet_SelectionChange() End Sub としたらエラーが返ってきました。 理由を教えてください。 よろしくお願いします。

共感・応援の気持ちを伝えよう!

  • 回答数6
  • 閲覧数23431
  • ありがとう数13

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

  • ベストアンサー
  • 回答No.6
  • rukuku
  • ベストアンサー率42% (401/933)

こんにちは >Target=ActiveCell >と言う認識でよろしいでしょうか? #5でKenKen_SPさんが説明されていますが、補足です。 セルを一つだけ選択したときには、 Target=ActiveCell と考えても問題ありません しかし、複数の範囲を選択したときは、 Target=ActiveCell はなりません。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) では Target=Selection です。 注! Private Sub Worksheet_SelectionChange(ByVal Target As Range) では Target=Selection 成り立っていますが、そうでない場合もあります。 Selectionは「選択されている物」という意味です。 そのために、場合によって内容が異なります。 例えば、オートシェイプが選択されているときには、Selectionは選択されているオートシェイプになります。 以下のコードを試してみてください。 上段にTargetのアドレス 中段にActiveCellのアドレス 下段にSelectionのアドレス が表示されます。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) MsgBox Target.Address & Chr(13) & ActiveCell.Address & Chr(13) & Selection.Address End Sub

共感・感謝の気持ちを伝えよう!

質問者からのお礼

試してみました! すごいですね。 ありがとうございます。

関連するQ&A

  • エクセルVBA/イベント発生でコピペ不能はなぜ?

    シートに以下のマクロを設定すると、そのシート内ではコピーしたもののペーストが不能になります。 どうしてでしょうか? Private Sub Worksheet_SelectionChange(ByVal Target As Range) Target.Interior.ColorIndex = 6 End Sub

  • エクセル デバッグできるのとできないのがある

    シートイベントについて教えてください。 シートモジュールに --------------------------------------------------------- Option Explicit Private Sub Worksheet_Activate() MsgBox "" End Sub Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) MsgBox "" End Sub Private Sub Worksheet_Change(ByVal Target As Range) MsgBox "" End Sub Private Sub Worksheet_SelectionChange(ByVal Target As Range) MsgBox "" End Sub --------------------------------------------------------- と記載した時に、 F8で動かせるのは、Worksheet_Activateだけなのですがなぜでしょうか? ほかのイベントは、F8で実行させても、OSの音が鳴るだけで、マクロの実行はされません。 ご回答よろしくお願いします。

  • マクロの疑問

    Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Address <> "A2" Then Range("A2").Select End If End Sub とすると、どのセルを選んでもA2に飛ぶのに、 Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Address = "A3" Then Range("A2").Select End If End Sub とすると、A3を選んでも全く移動しないのはなぜでしょうか。 なにか落とし穴がありそうで。。。 よろしくお願いします。

その他の回答 (5)

  • 回答No.5

最初のご回答にあるとおり、単純に変更のあったセルを教えてくれるもの 程度の説明が良い気がします。これは、理屈じゃなくて、   「そのように作られているもの」 と理解した方が良いでしょう。そして、実際に使ってみることです。理屈は 使ってさえいれば、あとからついてきますので。言葉で理解しようとしても 時間がかかるだけです。ただし、   Target ≠ ActiveCell ですよ。イコールではありません。 ActiveCell はどのような操作であっても必ず1つですよね? 仮に複数の セルが選択されていたとしても。 対して、例えば A1:C10 の範囲を選択した場合、Target には A1:C10 セル が参照されてきます。つまり   Target = Range("A1:C10") ですね。アクティブセルは A1 かもしれない、けど選択されたセルは A1:C10。   A1 ≠ A1:C10 ですから、アクティブセルと同意ではありません。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

Targetは複数ですね 覚えます。 ありがとうございます。

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

こんにちは。 最初に、あまり、そのような疑問は持たない方がよいです。聞いても良く分からないと思います。これを理解するために、C言語を勉強する、そうすると別の疑問が出てくる、また、オブジェクト指向の考え方を分からなくてはならない、と堂々めぐりになってしまいます。そういう私も、はっきり言って、このレベルは分かりません。 ただ、私の知っている範囲で初心者とか関係なく回答します。それは、私も初心者の頃があって、誠実に回答してくれない人たちがいました。自分が、分からないとしても、本物かそうでないかぐらいは分かりましたから。 こうしたものは、アプリケーションのクラス(設計図)の中にあるのだと思います。ExcelのCのコードを見たわけではありませんし、イベント・ドリブン型を作るプログラムの勉強をしたことがありません。それと、VBAでは、不安定ですが、まったく違う作り方をするからです。また、イベント・ドリブン型のクラスは、「お仕着せ」ですから、加工できません。 (ByVal Target As Range) 自体は、ByValは、値参照の引数の用語です。変数 Targetは、特に予約語ではないし、任意だけど、ユーザー変数と差別化をし、その変数名をイベント・ドリブン型の変数名として扱います。なお、ユーザーが、このTargetを変数で使うのはルールには外れています。その変数を、相手(アプリケーション)側の変数型を維持せずに、そのまま引数として取り込まないという、意味です。 Private Sub Worksheet_SelectionChange() 本来なら、クラスから、仕組まれてなければ、これはエラーになるはずがありません。エラーになるのは、Worksheet オブジェクトの中に、そういうクラスの仕組みがあるからです。 Private Sub MyWorksheet_SelectionChange() では、エラーが出ません。しかし、 '--------標準モジュール-------------- Public myClass As Class1 Sub Auto_Open()  Set myClass = New Class1  Set myClass.MyWorksheet = ThisWorkbook.Worksheets(1) End Sub '---------クラスモジュール(Class1)------------- Public WithEvents MyWorksheet As Worksheet Private Sub MyWorksheet_SelectionChange(ByVal Target As Range)  MsgBox Target.Address End Sub '-------------------------------------------- こうすれば、同じように、MyWorksheet は、イベント・ドリブン型となります。シートに組み込んだからです。Worksheet_SelectionChangeとは別の存在になります。なお、ByVal の部分を、ByRef(参照渡し)に書き換えても、これは、大元のアプリケーション側のクラスの設定ですから、エラーが発生します。理由は、Worksheet のクラスにはそのようなイベント・ドリブン型はないからです。 ------------------------------------- これはエラーが発生します。 Dim Target As Range 'モジュールスコープ Private Sub Worksheet_SelectionChange(ByVal Target As Range)  Set Target = Target '外に出せない(変数名を変えればTest1には来る)  Call Test1 End Sub Sub Test1()  MsgBox Target.Address 'Target は来ていない End Sub -------------------------------------- これなら、通ります。 Private Sub Worksheet_SelectionChange(ByVal Target As Range)   Call Test1(Target) End Sub Sub Test1(Target As Range) 'Target を引数にする  MsgBox Target.Address End Sub -------------------------------------- どういうプログラムで送られているのか、私にはわかりません。 ByVal なのだから、Target のデータ型は、Range 型ではないかもしれないと思うので、 ---------------------------------------- エラー発生 Private Sub Worksheet_SelectionChange(ByVal Target As Variant) Private Sub Worksheet_SelectionChange(Target As Variant) ----------------------------------------- ByVal というのは、相手から送られてきたデータ型を無視して、こちらの型にあわせるという意味と、相手から送られてきたデータを外に直接出さないということです。 Target は、単なる単語で、予約語でも何でもありませんから、 Target を myRng に換えてみました。 ----------------------------------------- これは通ります。 Sub Worksheet_SelectionChange(ByVal myRng As Range)   MsgBox Time End Sub ------------------------------------------ これでも、コードが通ります。Private を付けておけば、よそからプロシージャを呼び出されることがありません。 結論としては、(ByVal Target As Range)は、Worksheetオブジェクトに仕組まれたクラスの中に、イベント・ドリブン型のコードがあるもので、Application から送られてきたものを、受け取る規定の引数=レセプタだと思います。 こんな話ではさっぱり分からないと思いますが……。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

まずイベントドリブン型がなんだかわからないので調べてみます。 一生懸命回答いただいたのに理解できないくてすいません 汗 ありがとうございます。

  • 回答No.3
  • imogasi
  • ベストアンサー率27% (4560/16325)

こんなの自然にわかると思っていたが。 選択が変わったとき、 (1)変わったという事実も伝えてほしいのはもちろん (2)どのセルで変わったか教えてほしいものだ この(2)の役割を果たしてくれるのが ByVal Target As Range で As Range はRange 易しく言うと内容はセルで知らせますと言うこと。MsgBox Target.Addressを入れてみると、数量的な目に見える形でセルの場所を表示できるようになる。 Private Sub Worksheet_SelectionChange() End Sub ここ()内(引数部分という)はユーザーが触るものでない。 この仕組みを作ったのはエクセルシステムでユーザーじゃない。他のイベントでこんな引数を返してほしいなあ、という場合も有るが、普通の技量ではどうしようもない。ユーザーが作るSUB、Functionプロシージァーなら自分で決めるのだから、ニーズによる。 質問者が作ったもので、引数を入れても入れなくても動くようにもかけるが質問者にとってずっと先のニーズだろう。 >ByValは概念的にByRefと対になっているが、VBAの上級に熟練するまでは、自分がプロシージュアーを作る場合のことで、ニーズが少ないだろう。気になるなら、GoogleでByRefで照会して記事を読むこと。 http://homepage1.nifty.com/CavalierLab/lab/vb/byvalbyref.html など多数。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

よく読んでみます。ありがとうございます。

  • 回答No.2
  • rukuku
  • ベストアンサー率42% (401/933)

こんばんは >(ByVal Target As Range)部分は何なのでしょうか? 例えば、以下のプログラムを試してみてください。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) MsgBox Target.Address End Sub Targetには新たに選択させたセル(または範囲)が格納されます。 これによって、選択されたセルによって処理を変えることができます。 例えば Private Sub Worksheet_SelectionChange(ByVal Target As Range) Target.Value = "AAA" End Sub としておくと、選択したセルにAAAが表示されます。 Target.Row Target.Column Target.Address などを使えば、特定の場所が選択されたときにだけ実行されるプログラムを作成できます。 >Private Sub Worksheet_SelectionChange() >End Sub >としたらエラーが返ってきました。 これは、 Private Sub Worksheet_SelectionChange(ByVal Target As Range) End Sub と「ByVal Target As Range」も含めて1つの「決まり文句」だと思ってください。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 こういう使い方をするのですね。 Target=ActiveCell と言う認識でよろしいでしょうか?

  • 回答No.1

>(ByVal Target As Range)部分は何なのでしょうか? >何のためにあるのかわかりません。 それまでと違うセルが選択されたときに、このイベントが発生します。 そのときに、どのセルが選択されたのか知りたいですよね? 選択されたセルがTargetになります。 Range("A1") や Cells(1, 1) と同じように使えます。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。

関連するQ&A

  • Excel VBA 他のシートに演算結果を入れたい

    例えば、A&#65374;Dというシートのいずれかのo1セルに数値を入力すると、演算結果がp1に入る場合。 A&#65374;Dのどのシートでもo1に入力したら、Z!p1にp1の値を放り込みたいのです。 で、以下のようなコードを書いたのですが、上手くいきません。 因みに、セルの移動方向はオプションで「右方向」に設定してあります。 ※結果としてセルの移動を認識していないのか、まったく無反応です。 ※Range("Z!$P$1") =… の行にブレークポイントを設定しても、引っかかりません。 何が悪いのかお教え頂ければ幸甚です。 >違うシートには代入できない… ってことでしょうか? Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Address = "$P$1" Then Range("Z!$P$1") = Range("$P$1") End If End Sub ※なお、出典元のSubは以下の様なもので、正常に動作していました。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Address = "$A$1" Then Range("B1") = Range("B1")+1 End If End Sub

  • 標準モジュールで 『Sub test(ByVal Target As Range)』は動かない?

    選択されている複数のアドレスが知りたいので 標準モジュールに Sub test(ByVal Target As Range) Debug.Print Target.Address End Sub と書きました。 しかしF5ボタンを押しても何も起こりません。 デバッグ→コンパイルをしてもエラーになりません。 シートのイベントプロシージャーではなく 標準モジュールにした理由は イベント発生時ではなく、任意で起動させたいためです。 ためしに、 Sub test(ByVal Target As Range) Debug.Print Target.Address End Sub の下に、 Sub test2() Call test End Sub と書いたら、 「引数は省略できません。」 というエラーになりました。 何がダメなのかわかりません。 ご教授よろしくお願い致します。

  • Excel VBAで変数が定義されていません。

    このシートコードで「変数が定義されていません。」となります。どうすればいいでしょうか。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) Select Case Target.Address Case "$C$10:$C$13" SendKeys "%{DOWN}" Case "$H$10:$H$13" SendKeys "%{DOWN}" Case Else Exit Sub End Select Cancel = True End Sub

  • VBAでエラートラップがうまくいきません。

    VBAで次のようなプロシージャを実行してみました。 Private Sub Worksheet_SelectionChange(ByVal Target As Range)   If Target.Value = " " Then          ~コード~   END IF END SUB すると複数のセルが選択されるとエラーがでます。そこで次のようにしてみました。 Private Sub Worksheet_SelectionChange(ByVal Target As Range)   On Error GoTo エラー処理   If Target.Value = " " Then     On Error GoTo 0           ~コード~   END IF   EXIT SUB エラー処理:   EXIT SUB END SUB ところがこれでもやっぱりIF文のところでエラーがでます。 当方初心者でなぜエラーがでるのかわかりません。 わかりやすくご教授ください。 よろしくお願いします。

  • (エクセルVBA)セルを左クリックしたら実行させるには?

    エクセルVBA初心者です。 下のように、同じシート内のコードとして2つのサブプロシージャがある状態なのですが、 シート内のどこかのセルを左クリック→指示(1) シート内のどこかのセルを右クリック→指示(2) のようにするにはどうしたらいいのでしょうか? (この状態だと、右クリックすると選択範囲が変わったことが優先的に認識されて指示(1)のほうが実行されてしまうようです。) 説明不足かもしれませんが、何を説明していいのか分からないので、補足が必要だったら言ってください。すみませんがよろしくお願いします。 --------------------------------------------------------------- Private Sub Worksheet_SelectionChange(ByVal Target As Range) 指示(1) End Sub --------------------------------------------------------------- Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean) 指示(2) End Sub ---------------------------------------------------------------

  • エクセルVBAで Cancel=Trueの使い方

    Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address <> "$A$1" Then Exit Sub Cancel = True MsgBox "キャンセルしました" End Sub Private Sub Worksheet_Deactivate() Cancel = True MsgBox "キャンセルしました" End Sub Private Sub Worksheet_SelectionChange(ByVal Target As Range) Cancel = True MsgBox "キャンセルしました" End Sub 以上のように使ってみましたが、どれも「キャンセルしました」とメッセージは出るものの、直前の操作(入力、シート切替、セル移動)はキャンセルされませんでした。 どこが間違っているのでしょうか?

  • VBA マクロの削除について教えてください

    VBEのWorksheet上にある、下記のコードが消えません。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) End Sub 全選択して、Deleteするのですが、消しても復活しています。 これ以上方法が思いつかないので、ご教示をおねがいします。

  • エクセルのカーソル移動 横スクロールを最後の入力列まで

    エクセルのカーソル移動について エクセルシートのコードはどこから貼り付け出来るのですか? Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Taget.Column=11 Then ActiveCell.Offset(1,-10).Select End If End Sub

  • エクセルマクロ(VBA)で指定したセルが変化したときに実行するには?

    VBAでsheetの中のworksheet_changeなどでマクロを書くと、そのシー トの中のどのセルを変化させてもマクロが実行されるのですが、これ を、A1とc1とc2が変化したときだけ処理を実行させたいのです。 以下のマクロのどこかを編集すると、そのようなことが出来るのでし ょうか? Private Sub Worksheet_SelectionChange(ByVal Target As Range) ----実行する内容---- End Sub Private Sub Worksheet_Change(ByVal Target As Range) ----実行する内容---- End Sub

  • シートのイベント VBA

    シートをクリックしたらシートをクリアしたいのですが クリックするセルがA1の場合は、マクロを実行させたくないのですが 下記のコードだとエラーになってしまいます。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Not Target.Range = Range("a1") Then Cells.Clear End If End Sub ”Range("a1")でなければ、Cells.Clearする” にはどうすればいいですか?