Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3851 / 13646 ツリー ←次へ | 前へ→

【59814】文字列の分割について・・・ 文字ってわからん 09/1/9(金) 18:25 質問[未読]
【59817】Re:文字列の分割について・・・ かみちゃん 09/1/9(金) 20:16 発言[未読]
【59819】Re:文字列の分割について・・・ kanabun 09/1/9(金) 21:27 発言[未読]
【59820】Re:文字列の分割について・・・ kanabun 09/1/9(金) 23:18 発言[未読]
【59822】Re:文字列の分割について・・・ kanabun 09/1/10(土) 0:38 発言[未読]
【59844】Re:文字列の分割について・・・ kanabun 09/1/13(火) 11:30 発言[未読]

【59814】文字列の分割について・・・
質問  文字ってわからん  - 09/1/9(金) 18:25 -

引用なし
パスワード
   只今、仕事の業務にて文字列を分割してCSVにはき出すマクロを作っているのですが・・・。
説明しづらいので例を挙げさせていただきます。
1."あいうえおかきくけこ"
2."あいう111おかきくけこ"
3."あいう1えおかきくけこ"
と3つの文字列があって
文字列1=10バイトまで
文字列2=10バイトまでとわけたいのですが・・・。
=MIDB("文字列",1,10)
=MIDB("文字列",11,10)
と関数を入れますと

1.は
文字列1="あいうえお"
文字列2="かきくけこ"
2.は
文字列1="あいう111 "
文字列2="おかきくけ"
3.は
文字列1="あいう1え "
文字列2=" かきくけ "
と半角スペース的なものがはいってしまいます。
バイトで区切っているので原因はわかりますが、
スぺースでもないので、トリムもきかずどうしていいかわかりません

このように不正の文字がでてしまった場合どうやって判断し
どのような除去を入れればいいのでしょうか?
説明の方が上手くなくてわかりにくいと思いますが、よろしくお願いします。

【59817】Re:文字列の分割について・・・
発言  かみちゃん E-MAIL  - 09/1/9(金) 20:16 -

引用なし
パスワード
   こんにちは。かみちゃん です。

>1."あいうえおかきくけこ"
>2."あいう111おかきくけこ"
>3."あいう1えおかきくけこ"
>と3つの文字列があって
>文字列1=10バイトまで
>文字列2=10バイトまでとわけたいのですが・・・。
>=MIDB("文字列",1,10)
>=MIDB("文字列",11,10)
>と関数を入れますと
>
>1.は
>文字列1="あいうえお"
>文字列2="かきくけこ"
>2.は
>文字列1="あいう111 "
>文字列2="おかきくけ"
>3.は
>文字列1="あいう1え "
>文字列2=" かきくけ "
>と半角スペース的なものがはいってしまいます。
>バイトで区切っているので原因はわかりますが、
>スぺースでもないので、トリムもきかずどうしていいかわかりません
>
>このように不正の文字がでてしまった場合どうやって判断し
>どのような除去を入れればいいのでしょうか?

トリムとは、TRIM関数のことでしょうか?
また、VBAで処理する方法ですか?ワークシート関数で処理する方法ですか?
いずれにしても、
=TRIM(MIDB("文字列",1,10))
で10バイト目が、全角文字の1バイト目の場合は、除去されるようです。

VBAの場合ですと、以下のようなコードで除去されると思います。
イミディエイトウィンドウに結果が表示されますので、確認してみてください。

Sub Sample()
 Dim ss1 As String
 Dim ss2 As String
 Dim ss3 As String
 
 ss1 = "あいうえおかきくけこ"
 ss2 = "あいう111おかきくけこ"
 ss3 = "あいう1えおかきくけこ"
 
 Debug.Print "   1234567890"
 Debug.Print "1-1-1[" & MidB(ss1, 1, 10) & "]"
 Debug.Print "1-2-1[" & MidB(ss1, 11, 10) & "]"
 
 Debug.Print "2-1-1[" & MidB(ss2, 1, 10) & "]"
 Debug.Print "2-1-2[" & StrConv(MidB(StrConv(ss2, vbFromUnicode), 1, 10), vbUnicode) & "]"
 Debug.Print "2-1-3[" & Application.Trim(StrConv(MidB(StrConv(ss2, vbFromUnicode), 1, 10), vbUnicode)) & "]←除去されている"
 Debug.Print "2-2-1[" & MidB(ss2, 11, 10) & "]"
 
 Debug.Print "3-1-1[" & MidB(ss3, 1, 10) & "]"
 Debug.Print "3-2-1[" & MidB(ss3, 11, 10) & "]"
 
End Sub

【59819】Re:文字列の分割について・・・
発言  kanabun  - 09/1/9(金) 21:27 -

引用なし
パスワード
   横から失礼 m(_ _)m

>=MIDB("文字列",1,10)
>=MIDB("文字列",11,10)
>と関数を入れますと

1. あいうえおかきくけこ [あいうえお] [かきくけこ]
2. あいう111おかきくけこ [あいう111 ] [ かきくけ ]
3. あいう1えおかきくけこ [あいう1え ] [ かきくけ ]

となりますが、

2. 3. のように「10バイト目が全角文字の2バイト目」のとき、
どう処理したいのですか?

2. のばあい、
  1〜9バイト [あいう111]  10〜19バイト [おかきくけ] 
なのか、
  1〜11バイトまで [あいう111お] と [かきくけこ]
としたいのか?
はたまた、それ以外?

【59820】Re:文字列の分割について・・・
発言  kanabun  - 09/1/9(金) 23:18 -

引用なし
パスワード
   文字列を 10バイトで カンマを挿入するサンプルです。

なお、VBAのMidB関数を VBAの文字列に対して 直接適用してはいけません。
VBA上では 文字コードはUnicodeで(abc123あいう亜 すべて2バイト)
↓最後の参考例のように、目的の文字列は取り出せません。

'Try2 実行結果
あいう111 , おかきくけこ
あいう1え , おかきくけこ
1234567890,abcdefghij
12345     67890

Sub Try2()
  Const u1 = "1234567890abcdefghij"
  Const u2 = "あいう111おかきくけこ"
  Const u3 = "あいう1えおかきくけこ"
  
  Debug.Print USplit(u2, 10) '10バイトまでと それ以降に分割
  Debug.Print USplit(u3, 10)
  Debug.Print USplit(u1, 10)
  '参考
  Debug.Print MidB(u1, 1, 10), MidB(u1, 11, 10)
End Sub

Function USplit(UStr As String, ByVal m As Long) As String
  Dim bb() As Byte
  ReDim bb(1 To m * 2)
  bb = StrConv(UStr, vbFromUnicode) 'ShiftJISバイトコードに直す
  
  '指定のmバイト目が コード80〜9F、または E0〜FF だったら、
  Select Case bb(m + 1)
   Case &H80 To &H9F, &HE0 To &HFF '分割点が全角文字の中にあったら
     m = m - 1     '------ 分割点を1バイト前に移動
     'または m = m + 1 '------ 分割点を1バイト後ろに移動
  End Select
  USplit = StrConv(LeftB(bb, m), vbUnicode) & "," _
      & StrConv(MidB(bb, m + 1), vbUnicode)
End Function

【59822】Re:文字列の分割について・・・
発言  kanabun  - 09/1/10(土) 0:38 -

引用なし
パスワード
   ごめんなさい。↑の考え方、ShiftJIS コードの 2バイト目がまた
> コード80〜9F、または E0〜FF だったら
そこで1バイト移動してしまうので、
非常にまずかったです。スミマセン。

与えられた文字列の10バイト目と11バイト目以降を カンマで分割する
サンプルだけにしておきます。

Sub Try3()
  Const u1 = "1234567890abcdefghij"
  Const u2 = "あいう111おかきくけこ"
  Const u3 = "あいう1えおかきくけこ"
  
  Debug.Print SplitA(u2, 10) '10バイトまでと それ以降に分割
  Debug.Print SplitA(u3, 10)
  Debug.Print SplitA(u1, 10)
End Sub

Function SplitA(UStr As String, ByVal m As Long) As String
 Dim i As Long
 For i = m To m \ 2 Step -1
   If LenB(StrConv(Left$(UStr, i), vbFromUnicode)) <= m Then
     SplitA = Left$(UStr, i) & "," & Mid$(UStr, i + 1)
     Exit Function
   End If
 Next
End Function

'結果
あいう111,おかきくけこ
あいう1え,おかきくけこ
1234567890,abcdefghij

【59844】Re:文字列の分割について・・・
発言  kanabun  - 09/1/13(火) 11:30 -

引用なし
パスワード
   この問題は、他の掲示板の過去ログですが、
 全角5文字を2バイト目から5バイト分切り取る方法
ht tp://hanatyan.sakura.ne.jp/vb60bbs/wforum.cgi?mode=allread&no=10038&page=600
が参考になると思います。
とくに 記事No:10082 の 魔界の仮面弁士 さんの発言が。

要は、まず、分割位置が全角文字の中にあったら、
どう処理するか仕様をはっきりさせることですね。

なお、そのスレッドのリンク先の
 文字列を指定の幅にカット(漢字分断回避)
で、3つの関数が紹介されていますが、3つ目の関数 fStrCut は
初期の目的(漢字分断回避)を達成していないので、
使えないと思います。

3851 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free