こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

【ExcelVBA】英数記号の半角変換

こんにちは。

Excel2013を使用しています。
カタカナは全角、英数記号は半角で表示を統一したく、ネットで検索したサンプルコードを範囲や条件等を変更して下記コードを作成しました。
(サンプルコードが記載されていたページに簡易な例で全ての場合に対応できていないとの但し書きがありました。)

下記コードを実行すると、記号のうち、括弧、中点については半角表示になりますが、#については全角表示のままです。
Mid(rData, i, 1) Like "#" の Like を = に変更して、Mid(rData, i, 1) = "#" とすると、#についても半角表示になりました。
“全ての場合に対応できていない”に該当するものなのかもしれませんが、Like では希望する結果を得られない理由は何なのか気になり、質問させていただきました。
よろしくお願いします。

--------------------------------------------------
Sub test()
Dim c As Range
Dim i As Integer
Dim rData As Variant, ansData As Variant

For Each c In Range(Cells(3, "D"), Cells(Cells(Rows.Count, "D").End(xlUp).Row, "D"))
ansData = ""
For i = 1 To Len(c.Value)
rData = StrConv(c.Value, vbWide)
If Mid(rData, i, 1) Like "[A-z]" Or Mid(rData, i, 1) Like "[0-9]" _
Or Mid(rData, i, 1) Like "(" Or Mid(rData, i, 1) Like ")" _
Or Mid(rData, i, 1) Like "・" Or Mid(rData, i, 1) Like "#" Then
ansData = ansData & StrConv(Mid(rData, i, 1), vbNarrow)
Else
ansData = ansData & Mid(rData, i, 1)
End If
Next i
c.Value = ansData
Next c
End Sub

投稿日時 - 2014-08-28 14:32:55

QNo.8733608

暇なときに回答ください

質問者が選んだベストアンサー

こんにちは。お邪魔します。

テーマはLike演算子の扱い方、という理解でお応えします。

#以下Excel2010で確認した内容を基にします。

ヘルプを読んだのでしたら話は早いですが、
キャラセットとして"[角括弧]"の内側にマッチングパターンを書けば、
特別な意味を持つ記号=メタ文字【*?!#[-】も
エスケープした普通の文字として扱えます。

 If Mid(rData, i, 1) Like "[A-z]" Or Mid(rData, i, 1) Like "[0-9]" _
 Or Mid(rData, i, 1) Like "(" Or Mid(rData, i, 1) Like ")" _
 Or Mid(rData, i, 1) Like "・" Or Mid(rData, i, 1) Like "#" Then
と書く代わりに、
 If Mid(rData, i, 1) Like "[・#()0-9A-z]" Then
のように済ませるのが、Like演算子本来のマッチングの仕方で、必要十分なパターンです。
Or演算子で複数のマッチング結果を繋いでいるのは、
ビギナー向けの解説のイントロとしてはある意味正しいようにも思えますが
逆にLike演算子に熟れている人から見ると、何か訳があるのかな?と、
穿った目で見られそうな感、というか却って解り難く扱い難い気もします。
パターンがあまりにも長いとか、系統で分けて書くという時には、
Or演算子で繋ぐのもアリ、です。

一般的なパターンの書き方として、
ヘルプにもあるように文字コードの順番さえ頭に入っていれば、
"[角括弧]" の内側に 
連続した部分には区間を表す"-"ハイフンを挟むようにして、
ひたすら文字コード順に列挙していけばいいだけです。

加えて、
StrConv()関数の引数ConversionにvbNarrowを指定した場合は、
半角に変換できない文字はそのままの全角文字を返すという点や、
使われない文字コードは通常考慮する必要がない点を、
合わせて理解しておけば、簡素な(省略した)パターンを書くことが出来ます。

取り敢えず、半角・全角互換の文字種を文字コード順に並べてみます。
Excelシートに貼り付け[データ][区切り文字]を使ってスペース区切りで展開すれば、
そのまま一覧表になります。

全角 コード
‘ U+2018
’ U+2019
” U+201D
  U+3000 x
、 U+3001 x
。 U+3002 x
「 U+300C x
」 U+300D x
ァ U+30A1 x
ア U+30A2 x
ィ U+30A3 x
イ U+30A4 x
ゥ U+30A5 x
ウ U+30A6 x
ェ U+30A7 x
エ U+30A8 x
ォ U+30A9 x
オ U+30AA x
カ U+30AB x
ガ U+30AC x
キ U+30AD x
ギ U+30AE x
ク U+30AF x
グ U+30B0 x
ケ U+30B1 x
ゲ U+30B2 x
コ U+30B3 x
ゴ U+30B4 x
サ U+30B5 x
ザ U+30B6 x
シ U+30B7 x
ジ U+30B8 x
ス U+30B9 x
ズ U+30BA x
セ U+30BB x
ゼ U+30BC x
ソ U+30BD x
ゾ U+30BE x
タ U+30BF x
ダ U+30C0 x
チ U+30C1 x
ヂ U+30C2 x
ッ U+30C3 x
ツ U+30C4 x
ヅ U+30C5 x
テ U+30C6 x
デ U+30C7 x
ト U+30C8 x
ド U+30C9 x
ナ U+30CA x
ニ U+30CB x
ヌ U+30CC x
ネ U+30CD x
ノ U+30CE x
ハ U+30CF x
バ U+30D0 x
パ U+30D1 x
ヒ U+30D2 x
ビ U+30D3 x
ピ U+30D4 x
フ U+30D5 x
ブ U+30D6 x
プ U+30D7 x
ヘ U+30D8 x
ベ U+30D9 x
ペ U+30DA x
ホ U+30DB x
ボ U+30DC x
ポ U+30DD x
マ U+30DE x
ミ U+30DF x
ム U+30E0 x
メ U+30E1 x
モ U+30E2 x
ャ U+30E3 x
ヤ U+30E4 x
ュ U+30E5 x
ユ U+30E6 x
ョ U+30E7 x
ヨ U+30E8 x
ラ U+30E9 x
リ U+30EA x
ル U+30EB x
レ U+30EC x
ロ U+30ED x
ワ U+30EF x
ヲ U+30F2 x
ン U+30F3 x
・ U+30FB
! U+FF01
# U+FF03
$ U+FF04
% U+FF05
& U+FF06
( U+FF08
) U+FF09
* U+FF0A
+ U+FF0B
, U+FF0C
- U+FF0D
. U+FF0E
/ U+FF0F x
0 U+FF10
1 U+FF11
2 U+FF12
3 U+FF13
4 U+FF14
5 U+FF15
6 U+FF16
7 U+FF17
8 U+FF18
9 U+FF19
: U+FF1A
; U+FF1B
< U+FF1C
= U+FF1D
> U+FF1E
? U+FF1F
@ U+FF20
A U+FF21
B U+FF22
C U+FF23
D U+FF24
E U+FF25
F U+FF26
G U+FF27
H U+FF28
I U+FF29
J U+FF2A
K U+FF2B
L U+FF2C
M U+FF2D
N U+FF2E
O U+FF2F
P U+FF30
Q U+FF31
R U+FF32
S U+FF33
T U+FF34
U U+FF35
V U+FF36
W U+FF37
X U+FF38
Y U+FF39
Z U+FF3A
[ U+FF3B
] U+FF3D
^ U+FF3E
_ U+FF3F
a U+FF41
b U+FF42
c U+FF43
d U+FF44
e U+FF45
f U+FF46
g U+FF47
h U+FF48
i U+FF49
j U+FF4A
k U+FF4B
l U+FF4C
m U+FF4D
n U+FF4E
o U+FF4F
p U+FF50
q U+FF51
r U+FF52
s U+FF53
t U+FF54
u U+FF55
v U+FF56
w U+FF57
x U+FF58
y U+FF59
z U+FF5A
{ U+FF5B
| U+FF5C x
} U+FF5D
~ U+FF5E x
¥ U+FFE5

(上から4番目は全角空白)
(\から\ \から¥ のように全→半、半→全と変換を繰り返すと違う文字になるもの、
 StrConv()関数で変換できないもの、は省く)
(教えて!gooのIDでの投稿に際し、すべての文字種が正しく表示できるかは未確認)
(もし怪しいものがあれば、コードを参照してIMEパッド(Unicode)等で確認してください)

こちらで試しに仮定したものですが、
抽出対象から外す(半角に置換しない)文字種
(全角空白、句読点、かぎ括弧【 、。「」】全角カタカナ【ァ-ン】他【/|~】)
について、上の表での3列めに "x"を付けてみました。
この設定でのパターンは
 str Like "[‘-" & ChrW(&H201D) & "・-.0-{}¥]"
のように書くことも出来ます。
本来は "[‘-”・-.0-{}¥]" ですが、
VBEに全角の”をタイプすることが出来ない為、
ChrW()関数を使って代用しています。
例示としては「ただ列挙するだけなんです」と強調する意図です。

また、上の表を見ながら、
"[A-z]"
というパターンを見直すと、実はこれ、全角アルファベットとイコールでないことに気付くと思います。
余分な文字[]^_を拾っちゃいますから、
"[A-Za-z]"
という風に、無駄なく正確に全角アルファベットを指定してみようかな?とか、
コツさえ掴めば、色々な工夫が出来るようになると思います。

"簡易な例"という説明文の意味する、簡易と簡易でないものの違いは
以上の説明で理解できるのではないでしょうか?

尚、
ご提示のコードは英数字と幾つかの記号を 半角に置換するコードです。
カタカナは既に全角で書かれている、のか、
これから書き足す、のか、判りませんが、もしも、
これから半角カナの全角化に取り組むのでしたら、
■半角カナは一文字ずつ全角に置換することは出来ない■と覚えておいて下さい。
濁点・半濁点のカナは全角では一文字ですが、半角では二文字です。

そういった見通しや汎用性を考慮して、
現状の一文字ずつ置換する、というやり方から発展して、
置換対象の塊りを捉えて、塊りごと置換するような課題に挑戦することをお奨めしておきます。
例えば、
"AbcアイウXyzワヲン"
であれば、
"Abc" を "Abc"
"Xyz" を "Xyz"
纏めて置換する、ということです。

最後に、
Like演算子でのマッチングは世間で思われているより有用ですので、
是非この機会に熟れておいて貰えればと思います。
その先に余裕が出来たり不満が出て来たりしたら、
正規表現(VBAではVBScript.RegExpのこと)についても調べて
理解できたものを書いてみるといいと思います。

長、失礼しました。以上です。

投稿日時 - 2014-08-29 01:02:42

お礼

回答ありがとうございます。

今回の質問の意図するところを全て書いていただいたような回答で大変わかりやすかったです。
Or演算子を使わない書き方も教えていただき、勉強になります。
コードがスッキリまとまっていると、あとで見直したり変更したりする場合もわかりやすくていいです。

英数字といくつかの記号を半角にする前に
rData = StrConv(c.Value, vbWide) で
一旦全てを全角にしているので、質問文に記載したコードはとりあえず完成させることができました。

ご丁寧な回答ありがとうございました。

投稿日時 - 2014-08-29 16:05:51

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

No2です。

半角にしたい記号が増えた場合の事を考えると、一度すべて半角にして、その後カタカナだけ全角に戻した方がよいのではないかと思います。

こちらのページのコードは参考にならないでしょうか
http://hichon.cocolog-nifty.com/blog/2011/09/excelvba-a251.html

投稿日時 - 2014-08-28 16:33:31

お礼

再度の回答ありがとうございます。

教えていただいたURLに記載されたコードは私も質問投稿前に目にしました。
質問文に記載している方法とは逆の方法ですが、いろんな方法があるということで、時間が空いたときにでもこの方法でのコードを勉強がてら書いてみようと思っています。

ありがとうございました。

投稿日時 - 2014-08-29 15:50:28

ANo.2

「*」、「?」、「#」そのものをLikeしたいときには[]で囲んでください。#でしたら

Mid(rData, i, 1) Like "[#]" Then

のようにしてください。

投稿日時 - 2014-08-28 16:16:12

お礼

回答ありがとうございます。

先の回答者様から Like のヘルプに記載があるとのことで、ヘルプを読み、Like を使う場合の方法として[ ]で囲んで試してみたところ、うまくいきました。

ありがとうございました。

投稿日時 - 2014-08-28 16:24:35

ANo.1

Likeのヘルプを読めば記載あります。

「#」は、任意の 1 文字の数字 (0-9)を意味します。

つまり、
Mid(rData, i, 1) Like "#"
は0~9の何れかの時、Trueになります。

※Excelの関数では*が任意の文字、?が任意の1文字の2種類しかありませんが、VBAでは、#も存在するわけです。

投稿日時 - 2014-08-28 14:39:50

お礼

早速、回答いただきましてありがとうございます。

Like のヘルプ、読みました。
Like はExcelの関数で文字列をアスタリスクで囲んだときと同じという程度にしか考えていなかったので、勉強になりました。

ありがとうございました。

投稿日時 - 2014-08-28 15:28:46

あなたにオススメの質問