
ExcelVBAなのですが、
InstrB関数で、文字位置のバイト数を取得したいと考えています。
1.文字列[A BCDE] ・・・AとBの間に、半角空白が2つあります。
※OKWaveに登録すると半角が1つになってしまうようですが、実際は2つです。
2.文字列[A BCDE] ・・・AとBの間に、全角空白が1つあります。
この文字列に対し、Bの位置は、半角空白2つであっても全角空白1つであっても同じ結果であって欲しかったのですが、
1.の場合:7、2.の場合:5 と結果が返ってきました。
※実際には、文字列から、
ある記号の次の文字からある記号の前までの文字
を取り出したいため、その記号の位置を知りたいための処理です。
ヘルプには、
InStrB 関数は検索結果をバイト位置 (先頭からその位置までのバイト数) で返します
とあったので、同じだと思ったのですが・・・
この違いは、なぜ発生するのでしょうか?
ご指導、よろしくお願いします!
No.4ベストアンサー
- 回答日時:
16進定数と16進数はほとんど同義です
VBで扱う場合は &Hをつけます Cなどでは 0xを使います
ChrW(84A5)では 84A5自体を数値として認識できません
Aが入っているので 変数かなとVBは考えますが 84で始まる変数をVBが許容していないで エラーになるでしょう
そこで &Hをつけて これに続く文字列が16進数であると明示します
ChrW(&h84A5) これなら 84 A5 と並んだ 文字を作成できます
VB自体が これが文字として有効なのかどうかはチェックしていません
引数がIntegerで表せる範囲かどうかのチェックする程度のようです
ChrWはもともと文字を生成する関数です
VBが扱う一般的な文字(および文字列)ははUnicodeなのでリファレンスにもUnicode文字を生成すると記述されています
実際には文字列変数の格納先に引数で与えられたデータを与えられた順に格納しています
AscWも同様なことがいえます
文字列のデータのByte順で戻り値を決定します
引数で与えられた 文字列の先頭バイトを下位8ビット、次のデータを上位8ビットとして組み立てた整数(Integer)を返すのです
今回 InStrBでShiftJISでも動作しているのは InStrBの動作が
引数で与えられたデータをバイト順で検索して一致する位置を返すためです
2つの引数の文字体系をあわせてやればどのようなコード体系でも使えます
VBでPrintしたりTextBoxやセルへの代入を行うとそのままでは表示できない場合がありますが
逆にInStrでは失敗しますInStrは文字単位でデータを処理しますのでShiftJISのように 1バイトしかない文字コードは扱えません
> ChrW(&Ha584)とChrW(&H84A5)の両方でテストしましたが、
> 結果は同じでしたが、これはたまたまなのでしょうか?
これは InStrでやったのではありませんか
InStrBならば ChrW(&HA584)は正しい値、ChrW(&H84A5)は0を返すはずです
redfox63様、本当にありがとうございました。
おかげで、おぼろげながらも、大体を理解することができました。
まだ頭に完全にインプットされたわけではありませんが、redfox63様の回答と自分のロジックを照らし合わせて考えればちゃんと納得できるまでには理解できました!
ので、今後のためにもredfox63様の回答をちゃんと保存させていただきました!
> > ChrW(&Ha584)とChrW(&H84A5)の両方でテストしましたが、
> > 結果は同じでしたが、これはたまたまなのでしょうか?
> これは InStrでやったのではありませんか
> InStrBならば ChrW(&HA584)は正しい値、ChrW(&H84A5)は0を返すはずです
→その通りでした、先日テストした式が残っていないので(VBAのイミティエイトウィンドウでテストしていたので・・・)、どういう式でテストしたのか確実ではないのですが、本日InstrBでテストしたところ、ChrW(&HA584)は正しい位置情報、ChrW(&H84A5)の場合は0が返ってきました。
本当に助かりました。また、いつも文字コードをあやふやにしていたのですが、redfox63様のおかげで今度からは理解しながら記述できると思います。
本当にありがとうございました!
No.3
- 回答日時:
罫線素辺などを検索したいのであれば
AscW(StrConv( "├", vbFromUnicode) )
を使わないといけないでしょう
AscBでは取得した下位8ビットしか返さないでしょうから
半角文字なら AscBでいいと思います
> AscB("├")で得た数値が28だったので
では Unicodeの下位8ビットの取得になります
InStrB( StrConv( "├", vbFromUnicode), ChrW( &Ha584) )
といった具合になります
本来├ のShiftJISコードは&H84A5なのですが インテルCPUでは 上位8ビットと下位8ビットが入れ替わりますので &HA584 を与えます
この回答への補足
今回のモジュールは、
Dim str_w As String
Dim wk As Integer
Dim lng_Code As Long
str_w = ActiveSheet.Cells(1, "A").Value
lng_Code = AscW(StrConv("├", vbFromUnicode))
wk = InStrB(StrConv(str_w, vbFromUnicode), ChrW(lng_Code))
If wk = 0 Then
lng_Code = AscW(StrConv("└", vbFromUnicode))
wk = InStrB(StrConv(str_w, vbFromUnicode), ChrW(lng_Code))
End If
msgbox wk
というふうに、
まず、セルの値が入ってくる str_w の中から、"├"のバイト位置("├"がなければ"└"のバイト位置)を調べたい、というものだったのですが、
1.├や└などの全角文字は、Unicodeでは16ビットで表す
2.ヘルプより:「AscB 関数は、最初の文字の文字コードではなく、最初のバイト データを返します。AscW 関数は、Unicode 文字セットの文字を返します。」
・・・AscBは、最初のバイトデータ(1バイト=8ビット)を返す、ということは、16ビットのうちの8ビットしか取得できないから、AscWを使う
3.AscWを使うから、ChrWを使う
ということで、間違ってませんか?
そして、これは質問なのですが、
1.WEBでUnicodeのコード表を見てみたところ、"├"は、Shift-Jisコードは"84A5"でした。
CharW(&H84A5) の"&H"はなんだろう?と思い、調べたら、「16進定数」だそうですが、これはただの16進とは何が違うのでしょうか?
ChrW(84A5)で試したら、確かに正常には検索されませんでした。
2.ChrW(&Ha584)とChrW(&H84A5)の両方でテストしましたが、結果は同じでしたが、これはたまたまなのでしょうか?
3.今回は、実際は、AscW(StrConv("├", vbFromUnicode))で返ってきた数値を使ってChrW(数値)としましたが、これでも問題はないのでしょうか?(処理は動きました)
4.ヘルプより:「AscW 関数は、Unicode 文字セットの文字を返します。」
「ChrW 関数は、Unicode 文字セットの文字を含む文字列型 (String) で文字を返します。」
・・・ですが、ChaW()でShiftJISコードを入れても動くのはなぜ?
本当に、本当にすみません。
どうかよろしくお願いします。
redfox63様、何度も的確なご指導、本当にありがとうございます!
おかげさまで、処理できました!本当にありがとうございます。
ただ、すみません、せっかくご指導いただいているのに理解ができず、教えていただいた通り記述しただけで正常にできてしまったのですが、redfox63様がよろしければ、"文字コード"について、もう少し教えていただけないでしょうか?
本当にすみません、せっかく教えていただいたので、正しく理解したくて・・・
お時間があるときで構いませんので、またご指導いただけないでしょうか?
質問文が長くなったので、補足に記述します。
どうか、よろしくお願いいたします。
No.2
- 回答日時:
お求めのものはAscBでしょうか ・・・
redfox63様、再度ご回答ありがとうございます。
AscB、その通りのようです!
ですが・・・
実際の記号でテストしたところ、正常に動かなかったのです。
実際の記号は、"├"なのですが、
AscB("├")で得た数値が28だったので、
InStrB(StrConv("├", vbFromUnicode), ChrB(28))
として試してみたのですが、結果0で返ってきてしまいました・・・
「文字コード」について、知識が乏しいので、継続して調べていますが、ご指導いただけますでしょうか?
よろしくお願いいたします。
No.1
- 回答日時:
VBAが内部で保持する文字列は Unicodeになっているためです
dim b1() as byte, b2() byte, ss as string
ss = "A__BCDE" ' _ は半角スペース
b1 = ss
ss = "A BCDE" ' AB間は全角スペース
b2 = ss
とした場合
b1は 65 0 32 0 32 0 66 0 67 0 68 0 69 0
b2は 65 0 0 48 66 0 67 0 68 0 69 0
といった具合になります
66 0 のある位置は b1は7番目 b2は5番目になります
Shift_JIS文字列で調べるならば
InStrB( StrConv( ss, vbFromUnicode), ChrB(66))
ならば どちらも 4が返ってきます
すばやい回答、ありがとうございます!
そのものズバリ!の回答でした!ありがとうございます!
便乗してお聞きしたいのですが、
「ある記号」というのがいろいろあるのですが、
ChrB()で指定する文字コードを確認する関数、ってあるものなのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) capeofdragonと申します Excel2016を使っておりまして 半角又は全角の任意文字列が 2 2022/10/31 13:51
- その他(データベース) Accessのクエリで1フィールドの抽出条件設定をNullでなく全角半角含む空白のみの文字列でない文 1 2023/04/24 15:20
- Visual Basic(VBA) VBA 「,」・空白・カタカナ等の複数条件のマクロ 2 2023/08/23 11:57
- Visual Basic(VBA) VBA 改行コードの取り方 1 2022/03/22 14:14
- Excel(エクセル) Excelについて質問です(ver2019) 1 2023/06/30 21:20
- Java Java 南京錠 2 2023/02/04 11:46
- Excel(エクセル) エクセル 関数について質問です。 2 2022/10/03 11:14
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- Excel(エクセル) PowerQueryに詳しい方教えてください(Office365) 1 2022/07/24 21:11
- Excel(エクセル) Excel 値を返す数式についてです 3 2022/11/21 20:08
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
EXCELのVBAでLenB関数について
-
StrConvでUnicodeに変換出来な...
-
CString型 全角半角を意識せず...
-
一番右のスペース以降の文字列...
-
アクセス ステータスバーの文...
-
「シフトJIS X 0213」形式の文...
-
ファイル名の一部削除について
-
VB6 コントロールボックス内の...
-
TextFieldParserの固定長桁数を...
-
WSTRINGとは?
-
PocketPcでコマンドラインパラ...
-
Err.Number
-
C言語とWin32APIで全角かなの...
-
VBA 変数名に変数を使用したい。
-
VBとアクセスでSQL文に変...
-
ExcelVBAからAccessMDB内のテー...
-
INT64対応のprintf系関数はあり...
-
【C#】textBoxの指定行のデータ...
-
C# DataTableに最後に追加した...
-
vba フィルター 複数条件 3つ以...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
EXCELのVBAでLenB関数について
-
ファイル名の一部削除について
-
CString型 全角半角を意識せず...
-
StrConvでUnicodeに変換出来な...
-
機種依存文字と特殊文字について
-
一番右のスペース以降の文字列...
-
TextFieldParserの固定長桁数を...
-
文字列から、null値を除去する方法
-
アクセス ステータスバーの文...
-
マルチバイト混在の文字列整形
-
Access VBAの参照設定(DAO)につ...
-
全角文字と半角文字を判別して...
-
VBからID3タグをいじる方法
-
VB6のテキストボックスに入力し...
-
ASC関数
-
【Excel VBA】セル内テキストの...
-
エンコード・デコードの仕方
-
「シフトJIS X 0213」形式の文...
-
バイナリデータの取り方
-
VB.NET ListBox内の前方一致で...
おすすめ情報