質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

573閲覧

区切り対象文字を含むデータを区切り対象から外す方法

JanTh1989

総合スコア87

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2019/05/30 05:03

編集2019/05/30 05:04

Access2010のVBAでSplit関数を使ってタブ区切りデータを分割しようとしました。
ただ、元データの作りとして、1要素内に入ってほしいデータにも区切り文字と同様のタブ文字が入っており、
結局。

サンプル文字列(タブは\tで記載)

"\"AAA\tBBB\tCCC\"\tDDD"

上記は「"AAA\tBBB\tCCC"」と「DDD」の2分割になってほしかったのですが、結局各4分割になってしまいます。
こういったデータはコマンドプロンプトのパスのように、""で囲んでおけば通るだろうかと試してみてましたが、
望ましい結果にはなってくれませんでした。
こういったデータを期待値となる2分割にする方法は何かないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

正規表現を使うと一発でできると思いますが、私は苦手なので、
Split と Join で書いてみました。

vba

1'文字列をタブで分割したバリアント配列に変換 2'ただし " で囲まれた部分は分割しない 3Public Function SplitTSV(s As String) As Variant 4 Dim cols 5 cols = Split(s, """") 6 7 Dim i As Long 8 For i = LBound(cols) To UBound(cols) Step 2 9 cols(i) = Replace(cols(i), vbTab, vbCrLf) 10 Next 11 12 SplitTSV = Split(Join(cols, ""), vbCrLf) 13 'SplitTSV = Split(Join(cols, """"), vbCrLf) '"を残したい場合はこちらで 14End Function 15 16'動作確認 17Public Sub TestSplitTSV() 18 Dim s As String 19 s = """AAA\tBBB\tCCC""\tDDD" 20 s = Replace(s, "\t", vbTab) 21 22 Dim v As Variant 23 v = SplitTSV(s) 24 Debug.Print Join(v, "/") 25End Sub

ロジック
0. 引用符 " で分割する(Split)と、配列の奇数番目(1,3,5...)の要素が " で囲まれた部分になる。
0. 偶数番目(0,2,4...)の要素のタブを別の区切り文字(改行)に置換する。
0. 配列をJoinで結合する。
0. 結合した文字列を区切り文字(改行)で分割する。

投稿2019/05/30 16:24

編集2019/09/23 16:53
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

JanTh1989

2019/05/31 07:51

回答ありがとうございます。 処理が簡略化されており、わかりやすいです。 サンプルデータ前後に別データがあっても、配列の奇数偶数の位置も変わらいみたいなので、偶数の改行化固定でやれそうです。 "文字は残しておきたいので、2の次に奇数へ"文字を先頭と最後に付与する処理を足せば、万事解決しそうなので、そのあたりを検討に入れつつ作業にあたります。 ありがとうございました。
ttyp03

2019/05/31 07:55

”でSplitしたあとの法則に気づいたのはさすがです。
guest

0

なんか関数一発でできるといいんですが、知識がなかったのでゴリゴリ書いてみました。
とりあえずDebug.Printで出力しているので、必要であれば配列に入れたりなんかしてください。
あとExcelのVBAでテストしたので、AccessのVBAで不都合があるところは適宜修正してください。

VBA

1 s = """AAA\tBBB\tCCC""\tDDD" 2 s = Replace(s, "\t", vbTab) 3 4 cols = Split(s, """") 5 For Each col In cols 6 If Trim(col) <> "" Then 7 If Left(col, 1) = vbTab Then 8 col = Mid(col, 2) 9 If Right(col, 1) = vbTab Then 10 col = Mid(col, 1, Len(col) - 1) 11 End If 12 cols2 = Split(col, vbTab) 13 For Each col2 In cols2 14 Debug.Print col2 15 Next 16 Else 17 Debug.Print col 18 End If 19 End If 20 Next 21 22結果 23AAA BBB CCC 24DDD

別データでテスト。

VBA

1 s = """AAAA\tBBBB\tCCCC""\tDDD\tEEEE\t""FFFF\tGGGG""" 2 3結果 4AAAA BBBB CCCC 5DDD 6EEEE 7FFFF GGGG

指摘があったので修正しました。
結局まじめにパースしてます。

VBA

1 col = "" 2 For i = 1 To Len(s) 3 c = Mid(s, i, 1) 4 Select Case c 5 Case """" 6 If qs = False Then 7 qs = True 8 Else 9 Debug.Print col 10 col = "" 11 qs = False 12 End If 13 Case vbTab 14 If qs = False Then 15 If col <> "" Then 16 Debug.Print col 17 End If 18 col = "" 19 Else 20 col = col & c 21 End If 22 Case Else 23 col = col & c 24 End Select 25 Next 26 If col <> "" Then 27 Debug.Print col 28 End If 29

投稿2019/05/30 05:53

編集2019/05/30 07:49
ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

torisan

2019/05/30 07:23

条件が合っているかわかりませんが、最初の項目が単体だと纏められてしまう気がします。 s = "AAA\tBBB" AAA BBB
ttyp03

2019/05/30 07:26

あー、確かにそうですね。 考えます。
ttyp03

2019/05/30 07:50

修正版を追記しました。 なんかイマイチ洗練されてませんが。。。
torisan

2019/05/30 08:12

横槍すみませんでした。 自分も少し考えましたが意外とややこしいですね、これ。 対応ありがとうございます。
ttyp03

2019/05/30 08:14

いえ、指摘していただいて助かりました。 CSV,TSVのパースは面倒ですね。
JanTh1989

2019/05/31 07:34

返答が遅くなり申し訳ありません。 回答ありがとうございます。 Splitに変わる良い感じの関数はやはりありませんか・・・。 頂いたコードはタブと""""の2段分割と結合で対応ですね。 Accessに入れてみたところ、動きとしては大丈夫そうでした。 分割⇒連結のような動きが、妥当な気がしてきました。 ひとまずこの方向で進めてみます。
ttyp03

2019/05/31 07:41

hatena19氏の回答の方がスッキリ出来上がっているので、そちらのほうがいいかもしれません。 いずれにしても両方とも良く動作確認をして最適なものをお選びください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問