[[20090707115312]] 『Worksheet.Calculate イベント 』(テン) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『Worksheet.Calculate イベント 』(テン)
Worksheet.Calculate イベント を使いセルの値が埋め込んだ計算式により変化した時に
 マクロの自動実行をさせているシートがあります。
 この時、条件によっては(セル値>10 なら実行など)延々とマクロが
 実行されつづけてしまいます(多重起動?)。
 処理として
 「コマンドボタンを押されている間一度だけの実行、そして実行されればボタン解除」
 に出来れば最善なのですが。。
 ちょっとコマンドボタンの解釈が間違っているかもしれませんが
 よろしくお願いします。

 Private Sub Worksheet_Change(ByVal Target As Range) 
    Application.EnableEvents = False
    '実行コード
    Application.EnableEvents = True
 End Sub
 
上記はChangeイベントのものですが、実行コードがセルの値の変更を
伴うものの場合、その変更によってChangeイベントが呼び出されます。
(再帰呼出といいます)
これを抑制する為に、EnableEventsプロパティ に Falseを設定して
イベントマクロから他のイベントマクロを呼び出してしまうのを抑制
します。最後にEnableEventsプロパティ に Trueを設定してイベント
の発生を有効にするのをお忘れなく。
(みやほりん)(-_∂)b

ご回答ありがとうございます。
 試してみたところばっちりな手ごたえでした!ありがとうございます!
 これはCalculateのままではなくChangeに変更して使うと理解してよろしいでしょうか?
 いずれにせよEnableEventsプロパティを自分でも解釈してみようと思います。

 ありがとうございました!!

 Calculateではないといけないと思いますよ?
 計算させたときにマクロを実行するのですよね。
 Changeでは計算させたときに上記イベントが発生しません。
 (計算結果が変更になっていて計算式が変更になっているわけではないから。)

 Changeはセルの変更があったときのイベントマクロになります。
 (ミニドナ) 2009/7/7 13:30

 >上記はChangeイベントのものですが、
と、お断りを入れたつもりだったのですが・・・誤解しちゃいましたかね。
(みやほりん)(-_∂)b

質問者のテンです。
 すいません!やっぱり希望通りには動きませんでした!><;
 早とちりしてしまいました。ごめんなさい;;
 ミニドナさんの仰るとおり計算させたときにマクロを実行させています。
 もう少し具体的に書きます。

 「A1セルに計算式がありWorksheet.Calculate イベント を使い
 値が10以上になればbasp21を経由して携帯にメール送信」

 この時点でメール送信までは出来ているのですが
 セル値が10以上だと延々とメールが送られ続けてしまいます。
 このときのメール送信を一度までにしたいのです。(一度の定義はブックを開いて閉じるまでの間、
 もしくはコマンドボタン?が押されている間一度だけの実行などです。)

 また他サイトを見ますとメール関連はスパム利用されないようあまり詳しく記述されていないようでしたので 
 今回の質問もそれに触れるとすれば残念ですが諦めます;;
 よろしくお願いします。

 私はマクロに詳しくないので、回答するのは難しいですが、
 少なくとも具体的なマクロを見せていただかないと、
 どこに問題があるかわからないと思います。
 (アドバイスできたとしても推測でしかありませんし)

 送信するアドレス等はこちらに載せるときは適当なもので構わないと思いますので、
 今、お使いのマクロを提示されてみては?
 (ミニドナ) 2009/7/8 10:04

 よろしくお願いしますテンです。
 あれからEnableEventsを調べて見たところ
 EnableCalculationなるものを見つけまして素人解釈ながら作っておりました。
 現状では下記のマクロを組み合わせて一連の作業自体はできております。
 ただし非常に不安定です。
 では継ぎ接ぎだらけで少し恥ずかしいですがマクロ提示してみます。

 ※A1セル>10の時に... の10のところはB2参照にしました。
 Private Sub Worksheet_Calculate()
    If Cells(1, 1).Value > Cells(1, 2).Value  Then
    call メール送信
    ActiveSheet.EnableCalculation = False
    End If
 End Sub

 Sub 再計算有効()
    ActiveSheet.EnableCalculation = True
 End Sub

 Sub メール送信()
    Dim bobj, msg As String
    Dim Server As String, Mailto As String, MailFrom As String, Subject As String, Body As  String
    Set bobj = CreateObject("basp21")   
    Server = "SMTPサーバー"           
    Mailto = "宛先" 
    MailFrom = "差出し人"  
    Subject = "タイトル"               
    Body = "本文 "     
    msg = bobj.SendMail(Server, Mailto, MailFrom, Subject, Body, "")
    Set bobj = Nothing
    If msg <> "" Then MsgBox msg
 End Sub

 3番目の「メール送信」マクロは問題なく動くので関係ないかとおもいます。
 意図としては Cells(1, 1).Value > Cells(1, 2).Value  の時に「メール送信」マクロ起動、そしてそのシート自体の再計算を
 「ActiveSheet.EnableCalculation = False」  にて無効にする。
 そして再度「メール送信」マクロを設置(?)する際に「再計算有効」マクロを使う。
 といったところです。
 もう少しスマートに出来れば、と思います。
 よろしくお願いします。

 ちょっと最初予想していたものと、マクロの内容が違うので、
(再計算イベントでメールを送信しており、なおかつ、再計算の
起こるようなステートメントがあって、イベントの再起呼び出しにより
メールが何回も送られる・・・と予想した)
仕切りなおしになりますが、
どういうタイミングでメールを送りたいのか、
どういうタイミングでは送りたくないのか、
これをつめておかないと、思うように動かせません。
 
トリガーが再計算イベントなので、
メールを送ったら、グローバル変数でフラグを立てる。
再計算が行なわれてもフラグがたっている場合にはメールを送らない、
というような仕組みにしてみては。
(みやほりん)(-_∂)b ちょっと追記・修正

 返信おくれました質問者のテンです。 
 みやほりんさんのレスを見てから
 グローバル変数について調べてみました。(ほとんど初見といえるほどの初心者なもので。。)
 が、なかなか他サイトを巡ってみても良く理解できなく、消化せずに今います。
 なのでもう少し自分なりに調べて見てからまたご相談させてください。

 また、勝手ですがグローバル変数等、勉強するに良いサイトご存知であればお教え頂ければと思います。

 みやほりんさん、ミニドナさん、アドバイスありがとうございました!

 本質的にロジックを見直した方が良いように思います。

 たとえば、A1が再計算されるという事はその前になんらかのトリガーがありますよね?
 (A1の計算結果が変わる理由)
 そちらをトリガーにするとか
 あとは、Calcイベントを使うにしても送信の可否を問うMsgBoxを出すとか。

 というのは、再計算される度に勝手にメールを送信するような物は
 私はスパムと大して変わらないと思ってしまうのです。
 それをTestする事自体に不安がありますし、ネットワーク負荷を生むことになると思うので。

 (momo)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.