VBA練習問題
VBA100本ノック 24本目:全角英数のみ半角

VBAを100本の練習問題で鍛えます
最終更新日:2022-01-06

VBA100本ノック 24本目:全角英数のみ半角


全角英数のみ半角かつ大文字にするFunctionを作成する問題です。


ツイッター連動企画です。
ツイートでの見やすさを考慮して、ブック・シート指定等を適宜省略しています。

VBAテスト用のサンプルデータはご自身でご用意ください。


出題

出題ツイートへのリンク

#VBA100本ノック 24本目
引数で受け取った文字列に対して、以下の処理を行い文字列で返す関数(Function)を作成してください。
・英小文字は英大文字にする
・全角の英数文字は半角にする
※英数文字とは:A-Z,a-z,1-9
"あいうABCアイウabc123"

"あいうABCアイウABC123"


※英数文字とは:A-Z,a-z,1-9
↑これは書き間違いです。
※英数文字とは:A-Z,a-z,0-9
数字は0-9です。
普通に書き間違えました。


VBA作成タイム

この下に頂いた回答へのリンクと解説を掲載しています。
途中まででも良いので、できるだけ自分でVBAを書いてみましょう。


他の人の回答および解説を見て、書いたVBAを見直してみましょう。


頂いた回答

解説

いつもはるべく平易なコードから紹介するのですが、今回は私が解答用に作成した順番にしてみます。
まずは、
・Forで1文字ずつ取り出しながらLike+Midステートメント+StrConv
Mid関数ではなくMidステートメントです。

Function VBA100_24_01(ByVal s As String) As String
  Dim i As Long
  
  For i = 1 To Len(s)
    If Mid(s, i, 1) Like "[A-Za-za-c0-9]" Then
      Mid(s, i, 1) = StrConv(Mid(s, i, 1), vbNarrow + vbUpperCase)
    End If
  Next
  
  VBA100_24_01 = s
End Function


続いて、
・Forで1文字ずつ取り出しながらUCase+Select Case+StrConv
そういえば、回答でSelect Caseを使っているのは見なかった気がしますが、範囲指定できるので結構便利です。

Function VBA100_24_02(ByVal s As String) As String
  Dim i As Long, tmp As String
  
  For i = 1 To Len(s)
    tmp = UCase(Mid(s, i, 1))
    Select Case tmp
      Case "A" To "Z", "0" To "9"
        tmp = StrConv(tmp, vbNarrow)
    End Select
    VBA100_24_02 = VBA100_24_02 & tmp
  Next
End Function


その他としては、
・RegExp+Midステートメント+StrConv
・英数文字リストすべてをReplace
これらのVBAは、記事補足に掲載しました。


補足

上記VBAの要点は、
Like演算子Select CaseMidステートメント
これらの使い方だけだと思います。
これらについては以下を参照してください。
第22回.条件分岐(Select Case)
・Select Caseステートメントの構文 ・Select Case の例文 ・Select Case の応用
第49回.Like演算子とワイルドカード
・Like演算子 ・パターン文字列式(ワイルドカード、文字リスト、文字範囲) ・Like演算子の使用例 ・正規表現について
第101回.Midステートメント
・Midステートメント ・MidBステートメント ・Midステートメントの使用例 ・Midステートメントの必要性 ・実践での使用例

RegExp+Midステートメント+StrConv
Function VBA100_24_03(ByVal s As String) As String
  Dim re As New RegExp
  Set re = CreateObject("VBScript.RegExp")
  re.Pattern = "[A-Z0-9]+"
  re.Global = True
  
  Dim mc As Object, m As Object, rtn As String
  rtn = UCase(s)
  Set mc = re.Execute(rtn)
  For Each m In mc
    Mid(rtn, m.FirstIndex + 1, m.Length) = StrConv(m.Value, vbNarrow)
  Next
  Set re = Nothing
  
  VBA100_24_03 = rtn
End Function

正規表現で変換対象を取得するところまでは良いのですが、
その後の文字列置換にReplaceを使うのは、あまり良い感じがしませんでした。
いろいろ考えたのですが、結局最初に使ったMidステートメントに落ち着いてしまいました。
VBAで正規表現を利用する(RegExp)
・メタ文字 ・正規表現 ・正規表現RegExpの使い方 ・RegExpオブジェクト ・RegExpの使用例 ・RegExp関連のオブジェクト ・Execute(Matches,Match,SubMatches)の使用例 ・Replaceの使用例 ・先読み:肯定先読み、否定先読み ・正規表現の実践例

英数文字リストすべてをReplace
Function VBA100_24_04(ByVal s As String) As String
  Const targetChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  
  Dim i As Long
  For i = 1 To Len(targetChar)
    s = Replace(s, Mid(targetChar, i, 1), Mid(targetChar, i, 1), , , vbTextCompare)
  Next
  
  VBA100_24_04 = s
End Function

発想を逆にして、変換すべき文字リストを用意してReplaceで全て変換しています。
vbTextCompare
これは、全角半角、大文字小文字が区別されません。
Replace関数
Replace関数は、指定された文字列の一部を、別の文字列で指定された回数分で置換した文字列を返します。引数compareの指定りより、全角半角、大文字小文字の扱いが変わります。Replace関数 Replace(expression,find,replace[,start[,count[,compare]]]) …
したがって、
Replace(文字列, "A", "A", , , vbTextCompare)
これで、
半角小文字の"a"、全角大文字の"A"、全角小文字の"a"
これらが半角大文字の"A"に置換されます。

文字コードの変換で処理
文字コードの規則性を利用して変換するものです。
全角文字コードに一定数を加減算することで文字を変換します。
同種の文字コードは連続配置されているので規則性が見つかれば加減算することで対応する文字に変換できます。
これについては回答にあるので参考にしてください。


サイト内関連ページ

第22回.条件分岐(Select Case)
・Select Caseステートメントの構文 ・Select Case の例文 ・Select Case の応用
第47回.VBA関数(文字列操作,Replace,InStr,StrConv)
・文字列操作に関するVBA関数の一覧 ・Replace関数 ・InStr関数 ・StrConv関数 ・最後に
第49回.Like演算子とワイルドカード
・Like演算子 ・パターン文字列式(ワイルドカード、文字リスト、文字範囲) ・Like演算子の使用例 ・正規表現について
第101回.Midステートメント
・Midステートメント ・MidBステートメント ・Midステートメントの使用例 ・Midステートメントの必要性 ・実践での使用例
Replace関数
Replace関数は、指定された文字列の一部を、別の文字列で指定された回数分で置換した文字列を返します。引数compareの指定りより、全角半角、大文字小文字の扱いが変わります。Replace関数 Replace(expression,find,replace[,start[,count[,compare]]]) …
VBAで正規表現を利用する(RegExp)
・メタ文字 ・正規表現 ・正規表現RegExpの使い方 ・RegExpオブジェクト ・RegExpの使用例 ・RegExp関連のオブジェクト ・Execute(Matches,Match,SubMatches)の使用例 ・Replaceの使用例 ・先読み:肯定先読み、否定先読み ・正規表現の実践例




同じテーマ「VBA100本ノック」の記事

21本目:バックアップファイルの削除
22本目:FizzBuzz発展問題
23本目:シート構成の一致確認
24本目:全角英数のみ半角
25本目:マトリックス表をDB形式に変換
26本目:ファイル一覧作成
27本目:ハイパーリンクのURL
28本目:シートをブックに分割
29本目:画像の挿入
30本目:名札作成(段組み)
31本目:入力規則


新着記事NEW ・・・新着記事一覧を見る

列全体を指定する時のRangeとColumnsの違い|ツイッター出題回答 (2023-09-24)
シートのActiveXチェックボックスの指定方法|ツイッター出題回答 (2023-09-24)
ByRef引数の型が一致しません。|ツイッター出題回答 (2023-09-22)
シートコピー後のアクティブシートは何か|ツイッター出題回答 (2023-09-19)
Excel関数の引数を省略した場合について|ツイッター出題回答 (2023-09-14)
セル個数を返すRange.CountLargeプロパティとは|VBA技術解説(2023-09-08)
記号を繰り返してグラフ作成(10単位で折り返す)|ツイッター出題回答 (2023-08-28)
シートを削除:不定数のシート名に対応|VBAサンプル集(2023-08-24)
ランクによりボイントを付ける(同順位はポイントを分割)|ツイッター出題回答 (2023-08-22)
OneDrive使用時のThisWorkbook.Pathの扱い方|VBA技術解説(2023-07-26)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.繰り返し処理(For Next)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.マクロとは?VBAとは?VBAでできること|VBA入門
7.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
8.並べ替え(Sort)|VBA入門
9.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
10.条件分岐(IF)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ