[リストへもどる]
一括表示

投稿時間:2004/02/04(Wed) 10:26
投稿者名:入力文字数でのフォーカス制御
Eメール:
URL :
タイトル:
ゆきの
おはようございます。
テキストボックスでのイベントについて壁にあたってしまいました。
お忙しいところ申し訳ありませんがお知恵を貸して頂けますでしょうか。

1.フォームには20個ほどのテキストボックスが縦に並んで置いてあります。
2.各テキストボックスには最大入力文字数が決っています
3.Enterキーを押すと下のテキストボックスにフォーカスが移動します。 
  また、最大入力文字数を入力しても下のテキストボックスにフォーカスが移動します。
  例:最大入力数3の時「11」と入力後に「2」を入力した時に下のテキストボックスに
    フォーカスが移動します。
4.shiftキーを押しながらEnterキーを押すと上のテキストボックスに移動します。
5.各テキストボックスは上書きで入力し、テキストボックスの内容をクリアすることはできない

この5つの条件の元、プログラムを作成しようと思っておりますが、3と5の条件を満たせません。
3の最大入力文字数を入力した時次のテキストボックスにフォーカスを移動するときには
「KeyPress」イベントを利用し、最大入力文字数ー1の入力があったときには下の
テキストボックスにフォーカスを移動することで対応しようと思いました。
5ではInputManを利用してテキストボックスのプロパティを「上書き」にしようと思いました。
ですが、上書きにしても「KeyPress」イベントで文字が置き換わらずにフォーカスが移動してしまう
ことが分かりました。
Enterキーによる移動はこちらの逆引きヘルプを参考に作成いたしました。

どうか、上書きが可能で入力文字数でのフォーカス制御を行うためのお知恵を
お貸しください。

よろしくお願いいたします。

投稿時間:2004/02/04(Wed) 10:58
投稿者名:いちゆ
Eメール:
URL :
タイトル:
Re: ゆきの
EXCEL VBAで作ってみました。
TextBox1とTextBox2を貼り付けて使ってください。
…テストが不十分なので、参考程度です。

Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
Dim i  As Long
Dim st As String
Select Case KeyAscii
    Case vbKeyReturn
        TextBox2.SetFocus
    Case Else
        If Len(TextBox1.Text) >= TextBox1_MaxLength Then
            KeyAscii = 0
            TextBox1.Text = Left$(TextBox1.Text, TextBox1_MaxLength)
            TextBox2.SetFocus
        Else
            TextBox1.SelLength = 0
            st = TextBox1.Text
            If Mid$(st, TextBox1.SelStart + 1, 1) <> "" Then
                i = TextBox1.SelStart
                Mid$(st, TextBox1.SelStart + 1, 1) = ChrW$(KeyAscii)
                TextBox1.Text = st
                TextBox1.SelStart = i + 1
                KeyAscii = 0
            End If
            
        End If
End Select
End Sub

投稿時間:2004/02/04(Wed) 11:13
投稿者名:ゆきの
Eメール:
URL :
タイトル:
入力文字数でのフォーカス制御
すいません。間違いに気が付きました。
タイトルと名前が逆になっています。
また、私の開発環境はVB6.0のWindows2000です。
申し訳ありません。

いちゆ様
ありがとうございます。
私も同じことを考えました。
ですが
>        If Len(TextBox1.Text) >= TextBox1_MaxLength Then
>            KeyAscii = 0
>            TextBox1.Text = Left$(TextBox1.Text, TextBox1_MaxLength)
>            TextBox2.SetFocus
この部分がだめなんです。
テキストボックスにすでに最大文字数が入力されていて、そこに再度フォーカスが来て
上書きで文字を変更しようとしたときにこのIf文に入ってしまうのです。
そのため、上書きにならないのです。

どうしたらいいのでしょうか?

投稿時間:2004/02/04(Wed) 11:53
投稿者名:いちゆ
Eメール:
URL :
タイトル:
Re: 入力文字数でのフォーカス制御
じゃ、これは?

Const TextBox1_MaxLength = 10

Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
Dim i  As Long
Dim st As String
Select Case KeyAscii
    Case vbKeyReturn
        TextBox2.SetFocus
    Case Else
        TextBox1.SelLength = 0
        st = TextBox1.Text
        If Mid$(st, TextBox1.SelStart + 1, 1) <> "" Then
            i = TextBox1.SelStart
            Mid$(st, TextBox1.SelStart + 1, 1) = ChrW$(KeyAscii)
            TextBox1.Text = st
            TextBox1.SelStart = i + 1
            KeyAscii = 0
        End If
            
        If Len(TextBox1.Text) >= TextBox1_MaxLength Then
            KeyAscii = 0
            TextBox1.Text = Left$(TextBox1.Text, TextBox1_MaxLength)
            TextBox2.SetFocus
        End If
End Select
End Sub

投稿時間:2004/02/05(Thu) 10:13
投稿者名:ゆきの
Eメール:
URL :
タイトル:
Re^2: 入力文字数でのフォーカス制御
いちゆ様

お忙しいところありがとうございました。
ただいま、確認しています。
すいません。。。VBAには慣れていないもので。
でもVBでもなんとかできそうな予感がしました。
また分からなくなったら教えてください。
ありがとうございました。

投稿時間:2004/02/05(Thu) 11:42
投稿者名:いちゆ
Eメール:
URL :
タイトル:
Re^3: 入力文字数でのフォーカス制御
> すいません。。。VBAには慣れていないもので。
> でもVBでもなんとかできそうな予感がしました。
VBに直接移植して、
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

Private Sub TextBox1_KeyPress(ByVal KeyAscii As Integer)
にすれば動くと思うよ。
がんばってね。

投稿時間:2004/02/06(Fri) 16:52
投稿者名:ゆきの
Eメール:
URL :
タイトル:
ありがとうございました!!
いちゆ様

お忙しいところ本当にありがとうございました。
ChrW関数とか全く知らなかったのでとても勉強になりました。

本当にありがとうございました!!!

投稿時間:2004/02/04(Wed) 11:47
投稿者名:ak
Eメール:
URL :
タイトル:
サンプル(改)
下記サンプルを試してみてください。

'(*.Frm)フォームにTextBoxを配列で数個配置してください。(Text1(0)〜Text1(n))
Option Explicit

Private Sub Form_Load()
    Dim ii  As Integer
    
    Me.KeyPreview = True
    
    For ii = Text1.LBound To Text1.UBound
        Text1(ii).MaxLength = ii + 2
    Next ii
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    If TypeOf Screen.ActiveControl Is TextBox Then
        If KeyCode = 13 And Shift = 0 Then
            SendKeys "{TAB}"
        ElseIf KeyCode = 13 And Shift = 1 Then
            SendKeys "+{TAB}"
        ElseIf KeyCode = 46 Then
            KeyCode = 0 'Del無効
        End If
    End If
End Sub

Private Sub Form_KeyPress(KeyAscii As Integer)
    If TypeOf Screen.ActiveControl Is TextBox Then
        If KeyAscii = 8 Or KeyAscii = 13 Then KeyAscii = 0   'BS無効
    End If
End Sub

Private Sub Text1_Change(Index As Integer)
    If Text1(Index).MaxLength = Len(Text1(Index)) Then SendKeys "{TAB}"
End Sub

Private Sub Text1_GotFocus(Index As Integer)
    '反転表示
    Text1(Index).SelStart = 0
    Text1(Index).SelLength = Len(Text1(Index))
End Sub

投稿時間:2004/02/05(Thu) 11:07
投稿者名:ゆきの
Eメール:
URL :
タイトル:
Re: サンプル(改)
ak様

お忙しいところありがとうございました。
サンプル確認させていただきました。
ありがとうございます。
ですが、これですとテキストボックス内全部が選択されてしまうので・・・・
いちゆ様のサンプルと合体させていただいて1文字ずつの上書きのプログラムを
作成したいと思っております。


余談ですが
InputManでは・・・・やはり難しいのでしょうか?

投稿時間:2004/02/05(Thu) 14:27
投稿者名:ak
Eメール:
URL :
タイトル:
Re^2: サンプル(改)
> InputManでは・・・・やはり難しいのでしょうか?

InputManでしたらすごく簡単に実現できます。

下記サンプルを試してみてください。

'(*.Frm)フォームにimTextを配列で数個配置してください。(imText1(0)〜imText1(n))
Option Explicit

Private Sub Form_Load()
    Dim ii  As Integer
    
    For ii = imText1.LBound To imText1.UBound
        With imText1(ii)
            .MaxLength = ii + 2
            .EditMode = imOverwrite
            .Key.NextCtrl = "{Enter}"
            .Key.PrevCtrl = "+{Enter}"
        End With
    Next ii

End Sub

Private Sub imText1_Change(Index As Integer)
    If imText1(Index).SelStart = imText1(Index).MaxLength Then SendKeys "{TAB}"
End Sub

投稿時間:2004/02/06(Fri) 15:52
投稿者名:ゆきの
Eメール:
URL :
タイトル:
うぉぉぉーー感激!!
ak様

お忙しいところありがとうございました。
確認いたしました。

感激です!
私がして欲しい動きをまさにしておりました!
実はkyepressイベントで1文字1文字計算していたのですが・・・・・
すごいですね!changeイベントで取得するとは・・・・目からウロコです。

ありがとうございました!!

投稿時間:2004/02/12(Thu) 18:19
投稿者名:ゆきの
Eメール:
URL :
タイトル:
もう一つだけ教えてください!!
InputManを使用してどうにか、機能を作成でき始めたのですが、
また問題が発生してしまいました。
お忙しいところ申し訳ありませんが、もう少しだけお知恵をお貸しください。

imText1(0)〜imText1(20)のなかで、通常処理は
つぎのimText1にカーソルが移動するのですが、例外的にimText1(3)の時だけは
imText1(5)にカーソルを移動し、imText1(5)でShift+Enterを押されたら
imText1(4)にカーソルを移動する。
また、imText1(4)でEnterキーを押すとimText1(5)にカーソル移動すると
いう形にすることになりました。

imText1(3)の時だけ
Private Sub imText1_Change(Index As Integer)
    If imText1(Index).SelStart = imText1(Index).MaxLength Then
    select case Index
          case 3
               SendKeys "{TAB 2}"
          case else
        SendKeys "{TAB}"
       end select
End Sub
としようとしたのですが、カーソルが移動してくれません。

また、このときShift+Enterキーを押すと2つ前のテキストボックスに移動してしまいます。
(imText1(3)でShift+Enterキーを押すとimText1(1)にカーソルが移動する。正解はimText1(2))

どのように設定したらよろしいのでしょうか?
どうか教えてください。
よろしくお願いいたします。

投稿時間:2004/02/13(Fri) 11:11
投稿者名:ak
Eメール:
URL :
タイトル:
Re: もう一つだけ教えてください!!
> Private Sub imText1_Change(Index As Integer)
>     If imText1(Index).SelStart = imText1(Index).MaxLength Then
>     select case Index
>           case 3
>                SendKeys "{TAB 2}"
>           case else
>         SendKeys "{TAB}"
>        end select
> End Sub
> としようとしたのですが、カーソルが移動してくれません。

Changeイベント内のコードはこれでOKです。

しかしこれだけでは文字列を変更した時には移動するけど「Enter」押下時には移動
しませんよね。

よく考えてみてください。
Changeイベントはテキストに変更があった場合だけ発生するイベントです。
「Shift+Enter」または「Enter」押下時にはテキストに変更が無い為発生しません。

そこでKeyDownイベントでも処理してあげる必要があります。

KeyDownイベントに下記コードを追加してみてください。

Private Sub imText1_KeyDown(Index As Integer, KeyCode As Integer, Shift As Integer)
    If Index = 3 And KeyCode = 13 And Shift = 0 Then imText1(5).SetFocus
End Sub

これで思っていた通りの動きになる筈です。

> また、このときShift+Enterキーを押すと2つ前のテキストボックスに移動してしまいます。
> (imText1(3)でShift+Enterキーを押すとimText1(1)にカーソルが移動する。正解はimText1(2))

上記でも述べましたが「Shift+Enter」または「Enter」押下時にはChangeイベントは
発生しないので全く関係ありません。

恐らくTabIndexが配列順になっていないのではないでしょうか?

TabIndexが配列順になっているのであれば配置が配列順になって
いない可能性もあります。(良くありがちです。)

TabIndex、配置にも間違いない場合は間違いなく他のイベント内
でそのような動きになるような処理がされている筈です。

確認してみてください。

投稿時間:2004/03/03(Wed) 09:18
投稿者名:ゆきの
Eメール:
URL :
タイトル:
本当にどうもありがとうございました
ak 様

ご連絡がおそくなって申し訳ありませんでした。
KeyDownイベントについてもう一度勉強しなおしました。
KeyDown・KyePress・keyUp・・・・とうまく使い分けられないのも
分かっていたのですが、いままでこれといった障害がなかったため
あいまいで通してしまった自分を反省しました。

機能について、作成完了いたしました!
今回はこのKeyDownイベントに泣きましたが
うまくいってよかったです。
本当にお手数をおかけいたしました。
ありがとうございました。