Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


964 / 13644 ツリー ←次へ | 前へ→

【77218】関数ではなくてマクロでやりたいのです。 翔子 15/6/18(木) 15:27 質問[未読]
【77219】Re:関数ではなくてマクロでやりたいのです。 kanabun 15/6/18(木) 17:03 発言[未読]
【77220】Re:関数ではなくてマクロでやりたいのです。 β 15/6/18(木) 17:39 発言[未読]
【77221】Re:関数ではなくてマクロでやりたいのです。 kanabun 15/6/18(木) 17:54 発言[未読]
【77226】Re:関数ではなくてマクロでやりたいのです。 翔子 15/6/19(金) 8:53 質問[未読]
【77227】Re:関数ではなくてマクロでやりたいのです。 β 15/6/19(金) 11:40 発言[未読]
【77233】Re:関数ではなくてマクロでやりたいのです。 翔子 15/6/20(土) 21:08 お礼[未読]

【77218】関数ではなくてマクロでやりたいのです。
質問  翔子  - 15/6/18(木) 15:27 -

引用なし
パスワード
   よろしくお願いします。

E3に値が入っています。
1 D6に値が入ったら、C6にE3の値が入るように。
2 D7に値が入ったら、C7にE3の値が入るように。
3 D8に値が入ったら、C8にE3の値が入るように。
4 D9に値が入ったら、C9にE3の値が入るように。
5 D10に値が入ったら、C10にE3の値が入るように。
したいのですが、IF関数ではなくマクロでやりたいのですが
教えてください
よろしくお願いします。

【77219】Re:関数ではなくてマクロでやりたいので...
発言  kanabun  - 15/6/18(木) 17:03 -

引用なし
パスワード
   ▼翔子 さん:


>E3に値が入っています。
>1 D6に値が入ったら、C6にE3の値が入るように。
>2 D7に値が入ったら、C7にE3の値が入るように。
>3 D8に値が入ったら、C8にE3の値が入るように。
>4 D9に値が入ったら、C9にE3の値が入るように。
>5 D10に値が入ったら、C10にE3の値が入るように。
>したいのですが、

シートのモジュール(マクロを書くところ)に
以下のコードを記述します。

Private Sub Worksheet_Change(ByVal Target As Range)
  Dim r As Range
  Dim c As Range
  Set r = Intersect(Target, Range("D6:D10"))
  If r Is Nothing Then Exit Sub
  
  For Each c In r
    If Not IsEmpty(c.Value) Then
      c.Offset(, -1).Value = Range("E3").Value
    End If
  Next
End Sub

このコードは そのワークシートのセルに変化があったときに 動きます。

>  Set r = Intersect(Target, Range("D6:D10"))

このコードは 変化のあったセル Target(複数セルのばあいも考慮) と
[D6:D10] と比べ、変化のあったセルTarget が [D6:D10]のなかに入っているとき
のみ、それ以降の処理を実行します。

>    If Not IsEmpty(c.Value) Then
>      c.Offset(, -1).Value = Range("E3").Value
>    End If

ここは 変化のあったD列のセルの値が 空 でないときには [E3]セルの値を
そのセルの比ダル隣りのC列セルに 値コピー しています。

(Deleteキーがおされて セルの値がクリアされた時も このマクロは走ります。
そのばあいは どうしたらいいのかな? 今は、何も書いていません)

【77220】Re:関数ではなくてマクロでやりたいので...
発言  β  - 15/6/18(木) 17:39 -

引用なし
パスワード
   ▼kanabun さん:

失礼します。
イベント連鎖があっても、最初の領域チェックで抜けますので問題はありませんが
やはり、無駄なイベント連鎖はなくしたほうがいいと思いますが。

【77221】Re:関数ではなくてマクロでやりたいので...
発言  kanabun  - 15/6/18(木) 17:54 -

引用なし
パスワード
   ▼β さん:
>▼kanabun さん:
>
>やはり、無駄なイベント連鎖はなくしたほうがいいと思いますが。

おお、そうでした。ご指摘、感謝
プロシージャ・コード、再掲します。

Private Sub Worksheet_Change(ByVal Target As Range)
  Dim r As Range
  Dim c As Range
  Set r = Intersect(Target, Range("D6:D10"))
  If r Is Nothing Then Exit Sub
  
  Application.EnableEvents = False '●追加
  For Each c In r
    If Not IsEmpty(c.Value) Then
      c.Offset(, -1).Value = Range("E3").Value
    End If
  Next
  Application.EnableEvents = True  '●追加
End Sub

【77226】Re:関数ではなくてマクロでやりたいので...
質問  翔子  - 15/6/19(金) 8:53 -

引用なし
パスワード
   kanabun様
β様
コメントが大変遅くなりまして申し訳ございません。


kanabun様
<(Deleteキーがおされて セルの値がクリアされた時も このマクロは走ります。
<そのばあいは どうしたらいいのかな? 今は、何も書いていません)
Deleteキー押されたときは、そのままでで大丈夫です。
再コメント有難うございました。

β様
<イベント連鎖があっても、最初の領域チェックで抜けますので問題はありませんが
<やはり、無駄なイベント連鎖はなくしたほうがいいと思いますが。
無駄なイベント連鎖とは何ですか?
何かあるのですか?

【77227】Re:関数ではなくてマクロでやりたいので...
発言  β  - 15/6/19(金) 11:40 -

引用なし
パスワード
   ▼翔子 さん:

>無駄なイベント連鎖とは何ですか?
>何かあるのですか?

Changeイベントはご存知の通り、そのシートのセルに変更があった場合にとんできますね。

で、この処理コードの中で

c.Offset(, -1).Value = Range("E3").Value

これは変更のあったセルの1つ左、つまりC列のセルに書き込みを行っていますね。
すると、その瞬間に、Changeイベントが発生して、このプロシジャに再入してきます。
先頭に、D6:D10 以外の変更なら抜けるコードがありますので、何もしないで抜けるわけですが
無駄ですよね。

また、要件によって先頭の領域チェックがないような処理の場合、無限ループにおちります。

なので、Chengeイベント内で、セル変更をする場合はkanabunさんが再掲されたように
Application.EnableEvents を事前に False にし、変更が終わったら True にするのが
「鉄則」です。

【77233】Re:関数ではなくてマクロでやりたいので...
お礼  翔子  - 15/6/20(土) 21:08 -

引用なし
パスワード
   β様

説明ありがとうございました。
勉強になりました

964 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free