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

VBAを100本の練習問題で鍛えます
公開日:2020-11-13 最終更新日: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 ・・・新着記事一覧を見る

ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)
いくつかの数式の計算中にリソース不足になりました。|エクセル雑感(2023-12-28)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|VBA入門
4.ひらがな⇔カタカナの変換|エクセル基本操作
5.繰り返し処理(For Next)|VBA入門
6.変数宣言のDimとデータ型|VBA入門
7.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
8.並べ替え(Sort)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.Findメソッド(Find,FindNext,FindPrevious)|VBA入門




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


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


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