システムメンテナンスのお知らせ

Excel VBA で、コンボボックスの選択をユーザーが変更した時はイベントハンドラが呼び出されて処理をしていますが、VBAのコードからコンボボックスの選択を変更した時には、このイベントハンドラが呼び出されないようにしたいのですが、どのように記述すればよいでしょうか。
例えば、下記のコードの (A) の部分で、VBAのコードからコンボボックスの選択を変更していますが、ここでイベントが発生しないようにしたいのですが、Application.EnableEvents = False を記述してもイベントが発生していますがなぜでしょうか。どのように記述すれば (A) の部分でイベントが発生しなくなりますでしょうか。
よろしくお願いします。(Windows7 , Excel2010 )

---Module1----------
Option Explicit
Sub main()
 UserForm1.Show
End Sub
---UserForm1--------
Option Explicit
Private Sub UserForm_Initialize()
 Dim i As Integer
 ComboBox1.Style = fmStyleDropDownList
 For i = 1 To 30
  ComboBox1.AddItem Format(i, "00")
 Next i
End Sub
Private Sub CommandButton1_Click()
 Dim num As Integer
 Dim index As Integer
 num = ComboBox1.ListCount
 index = ComboBox1.ListIndex
 If index = num - 1 Then
  Application.EnableEvents = False
  ComboBox1.ListIndex = -1 '<----------(A)
  Application.EnableEvents = True
 Else
  ComboBox1.ListIndex = index + 1
 End If
End Sub
Private Sub ComboBox1_Change()
 MsgBox ("ComboBox1_Changeイベント発生")
End Sub

------------------------------------

gooドクター

A 回答 (3件)

こんにちは。



まだ、閉じていない所をみると、満足していないということでしょうか。
ただ、常識的には、ComboBox1.ListIndex = -1 と、ComboBox 側の値を変更しているのですから、Changeイベントは発生します。本来、避けられないことというよりも、以下の部分に疑問が残ります。

問題は、
Private Sub ComboBox1_Change()
 '本当は、ここで何をしているのか、何をするのかではないのでしょうか?
End Sub

この部分が明らかになっていないようです。
何を言いたいかというと、ComboBox1_Changeの選択自体が安易ではなかったのではないか、ということになりますね。おそらく、私なら、ComboBox1_Changeのイベントを他のものに変えていると思います。
ComboBox1_Changeのイベントは、センシティブのような気がします。選択すること自体にイベントが発生していたら、たまったものではないと思うのですが……

ただ、それは私自身の問題になってしまいますから、
その部分で、CommandButtonからのものは排除するという暫定処置を考えます。
ブランクなら、ブランクのIf文を作ればよいです。

'//
Private Sub ComboBox1_Change()
 If ActiveControl.Name Like "CommandButton*" Then Exit Sub
 MsgBox ("ComboBox1_Changeイベント発生")
End Sub
    • good
    • 0
この回答へのお礼

If ActiveControl.Name Like "CommandButton*" Then Exit Sub がすっきりしていていい感じです。
最初、このコードを見た時、CommandButton1_Click()の中のComboBox1.ListIndex = -1 の処理で、ComboBox1_Change()のイベントが発生しているので、ActiveControl.Nameの部分はComboBox1になるのではないかと心配していましたが、実際に確認してみると、CommandButton1になっていて期待通りExitします。
また、この方法で、ユーザーが操作したのか、VBAコードで操作したのか、どちらなのかを知ることもできるので、とても参考になりました。
ありがとうございました。

お礼日時:2014/07/07 09:16

行おうとしていることは、コンボボックスで最終番号を選んだ場合、コマンドボタンを押せば選択状態をクリアするように読めました。



そもそもの話ですが、「Application.EnableEvents = False」で止められるのは、Excelオブジェクトのイベントだけで、Formsオブジェクトのイベントは止めることはできません。コードはいいんですが、機能しないわけです。

EnableEventsを使うという考えを生かすには、以下のようにすれば(フラグを設定する)イベントは実行されないはずです。

机上デバッグです。確認してください。


Option Explicit

Dim CancelFlg as Boolean   ’■追加

Private Sub ComboBox1_Change()
  If CancelFlg Then Exit Sub           ’■追加

  MsgBox ("ComboBox1_Changeイベント発生")
End Sub

::
::
If index = num - 1 Then
’  Application.EnableEvents = False  ’■コメント
  CancelFlg=True              ’■追加
  ComboBox1.ListIndex = -1 '<----------(A)
’  Application.EnableEvents = True   ’■コメント
  CancelFlg=False              ’■追加
Else

    • good
    • 0
この回答へのお礼

nishi6さん。
やはりフラグなどでの対処ということになりますかね。
暫定対策として、ComboBox1_Change()の中で、ブランクの時は何もしないでそのまま戻るようにしていたのですが、なぜイベントが起きてしまうのかという不思議な思いもあったので、Formsオブジェクトのイベントには使えないということが分かっただけでも質問してよかったです。
ありがとうございました。

お礼日時:2014/07/02 15:50

 If index = num - 1 Then


  Application.EnableEvents = False
  ComboBox1.ListIndex = -1 '<----------(A)
  Application.EnableEvents = True
 Else
  ComboBox1.ListIndex = index + 1
 End If

 If index <> num - 1 Then
  ComboBox1.ListIndex = index + 1
 End If
のようにすればいいのではないでしょうか。

この回答への補足

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

でもこれだと30の時にブランクにならないという問題があります。

補足日時:2014/07/02 15:31
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

gooドクター

人気Q&Aランキング