質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

2968閲覧

テキストボックスの入力文字数に上限を設定したいが、半角全角が混じっていた場合は…?(VBAユーザーフォーム)

arakuman

総合スコア17

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2021/04/14 23:51

Excel2016 32bit版

お世話になります。
ビジネスホンへの電話帳登録をVBAで書いています。
相手先名の入力が全角10文字・半角20文字までという制限があるため、テキストボックスの入力文字数に上限を設けたつもりです。

VBA

1Private Sub TextBox1_Change() 2 Dim convFromUcode As String 3 Dim leftFromUcode As String 4 convFromUcode = StrConv(TextBox1.Text, vbFromUnicode) 5 leftFromUcode = LeftB(convFromUcode, 20) 6 TextBox1.Text = StrConv(leftFromUcode, vbUnicode) 7End Sub

架空の [株式会社川崎インダストリーズ] を入力すると20byteまで表示されますが、
イメージ説明イメージ説明

")"を半角にして [株)川崎インダストリーズ本社] を入力すると、最後の"社"の半分までと言いますか中途半端な表示となってしまいます。
イメージ説明イメージ説明

LeftBで20と決めずに、20番目のバイト数を判定して2byteなら19にしたいと考えています。

VBA

1leftFromUcode = LeftB(convFromUcode, 20) '20と決め打ちしたくない

20文字目というか LenBの20番目が半角か全角かを判定する方法がわかればと以下のようにしてみましたが、"不明"が出るばかりです…。

VBA

1Private Sub TextBox1_Change() 2'注意 これは動きません 3 4 Dim convFromUcode As String 5 Dim leftFromUcode As String 6 Dim midFromUcode 7 Dim tmp as Integer 8 convFromUcode = StrConv(TextBox1.Text, vbFromUnicode) 9 If LenB(convFromUcode) > 20 Then 10 midFromUcode = MidB(convFromUcode, 20, 1)        '20番目? 11 If midFromUcode = StrConv(midFromUcode, vbNarrow) Then 12 tmp = 20 13 ElseIf midFromUcode = StrConv(midFromUcode, vbWide) Then 14 tmp = 19 15 Else 16 MsgBox "不明" 17 End If 18 leftFromUcode = LeftB(convFromUcode, tmp) 19 TextBox1.Text = StrConv(leftFromUcode, vbUnicode) 20 End If 21End Sub

どうかお知恵をお貸しください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yo_u

2021/04/15 01:27

全角、半角の判定方法の前に、どうして”不明”になるのか調べてはどうでしょう。 実際に、StrConv(midFromUcode, vbNarrow)がどういう値になっているのか、 StrConv(midFromUcode, vbWide)がどういう値になっているのか調べてみれば 原因がわかるような気がするのですが。。。
arakuman

2021/04/15 03:04

その前の段階で、MidB(convFromUcode, 20, 1) を Debug.Print させても何も表示されず、ローカルウィンドウでは "" なので、MidB で20文字目を判定するのは無理なのかもしれません。 1文字ずつ数えて足していく方向で考え直してみます。ありがとうございました。
guest

回答2

0

自己解決

ご指摘いただいたサロゲートペア文字の判定は入っていないのですが、先頭から1文字ずつ数えて20byteを超えないかどうかは判定できるようになりました。
…もっと勉強します。

VBA

1Private Sub TextBox1_Change() 2 '全角10文字 or 半角20文字の入力制限 3 'サロゲートペア文字には非対応 4 Dim s As String: s = TextBox1.Text 5 Dim convFromUcode As String 6 Dim midFromUcode As String 7 Dim leftFromUcode As String 8 Dim cnt As Integer 9 Dim i As Integer 10 convFromUcode = StrConv(s, vbFromUnicode) 11 If LenB(convFromUcode) > 20 Then 12 cnt = 0 13 For i = 1 To Len(s) 14 midFromUcode = Mid(s, i, 1) 15 '全角 16 If Len(midFromUcode) <> LenB(StrConv(midFromUcode, vbFromUnicode)) Then 17 If cnt + 2 <= 20 Then 18 cnt = cnt + 2 19 Else 20 Exit For '20を超えそうならForを抜ける 21 End If 22 '半角 23 Else 24 If cnt + 1 <= 20 Then cnt = cnt + 1 25 End If 26 Next 27 leftFromUcode = LeftB(convFromUcode, cnt) 28 TextBox1.Text = StrConv(leftFromUcode, vbUnicode) 29 End If 30End Sub

投稿2021/04/16 09:01

arakuman

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

leftFromUcode = LeftB(convFromUcode, 20) '20と決め打ちしたくない

この部分ですが、
ちょっと長くなりますが・・・。

leftFromUcode = Right(convFromUcode, 1) ' 文字列の右側から一文字取得
詳しくは、https://www.tipsfound.com/vba/05right を見てください。

最後の文字を取得するだけでは問題は解決しないです。

サロゲートペア文字を判定して、頭から文字数をカウントするのが必要だと思います。

投稿2021/04/15 01:21

nfox

総合スコア231

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

arakuman

2021/04/15 03:05

御回答ありがとうございます。 恥ずかしながらサロゲートペア文字というのは初めて聞きました。これは1文字=4bytesということですね。 ループを回して文字数を足し算という方向で考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問