Excel VBA質問箱 IV

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

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


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

【41630】ユーザーフォームのコントロールのイベント処理選択 ハナ 06/8/17(木) 15:11 質問[未読]
【41632】Re:ユーザーフォームのコントロールのイ... neptune 06/8/17(木) 17:38 回答[未読]
【41633】Re:ユーザーフォームのコントロールのイベ... ichinose 06/8/17(木) 21:29 発言[未読]
【41644】Re:ユーザーフォームのコントロールのイベ... ハナ 06/8/18(金) 8:25 発言[未読]
【41646】ユーザーフォームのコントロールのイベント... ハナ 06/8/18(金) 9:20 質問[未読]
【41647】Re:ユーザーフォームのコントロールのイベ... ichinose 06/8/18(金) 9:56 発言[未読]
【41650】Re:ユーザーフォームのコントロールのイ... ハナ 06/8/18(金) 10:34 お礼[未読]
【41653】Re:ユーザーフォームのコントロールのイ... neptune 06/8/18(金) 11:28 発言[未読]
【41657】Re:ユーザーフォームのコントロールのイ... ハナ 06/8/18(金) 14:18 発言[未読]
【41668】Re:ユーザーフォームのコントロールのイ... neptune 06/8/18(金) 21:50 発言[未読]

【41630】ユーザーフォームのコントロールのイベン...
質問  ハナ  - 06/8/17(木) 15:11 -

引用なし
パスワード
   いつも参考にさせていただいております。
今回、ユーザーフォーム上に入力必須のテキストボックスtxtTCDとそれ以外のテキストボックスを幾つか。それとCommandButton1を配置して 
  ・txtTCDには7桁の数字(取引先コード)以外の入力はエラー先に進めない。
  ・全てのテキストボックスクリア(入力内容消去)をCommandButton1_Clic
   に割り付け、随時実行可能とする
といったフォームを作成したところ

Private Sub txtTCD_Exit(ByVal Cancel As MSForms.ReturnBoolean)
  If (Len(txtTCD.Text) <> 7) Or (IsNumeric(txtTCD.Text) = False) Then
    Cancel = True
    Exit Sub
  End If
End Sub
一旦、txtTCDに違ったコードを入力してしまうと、その時点で
  ・CommandButton1が実行不能状態になります
  ・条件に合うコードを入力する以外抜けられない状態になる
といった、ある意味不具合が発生してしまいます
せめて、CommandButton1_Clicが効くようにするにはどのようにすればよいのでしょうか?
 選んだイベント処理 Exit と Cancel が悪かったのかと思い、After_update
にしたりしてもなかなか思うような動きが得られませんので(txtTCDをSetfosして次にうつらないようにしても、移行してしまったり・・・・)行き詰ってしまいました。
 どうか、アドバイスをお願いします。

【41632】Re:ユーザーフォームのコントロールのイ...
回答  neptune  - 06/8/17(木) 17:38 -

引用なし
パスワード
   ▼ハナ さん:
>といった、ある意味不具合が発生してしまいます
>せめて、CommandButton1_Clicが効くようにするにはどのようにすればよいのでし>ょうか?
多くの場合、
1.全てのデータを入力させ、
2.データ入力、変更などのBottonをクリックした時に、
3.全てのデータを検査し、
4.不適正なデータがあれば
5.そのTextBoxなどにフォーカスを当て、そのデータを選択状態にする
事が多いと思います。

ある条件のデータのみを入力させたい場合はコンボボックス等にあらかじめ
データを用意してやります。

【41633】Re:ユーザーフォームのコントロールのイ...
発言  ichinose  - 06/8/17(木) 21:29 -

引用なし
パスワード
   こんばんは。

このExitイベントって、使いづらいイベントですよね!
帯に短し、襷に長しじゃなく、襷にも短し?

・neptuneさんのように仕様を思い切って変更するのも一案です。

・「条件に合うコードを入力する以外抜けられない状態になる」を仕様にする。

>ある意味不具合が発生してしまいます

とおっしゃっていますが、MS社のように正々堂々と仕様だと言い切る・・・。
↑これ、結構、真面目に言っています。
(私は、値切られた仕事ではこの程度のことは仕様だと言い切ります)


・独自イベントを作成して、コマンドボタンのクリックを可能にする。
 これも一案ですが、アクティブなコントロールを監視しなければならない。
 動作が不安定・・・・。


・仕様を変更するPART2



新規ブックで試してください。

ユーザーフォーム(Userform1)に
  テキストボックス(Textbox1)----7桁の数字入力用 必須入力
  テキストボックス(Textbox2)----データ入力用
  テキストボックス(Textbox3)----データ入力用
  コマンドボタン(Commandbutton1)--入力内容クリア用

の4つのコントロールを配置します。
(コントロールのTabオーダーも上記の記述順序です)

標準モジュールに

'====================================================
Sub main()
  UserForm1.Show
End Sub


Userform1のモジュールに
'============================================================
Private Sub TextBox1_Enter()
  txtenbl = False
End Sub
'============================================================
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  With TextBox1
    If KeyCode = 13 Then
     If (Len(.Text) <> 7) Or (IsNumeric(.Text) = False) Then
       KeyCode = 0
     Else
       txtenbl = True
       End If
     End If
    End With
End Sub
'============================================================
Private Sub CommandButton1_Click()
  Dim idx As Long
  For idx = 1 To 3
   Controls("textbox" & idx).Text = ""
   Next
  TextBox1.SetFocus
End Sub
'============================================================
Property Let txtenbl(ByVal enbl As Boolean)
  Dim idx As Long
  For idx = 2 To 3
   Controls("textbox" & idx).Enabled = enbl
   Next
  CommandButton1.Enabled = False
  CommandButton1.Enabled = True
End Property


として、mainを実行してみてください。

Textbox1には、7桁の数字を入力して、Enterキーを押さないと

次のTextbox2には、移動できません。
(7桁の数字を入力してもEnterキー押さないと移動は不可)

しかし、コマンドボタンのクリックは可能です。
  

これも一つの案です。

検討してみてください。

【41644】Re:ユーザーフォームのコントロールのイ...
発言  ハナ  - 06/8/18(金) 8:25 -

引用なし
パスワード
   ▼neptuneさんichinose さん
ご回答ありがとうございます

>・neptuneさんのように仕様を思い切って変更するのも一案です。
おっしゃるとおり、フォームを使用したプログラムの殆どはneptuneさんの
書かれた手順での仕様になっていますが、
   ・コード入力項目が多く、入力したらすぐに検索結果をLblに出力
    することによってオペレーターに確認させる
   ・入力候補(コード数)が膨大であることからListBoxを使用すると
    オペレーションがしづらくなる
   ・マウスとキーボードの持ち替えを極力少なくする
などという条件がついていることもあり、通常のパターンからはずれた
コーディングをしました。
しかし、neptuneさんやichinose のご回答で再度仕様を検討する(基本に帰る)ことも視野にいれて考えたいと思います。
>・「条件に合うコードを入力する以外抜けられない状態になる」を仕様にする。
>
>>ある意味不具合が発生してしまいます
>
>とおっしゃっていますが、MS社のように正々堂々と仕様だと言い切る・・・。
>↑これ、結構、真面目に言っています。
>(私は、値切られた仕事ではこの程度のことは仕様だと言い切ります)
うらやましいです。小さな会社で周りにVBAがわかる人がいないと、この程度の
使用制限でも”無能”よばわりされちゃうんですよ(それだけ信用がない・・)
そこで ichinose さんにご提示いただいた
>・仕様を変更するPART2
を本日試してみます。結果はまた報告させていただきますが
とりあえず、遅くなりましたが、ご回答のお礼を申し上げます。

【41646】ユーザーフォームのコントロールのイベン...
質問  ハナ  - 06/8/18(金) 9:20 -

引用なし
パスワード
   ▼ichinose さん:
提示いただいたコードをテストしたところ、不満だった部分が
完全に解消されています。ご教示本当にありがとうございます
ここで ひとつ質問があるのですが

>Property Let txtenbl(ByVal enbl As Boolean)
'Property Let や Getをクラスモジュールとのセット以外で使用するのを
 見たのは初めてなので、簡単な解説をいただければ幸いです

>  Dim idx As Long
>  For idx = 2 To 3
    Controls("TextBox" & idx).Enabled = enbl
>   Next

>  CommandButton1.Enabled = False
>  CommandButton1.Enabled = True
'CommandButton1.Enabled をFalseにしたあとすぐにTrueにしている部分が
 なかなか理解できなくて・・・(ちなみに、Falseにしている行をコメント
 にしても動作はOKでした)
>End Property
>
KeyDownイベントでKeyCode=13も考えてはみたものの、その後の処理が
行き詰って放棄してしまったので、今回のご回答は地獄に仏でした。
お助けついでに、お手数でも上記の解説をいただけないでしょうか
よろしくお願いします。

【41647】Re:ユーザーフォームのコントロールのイ...
発言  ichinose  - 06/8/18(金) 9:56 -

引用なし
パスワード
   ▼ハナ さん:
おはようございます。

>>Property Let txtenbl(ByVal enbl As Boolean)
>'Property Let や Getをクラスモジュールとのセット以外で使用するのを
> 見たのは初めてなので、簡単な解説をいただければ幸いです

ん?、Property Get Letは、全てのモジュールで使用可能ですよ!!
もっとも標準モジュールで使用する場合、その意味が説明出来ませんが・・・。

オブジェクトモジュール(クラスモジュール、フォームモジュール、
Thisworkbookのモジュール、各シートのモジュール)であれば、
Property Get Letを記述することは、独自のプロパティを作成することを意味します。

例えば、Thisworkbookのモジュールに

'=====================
private b as long
property let aaa(a as long)
  b=a
end sub

と記述すれば、

thisworkbook.aaa=5

とThisworkbookにプロパティが追加されます。

同じようにユーザーフォームのモジュールにもProperty Let Getは記述できます。


>>>  CommandButton1.Enabled = False
>>  CommandButton1.Enabled = True
>'CommandButton1.Enabled をFalseにしたあとすぐにTrueにしている部分が
> なかなか理解できなくて・・・(ちなみに、Falseにしている行をコメント
> にしても動作はOKでした)
>>End Property

これは、Textbox1で正しく数字が入力され、Enterキーを押すと、
Textbox2、または、Textbox3にフォーカスが移りますよね?

この時、再度Textbox1にマウスで移動しようとした時、
>>>  CommandButton1.Enabled = False
>>  CommandButton1.Enabled = True
この記述がないと、コマンドボタンにフォーカスが移ってしまいます。
(Excel2002 SP3で確認しました)
これを是正するためにコードを入れました。

確認してください。

【41650】Re:ユーザーフォームのコントロールのイ...
お礼  ハナ  - 06/8/18(金) 10:34 -

引用なし
パスワード
   ▼ichinose さん:
Commandbuttonの件確認しました。了解です
あわせてPropertyの丁寧な解説ありがとうございます
アイデアは十分な知識から出るものなんですね(笑)
neptuneさんやichinoseさんに少しでもおいつけるように
これからも頑張ります。

【41653】Re:ユーザーフォームのコントロールのイ...
発言  neptune  - 06/8/18(金) 11:28 -

引用なし
パスワード
   ▼ハナ さん:
>▼ichinose さん:
解決後だからもう見ないかな?
いや〜こんな方法があったんですね。

で、私も思いつきですが、
CommandButtonのTabStopプロパティをFALSEにしておいて
TextBox3のExitイベントで(検査必要なら検査して)
CommandButtonにフォーカスを当てるという方法も思いつきました。
どうですかね?

【41657】Re:ユーザーフォームのコントロールのイ...
発言  ハナ  - 06/8/18(金) 14:18 -

引用なし
パスワード
   ▼neptune さん:
>解決後だからもう見ないかな?
いえいえ、しっかり見ております

>CommandButtonのTabStopプロパティをFALSEにしておいて
>TextBox3のExitイベントで(検査必要なら検査して)
>CommandButtonにフォーカスを当てるという方法も思いつきました。
>どうですかね?

実はこの方法に近いことを一番最初にやってみたんです。
こんな感じです
Private Sub txt3_Exit(ByVal Cancel As MSForms.ReturnBoolean)
  Dim X As Integer
  X = Val(txt3.Text)
  Select Case X
    Case 10:
      Lbl_3.Caption = "新規"
      Kub = Get_Kub(Val(txt1.Text), Val(txt2.Text))  '区分取得
      Me.txtKNO.Text = _
        Mid(GET_KN(Kub), 1, 1) & CInt(Mid(GET_KN(Kub), 2, 4)) + 1 '新規工事番号出力
      With Me.txtKNOS
        .Text = "00"
        .Enabled = False
      End With   'サブコードに 00 セット
      txtDCODE.SetFocus
    Case 20, 30:
      If X = 20 Then Lbl_3.Caption = "追加"
      If X = 30 Then Lbl_3.Caption = "変更"
      With txtKNOS
        .Enabled = True
      End With
    Case Else:
      Lbl_3.Caption = ""
      CommandButton2.SetFocus
       ↑が機能しないで(ボタンのTabstopはFALSEです)次のTABへ
        移動してしまうんです
 
    End Select
End Sub

その結果、
  ・最初に相談したようにExitイベントのCancel = TRUE
   になるとSetFocusが効かなくなる & このイベントプロシジャー
   の中ではSETFOCUSが効かないみたいなんです
  ・エラー入力した場合、オペレーターから見て、画面クリアが優先処理
   になる(正規コードを入れなおすためにはTextBoxをあらためて
   選択する)といった問題が発生します
  ・Cancel値を使わなければ最大の問題である”正規コードを入れなければ
   抜けられない”問題はneptuneさんの思いつかれた方法で解決するようで    す。
そのへん、いかがなものなんでしょう・・・・
いずれにしましても、考えてくださってありがとうございます
心強いです。

【41668】Re:ユーザーフォームのコントロールのイ...
発言  neptune  - 06/8/18(金) 21:50 -

引用なし
パスワード
   ▼ハナ さん:
書いたの忘れてました。 ^ ^;;
>  ・最初に相談したようにExitイベントのCancel = TRUE
>   になるとSetFocusが効かなくなる & このイベントプロシジャー
>   の中ではSETFOCUSが効かないみたいなんです
調べました。バグくさいですね。XL2Kでも再現しますから。
ユーザー フォームのイベントで SetFocus メソッドが正しく動作しない場合がある
http://support.microsoft.com/default.aspx?scid=kb%3Bja%3B436443

>  ・エラー入力した場合、オペレーターから見て、画面クリアが優先処理
>   になる(正規コードを入れなおすためにはTextBoxをあらためて
>   選択する)といった問題が発生します
私が最初に書いたようなオーソドックスな方法の話になりますが、
コンボボックスを使用してあらかじめデータを用意して置き、
MatchEntry プロパティを設定すれば入力はかなり楽になります。
又どうしてもTextBoxなら、「TextBoxをあらためて選択する」という作業を
プログラムでやってやればよいだけのことです。ついでにSelStart、SelLength プロパティ
で、選択状態にしてやれば再入力だけです。


>  ・Cancel値を使わなければ最大の問題である”正規コードを入れなければ
>   抜けられない”問題はneptuneさんの思いつかれた方法で解決するようです。
>そのへん、いかがなものなんでしょう・・・・
ん〜先のバグの回避方法ということですよね。

今思いつくのは、UserForm上のActiveControlを監視することですが、
これは、やれば出来るとは思いますが、実用上かなり問題あると思います。

やはり、私が最初に書いたようなオーソドックスな方法を取るか、
ichinoseさんの方法を利用させてもらうという方法になりますか。

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