のんびりよりみちきっぷ

考えた事や実施したことをのんびりと。

エクセルマクロ テキストボックスへの日付入力中に、指定したフォーマットにする

f:id:yorimichi_ticket:20180306081424j:plain
問題点もありますが、色々やってみたらそれなりのものができたので記録しておきます。


日付入力中に西暦4ケタを入力したら自動で"/"が入力され、さらに月2桁を入力したらまた自動で"/"が入力されるようにするコードです。

C#では形式付きのテキストボックス「MaskedTextBox」コントロールなんてものがあるみたいですが、VBAでは見当たりませんでした。

いくつか試してみましたが、KeyPressイベント時に、入力文字列の長さを取得し"/"を入れる場所かどうかを判断するってのがよさそうなので、多少問題もありますが、これを採用です。

このやり方知っていれば、誕生日等の日付はもちろん、郵便番号や電話番号も入力フォーマットを合わせられますね。


やりたいこと

・VBAのフォームで日付「西暦/月/日」を入力する。
・数値以外は入力できないようにする。
・"/"は自動で入力されるようにする。


お試し1:不採用

KeyPressイベントで数字かどうかをチェックし、Changeイベントで指定の長さになったら"/"を入れる。
問題点:BS押しても"/"が消えない

Private Sub txtDate_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If IsNumeric(Chr(KeyAscii)) = False Then
        MsgBox ("数字を入力してください")
        KeyAscii = 0
    End If
End Sub

Private Sub txtDate_Change()
    If Len(txtDate.Value) = 4 Or Len(txtDate.Value) = 7 Then
        txtDate.Value = txtDate.Value & "/"
    End If
End Sub
お試し2:不採用

KeyPressイベント内で数字のチェックに加え、テキストの長さを取得し、指定の長さであれば"/"を入れる。
問題点:"/"の次の値を入力しないと"/"が入らない。

Private Sub txtDate_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If IsNumeric(Chr(KeyAscii)) = False Then
        MsgBox ("数字を入力してください")
        KeyAscii = 0
    ElseIf Len(txtDate.Value) = 4 Or Len(txtDate.Value) = 7 Then
        txtDate.Value = txtDate.Value & "/"
    End If
End Sub
お試し3:採用

KeyPressイベント時に、入力文字列の長さを取得し"/"を入れる場所かどうかを判断。

問題点:
入力後の修正で、一部の文字を削除すると"/"の位置がずれる。
修正する場合には全部消してから入力しないといけない。
ただ他にいい方法思い浮かばなかったのでこれを使用。

Private Sub txtDate_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If IsNumeric(Chr(KeyAscii)) = False Then
        MsgBox ("数字を入力してください")
    ElseIf Len(txtDate.Value) = 3 Or Len(txtDate.Value) = 6 Then
        txtDate.Value = txtDate.Value & Chr(KeyAscii) & "/"
    ElseIf Len(txtDate.Value) = 10 Then
        KeyAscii = 0
    Else
        txtDate.Value = txtDate & Chr(KeyAscii)
    End If
    KeyAscii = 0
End Sub


以上、VBA備忘録でした。