過去ログ

                                Page     838
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   通常モードに戻る  ┃  INDEX  ┃  ≪前へ  │  次へ≫   
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 ▼Clearメソッドはイベント抑止無効?  自己満足 03/3/6(木) 11:41
   ┗Re:Clearメソッドはイベント抑止無効?  ichinose 03/3/6(木) 12:31
      ┗やってみました....が  自己満足 03/3/6(木) 13:19
         ┗Re:やってみました....が  ichinose 03/3/6(木) 15:04
            ┗やっとわかりました m(_ _)m  自己満足 03/3/6(木) 17:02

 ───────────────────────────────────────
 ■題名 : Clearメソッドはイベント抑止無効?
 ■名前 : 自己満足
 ■日付 : 03/3/6(木) 11:41
 -------------------------------------------------------------------------
   皆さんこんにちは。
Clearメソッド(メソッドで良かったですよね)に付いてお聞きします。

EnableEventsプロパティーでイベント抑止を掛けているはずなのですが、
Aと言うコンボボックス内に値がある場合、抑止を記述している別プロシージャーから
そのAのコンボボックスに対しClearメソッドを実行すると
そのAのコンボボックスのChangeイベントプロシージャーを実行してしまいます。
VBEデバッグのステップイン実行でEnableEvents行にカーソルを持っ行き、確認すると
Changeイベントプロシージャー実行中もEnableEvents は False になっています。
Clearメソッドにイベント抑止は無効なのでしょうか?それともプロシージャーが
まずいのでしょうか?

以下はテストマクロです。

<やりたい事>
ComboBox1とComboBox2の項目関係をトーナメント形式で対応させ
ComboBox1でAの項目を選択するとComboBox2にaの項目が登録され、B項目を選択するとb項目が登録されるようにする。
操作としては、すでにComboBox2の項目が選択されていてもComboBox1の項目を再選択するとComboBox2の値はクリアーしたい。
また、ComboBox1を選択せずにComboBox2に値を入れさせたくない。

<準備とコード概要>
UserForm1にComboBox1とComboBox2が有り、シート1の10行目と20行目と30行目の
それぞれのA列セルに数字、B列以降にA列セル数字の数だけ文字列データーが有ります。
ComboBox1の項目はフォーム読込み時に登録し、ComboBox2の項目は
ComboBox1の選択値によってシート1の文字列データーを登録するようにしています。
UserForm1にコードを書きます。
ComboBox2の作成時にプロパティーウインドウ内でEnable=Falseとしておく。

<現象>
ComboBox1で項目を選択し、ComboBox2で項目を選択した後、続けてComboBox1の別項目を選択すると
一時はComboBox2がフォーカスを取得しますがCliarでChangeイベントを拾ってしまい、ComboBox2がフォーカスを破棄します。
さらにもう一度ComboBox1の別項目を選択するとComboBox2のListIndexは -1 であるので
Changeイベントが発生せずにComboBox2がフォーカスを取得したままとなります。


Private Sub ComboBox1_Change()
Application.EnableEvents = False
  With UserForm1
    If .ComboBox1.ListIndex = -1 Or .ComboBox1.ListIndex = 0 Then
        .Controls("ComboBox" & 2).Clear
        .Controls("ComboBox" & 2).Enabled = False
      Else
        .Controls("ComboBox" & 2).Enabled = True
        .Controls("ComboBox" & 2).Clear  '既入値有ればここでイベント発生
        For i = 1 To Val(Sheet1.Cells(.ComboBox1.ListIndex * 10, 1).Text)
          .ComboBox2.AddItem Sheet1.Cells(.ComboBox1.ListIndex * 10, 1 + i).Value
        Next i
    End If
  End With
Application.EnableEvents = True
End Sub

Private Sub ComboBox2_Change()
With UserForm1
  If .ComboBox2.ListIndex = -1 Then
        .Controls("ComboBox" & 2).Enabled = False
    Else
        .Controls("ComboBox" & 2).Enabled = True
  End If
End With
End Sub

Private Sub UserForm_Initialize()
  With UserForm1.ComboBox1
    .AddItem ""
    .AddItem "1"
    .AddItem "2"
    .AddItem "3"
  End With
End Sub
 ───────────────────────────────────────  ■題名 : Re:Clearメソッドはイベント抑止無効?  ■名前 : ichinose  ■日付 : 03/3/6(木) 12:31  -------------------------------------------------------------------------
   ▼自己満足 さん:
こんにちは。
>Clearメソッド(メソッドで良かったですよね)に付いてお聞きします。
>
>EnableEventsプロパティーでイベント抑止を掛けているはずなのですが、
>Aと言うコンボボックス内に値がある場合、抑止を記述している別プロシージャーから
>そのAのコンボボックスに対しClearメソッドを実行すると
>そのAのコンボボックスのChangeイベントプロシージャーを実行してしまいます。
>VBEデバッグのステップイン実行でEnableEvents行にカーソルを持っ行き、確認すると
>Changeイベントプロシージャー実行中もEnableEvents は False になっています。
>Clearメソッドにイベント抑止は無効なのでしょうか?それともプロシージャーが
>まずいのでしょうか?
>
>以下はテストマクロです。
>
><やりたい事>
>ComboBox1とComboBox2の項目関係をトーナメント形式で対応させ
>ComboBox1でAの項目を選択するとComboBox2にaの項目が登録され、B項目を選択するとb項目が登録されるようにする。
>操作としては、すでにComboBox2の項目が選択されていてもComboBox1の項目を再選択するとComboBox2の値はクリアーしたい。
>また、ComboBox1を選択せずにComboBox2に値を入れさせたくない。
>
><準備とコード概要>
>UserForm1にComboBox1とComboBox2が有り、シート1の10行目と20行目と30行目の
>それぞれのA列セルに数字、B列以降にA列セル数字の数だけ文字列データーが有ります。
>ComboBox1の項目はフォーム読込み時に登録し、ComboBox2の項目は
>ComboBox1の選択値によってシート1の文字列データーを登録するようにしています。
>UserForm1にコードを書きます。
>ComboBox2の作成時にプロパティーウインドウ内でEnable=Falseとしておく。
>
><現象>
>ComboBox1で項目を選択し、ComboBox2で項目を選択した後、続けてComboBox1の別項目を選択すると
>一時はComboBox2がフォーカスを取得しますがCliarでChangeイベントを拾ってしまい、ComboBox2がフォーカスを破棄します。
>さらにもう一度ComboBox1の別項目を選択するとComboBox2のListIndexは -1 であるので
>Changeイベントが発生せずにComboBox2がフォーカスを取得したままとなります。
ActiveXControlのイベント発生の有無をApplication.EnableEventsプロパティーでは
制御できなかったと思いますよ。
ですから、それぞれのイベントでApplication.EnableEventsプロパティーをみて、
Falseだったら、処理をしないコードをかかなくてはならないかと思います。
'=================================
Private Sub ComboBox1_Change()
if Application.EnableEvents = true then
  application.EnableEvents = false
  With UserForm1
    If .ComboBox1.ListIndex = -1 Or .ComboBox1.ListIndex = 0 Then
        .Controls("ComboBox" & 2).Clear
        .Controls("ComboBox" & 2).Enabled = False
      Else
        .Controls("ComboBox" & 2).Enabled = True
        .Controls("ComboBox" & 2).Clear  '既入値有ればここでイベント発生
        For i = 1 To Val(Sheet1.Cells(.ComboBox1.ListIndex * 10, 1).Text)
          .ComboBox2.AddItem Sheet1.Cells(.ComboBox1.ListIndex * 10, 1 + i).Value
        Next i
    End If
  End With
  end if
Application.EnableEvents = True
End Sub
のような処理です。
 ───────────────────────────────────────  ■題名 : やってみました....が  ■名前 : 自己満足  ■日付 : 03/3/6(木) 13:19  -------------------------------------------------------------------------
   ichinose さん
早速のご回答ありがとうございます。

投稿原稿を書く時間より短い時間で原因がおわかりになるとは
やはり、知識人には脱帽です。

で、記入頂いたコードそのままをコピーして実行したのですが同じ現象が発生します。

VBEデバッグのステップイン実行でEnableEvents行にカーソルを持っ行き、確認すると
ClearでChangeイベントプロシージャーに飛ぶ前、実行中、後もEnableEvents=False になっています。
Private Sub ComboBox1_Change()の最終行にある
Application.EnableEvents = True

Trueに戻るのは End Sub 行に黄色い帯が入ったときに確認できました。

もしかして、何かVBAで初期設定的なものが有るのでしょうか。
他のPCでこのコードが入っているファイルを起動して、試したいのですが15時頃でないと空かないそうですのでおあずけを食らっています。
 ───────────────────────────────────────  ■題名 : Re:やってみました....が  ■名前 : ichinose  ■日付 : 03/3/6(木) 15:04  -------------------------------------------------------------------------
   ▼自己満足 さん:
>早速のご回答ありがとうございます。
>
>投稿原稿を書く時間より短い時間で原因がおわかりになるとは
>やはり、知識人には脱帽です。
>
>で、記入頂いたコードそのままをコピーして実行したのですが同じ現象が発生します。
>
>VBEデバッグのステップイン実行でEnableEvents行にカーソルを持っ行き、確認すると
>ClearでChangeイベントプロシージャーに飛ぶ前、実行中、後もEnableEvents=False になっています。
>Private Sub ComboBox1_Change()の最終行にある
>Application.EnableEvents = True
>で
>Trueに戻るのは End Sub 行に黄色い帯が入ったときに確認できました。
前回のコードは一例で載せたにすぎません。
私が言いたかったのは、EnableEventsのTrue、Falseがコントロールのイベント発生の
有無には関係ないのでは・・・と言う事でして・・。
示したコードのように、フラグでイベントの実行を制御しなければならないということです(私は、既製のApplication.EnableEventsプロパティを使いましたが)。
よって、Combobox2のChangeイベントでも同じような制御、
if application.EnableEvents=true then
  '実行処理
'
'
  end if
の制御が必要になってきます。
 ───────────────────────────────────────  ■題名 : やっとわかりました m(_ _)m  ■名前 : 自己満足  ■日付 : 03/3/6(木) 17:02  -------------------------------------------------------------------------
   ichinose さん:
やっ、やっとわかりました。

>私が言いたかったのは、EnableEventsのTrue、Falseがコントロールのイベント発生の
>有無には関係ないのでは・・・と言う事でして・・。
>示したコードのように、フラグでイベントの実行を制御しなければならないということです(私は、既製のApplication.EnableEventsプロパティを使いましたが)。

私なりの理解で、ちょっとニアンスが違うかもしれませんが
VBコードで設定しているからとVB任せにせずに、やばそうな所や動きがおかしい所はちゃんと明確なチェックを入れなさいよ....と言うことでフラグチェックの一例をあげて頂けた訳ですね。

>よって、Combobox2のChangeイベントでも同じような制御、
>if application.EnableEvents=true then
>  '実行処理
>'
>'
>  end if
>の制御が必要になってきます。

これできっちりと出来ました。
お手数をお掛けました。ありがとうございます。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    通常モードに戻る  ┃  INDEX  ┃  ≪前へ  │  次へ≫    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━                                 Page 838