[[20210716094020]] 『コンマ区切りtxt.取込VBAで』(ナマステ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『コンマ区切りtxt.取込VBAで』(ナマステ)

Excelにテキストファイルを取り込むのに、毎回データのテキストファイル取込を選ぶのが面倒だったので、VBAでボタンを押すだけで取込ができるようにしたいと思い、ネットで調べて次のVBAを使用してみたのですが、

Sub Macro1()

' Macro1 Macro

Dim txtName As String

    txtName = Application.GetOpenFilename("テキストファイル,*.txt")

    If txtName <> "False" Then
        Open txtName For Input As #1
    End If

    Dim r As Long
    r = 1

    Do Until EOF(1)

        Dim buf As String
        Line Input #1, buf

        Dim aryLine As Variant
        aryLine = Split(buf, ",")

        Dim i As Long
        For i = LBound(aryLine) To UBound(aryLine)
            Cells(r, i + 1) = aryLine(i)
        Next

        r = r + 1

    Loop

    Close #1

    MsgBox "終了しました。"

End Sub

取り込んだセルの数字が
"0000000000"
のように両端に""がついてしまいます。
元のテキストファイルが""で囲まれているせいだとはわかるのですが、""を削除するには何を加えたらよいのか教えてください。

< 使用 Excel:Excel2010、使用 OS:Windows10 >


 おはよ〜ございます ^^
Replace
で、""に、置き換え
とか
文字列操作 Mid とかで、両端、1文字ずつ、切り落とすとか。。。^^;
でも
後の書式等は書き出し後、範囲指定で、一括変換とか
いろいろ、方法はたくさんあるかと思います。
m(__)m
(隠居じーさん) 2021/07/16(金) 10:12

 CSVで"0000000000"だった場合、セルに0000000000と文字列で入れたいのだろうか?
 もし、そうであれば工夫が必要だと思うが。
 また、""内に,があることはないのだろうか?
(ねむねむ) 2021/07/16(金) 10:23

>>隠居じーさんさん
 申し訳ありません。VBA初心者のため応用力がありません。

>>ねむねむさん
文字列ではなく数値として入れたいです。
しかし元のテキストファイルが全ての項目の最初と最後に""がついているため、最初に書いた式だとセルに入ってしまい困っています。
テキストファイルを確認しましたが、""内に,はありませんでした。
「データ」の外部データ取込「テキストファイル」なら
コンマやタブなどの‥‥
区切り文字「コンマ」
で""も消えてくれるのですが、VBAだと残るので、違いは何なのか教えて欲しいです。
(ナマステ) 2021/07/16(金) 14:54


 Option Explicit
Sub OneInstanceMain()
    Dim x() As Variant
    Dim v As Variant
    x = Array("""00000""", """Excel""")
    For Each v In x
        MsgBox Mid(v, 2, Len(v) - 2)
    Next
End Sub
と
おなじよぉ〜な事でせうか。。。
""の間に,なかってよかったですね。。。あれば、さらに
もう一工夫。。。^^;
違いは。。。多分。↑をエクセル様が気をきかして
自動処理して下さっているのでは。と推測致します。。← あやしい^^;
m(_ _)m
(隠居じーさん) 2021/07/16(金) 15:14

発想を変えて、外部データのインポートをつかってみては?
出先なので説明は省きますが、↓が参考になるとおもいます。
 【参考】
[[20210221200244]]『あるシートから、メインのBookのシートへコピー&貼り付けする方法』(けろりん)

(もこな2) 2021/07/16(金) 15:30


 >取り込んだセルの数字が 
 >"0000000000" 
 >のように両端に""がついてしまいます。

 それは、文字列として作ってあるので正常だと思いますけど。
 ただ、質問者が理解していないまま処理をしているからだと思います。
 CSVファイルの中身がどうなっているのぐらい確認したらどうですか。
(ブヒ) 2021/07/16(金) 15:40

 ああ、一応確認しているのか・・・。
 しかし、作ってください、見つけたので直してください。が、
 やたら多いような気がします。

(ブヒ) 2021/07/16(金) 16:17


 >「データ」の外部データ取込「テキストファイル」なら
 >コンマやタブなどの‥‥
 >区切り文字「コンマ」
 >で""も消えてくれるのですが、

 正に↑をマクロでやっちゃえば良いのでは?
 つまり
 カンマで分割せずに、行単位で一旦A列に書きだした後で、
 TextToColumns([データ]-[区切り位置]のメソッド版)使ってシート上で分割する。

 当然、引用符の除去も指定できますよ。

(白茶) 2021/07/16(金) 19:30


 あったあった^^;

 ウチの会社のシステムに、非っ常wwwwに鬱陶しいcsvで、単純にカンマでSplitしたらデータがエライ事になるのがあるんですよ。
 (タブ文字混入。桁区切りカンマ付き数値あり。変な引用符があったりなかったり等々...もはやcsvとは呼べない代物)
 ソイツを何とかしたいが為に以前作った関数が出てきました。
 Line Inputした1行をチマチマと自力で配列に分割する為のものです。

 (今回のトピ内容的には無用物ですが、せっかく発掘できたので載せときます)

    Function SpitTextLine(TextLine As String, Delimiter As String, Optional Qualifier As String = """") As Variant()
        Dim i As Long, str As String
        Dim strD As String, lnD As Long
        Dim strQ As String, lnQ As Long, innerQ As Boolean
        Dim Ary() As Variant, c As Long
        lnD = Len(Delimiter)
        lnQ = Len(Qualifier)
        ReDim Ary(0 To Len(TextLine))
        For i = 1 To Len(TextLine)
            str = Mid$(TextLine, i, 1)
            strD = Mid$(TextLine, i, lnD)
            strQ = Mid$(TextLine, i, lnQ)
            If lnQ > 0 And strQ = Qualifier Then
                innerQ = Not innerQ
                i = i + lnQ - 1
            Else
                If Not innerQ And strD = Delimiter Then
                    c = c + 1
                    i = i + lnD - 1
                Else
                    Select Case AscW(str) 'Clean関数でよい
                        Case Is < 32
                        Case 127, 129, 141, 143, 144, 157
                        Case Else
                            Ary(c) = Ary(c) & str
                    End Select
                End If
            End If
        Next
        ReDim Preserve Ary(0 To c)
        SpitTextLine = Ary
    End Function

 今回ご提示のマクロに組み込むとするとしたら↓こんな感じになりますかね

    Sub Macro2()
        Dim txtName As String
        Dim r As Long
        Dim buf As String
        Dim aryLine As Variant
        txtName = Application.GetOpenFilename("テキストファイル,*.txt")
        If txtName = "False" Then Exit Sub
        Open txtName For Input As #1
        r = 1
        Do Until EOF(1)
            Line Input #1, buf
            aryLine = SpitTextLine(buf, ",")
            Cells(r, 1).Resize(, UBound(aryLine) - LBound(aryLine) + 1) = aryLine
            r = r + 1
        Loop
        Close #1
        MsgBox "終了しました。"
    End Sub

(白茶) 2021/07/16(金) 21:56


申し訳ありません。PCの調子が悪く返答いただいた方へのお返事が遅くなってしまいました。

>>隠居じーさん様
Excelが自動判断してくれているのですね。別シートで""を除外して数値に直す方向で考えてみます。

>>もこな2様
そういう方法もあるのですね。試してみます。

>>ブヒ様
申し訳ありません。周りに相談できる人がいないため、こちらに頼ってしまいました。以後気を付けます。

>>白茶様
いただいたMacro2を使ってみたのですが、SpitTextLineの部分で「コンパイルエラー:sub または Functionが定義されていません」と出ました。ツールの参照設定関係?かとおもうのですが、どれを参照にすれば良いのか良く分かりません。もしよろしければお教え願えませんでしょうか。

(ナマステ) 2021/07/21(水) 08:52


 えー。
 参照設定が必要なパーツなんて書いてないですよ? (コード見渡して頂ければ分かると思いますけど..)
 Macro2から目の届く場所にSpitTextLineを定義してない、あるいはそもそも定義してないのではないですか?

 まあ私のコードは完全に「オマケ」ですからね。
 まずはそれ以前のアドバイスをモノにしていく事に専念することをお勧めしておきます。

 隠居じーさんさんから""の除去についてコードの提示がありましたが、
 現状のコードから言えばコレが一番の近道ではないですか?
 aryLine(i)をセルに書き込む前に、その内容の最初と最後が「"」かどうか判定して
 「"」で囲まれてたら、Midで中身取り出してから書き込めばいいですよね。

 もこな2さんからもQueryTablesのご提案もありました。
  .TextFileTextQualifier = xlTextQualifierDoubleQuote
 の指定で""の除去をやってくれます。
 純正機能でやってくれるんだから、それに頼るのが一番でしょ。
 私が先に申しましたTextToColumnsでも
 引数内でTextQualifier に xlTextQualifierDoubleQuoteを指定できます。
 (というか、省略時が既にxlTextQualifierDoubleQuoteです)

 どちらもColumnDataTypeを配列で指定できますから、
 セルに文字列として書き出すのか数値として書き出すのかも指定できます。
 便利ですね〜

(白茶) 2021/07/21(水) 12:11


 あかん。...orz

 どうやら恥ずかしい掘出物を掲載してしまった模様...orz
 >>SpitTextLine
 Spitて全然意味違うんでない? ...orz

 いいや。もう恥の上塗りのつもりで後継機再掲しときます。
 (はたして↓も完成に至った代物なのか自信ないという...)

    Function SplitTextLine(TextLine As String, Delimiter As String, Optional Qualifier As String = """", Optional Qualifier2 As String) As String()
    Rem 文字列を[Delimiter]で区切った一次元配列にして返す(Split関数にならって戻値はString型配列とする)
    Rem [limit]は使わないから省略。[compare]もモジュールのOption Compareに任せるつもりで省略
    Rem [Qualifier]省略時はダブルクォーテーションを仮定。
    Rem [Qualifier2]は引用符が先頭と末尾で異なる場合に末尾引用符として指定(省略時は先頭も末尾も[Qualifier]と仮定)
    Rem (一応csvで「="」から「"」の内側がデータという実例があったので機能追加)
        Dim i As Long, str As String
        Dim strD As String, lnD As Long
        Dim strQ As String, lnQ As Long, levelQ As Long
        Dim strQ2 As String, lnQ2 As Long
        Dim Ary() As String, c As Long, TextBuff As String
        lnD = Len(Delimiter) '区切り文字数
        lnQ = Len(Qualifier) '引用符文字数
        If Qualifier <> Qualifier2 Then lnQ2 = Len(Qualifier2)  '末尾引用符文字数(引用符が2種類の場合のみ)
        ReDim Ary(0 To Len(TextLine)) 'とりあえず配列を最大サイズに設定(後でカットする)
        For i = 1 To Len(TextLine)
            str = Mid$(TextLine, i, 1)      '現在の1文字
            strD = Mid$(TextLine, i, lnD)   '確認用(区切り文字)
            strQ = Mid$(TextLine, i, lnQ)   '確認用(引用符)
            strQ2 = Mid$(TextLine, i, lnQ2) '確認用(末尾引用符)
            If lnQ > 0 And strQ = Qualifier Then                        '▼先頭引用符に遭遇した時
                levelQ = levelQ + IIf(levelQ > 0 And lnQ2 = 0, -1, 1)   ' [引用符内]且つ[末尾引用符指定あり]ならは引用ネストレベル下げ
                i = i + lnQ - 1                                         ' ([引用符外]または[末尾引用符指定なし]なら引用ネストレベル上げ)
            ElseIf levelQ > 0 And lnQ2 > 0 And strQ2 = Qualifier2 Then  '▼末尾引用符に遭遇した時([引用符内]限定)
                levelQ = levelQ - 1                                     ' 引用ネストレベル下げ
                i = i + lnQ2 - 1                                        ' ([末尾引用符指定なし]、[引用符外]の場合は↓に処理移行)
            Else                                                        '▼他
                If levelQ = 0 And strD = Delimiter Then                 '  ▼[引用符外]且つ区切り文字遭遇時なら
                    Ary(c) = RTrim$(Ary(c))                             '   ここまで継ぎ足した文字列に右トリム掛けて
                    c = c + 1                                           '   継ぎ足しカーソルを次の配列要素へ移動
                    i = i + lnD - 1
                Else                                                    '  ▼他
                    Select Case AscW(str)                               '   配列の現カーソル要素で文字列を継ぎ足し(印刷可能文字のみ)
                        Case 0 To 31
                        Case 127, 129, 141, 143, 144, 157
                        Case Else
                            Ary(c) = Ary(c) & str
                    End Select
                End If
            End If
        Next
        ReDim Preserve Ary(0 To c) '配列の未使用要素をカットして
        SplitTextLine = Ary        '戻値に渡す
    End Function

(白茶) 2021/07/27(火) 20:33


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.