Excel VBA質問箱 IV

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

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


52239 / 76738 ←次へ | 前へ→

【29340】Re:TextBoxの入力値制限
発言  ichinose  - 05/10/1(土) 20:34 -

引用なし
パスワード
   > 3Exitイベントでは物足りない・・・
>  VBにはExitイベントではなく、Lostfocusイベントというのが
>  あるのですが、Exitイベントはこれほど使いやすくないこと。
3について例題を作成したのですが、
仕様が悪かったのかExitイベントの悪い箇所が目立たない・・・。
後述しますが、「そんなにたいした事では無い」なんて思われるかもしれませんが、
でも私は厄介だと思っています。

では、例題の仕様から・・・。

ユーザーフォームで足し算の問題を出題し、ユーザーに回答してもらうプログラムを
考えます。

Userform1に

ラベルコントロールを8個配置して下さい。
  名前は、自動作成される Label1〜Label8
  問題を表示するために使います

テキストボックスを2個配置して下さい。
  名前は自動作成される Textbox1とTextbox2
  回答入力用に使います。

コマンドボタンを2個配置して下さい。
  名前は自動作成される Commandbutton1とCommandbutton2
  Commandbutton1----次の問題を表示
  Commandbutton2----プログラムの終了 


ではコードです。

標準モジュールに
'================================================================
Sub main()
  UserForm1.Show
End Sub


Userform1のモジュールに
'=================================================================
Private seikai(1 To 2) As Boolean
'=================================================================
Private Sub UserForm_Initialize()
  Dim lbl_lt As Variant
  Dim lbl_ht As Variant
  Dim lbl_wd As Variant
  Dim btn_lt As Variant
  Dim btn_cap As Variant
  Dim txt_ht As Variant
  lbl_lt = Array(36, 90, 126, 180, 36, 90, 126, 180)
  lbl_ht = Array(54, 54, 54, 54, 90, 90, 90, 90)
  lbl_wd = Array(54, 36, 54, 36, 54, 36, 54, 36)
  txt_ht = Array(54, 90)
  btn_lt = Array(48, 174)
  btn_cap = Array("次の問題", "終了")
  With Me
   .Caption = "足し算問題"
   .Height = 263
   .Width = 350
   End With
  For g0 = 1 To 8
   With Controls("label" & g0)
    .Caption = ""
    .BackColor = &HFFFFFF
    .SpecialEffect = fmSpecialEffectSunken
    .Font.Size = 16
    .TextAlign = fmTextAlignRight
    .Left = lbl_lt(g0 - 1)
    .Top = lbl_ht(g0 - 1)
    .Height = 20.5
    .Width = lbl_wd(g0 - 1)
    End With
   Next g0
  For g0 = 1 To 2
   With Controls("textbox" & g0)
    .Text = ""
    .Font.Size = 16
    .TextAlign = fmTextAlignRight
    .Left = 216
    .Top = txt_ht(g0 - 1)
    .Height = 20.5
    .Width = 66
    End With
   Next g0
  For g0 = 1 To 2
   With Controls("commandbutton" & g0)
    .TabStop = False
    .Caption = btn_cap(g0 - 1)
    .Font.Size = 16
    .Left = btn_lt(g0 - 1)
    .Top = 180
    .Height = 30
    .Width = 90
    End With
   Next g0
  Call disp_ques
End Sub
'=================================================================
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
  With TextBox1
   If (Not IsNumeric(.Text)) And .Text <> "" Then
     MsgBox "答えは数字です"
     .SelStart = 0
     .SelLength = Len(.Text)
     Cancel = True
   ElseIf .Text <> "" Then
     If Val(Label1.Caption) + Val(Label3.Caption) = Val(.Text) Then
      seikai(1) = True
     Else
      MsgBox "不正解"
      .SelStart = 0
      .SelLength = Len(.Text)
      Cancel = True
      End If
     End If
   End With
End Sub
'=================================================================
Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
  With TextBox2
   If (Not IsNumeric(.Text)) And .Text <> "" Then
     MsgBox "答えは数字です"
     .SelStart = 0
     .SelLength = Len(.Text)
     Cancel = True
   ElseIf .Text <> "" Then
     If Val(Label5.Caption) + Val(Label7.Caption) = Val(.Text) Then
      seikai(2) = True
     Else
      MsgBox "不正解"
      .SelStart = 0
      .SelLength = Len(.Text)
      Cancel = True
      End If
     End If
   End With
End Sub
'=================================================================
Private Sub CommandButton1_Click()
  For g0 = 1 To 2
   If seikai(g0) = False Then
    MsgBox "正解するまで次の問題にはいけません"
    With Controls("textbox" & g0)
      .SelStart = 0
      .SelLength = Len(.Text)
      .SetFocus
      End With
    Exit Sub
    End If
   Next g0
  Call disp_ques
End Sub
'=================================================================
Private Sub CommandButton2_Click()
  Unload Me
End Sub
'=================================================================
Private Sub disp_ques() '問題表示
  For g0 = 1 To 7 Step 2
   Controls("label" & g0).Caption = _
     Int(Rnd() * 10000) + 1
   Next g0
  For g0 = 2 To 8 Step 4
   With Controls("label" & g0)
     .TextAlign = fmTextAlignCenter
     .Caption = "+"
     End With
   With Controls("label" & g0 + 2)
     .TextAlign = fmTextAlignCenter
     .Caption = "="
     End With
   Next g0
  For g0 = 1 To 2
   seikai(g0) = False
   Controls("textbox" & g0).Text = ""
   Next g0
End Sub


ちょっと例題に懲りすぎてしまったかな??
因みにこのプログラム正解の記述がないと「次の問題」ボタンを押しても
エラーになります。

ここで問題の個所は、
  一度に出題される問題数は2問ですが、たとえば

 8715+563= という問題に対して 不正解である50と入力した後、

プログラムの終了ボタンであるCommandbutton2をクリックしたとき
終了できない事なのです。
(これだけの事のために例題が長すぎました)

一般のアプリでは終了するんですよ、こういう場合・・・。

Exitイベントでは、フォーカスが次に移るコントロールが何なのか
Exitイベント内ではわからないという問題があります。

よって、私は、Keydownイベントを使用することが多いのですが、
これはこれでコードの記述が面倒なところもあります。

結論の割に記述が長すぎました。反省。

よって、Excelのユーザーフォームで一般のアプリのような画面操作を
行おうと思うとサポートされているイベントでは
「帯に短し、襷に長し」だなあ というのが私の正直な感想です。
0 hits

【29331】TextBoxの入力値制限 年寄り 05/10/1(土) 9:58 質問
【29332】Re:TextBoxの入力値制限 ichinose 05/10/1(土) 10:52 発言
【29333】Re:TextBoxの入力値制限 年寄り 05/10/1(土) 11:13 発言
【29339】Re:TextBoxの入力値制限 ichinose 05/10/1(土) 19:39 発言
【29340】Re:TextBoxの入力値制限 ichinose 05/10/1(土) 20:34 発言
【29392】Re:TextBoxの入力値制限 年寄り 05/10/4(火) 12:04 お礼

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