TextBoxへのキー入力とバーコード読込みを両立させるには?


ダン  2006-05-11 02:48:18  No: 95323

[VB6.0]で開発しております。

キー入力とバーコードリーダーの仕組みを両立させようと
しているのですがなかなかうまくいかず悩んでおります・・・。

ふたつのTextBoxに表示する桁は5桁ずつ。

キー入力は、5桁入力したら、次のTextBoxへフォーカス移動し、次の5桁が入力できる。という処理。

バーコードリーダーは
キー入力と同じ動きをさせたい!のです。
↓但し、読込むコードは間にハイフンがあります。
xxxxx-xxxxx
どうしても、現在フォーカスがあるTextBoxに
全て表示されてしまうのです・・・。

バーコードリーダーはKeyインターフェースを使用しています。


魔界の仮面弁士  2006-05-11 03:36:38  No: 95324

# MaskEdit あたりを使って、一つのボックスにしてしまった方が楽かも。

> バーコードリーダーは
> キー入力と同じ動きをさせたい!のです。

リーダから「12345-67890」と入力された場合も、
キーボードから「1234567890」と入力された場合も、
キーボードから「12345-67890」と入力された場合も、
いずれも同じ動きになるようにすれば良いかと。

とりあえずのイメージ。

'-----------
Option Explicit

Private Sub Form_Load()
    Text1(0).MaxLength = 5
    Text1(1).MaxLength = 5
    Text1(0).Text = ""
    Text1(1).Text = ""
End Sub

Private Sub Text1_Change(Index As Integer)
    If Len(Text1(Index).Text) = 5 Then
        If ActiveControl Is Text1(0) Then
            Text1(1).SetFocus
            Text1(1).SelStart = Len(Text1(1).Text)
        End If
    End If
End Sub

Private Sub Text1_KeyPress(Index As Integer, KeyAscii As Integer)
    If KeyAscii = Asc("-") Then
        KeyAscii = 0
    End If
End Sub

Private Sub Command1_Click()
    Text1(0).Text = ""
    Text1(1).Text = ""
    
    'こちらの環境にはバーコードリーダーが無いので、
    'SendKeys からキー入力を送信する事で、
    'リーダーからの入力を擬似的に再現してみたり
    Text1(0).SetFocus
    SendKeys "12345-67890", True
End Sub
'---------------

あとはこれの応用で、たとえば Text1(1) の先頭で BackSpace を押されたら、
Text1(0)に移って一文字削除…なんてのを組み込んだりとか。


ダン  2006-05-11 04:01:59  No: 95325

お返事ありがとうございます。m(_ _)m
処理を参考に試してみます!!!

>いずれも同じ動きになるようにすれば良いかと。
そうなんですけど、だいぶ頭の中が迷路状態で
単純な事を考えられなくなってます(-_-;)

[ # MaskEdit ]ってなんでしょうか(T_T)

物知らずですいません・・・。


ダン  2006-05-11 04:40:44  No: 95326

記述して下さったソースを試してみたのですが、
バーコードリーダーで読込んだ場合、Text(1)にデータが入りませんでした。
フォーカスはText(1)にいる状態です。


魔界の仮面弁士  2006-05-11 05:10:06  No: 95327

リーダーが無いと試せないので、案だけ。

案1) 『TextBoxではなく、Form側で入力を受け取る』

  KeyPrevious = True にしておき、Form_KeyPress でデータを
  受け取って、そのまま KeyAscii = 0 で入力キャンセル。その上で、
  Label なり TextBox なりに、Chr(KeyAscii) 値を記録していく。

案2) 『入力用のTextBox と、表示用のTextBoxを別にする』

  入力用をText1、表示用をText2(0),Text2(1)とする。
  Text2()がGotFocusしたら、直ちにText1にSetFocusして、
  入力自体は、Text1_Change で処理する。Text1.Text の内容を
  Mid関数で適宜切り出して、Text2(0)/Text2(1) に転記。

> MaskEdit
これの事。
http://www.microsoft.com/japan/developer/library/masked98/vbobjmaskedit.htm
http://www.microsoft.com/japan/developer/library/vbcon98/vbconusingmaskededitcontrol.htm


ダン  2006-05-11 05:50:39  No: 95328

>MaskEdit
アドレスありがとうございました。
確かにこのコントロールを使うと悩みは解消されました(^_^;)
便利ですね。
でも、それならTextBoxをひとつにしたのと同じか?と、
ちょっと思ってしまった。。すいません、いろいろ案を
だしてもらっておきながら。

あ、"-"の入力をしなくていいからやっぱり便利なのか・・・。

とりあえず、最終手段として考えます。

まだ最初の案に手を加え、あれこれやっているのですが。。。。
ふたつの案もこなしてみます。


ダン  2006-05-11 18:06:02  No: 95329

やっぱり、MaskEditを使うのがベストかな・・・・
と、一夜明けて改めて思いました。

無理にイベントなどを駆使すると
バグの原因にもなるのかな・・・・と。
また、変更をしようとすると
とても面倒なのかな・・・と。

MaskEditも使った事がないので、吉とでるか凶とでるか
わかりませんが、使ってみようと思います。

引き続き、何かあったら教えて下さいm(_ _)m
よろしくお願いします!


ダン  2006-05-12 02:10:58  No: 95330

やりたかった事の90%はできました。
ホントにありがとうございます。

が、MaskEdBoxコントロール上で表示されている値を
削除した後、カーソルが一番後ろにきてしまいます。。。
SelStartを使ったりしているのですが
うまく先頭にきてくれません。

どうしたら、先頭に持ってこれるんでしょうか?


ダン  2006-05-12 02:52:21  No: 95331

ソースはこんな感じです。

Private Sub MaskEdBox1_Change()
    
    If (Len(MaskEdBox1.ClipText) = 10) Then
        
        If (MaskEdBox1.ClipText = "0000000001") Then
            Call MsgBox("この番号は無効です", vbExclamation)
            MaskEdBox1.Mask = ""
            MaskEdBox1.Text = ""
            MaskEdBox1.Mask = "aaaaaaaaaa"
        End If
    End If
End Sub

Private Sub MaskEdBox1_GotFocus()

    MaskEdBox1.SelStart = 0
    If (Len(MaskEdBox1.ClipText) = 10) And _(MaskEdBox1.ClipText<> "") 
        MaskEdBox1.SelLength = Len(MaskEdBox1.Text)
    End If
End Sub


特攻隊長まるるう  2006-05-12 20:19:19  No: 95332

コンパイルが通らないですが。。。
…改行して Then を付ければいいだけならやりました。

>削除した後、カーソルが一番後ろにきてしまいます。。。
現象を再現できませんでした。こちらでは
>            MaskEdBox1.Mask = ""
>            MaskEdBox1.Text = ""
を実行したために PromptChar とかが都合悪くなって正常な処理
が行われず、MaskEdBox1_Change が何度も実行されて繰り返し
設定が変更され、最終的に Mask = "aaaaaaaaaa" の処理が有効に
なっていない状態(全角入力できてしまう)になってしまいました。
何かのプロパティが自動で変更されているかもしれません。
MaskEdBox1.Text = "" では後ろも何も無いと思うんですが。
…カーソルの移動はできませんでした。

新規プロジェクトでデフォルト設定のまま、提示したコードのみ
実行してみてください。どうなりますか?


ダン  2006-05-12 22:36:51  No: 95333

実行していただきありがとうございます。

特攻隊長まるるう さんの言われるとおり
.Mask = ""
.Text = ""
でイベントが発生して次にいきついていないようです。。。
現在自分が行っているプロジェクトと違う動きでした・・・
申し訳ないです。

初めて使ったのでプロパティをいじっているかもしれないです。
調べます。


ダン  2006-05-12 22:52:01  No: 95334

大変申しわけありません!!!

MaskEdBox1.Mask = "aaaaaaaaaa"

MaskEdBox1.Mask = "aaaaa-aaaaa"

と間に"-"を入れてみて下さい。

なぜ、間に"-"をいれると動きが変わってしまうのか
わからないのですが、本来自分がしたかった質問の
動きをします。。。。。

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


特攻隊長まるるう  2006-05-13 00:02:34  No: 95335

再現しました。

どっちにしろ
>            MaskEdBox1.Mask = ""
>            MaskEdBox1.Text = ""
がマズイ処理のようですね。

Private Sub MaskEdBox1_Change()
    Debug.Print "MaskEdBox1_Change"
    If (Len(MaskEdBox1.ClipText) = 10) Then
        Debug.Print "Len_ClipText = 10"
        If (MaskEdBox1.ClipText = "0000000001") Then
            Debug.Print "ClipText = 0000000001"
            Call MsgBox("この番号は無効です", vbExclamation)
            Debug.Print "Mask = """""
            MaskEdBox1.Mask = ""
            Debug.Print "Text = """""
            MaskEdBox1.Text = ""
            Debug.Print "Mask = aaaaaaaaaa"
            MaskEdBox1.Mask = "aaaaaaaaaa"
        End If
    End If
End Sub
のようにして処理の流れを追いました。

[aaaaa-aaaaaの場合]
>Len_ClipText = 10
>ClipText = 0000000001
>Mask = ""
>Text = ""
>MaskEdBox1_Change
>Mask = aaaaa-aaaaa

[aaaaaaaaaaの場合]
>Len_ClipText = 10
>ClipText = 0000000001
>Mask = ""
>MaskEdBox1_Change
>Len_ClipText = 10
>ClipText = 0000000001
>Mask = ""
>Text = ""
>MaskEdBox1_Change
>Mask = aaaaaaaaaa
>MaskEdBox1_Change
>Text = ""
>MaskEdBox1_Change
>Mask = aaaaaaaaaa

複雑な動きをするコントロールになるほど、余計な
処理を排除すべきです。どのタイミングでどんな
イベントが起こってるか把握しておかないと予期
せぬ動きになってしまいます。

それとは別に、今回の問題はChange イベントの
後でOSかマスクエディットの内部処理による
カーソル移動が起こっているのではないかと予想
します。他のイベントやら何か打開策を模索しました
が、かなり時間を掛けて調べる必要がありそうです
ので、タイマーを使い、更に後からイベントを起こす
事で回避できました。…あまりきれいなコードでは
ないですが、以下のコードを試してみてください。
(できれば一度既存のマスクエディットを削除して
新規マスクエディットを貼り付けるか、新規フォーム
で。)

[VB6.0]
Option Explicit

Private Const MASK_ED_MAX As Long = 10
Private mEventIgnore As Boolean
Private mInitMaskEdText As String

Private Sub Form_Load()
    Call InitializeMaskEd(True)
End Sub

Private Sub InitializeMaskEd(ByVal LoadEvent As Boolean)
    mEventIgnore = True
    With Me.MaskEdBox1
        .SelStart = 0
        Debug.Print "{" & .Text & "}"
        If LoadEvent Then
            .MaxLength = MASK_ED_MAX
            .Mask = "aaaaa-aaaaa"
            mInitMaskEdText = .Text
            Debug.Print "{" & .Text & "}"
        Else
            .Text = mInitMaskEdText
        End If
    End With
    mEventIgnore = False
End Sub

Private Sub MaskEdBox1_Change()
    If mEventIgnore Then Exit Sub
    With Me.MaskEdBox1
        If (Len(.ClipText) = MASK_ED_MAX) Then
            If (.ClipText = "0000000001") Then
                Call MsgBox("この番号は無効です", vbExclamation)
                Me.Timer1.Interval = 1
            End If
        End If
    End With
End Sub

Private Sub Timer1_Timer()
    Me.Timer1.Interval = 0
    Call InitializeMaskEd(False)
End Sub


ダン  2006-05-13 01:51:16  No: 95336

大変感謝です!
上記処理、ありがとうございます。
試して参考にさせて頂きます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加