ロゴ(青) Excel/VBA Tips ロゴ(緑)

Tips07: 油断のならない『Activate 』

 UserForm の[Activate]イベント‥‥その名の通り「フォームがアクティブになる時に発生」
するイベントですが、実は油断のならない奴だって事を知ってますか?
  同じマクロを、Excel の「あるバージョン」から「別のバージョン」へ持っていくと、今まで発生
していたイベントが出なくなる(発生しなかったイベントが急に出て来る)んです。

-------------------------------------------------------------------------
  以下のような動作で
    UserForm1表示→UserForm1からUserForm2を表示→UserForm2を閉じてUserForm1へ戻る
『UserForm1へ戻った時』に、UserFormの[Activate]イベントが発生するバージョンと発生しな
いバージョンが有ります。
      ・Excel97(SR無し〜SR2)  ‥‥‥ 発生する
      ・Excel2000(SR無し)      ‥‥‥ 発生する
      ・Excel2000(SR1〜SP3)  ‥‥‥ 発生しない
      ・Excel2002                  ‥‥‥ 発生しない
  つまり、昔作った(複数のバージョン環境で使うので、古い方のバージョンで開発した)マクロが、
      『他UserFormから戻って来た時には[Activate]が発生する』
という前提で、「復帰処理」などをActivateイベントに書いていると、新しい方のバージョンでは、
期待通りに動かない事になります。
  逆に、新しい方のバージョンで[Activate]は、
      『[Initialize]直後、または、Hide 後に再びShowした瞬間、にのみ発生する』
と思って、Activateイベントに初期化処理などを入れたマクロを作った場合、昔の方のバージョン
で実行すると、その初期化処理が「他UserFormからの復帰時」にも動いてしまう事になります。

Activate イベント発生確認テスト
  1. UserForm1 と UserForm2 を用意する。
  2. UserForm1 には、TextBox1 と ListBox1 を貼り付け、下記コードをコピーする。
     尚、タブオーダーは、TextBox1→ListBox1 の順。LisBox1 がタブオーダー先頭だと、
     テスト(2)のパターンにより Activateが発生するようになる。
  3. UserForm2 には、任意のコントロールを貼り付ける。
  4. UserForm1 を実行し、フォーム上をクリックして UserForm2 を表示させ即閉じる。
  5. リストボックスに2個目の時刻(1個目はフォーム表示時)が表示されるか確認する。
  6. UserForm1 の TextBox1/ListBox1 を [TabStop = False] に変更してテストする。
  7. UserForm2.Show をコメントにして、代わりに MsgBox で同様にテストする。

      Private Sub UserForm_Activate()
          ListBox1.AddItem Format(Now, "hh:nn:ss")
      End Sub
      Private Sub UserForm_Click()
          UserForm2.Show    'MsgBox "Activate Test"
      End Sub



  補)  Excel2000(SR1〜SP3) / Excel2002でも、
              UserForm1 上に【有効なコントロール】がひとつも無い
      という場合では、上記のタイミングでActivateが発生します。
    「有効なコントロールが無い」とは
          ・UserForm1 上に入力系コントロールが全く無い
          ・UserForm1 上の入力系コントロールが全て[TabStop=False]または[Enabled=False]
      の何れかの状態の事です。

  同じようなパターンですが
      UserForm1表示→UserForm1からMsgBox(InputBox)を表示
                                    →MsgBox(InputBox)を閉じてUserForm1へ戻る
という場合には、どのバージョンであっても、「戻った時」にActivateイベントは発生しません

(2006/2/1 追記)
  Excel2000SR1以降のバージョンで、上記の「有効なコントロールがひとつも無い」の他にも
  Activate が発生するケースが見つかりました。
      UserForm2 を表示する直前に【リストボックスにフォーカスが有る】
  という状態では、UserForm2を閉じてUserForm1へ戻って来た際に[Activate ]が発生します。
  具体的には
    (a) リストボックスの Click もしくは DblClick イベントでUserForm2を表示する。
    (b) コマンドボタンやテキストボックスの Click もしくは DblClick イベント等からUserForm2を
        表示する場合は、その前にリストボックスへフォーカスを移す。
  という場合です。
 尚、MsgBox(InputBox) では、このケースでもActivate イベントは発生しません。

Activate イベント発生確認テスト(2)
  1. UserForm1 と UserForm2 を用意する。
  2. UserForm1 には、CommandButton1, ListBox1, TextBox1 を貼り付け、下記コードを
     コピーする。 尚、タブオーダーは CommandButton1/TextBox1→ListBox1 の順。
  3. UserForm2 には、任意のコントロールを貼り付ける。
  4. UserForm1 を実行し、フォーム上/ComanndoButton1のクリック、ListBox1のダブル
     クリック で UserForm2 を表示させ即閉じる。フォーム上のクリックテストの際は
     テキストボックスに フォーカスを移してから行なう。
  5. リストボックスに2個目の時刻(1個目はフォーム表示時)が表示されるか確認する。
  6. [ListBox1.SetFocus] をコメントにしてテストしてみる。
  7. UserForm2.Show をコメントにして、代わりに MsgBox で同様にテストする。

      Private Sub UserForm_Activate()
          ListBox1.AddItem Format(Now, "hh:nn:ss")
      End Sub
      Private Sub UserForm_Click()
          ListBox1.SetFocus UserForm2.Show    'MsgBox "Activate Test"
      End Sub
      Private Sub CommandButton1_Click()
          ListBox1.SetFocus UserForm2.Show    'MsgBox "Activate Test"
      End Sub
      Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
          UserForm2.Show    'MsgBox "Activate Test"
      End Sub



-------------------------------------------------------------------------
  Excel97 は、今でも多くの企業で現役として使われていますが、最近追加したPCや、これか
らリプレースして行こうとするPCは、時期からして「Excel2002」でしょう。そうすると、単純にマク
ロを新しいPCへ移行した際に、ここで説明する差異が原因で障害になる可能性が有りますから、
充分に注意してください。
  現在、Excel97が無くて、Excel2000と2002の混在といった環境ならば、Excel2000を【SR1】以
降へアップデートして機能を統一しておいた方が良いでしょう。



 Home   Back Page   Next Page

ロゴ(ゴールド)   ロゴ(ゴールド)

角田 桂一 Mail:addinbox@h4.dion.ne.jp CopyRight(C) 2001 Allrights Reserved.