- ベストアンサー
エクセルで英数のみを半角に変換するマクロ
エクセル2003を使っています エクセルで英数のみを半角に変換するマクロの作り方を教えてください。 予め複数のセルを選択しておいて、それらに含まれる文字列の英数のみを半角に(カタカナは全角のまま)変換したいのです。 以前他のサイトで同様の機能のユーザー関数の作り方は見つけたのですが、マクロにする方法がわかりません。 よろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 まず、#3 のコードでバグ修正します。TextCompare ではマズかったです... SourceText = Replace$(SourceText, _ M.Value, _ StrConv(M.Value, ConvMode), _ Compare:=vbTextCompare) ↓ SourceText = Replace$(SourceText, _ M.Value, _ StrConv(M.Value, ConvMode)) 次に... > 英数、日本語、半角全角・大文字小文字が入り乱れていて、同じ曲でも > 表記方法がバラバラなため、その表記を統一したいのです。 このような質問の核心部分は最初に提示すべきでしたね... > それらに含まれる文字列の英数のみを半角に(カタカナは全角のまま) > 変換したいのです。 目的が提示されると、これは手段の一部でしかなくなってしまいました。 何をしたいのか? を最初に明示しないと不要に補足+再回答を繰り返すこと になります。 で実現方法ですが... Sub Sample() ' 半角化できるものは全て半角化する+アルファベットは一度大文字へ Call RegStrConvRng(Selection, ".*", vbNarrow + vbUpperCase) ’半角カナは全て全角へ Call RegStrConvRng(Selection, "[\uff66-\uff9f]+", vbWide) ' 半角アルファベットの頭のみ大文字へ Call RegStrConvRng(Selection, "[A-z']+", vbProperCase) End Sub これで次のように変換されます。一応希望どおりですか? i can’t speak english. ↓ I Can't Speak English. ちなみに、頭のみ大文字は、単語の頭を大文字、それに続く文字を小文字 です。つまり、 this is a pen. → This Is A Pen. です。これを This is a pen. にしたいというなら、正規表現のパターンの 設定次第で可能ですが、今回のご質問趣旨からはずれますからご自分で お調べ下さい。
その他の回答 (5)
- ham_kamo
- ベストアンサー率55% (659/1197)
No.1です。補足拝見しました。 > ちなみにユーザー関数は次のようなものですが > ひとつのマクロにする場合はどうしたらいいですか 立派な回答が出ている中、恐縮ですがお答えさせていただきます。 まず、ひとつのマクロにするというより、そのユーザ定義関数はそっくりそのまま使い、マクロ(プロシージャ)の中からそのFunctionを呼んで利用する、という形になります。 手順としては、Alt+F11を押してVBAの画面を出したとき、横のVBAProject(Book1)とかある下に「標準モジュール」というのがあるか確認してください。 なければ、「挿入」>「標準モジュール」を選択してください。「標準モジュール」というのができて、その中にModule1というのができます。 その状態で、右の画面に Function asca(文字列) : (補足にあるユーザ定義関数をそのまま貼り付ける) : End Function Sub ASC2() Dim r As Range For Each r In Application.Selection r.Value = asca(r.Value) Next End Sub を貼り付けてください。 使用するときは、選択範囲を選択してAlt+F8からASC2を実行してください。選択されたセルの全角英数字が半角に変換されます。
お礼
わかりやすくご回答いただきありがとうございました
- KenKen_SP
- ベストアンサー率62% (785/1258)
> 文字列を英数半角化+頭のみ大文字にする場合は... Call RegStrConvRng(Selection, "[A-z0-9]+", vbNarrow) ↓ Call RegStrConvRng(Selection, "[A-z0-9]+", vbNarrow + vbProperCase) vbNarrow の後ろで + を入力すると選択できる候補がポップアップ表示されます。 組み合わせる方法は単純に + で連結しいくだけです。 組み合わせによっては効果なし...もありますけどね。適当に幾つかの組み合わせ を実際に試してみるとわかります。 それから、コードにもコメントが入ってますが、 RegStrConv........VBA でもワークシートでも使えます。 ワークシートで使う場合、 B1セルの数式:=RegStrConv(A1,"[A-z0-9]+",8) この場合、第三引数の 8 の意味は、RegStrConv 関数のコメント欄に書いてあります。 1: 大文字 2: 小文字 3: 頭のみ大文字 4: 全角 8: 半角 16:カタカナ 32:ひらがな なので、この例では半角化...ということです。ワークシート関数で使う場合、 VBE での編集のように候補がポップアップ表示されませんし、vbNarrow といった VBA 専用定数を使用できませんので、数値を直接指定しなければなりません。 この時の組み合わせ方は、半角化+カタカナにするなら 例)半角化+頭のみ大文字 --> 8 + 3 = 11 と単純に足し算したものを第三引数とします。最終的に数式は =RegStrConv(A1,"[A-z0-9]+",11) で、A1 セルの値のうち、全角英数のみを「半角化+頭のみ大文字」にします。 もちろん数字に大文字はないので、数字は半角化のみの効果です。
補足
ありがとうございました 全角英数と半角英数が混在しているばあい >Call RegStrConvRng(Selection, "[A-z0-9]+", vbNarrow + vbProperCase) この処理ですと全角英数の文字列には有効ですが、もともと半角大文字の文字列に対しては先頭文字のみ大文字(以下小文字)とはなってくれません、またこの処理ですとアポストロフィーの後の文字が大文字になってしまいます(CAN’T→Can'T) 何をしたいかと言いますと、mp3のタグ(曲名等)を整理しているのですが英数、日本語、半角全角・大文字小文字が入り乱れていて、同じ曲でも表記方法がバラバラなため、その表記を統一したいのです。 (1)英語表記の場合、先頭文字を大文字以下は小文字の半角に統一 (2)日本語の場合、全角に統一(カタカナ) (3)英語と日本語が混在している場合は英数は半角カタカナは全角に統一 こういうことができますでしょうか、よろしくお願いします。
- KenKen_SP
- ベストアンサー率62% (785/1258)
ちょいと複雑になってしまいましたが、こんな感じだと正規表現を使って、 変換する対象を限定することも可能ですよ。 ' Option Explicit Private m_RegExp As Object ' // RegExp Object ' 使いかたサンプル Sub Sample() Cells.Clear With Range("A1:E500") .Value = "あいうアイウABCabc123" .Select End With DoEvents MsgBox CStr(Selection.Count) & "個のテストデータセット完了。デモを開始" MsgBox "全角英数字を半角にします" Call RegStrConvRng(Selection, "[A-z0-9]+", vbNarrow) DoEvents MsgBox "半角英数字を全角にします" Call RegStrConvRng(Selection, "[A-z0-9]+", vbWide) DoEvents MsgBox "カタカナを平仮名にします" Call RegStrConvRng(Selection, ".*", vbHiragana) DoEvents MsgBox "平仮名をカタカナにします" Call RegStrConvRng(Selection, ".*", vbKatakana) DoEvents MsgBox "正規表現で置換対象を限定することが可能です" Cells.Clear Range("A1").Value = "アイウあいうABC123" MsgBox "B1 セルにユーザー定義関数を設定します" Range("B1").Formula = "=RegStrConv(A1,""[A-z0-9]+"",8)" MsgBox "終わり" End Sub ' // 指定した Range に対して RegStrConv 関数を実行する Private Sub RegStrConvRng( _ ByVal Target As Range, _ ByVal Pattern As String, _ ByVal ConvMode As VbStrConv _ ) Dim rArea As Range Dim vBuf As Variant Dim i As Long Dim j As Long ' 終了条件:: データが無い If Application.CountA(Target) = 0 Then Exit Sub ' 終了条件:: 定数セルが無い If Not Target.MergeCells And Target.Count > 1 Then On Error Resume Next Set Target = Target.SpecialCells( _ xlCellTypeConstants, _ xlNumbers Or xlTextValues) On Error GoTo 0 If Target Is Nothing Then Exit Sub End If ' 置換メイン On Error GoTo ERROR_HANDLER For Each rArea In Target.Areas vBuf = rArea.Value If Not IsArray(vBuf) Then ReDim vBuf(1 To 1, 1 To 1) vBuf(1, 1) = rArea.Value End If For i = 1 To UBound(vBuf, 1) For j = 1 To UBound(vBuf, 2) vBuf(i, j) = RegStrConv(vBuf(i, j), Pattern, ConvMode) Next j Next i rArea.Value = vBuf Erase vBuf Next rArea Set Target = Nothing Exit Sub ERROR_HANDLER: MsgBox Err.Description, vbCritical End Sub ' // StrConv 拡張関数(ワークシート関数としても使えます) Public Function RegStrConv( _ ByVal SourceText As String, _ ByVal Pattern As String, _ ByVal ConvMode As VbStrConv _ ) As String ' 目 的: 正規表現を使って StrConv 関数の対象を限定させることが可能 ' 引 数: SourceText 対象文字列 ' : Pattern 正規表現マッチングパターン ' : ConvMode StrConv 関数の第二引数と同一 ' : 1:大文字 2: 小文字 3: 頭のみ大文字 4: 全角 8: 半角 ' : 16:カタカナ 32:ひらがな ' 備 考: ConvMode の定数は組み合わせが可能(例)半角化+カタカナ=8+16=24 Dim MC As Object ' MatchCollection Dim M As Object ' Match Dim Buf Dim i As Long If m_RegExp Is Nothing Then Set m_RegExp = CreateObject("VBScript.RegExp") End If With m_RegExp .Pattern = Pattern .Global = True .IgnoreCase = False Set MC = .Execute(SourceText) End With For Each M In MC SourceText = Replace$(SourceText, _ M.Value, _ StrConv(M.Value, ConvMode), _ Compare:=vbTextCompare) Next M Set MC = Nothing: Set M = Nothing RegStrConv = SourceText End Function
補足
ありがとうございました すごいですね 残念ながら初心者なのでマクロの記述部分はまだ理解できませんが やりたいことはこれでできそうです 英数のみ半角にしたいときは Sub 英数半角変換() ' MsgBox "全角英数字を半角にします" Call RegStrConvRng(Selection, "[A-z0-9]+", vbNarrow) ' DoEvents End Sub とすればよいのですね ' 備 考: ConvMode の定数は組み合わせが可能(例)半角化+カタカナ=8+16=24 とありますが たとえば、文字列を英数半角化+頭のみ大文字にする場合は どうしたらいいのか教えてください。
- papayuka
- ベストアンサー率45% (1388/3066)
スマートじゃありませんが、、、 A-Z、a-z、0-9 を A-Z、a-z、0-9 にします。 Sub Test() Dim r As Range, s As String For Each r In Selection If Not r.HasFormula Then s = "" For i = 1 To Len(r.Text) Select Case Asc(Mid(r.Text, i, 1)) Case -32127 To -32102, -32160 To -32135, -32177 To -32168 s = s & StrConv(Mid(r.Text, i, 1), vbNarrow) Case Else s = s & Mid(r.Text, i, 1) End Select Next i r.Value = s End If Next r End Sub
お礼
ありがとうございました これでも十分ですね、うまくいきました
- ham_kamo
- ベストアンサー率55% (659/1197)
> 以前他のサイトで同様の機能のユーザー関数の作り方は見つけた ということは、その機能を持ったFunctionの定義はある、ということでしょうか。それならば、その関数(仮にF0()とします)を使って、 Sub ASC2() Dim r As Range For Each r In Application.Selection r.Value = F0(r.Value) Next End Sub という感じでできるのでは。F0()は標準モジュールにあると仮定しており、実際に英数字のみを半角に変換するユーザ定義関数の名前に書き換えてください。また引数に文字列を指定する、と仮定しているので、もしその関数が引数としてセルを指定するようになっている場合、 r.Value = F0(r.Value) の行は、 r.Value = F0(r) としてください。
補足
ありがとうございます、お礼が遅くなってすみません おかげさまでうまくいきました ちなみにユーザー関数は次のようなものですが ひとつのマクロにする場合はどうしたらいいですか よろしくお願いします Function asca(文字列) Dim L, Tx, LT, t, c Application.Volatile L = Len(文字列) Tx = "" For LT = 1 To L t = Mid(文字列, LT, 1) c = Asc(t) If c < -32000 Then t = Application.Asc(t) Tx = Tx & t Next asca = Tx End Function
お礼
>このような質問の核心部分は最初に提示すべきでしたね すみませんでした、お手間を取らせる結果となってしまいました。 お蔭様でやりたかったことが完璧にできました。 ありがとうございました。