• ベストアンサー

変化するセルが変更されたら実行、というVBAを組みたい

たとえば、このセルが変更されたら実行、というのは Private Sub WorkSheet_change (Byval Target As Range) If(Target.Address = "$D$3") Then call *** End If End Sub のようにしますよね? この場合、指定したセルは「D3」ですが、たとえば、 A列、B列、C列、D列のアクティブの行のセルが変更されたらコード実行、 というようにするにはどうしたらいいのでしょうか?

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

  • ベストアンサー
noname#240783
noname#240783
回答No.3

ChangeプロシージャのTargetには内容が変更されたセルの 位置情報が入っています。 しかし、ActiveCellには現在カーソルのある(太枠表示)セルの 位置情報が入っています。 Activeプロシージャは、Enterキーが押されたり、他のセルがクリックされたり した時に発生します。ということは、ActiveCellは常に「Changeイベントが発生したセル」とは 異なっています。 よって、メッセージボックスは表示されません。 > A列、B列、C列、D列のアクティブの行のセルが変更されたらコード実行 「セルが変更」されるとは、 「内容が変更されたセルからフォーカスが別のセルに移」 らないとなりません。つまりアクティブセルは常に 「変更を加えたセル」以外になりますので、 ちょっと意味がわからないのですが、 下記のようではダメでしょか?? ' A列~D列で変更があった場合 Dim r&, c& c = target.Column If 1 =< c And c <= 4 Then MsgBox r End If ' A列~D列の3行目から5行目のセルで変更があった場合 Dim r&, c& r = Target.Row c = target.Column If (3 <= r And r <= 5) and (1 =< c And c <= 4) Then MsgBox r End If などなど...

w-inty
質問者

お礼

回答ありがとうございます。 どうやら無事動いているようです。 追加質問なのですが、 Dim r&, c& c = Target.Column Dim w As Integer Dim Mark As String w = ActiveCell.Row Mark = Cells(w - 1, 2) If 2 <= c And c <= 16 Then If Mark = "" Then Call A ElseIf Mark = "休" Then Call B End If End If とあり、Aの方は無事ちゃんと動きました。 Bの方が以下のようになっています。 Dim w As Integer w = ActiveCell.Row w = w - 1 Cells(w, 11) = "あ" Cells(w, 14) = "い" これで無限ループになってしまうのです。 なぜなのでしょうか? よろしくお願いします。

その他の回答 (3)

noname#240783
noname#240783
回答No.4

うむむ、ハマりましたね、ドツボに。 > Cells(w, 11) = "あ" セルに値を代入していますね。 ということはこの時点で「Changeイベント」が発生して、 「Cahngeプロシージャ」に制御が飛び込んできますが そこでまたCall B が発生して、 セルに値を代入してChangeイベントが発生して...ひい~っ! ということではないでしょうか!?。 どのような仕様のプログラムかわからないのでなんともいえませんので とりあえず手がかりを提示しておきます。 ・ひとつの案 Changeイベントを拾わずに、SelectionChangeイベントにする。 具体的には、今 Worksheet_Change()プロシージャに書かれているコードを Worksheet_SelectionChange()プロシージャに移し変える。 ・もうひとつの案 フラグ用にパブリック変数を作り、Call B が発生するときは フラグを立てて、対象範囲を処理中はChangeプロシージャに再度飛び込んできても 無処理で抜けるようにする。 SelectionChangeイベントを使う方法は、作成するプログラムの目的や仕様に よってはうまくいかないかもしれません。 また、フラグで制御は結構面倒くさいんですが...(ワラシこれちか知ゅらないの、たはは) こういった問題で別に質問を立てたほうが 色々なアイデアを出してくれる「すごい」人がいるかもしれませんねぇ

w-inty
質問者

お礼

回答ありがとうございます。 ハマってました…(笑) ifやら何やら使い何とかぬけだしました(^^; ありがとうございました。

  • kmb01
  • ベストアンサー率45% (63/138)
回答No.2

if文のところにブレークポイントを設定して実行時の値を確認してください

w-inty
質問者

お礼

すいません、#3の方の回答でうまくいきそうです。 ありがとうございました。

  • kmb01
  • ベストアンサー率45% (63/138)
回答No.1

Dim r&, c& r = Target.Row: c = Target.Column If r = ActiveCell.Row And c >= 1 And c <= 4 Then みたいなかんじですかね

w-inty
質問者

お礼

回答ありがとうございます。 こういうことでいいのでしょうか? Private Sub worksheet_change(ByVal target As Range) Dim r&, c& r = target.Row: c = target.Column If r = ActiveCell.Row And c >= 11 And c <= 16 Then MsgBox r としてみたんですが、メッセージボックスが表示されませんでした。