[[20221111143948]] 『csvファイルを普通にEXCELに読み込ませた場合』(称さん) ページの最後に飛ぶ

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

 

『csvファイルを普通にEXCELに読み込ませた場合』(称さん)

csvファイルを普通にEXCELに読み込ませました。
(csvファイルを読み込ませるには、他の読み込ませ方がある?)

直後に「データ損失の可能性」のエラー?が表示されました。
「このブックをカンマ区切り(csv)形式で保存すると、一部の機能が失われる可能性があります。
 機能が失わないようにするには、Excel ファイル形式で保存してください」と表示され、
「次回から表示しない」「名前を付けて保存」のいずれかの選択を要求されました。

理由は、何となく以下で理解できたました。
https://pcclick.seesaa.net/article/490681728.html

「名前を付けて保存」を選択するとデフォルテでは、「CSV(コンマ区切り)」が表示されます。
これは、後でマクロを追加したいので「EXCELマクロ有効ブック」で保存してはダメと言うことですか?

注意しないといけない事などありますか?

< 使用 Excel:Excel2019、使用 OS:unknown >


>csvファイルを普通にEXCELに読み込ませました。

普通にってどんな方法?
(未体験) 2022/11/11(金) 15:04:48


普通の意味は、
記載した、サイト記事では、「デフォルトの設定では、Excel で CSVファイル を開こうとすると」と記載されています。

(称さん) 2022/11/11(金) 15:16:23


>>後でマクロを追加したいので「EXCELマクロ有効ブック」で保存してはダメと言うことですか?
ダメではないと思います。私はあまりしませんけど^^;
どちらかと云うと、マクロブックからcsvを操作[取込も含めて]する方が多いかもです
まぁ、いろいろ方法は有ると思いますので。。。(*'▽')
読み込み時、ファイルの開く、から開くと
00120

120
になるとか、書式関連で不都合が有る場合が有るのではないでしょうか。
マクロで、OpenステートメントとかADODBとかで直接アクセスすると細目に
設定を保持しながら思ったように取り込むことが出来るみたいですよ。。
データー、データーの取得、従来のウイザード
とか
クエリーとか、最近は様々な取込方があるみたいですね。
もっと他にもあるかもしれませんが、気が付いた点だけで。済みません
m(__)m

(隠居Z) 2022/11/11(金) 15:29:15


>「EXCELマクロ有効ブック」
その形式で保存して問題ありません。
余り悩まないほうがいいです。
(ご参考) 2022/11/11(金) 15:45:47

>ダメではないと思います。私はあまりしませんけど^^;
>どちらかと云うと、マクロブックからcsvを操作[取込も含めて]する方が多いかもです

「EXCELマクロ有効ブック」で保存しても問題ないとのご意見もありますが 
つまり、デフォルテの「CSV(コンマ区切り)」で保存するか
マクロから設定が保存できるのOpenステートメントで保存したほうが良いとのお考えですね。

>データー、データーの取得、従来のウイザード
>とか

これは、どう言うことですか?

(称さん) 2022/11/11(金) 15:53:51


 >データー、データーの取得、従来のウイザード
 Excelを開いてからデータタブのデータの取得の中に色々な取込があります

 CSVを取り込むときにこそ注意する必要があるのでは
 隠居Zさんが言っている
 >00120が120になる
 の頭の0が消えてしまうとか指数表示になって戻らないとかなど色々Excelが変更する場合があります
(なるへそ) 2022/11/11(金) 16:07:03

こんばんは^^ データーの件は
なるへそ さんからアドバイスがあったみたいで。m(__)m

その、私の場合マクロ処理が中心になりますので。直接csvから必要性が有れば
書式の調節[読み込み時、若しくはセルに書込み時]をしながら、配列に取り込む
事が多いというだけです。
そういえば
名前を付けて保存でcsv形式を指定して保存する時、セルの書式が
123,500
とか、金額で使う書式が施されている時とかテキストでも
ある日,ある時,Excel,Word,Office
な、ときは要注意ですよね。^^;
ま、ケースバイケースで使い分けとかで、いけるかも
でわ
m(_ _)m

(隠居Z) 2022/11/11(金) 16:53:42


皆さん、アドバイスありがとうございます。

書式関連で不都合が有る場合が有るとの事なので
マクロからCSVを読み込むようにしました。

ネットを参考に手始めで以下のコードを書きました。
CSVの読み込み書き出しは上手く言っていますがコードの不備があれば訂正ください。
又、
7万行程あるのでもう少し高速化出来ませんか ?

Option Explicit

Sub CSVファイル読み込み()

Dim OpenFileName As String
Dim tmp As String ' テキストファイルの1行分文字列(1レコード)
Dim fNum, rowNum, colNum As Integer
Dim str As String
Dim spAry() As String
Dim Sh1 As Worksheet

    Set Sh1 = Worksheets("Drive_List")

    Sh1.Cells.Clear 'シートの初期化

    OpenFileName = Application.GetOpenFilename("CSVファイル,*.csv")
    Open OpenFileName For Input As #1

    rowNum = 1 '行番号の初期値

    While EOF(1) = False   'EOFがFalseの間
        Line Input #1, tmp '1行読込んで次の行に移行
        spAry = Split(tmp, ",") 'ファイルデータを配列に格納

        For colNum = 0 To UBound(spAry) '列から書込み
            Cells(rowNum, colNum + 1) = spAry(colNum) 'セルに書き込む
        Next

        rowNum = rowNum + 1 '次の行に移動して処理

    Wend

    Sh1.Columns("A:F") = 40 '列の幅を設定

Close #1

End Sub

(称さん) 2022/11/11(金) 17:23:17


こちらの環境では26項目、10万行、25MBのデータで20秒ぐらいでした
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
はあまり関係なかった。

  Sub test00()
    Dim v As Variant
    Dim t As Double
    Dim OpenFileName As String
    Dim Sh1 As Worksheet

    Set Sh1 = Worksheets.Item("Drive_List")
    Sh1.Cells.Clear

    OpenFileName = Application.GetOpenFileName("CSVファイル,*.csv")
    t = time

  '  Application.ScreenUpdating = False
  '  Application.Calculation = xlCalculationManual

    With Workbooks.Open(OpenFileName)
      v = .Worksheets.Item(1).Range("A1").CurrentRegion
      .Close False
    End With

    Set Sh1 = Worksheets.Item("Drive_List")
    Sh1.Cells.Clear
    Sh1.Range("A1").Resize(UBound(v, 1), UBound(v, 2)) = v

  '    Application.ScreenUpdating = True
  '    Application.Calculation = xlCalculationAutomatic

    Debug.Print time - t

(スズキ) 2022/11/11(金) 20:25:03


高速版のコードありがとうございます。

私のPCでは、私版が23.3秒で高速版が5.6秒でした。
これからも読み込むCSVの行数が増えるので活用させていただきます。

(称さん) 2022/11/12(土) 06:46:01


高速版、出力後にセルを見たら
 カンマ区切りでセルに分割されずにA列に1列分全て書き出されていました。

カンマ区切りで各セルに書き出すようにコードの訂正お願いします。

(称さん) 2022/11/12(土) 07:56:52


>>カンマ区切りでセルに分割されずにA列に1列分全て書き出されていました。
それを、一行分でもいいので、こちらに、貼り付けてみて下さい
よろしければですけど。。。^^;
(スズキ) 様 2022/11/11(金) 20:25:03 のコードでしたら
当方では正常に書込みされていましたですよ。
(隠居Z) 2022/11/12(土) 10:11:41

追記
書式に問題が無いなら、マクロを使わずとも、ファイルから開くでも
問題ないと思いますです。
もし、書式等、[文字コード、取り込まない列指定含む]指定する必要があるなら
下記の様な感じでも
マクロブックと同じフォルダの項目行+10万行、52列のcsvが対象です。
最初の3列だけ取り込んで後は除外しています
お試しの際は実際のcsvに合わせて下さい。ご興味がなければ、ゴミ箱ポイで。。。(*^^*)
 でわ
Option Explicit
Sub OneInstanceMain()
    Dim i As Long
    Dim fd As String
    Dim tq
    fd = ThisWorkbook.Path & "\" & "IJ00546.csv"
    With Worksheets("Sheet1")
        Set tq = .QueryTables.Add(Connection:="TEXT;" & fd, Destination:=.Range("A1"))
        With tq
            .TextFilePlatform = 932
            .TextFileParseType = xlDelimited
            .TextFileCommaDelimiter = True
            .RefreshStyle = xlOverwriteCells
            .TextFileColumnDataTypes = Array(2, 1, 5, _
                                       9, 9, 9, 9, 9, 9, 9, 9, 9, 9, _
                                       9, 9, 9, 9, 9, 9, 9, 9, 9, 9, _
                                       9, 9, 9, 9, 9, 9, 9, 9, 9, 9, _
                                       9, 9, 9, 9, 9, 9, 9, 9, 9, 9, _
                                       9, 9, 9, 9, 9, 9, 9, 9, 9)
            .Refresh
            .Delete
        End With
    End With
    MsgBox "end"
End Sub

(隠居Z) 2022/11/12(土) 10:38:46


編集が被りましたがそのまま。
 ------------------------------------------------

横からですが何点か。

■1
>csvファイルを普通にEXCELに読み込ませました。
まぁブックとして開きましたという意味ですよね。
言わんとすることは分かりますが、参考とされたサイトで確認されたように、csv(Comma Separated Values)ファイルは、カンマで区切られたテキストデータです。
なので、あくまでテキストファイルを扱っているということを念頭に置かれたほうが良いと思います。

>このブックをカンマ区切り(csv)形式で保存すると、一部の機能が失われる可能性があります。
既に理解できたかとおもいますが、テキストファイルで保存しようとしたら、画像とかセルの書式設定とか【ブック】として保持しているデータは保存できません。
エクセル君の警告はそういう意味です。

■2
>ネットを参考に手始めで以下のコードを書きました。
1行ずつ読み込むのもよい手だと思いますが、一気に読み込んでしまう手もあります。
古いアプローチになりますが「QueryTables.Addメソッド」を使い、インポートしてしまうのも有効だと思います。
興味があれば↓などが参考になると思いますので、一度読んでみてはいかがでしょうか?

 【参考】
[[20220729144055]] 『フォルダ内のCSVを一つのブックにまとめたい』(CSVまとめたい)
[[20220501221715]] 『セル内容の転記ミスについて』(hoge22)
[[20211102112449]] 『vba ファイル  seek 先頭に戻る』(hiro)
[[20210909165158]] 『csvを結合するマクロで1つ目以外の1行目を消したい』(レッドル)

他にも、PowerShellを使うことでも対応できるとおもいます。
私自身は詳しくありませんが、余力があれば研究してみるのもよいかもしれません。

■3
>後でマクロを追加したいので
既に理解できているかとおもいますが、【ブック】ではありませんからcsvにVBAのコードを保存することはできません。
なので、【マクロ付きブック】として保存するということになりますが、どういう理由で【マクロ付きブック】として保存したいのですか?
csvファイルを読み込んだ(取り込んだ)後どういう処理をする予定なのかわかりませんが、取り込む処理や、加工処理の部分は、出力されるブックに必要とも思えませんから、【マクロ無しのブック】で保存するなら理解できますが、わざわざ【マクロ付きブック】にする必要もないように思います。

(もこな2) 2022/11/12(土) 10:50:14


隠居Zさん、ありがとうございます。

>>カンマ区切りでセルに分割されずにA列に1列分全て書き出されていました。

それを、一行分でもいいので、こちらに、貼り付けてみて下さい

試した結果の、上手く処理できなかった参考画像です。

https://imgur.com/KSDdXc7

以下は試したコードです。
(スズキさんのコードに時間計測のコードを付加しています。)

Sub CSVファイル読み込み_2() ' 高速版 (スズキ) 2022/11/11(金) 20:25:03 改

    Dim v As Variant
    Dim OpenFileName As String
    Dim Sht1 As Worksheet

    Dim startTime As Double
    Dim endTime As Double
    Dim processTime As Double

    '開始時間取得
    startTime = Timer

    Set Sht1 = Worksheets.item("Drive_List")

    Sht1.Cells.Clear

    OpenFileName = Application.GetOpenFilename("CSVファイル,*.csv")

  '  Application.ScreenUpdating = False
  '  Application.Calculation = xlCalculationManual

    With Workbooks.Open(OpenFileName)
      v = .Worksheets.item(1).Range("A1").CurrentRegion
      .Close False
    End With

    Set Sht1 = Worksheets.item("Drive_List")
    Sht1.Cells.Clear
    Sht1.Range("A1").Resize(UBound(v, 1), UBound(v, 2)) = v

  '    Application.ScreenUpdating = True
  '    Application.Calculation = xlCalculationAutomatic

    'Sht1.Range("A:B").ColumnWidth = 40 '列の幅を設定
    'Sht1.Columns("C").ColumnWidth = 10 '列の幅を設定
    'Sht1.Range("D:F").ColumnWidth = 20 '列の幅を設定

    'Set Sht1 = Nothing

'終了時間取得
endTime = Timer

'処理時間計算
processTime = endTime - startTime
MsgBox "処理時間:" & processTime

End Sub

(称さん) 2022/11/12(土) 13:12:57


貼っていただいた、リンク?
真っ黒で。。。そのぉ。。。何も表示されません。^^;
(称さん) 2022/11/12(土) 13:12:57 ご提示のコードで
問題なく各セルに取り込まれていますよ。
メモ帳で開いてみて
情報1,情報2,情報3,情報 〜 ,情報3,情報

コンマで区切らていますよね。^^;
というか
手動で、ファイルの開くメニューから、開けばどぉ〜なりますでせう。
m(_ _)m

(隠居Z) 2022/11/12(土) 13:38:09


>真っ黒で。。。そのぉ。。。何も表示されません。^^;

こちらでは、意図した画像が表示されます。

直接、jpegが貼れるようなので以下に添付します。

>手動で、ファイルの開くメニューから、開けばどぉ〜なりますでせう。

D_Drive.csvを開くと
  1行が全てA列に表示されます。
  カンマ区切りでセルに分割されていません。

添付画像の上部と同じ状況です。
(称さん) 2022/11/12(土) 13:57:16


こんにちわ ^^
多分ですが。。。考えられる一因として、コンマが半角ではなく、全角なのでは
 spAry = Split(tmp, ",") 'ファイルデータを配列に格納

                     ↑
が、全角なら、辻褄が合います。^^;
ご確認を。m(__)m
(隠居Z) 2022/11/12(土) 14:19:14

>コンマが半角ではなく、全角なのでは
との事ですが、

コンマが全角なら、コードは
spAry = Split(tmp, "、") 'ファイルデータを配列に格納
ですが、

実際のコードは、
spAry = Split(tmp, ",") 'ファイルデータを配列に格納
でコンマは半角です。

"、"(全角)と ","(半角)で「プレビュー」では両者の違いが分かりやすいのですが
「ページの更新」で書き込んでしますと差が判りにくいのですがご容赦ください。

ご指摘では上記のように理解しましたが
私の解釈が間違っていますか ?

(称さん) 2022/11/12(土) 14:34:24


だめだこの質問者。
自分の事でしか言わない。
CSVファイルを解ろうともしない
CSVファイルは、CSVファイルであって、エクセルでも開けるようになってるだけ。
自分のペンネームに敬称つけるだけある。
(だめだこりゃ) 2022/11/12(土) 14:42:53

こんにちわ ^^
そおなのですね。不思議ですね。^^;
シート "Drive_List" の A1 が
(称さん)  さん の 2022/11/12(土) 13:57:16
でのスズキさんのマクロの場合
の状態で、下記のマクロを実行して見て、新規にシートが作成されますので
そのA1以降をコピペでこちらに貼り付けてみて、いただけますか。
44

三個有れば、私の手には負えません( ̄▽ ̄)。とほほ〜おてあげ〜(T_T;)

Private Sub xxx()

    Dim t, spAry, i&, y&
    With Worksheets("Drive_List")
        t = .Range("A1").Value
        .Copy after:=Worksheets("Drive_List")
    End With
    With ActiveSheet
        .UsedRange.Clear
        For i = 1 To Len(t)
            y = y + 1
            .Cells(y, 1) = AscW(Mid(t, i, 1))
        Next
    End With
End Sub

(隠居Z) 2022/11/12(土) 14:54:46


>スズキさんのマクロの場合
>の状態で、下記のマクロを実行して見て、新規にシートが作成されますので
>そのA1以降をコピペでこちらに貼り付けてみて、いただけますか。

マクロを実行すると新規シート(Drive_List(2))が作成されました。

下記の添付画像のように「44」をサーチすると行番号24以外に
「44」が全73行で5個存在しました。


この結果で、手に負えない状態でとの事ですが
どう言う状況なのでしょうか?

正直、スズキさんのコードは高速なので廃棄するには
惜しいのですが、無理なら諦めます。

(称さん) 2022/11/12(土) 15:18:23


 元データが、一行ごとに全体をダブルクートされている("abc,123,ccc"の如く)のでは?
 Excel君は正しく読み込んでいると思いますね。それは一列になります。
  
(γ) 2022/11/12(土) 15:21:37

あ!。。。(*'▽')。なるほど、なるほど。。。
γさんありがとうございます!
気が付きませんでした。
そぉいえば、一番左端に " が
有りましたね。w
とても、勉強になります。
今テストで読み込んでみましたら
一行表示になりました。(*'▽')
m(_ _)m

(隠居Z) 2022/11/12(土) 15:39:50


ターゲットになるリストをCSVでは無く、テキストファイルで書き出して保存してチェックすると
"abc,123,ccc"では無く"---","----"の形式でした。

但し、数字部は以下のように""で包まれていませんでした。
"abc",100245,"07/27/2020",

(称さん) 2022/11/12(土) 15:55:11


称さん さん のコードで
読み込み時に、置き換えで”をとっぱらって、
配列で一括処理すれば、処理速度も、そんなに遅くもないかと
(隠居Z) 2022/11/12(土) 16:04:35

 > ターゲットになるリストをCSVでは無く、テキストファイルで書き出して保存してチェックすると
 > "abc,123,ccc"では無く"---","----"の形式でした。
 今議論されているのはCSVの話ですよね。
 別の話をされても当惑するねえ。どう関係するんですか?
  
(γ) 2022/11/12(土) 16:13:47

隠居Zさん、長々とありがとうございました。

コードの書き換えは出来そうにないので
 高速化は諦めて最初のコードのままで処理します。

γさん、すいません。
 的はずれな返事を。返してしまいました。

(称さん) 2022/11/12(土) 16:20:30


いえいえ、お役に立てず、済みませんでした。
楽しく、お勉強させて戴きました。
こちらで試したところ、余分な処理が増える為、配列を使用いたしましても
40秒弱、かかっております。
ま、それでも、昔のことを思えば、8インチフロッピー。。。^^;
よく、転記処理かけてから、ゆ〜っくり、食事休憩にしていましたよ。
食堂から帰ってきたら、出来てたりしてました。(@_@;)...(*^^*)
では
m(_ _)m
(隠居Z) 2022/11/12(土) 16:59:13

 とりあえず現状維持ということで解決したのでしょうか?

 (称さん) 2022/11/11(金) 17:23:17 のコードを継続使用するということですか?
 今のCSVファイルを前提とすると、最初と最後の列に余計な"が入るので
 なんらかの修正が必要ではないですか?(提示された画像を見ても不適当であると思われます)

 そのCSVファイルの作成方法の説明がないので想像になりますが、
 ・その処理を、"が入らないように修正するか
 ・それは所与のもので変更できないとすれば、テキストエディタか何かで"を削除(置換)
   する処理を追加
 する必要があります。(尤も、Excel上で対応する方法もありえます)

 また、そうした修正を行えば、提案のあった高速処理コードも同時に使えるようになるはずです。
  
(γ) 2022/11/12(土) 18:35:32

  Sub test03()

    Dim Sh1 As Worksheet
    Set Sh1 = Worksheets("Drive_List")
    Sh1.Cells.Clear 'シートの初期化

    Dim OpenFileName As String
    'OpenFileName = Application.GetOpenFileName("CSVファイル,*.csv")
    OpenFileName = "F:csv_data.csv"

    Dim t As Double
    t = time

    'ダブルクォートを消去しているので1,2,"ssss""dddd",4,...のデータは駄目
    '列数をカンマで数えているので1,2,"ssss,dddd",4,...のデータはダメ
    'Line Inputを使っているので1,2,"ssss改行コードdddd",4のデータは駄目
    '要するにカンマとダブルクォートと改行コードをデータとして使ったCSVは駄目

    'Open Line Input Closeは結構速いことがわかった
    'こちらの環境で26項目、10万行、25MBのデータで10秒ぐらい、workbooks.open(cvs)より速い
    'けど上記の欠点あり

    '行数と列数を数える
    Open OpenFileName For Input As #1
    Dim row_num As Long, clm_num As Long
    Dim tmp As String

    row_num = 0
    While EOF(1) = False
        Line Input #1, tmp
        If row_num = 0 Then clm_num = Len(tmp) - Len(Replace(tmp, ",", "")) + 1
        row_num = row_num + 1
    Wend
    Close #1

    '配列を行数×列数作ってデータを格納
    Dim v() As String '00001->1が起こらなくなるが、数値も文字列になる、数値にしたい場合は"エクセル 文字列 数値 変換で検索"
    Dim spAry() As String
    ReDim v(1 To row_num, 1 To clm_num)

    Open OpenFileName For Input As #1
    i = 1
    While EOF(1) = False
        Line Input #1, tmp
        spAry = Split(Replace(tmp, """", ""), ",")
        For j = 1 To clm_num
          If UBound(spAry) = -1 Then
            v(i, j) = ""
          Else
            v(i, j) = spAry(j - 1)
          End If
        Next
        i = i + 1
    Wend
    Close #1

    'セルに書き込み
    Range("A1").Resize(UBound(v, 1), UBound(v, 2)) = v

    Debug.Print time - t

  End Sub
(スズキ) 2022/11/12(土) 19:13:03

Open Line Input Close ってShift_JISでしたよね。
UTF-8で日本語が入っていると文字化けする。
なので日本語をあつかうならCSVファイルをShift_JISで保存私ないとダメ。
(スズキ) 2022/11/12(土) 19:19:05

最初のコードで不本意ながら渋々解決としましたが

γさんのお陰で高速化版が機能しなかった理由が理解できました。

ターゲットのcsvファイルは、別の人が作成したテキストファイルを
CSVファイルもテキストファイルのようなモノと解釈して拡張子だけcsvに変えて利用しています。
(この発想が問題とは少しも想像できずにいました。)

助言、感謝いたします。

スズキさん、高速版の修正版のコードをありがとうございます。

コードを丸々お借りして(一部追加有り)検証結果
高速に処理できました。

CSVファイル(元はテキストファイルで拡張子だけcsvに変えたファイル)は
ずっとShift_JisでSAVEしていたのでその点だけは外さなかったのは幸いでした。

Sub CSVファイル読み込み_3() '『csvファイルを普通にEXCELに読み込ませた場合』(称さん)高速改定版 (by スズキ)2022/11/12(土) 19:13:03

    Dim Sh1 As Worksheet
    Dim OpenFileName As String
    Dim row_num As Long, clm_num As Long
    Dim tmp As String

    Dim startTime As Double
    Dim endTime As Double
    Dim processTime As Double

    '開始時間取得
    startTime = Timer

    Set Sh1 = Worksheets("Drive_List")
    Sh1.Cells.Clear 'シートの初期化

    OpenFileName = Application.GetOpenFilename("CSVファイル,*.csv")
    'OpenFileNameでCSVファイルに日本語を含む場合はShift_JISで保存の事
    'ダブルクォートを消去しているので1,2,"ssss""dddd",4,...のデータは駄目
    '列数をカンマで数えているので1,2,"ssss,dddd",4,...のデータはダメ
    'Line Inputを使っているので1,2,"ssss改行コードdddd",4のデータは駄目
    '要するにカンマとダブルクォートと改行コードをデータとして使ったCSVは駄目

    'Open Line Input Closeは結構速いことがわかった
    'こちらの環境で26項目、10万行、25MBのデータで10秒ぐらい、workbooks.open(cvs)より速い
    'けど上記の欠点あり
    '行数と列数を数える

    Open OpenFileName For Input As #1

    row_num = 0
    While EOF(1) = False
        Line Input #1, tmp
        If row_num = 0 Then clm_num = Len(tmp) - Len(Replace(tmp, ",", "")) + 1
        row_num = row_num + 1
    Wend

    Close #1

    '配列を行数×列数作ってデータを格納
    Dim v() As String '00001->1が起こらなくなるが、数値も文字列になる、数値にしたい場合は"エクセル 文字列 数値 変換で検索"
    Dim spAry() As String
    Dim i As Long, j As Long
    ReDim v(1 To row_num, 1 To clm_num)

    Open OpenFileName For Input As #1

    i = 1

    While EOF(1) = False
        Line Input #1, tmp
        spAry = Split(Replace(tmp, """", ""), ",")
        For j = 1 To clm_num
          If UBound(spAry) = -1 Then
            v(i, j) = ""
          Else
            v(i, j) = spAry(j - 1)
          End If
        Next
        i = i + 1
    Wend

    Close #1

    'セルに書き込み
    Sh1.Range("A1").Resize(UBound(v, 1), UBound(v, 2)) = v

    'セル幅調整
    Sh1.Range("A:B").ColumnWidth = 40 '列の幅を設定
    Sh1.Columns("C").ColumnWidth = 10 '列の幅を設定
    Sh1.Range("D:F").ColumnWidth = 20 '列の幅を設定

    'シート解除
    Set Sh1 = Nothing

    '終了時間取得
    endTime = Timer

    '処理時間計算
    processTime = endTime - startTime
    MsgBox "処理時間:" & processTime

  End Sub
(称さん) 2022/11/13(日) 05:52:35

こんにちわ。。。^^
解決されたようでよかったですね。いまさらですが
40秒から← → 3〜4秒に短縮出来ましたので
γさんとスズキさんのおかげです。称さん さんには
なにやら、惑わしてしまったみたいで、相済みませんでした。
スズキさんのよりは、遅いです。^^;
VBAのお勉強というう事で。使用することは出来ないかも。^^;
一つ変なファイルが出来てしまいますが、後始末していません。
10万行5列のcsvが対象です。
 Option Explicit
Sub OneInstance02()
    Dim i As Long
    Dim fd As String
    Dim fd2 As String
    Dim tq
    Dim buf
    Dim tt
    Set tt = New sE
    fd = ThisWorkbook.Path & "\" & "IJ00546.csv"
    fd2 = ThisWorkbook.Path & "\" & "newIJ00546.csv"
    Open fd For Input As #1
    Open fd2 For Output As #2
    Do Until EOF(1)
        Line Input #1, buf
        buf = Replace(buf, ChrW(34), "")
        Print #2, buf
    Loop
    Close #1
    Close #2
    With Worksheets("Drive_List")
        .UsedRange.Delete
        Set tq = .QueryTables.Add(Connection:="TEXT;" & fd2, Destination:=.Range("A1"))
        With tq
            .TextFilePlatform = 932
            .TextFileParseType = xlDelimited
            .TextFileCommaDelimiter = True
            .RefreshStyle = xlOverwriteCells
            .TextFileColumnDataTypes = Array(1, 1, 1, 1, 1)
            .Refresh
            .Delete
        End With
    End With

End Sub
(隠居Z) 2022/11/13(日) 15:48:32


隠居Zさん、気を使っていただいたありがとうございます。

>解決されたようでよかったですね。

解決したと思ったら問題発生しました。

C:\test\Joinに同じ形式でDATAが異なるCSVファイルを集めて以下のBATで結合しました。
Copy C:\test\Join\*.csv C:\test\Join\Merge.csv

このMerge.csvがターゲットになるCSVファイルです。

このMerge.csvを 2022/11/13(日) 05:52:35 の
「Sub CSVファイル読み込み_3()」 でシートに読み込ませると以下のエラーがでます。

v(i, j) = spAry(j - 1)

インデックスが有効範囲にありません。

但し、2022/11/11(金) 17:23:17 の
「Sub CSVファイル読み込み()」 では、エラー無く処理できました。

エラー無く読み込まれたA列を見ると
それぞれのCSVを読み込んだ時に間に空行がありました。
これがエラーの原因でしょうか ?

参照画像

'----------------------------------

思うに元は、テキストファイル(.txt)を安易に拡張子だけ(.csv)に変えただけなので
元のテキストファイルをテキストエディターで読み込んで
"(引用符)を""(ヌル)に置換してテキストファイル内に"が存在しないようにしてCSVに変名したほうが
EXCEL(VBA)では問題がないように思われますがどうでしょうか ?

各セルは、全て文字列として読み込まれても問題ありません。
(セル間で計算を行うことはないので数値として扱う予定はありません。)

'----------------------------------
隠居Zさん、15:48:32にいただいたコードですが以下で
Set tt = New sE

New sE で「ユーザー定義型は定義されていません」とエラーがでます。

VBAのお勉強というう事で。使用することは出来ないかも。^^;

とあるので、先にMerge.csvのエラー問題を優先して解決したいと思います。
(称さん) 2022/11/14(月) 09:05:15


空白をSplitして、想定の配列になりません。
ご自身で実験して確認してください。
(tkit) 2022/11/14(月) 09:22:04

おはようございます。
w!。。。済みません、済みません。
そこは、消してから、アップする予定でした。当方で、マクロ実行所要時間
のMsgboxを出すマクロを、クラス化していますので。残骸です。( ̄▽ ̄)
削除、お願いいたします。

既にご指摘が御座いますが、空白を調べて、読み飛ばす、か、書き飛ばす。とか
すれば。良いかと、思います。
お試し戴きますと、" は全て除去するロジックになっておりますが。。。
空白除去処理は御座いません。^^;
ちょい、考えてみます。引き続き他のご回答者様のアドバイスもお待ちくださいませ。
でわ
m(__)m
(隠居Z) 2022/11/14(月) 09:30:33

  Sub CSVファイル読み込み_3() '『csvファイルを普通にEXCELに読み込ませた場合』(称さん)高速改定版 (by スズキ)2022/11/12(土) 19:13:03

  '速度の関係で一行目だけで列数を判断してが、全行で判断してもあまり変わらなかった。
  '原因はCSVが長方形になっていないから。
  'なんとなく空行は
  '          If UBound(spAry) = -1 Then
  '            v(i, j) = ""
  '          Else
  '            v(i, j) = spAry(j - 1)
  '          End If
  'で想定していたけど。。。
  '以下ので何行で、サイズが何バイドの時どれくらいかかります?
  'こちらだと10万行、28MBで10秒ぐらいです。

    Dim Sh1 As Worksheet
    Dim OpenFileName As String
    Dim row_num As Long, clm_num As Long, tmp_num As Long
    Dim tmp As String

    Dim startTime As Double
    Dim endTime As Double
    Dim processTime As Double

    '開始時間取得
    startTime = Timer

    Set Sh1 = Worksheets("Drive_List")
    Sh1.Cells.Clear 'シートの初期化

    'OpenFileName = Application.GetOpenFileName("CSVファイル,*.csv")
    OpenFileName = "F:csv_data.csv"

    'OpenFileNameでCSVファイルに日本語を含む場合はShift_JISで保存の事
    'ダブルクォートを消去しているので1,2,"ssss""dddd",4,...のデータは駄目
    '列数をカンマで数えているので1,2,"ssss,dddd",4,...のデータはダメ
    'Line Inputを使っているので1,2,"ssss改行コードdddd",4のデータは駄目
    '要するにカンマとダブルクォートと改行コードをデータとして使ったCSVは駄目
    'でもダブルクォートと改行はともかくカンマを使いたいケースはあるなー

    '行数と列数を数える
    Open OpenFileName For Input As #1
    row_num = 0: clm_num = 0
    While EOF(1) = False
        Line Input #1, tmp
        '一行一行ちゃんと列数を調べるようにした
        If clm_num < Len(tmp) - Len(Replace(tmp, ",", "")) + 1 Then clm_num = Len(tmp) - Len(Replace(tmp, ",", "")) + 1
        row_num = row_num + 1
    Wend
    Close #1

    '配列を行数×列数作ってデータを格納
    Dim v() As String '00001->1が起こらなくなるが、数値も文字列になる、数値にしたい場合は"エクセル 文字列 数値 変換で検索"
    Dim spAry() As String
    Dim i As Long, j As Long
    ReDim v(1 To row_num, 1 To clm_num)

    Open OpenFileName For Input As #1
    i = 1
    While EOF(1) = False
        Line Input #1, tmp
        spAry = Split(Replace(tmp, """", ""), ",")
        For j = 1 To UBound(spAry) + 1 'ジャグCSV?に対応
            v(i, j) = spAry(j - 1)
        Next
        i = i + 1
    Wend
    Close #1

    'セルに書き込み
    Sh1.Range("A1").Resize(UBound(v, 1), UBound(v, 2)) = v

    'セル幅調整
    Sh1.Range("A:B").ColumnWidth = 40 '列の幅を設定
    Sh1.Columns("C").ColumnWidth = 10 '列の幅を設定
    Sh1.Range("D:F").ColumnWidth = 20 '列の幅を設定

    'シート解除
    Set Sh1 = Nothing

    '終了時間取得
    endTime = Timer

    '処理時間計算
    processTime = endTime - startTime
    MsgBox "処理時間:" & processTime

  End Sub

(スズキ) 2022/11/14(月) 10:49:02


シートの最大行数って1,048,576ですが
別のCSVをテキトーにくっつけるとそのうち超えませんか?
100万行以上のCSVを扱うなら、エクセルのシートは使えないので
エクセルのpowerquery、
powershell、
VSCodeなどの優れたテキストエディターでやるしかないと思います。

(スズキ) 2022/11/14(月) 11:10:03


質問なんですが、他の人が作ったCSVをくっつけてエクセルに書き出して何がしたいのですか?
計算をすることもないみたいなので。
解析するなら、一行を文字列で配列にいれたまま、Likeなり正規表現で抽出すればいいし、
良いテキストエディターで検索してもいいと思うのですが。
(スズキ) 2022/11/14(月) 12:27:14

スズキさん、何度もありがとうございます。

>以下ので何行で、サイズが何バイドの時どれくらいかかります?

"(引用符)を""(ヌル)に置換してファイル内に"(引用符)が存在しないようにしていたら
DATAが変になってしまいました。
(多分、私の置換/加工方法が原因だと思います。)

置換作業は止めてDATA(Copyで3つのCSVを結合)を再構築して
2022/11/14(月) 10:49:02の修正されたコードを試してみました。
今度はエラー無く最後にシートに書き出しが成功しました。

計測時間は、427、041行(76.7MB)で38.6秒でした。
(スズキさんよりかなり遅い結果です。
  PCの性能がそれほど良くないので個人的はこのぐらいの時間なら満足しています。)

>シートの最大行数って1,048,576ですが
>別のCSVをテキトーにくっつけるとそのうち超えませんか?
>100万行以上のCSVを扱うなら、エクセルのシートは使えない

現在約42万なので100万の約半分ほどですが
約10年ほどで今のDATA数ですので後10年は利用可能と思われますが
もし100万件に近づいたらDATAを前後に分けるなどを考えます。

>他の人が作ったCSVをくっつけてエクセルに書き出して何がしたいのですか?

検索するHDDがそれぞれ別の場所にあるので
私一人で全てのCSVを作る事が難しいので一部は他の人に頼んでいます。
集計作業的な事を私が引き受けています。

>良いテキストエディターで検索してもいいと思うのですが。

なるほどです。
EM EDITORの利用者なのでテキストエディターで検索すると言う手段もありますね。
教えてもらわなかったら灯台下暗しで気がつきませんでした。
ありがとうございます。
(称さん) 2022/11/14(月) 14:20:27


        ∧∧ 
       ヽ(・ω・)/   ズコー 
      \(.\ ノ 
    、ハ,,、  ̄ 

EmEditorってほぼ最強エディターじゃないですか、
free版でも1000万行、2.65GBのファイルも10秒かからず開けるし、
検索もできる。
いままでの苦労はなんだった。。。
(スズキ) 2022/11/14(月) 15:03:27


こんにちわ ^^ そんなに、すごい エデターなのですね ^^;
後学のために教えて戴きたいのですが、
今回のエラー原因は下記の様なcsvだという事でしょうか

"あ","い","う","え",お
た,ち,つ,て,と
い,ろ,は,に,ほ,へ,と,ち,り,ぬ,る,お
""
わ,が,よ,た,れ,そ,う,い,な,ら,む
けふ,のお,くやま
き,ょ,う,こ,え,て

"あさきゆ,めみしえ,ひもせす,ん"
あ、v、j、k

(隠居Z) 2022/11/14(月) 15:22:06


  Sub test05()

    csv = Array("""あ"",""い"",""う"",""え"",お", _
                "た,ち,つ,て,と", _
                "い,ろ,は,に,ほ,へ,と,ち,り,ぬ,る,お", _
                """", _
                "わ,が,よ,た,れ,そ,う,い,な,ら,む", _
                "けふ,のお,くやま", _
                "き,ょ,う,こ,え,て", _
                 """あさきゆ,めみしえ,ひもせす,ん""", _
                "あ、v、j、k")
    row_num = UBound(csv) + 1

    '一行めで判断
    clm_num = UBound(Split(csv(0), ",")) + 1 '5

    Dim v()
    ReDim v(1 To row_num, 1 To clm_num)
    For i = 1 To row_num
      sp = Split(csv(i - 1), ",")
      For j = 1 To clm_num
        v(i, j) = sp(j - 1) '(i,j)=(4,2),(6,4),(8,5),(9,2)でエラー,ctrl+F9で二番目のNextに飛ばす
      Next
    Next 'ctrl+F9でここに飛ばす

    '全行で列数判断
    clm_num = 0
    For i = 1 To row_num
      If clm_num < UBound(Split(csv(i - 1), ",")) + 1 Then
        clm_num = UBound(Split(csv(i - 1), ",")) + 1
      End If
    Next
    'clm_num=12

    Dim v2()
    ReDim v2(1 To row_num, 1 To clm_num) '列数最大値で配列を作る
    For i = 1 To row_num
      sp = Split(csv(i - 1), ",")
      For j = 1 To UBound(sp) + 1 'ここで各行の列上限を設定
        v2(i, j) = sp(j - 1)
      Next
    Next

    'ローカルウィンドで確認

  End Sub

(スズキ) 2022/11/14(月) 17:47:38


称さん さん、横入り、すみません
スズキ 様
ご教授、有難う御座いました。済みませんでした。
書き出し、確認致しました。お手間をお掛け致しました
有難う御座います。
(隠居Z) 2022/11/14(月) 18:25:51

空白判定に確信が持てなかったため、コードは撤廃致しました
また、整理が出来ましたら。後日、アップさせて戴くかもしれません
相済みませんでした 23:01
 m(__)m

(隠居Z) 2022/11/14(月) 21:25:27


スズキさん、

>いままでの苦労はなんだった。

最後の最後で気落ちする自体となりお詫びいたします。

Em Editorで検索する事に頭が回らなかった私が悪いのですが
Excelを利用したいと思ったのは、Em Editorで検索は出来ますが、
検索後に絞り込みの為の作業が必要だったのです。

質問の最初で
「後でマクロを追加したいので「EXCELマクロ有効ブック」で保存」
と書いたのは絞り込み(抽出)を想定して作業を行うVBAを追加したかったからです。

教えていただいたVBAは決して無駄になる事はありませんし
これからも私のところで利用させて頂きます。

隠居Zさん、スズキさん トンチンカンな内容や不手際が多くすいませんでした。
見捨てずに協力いただき感謝いたします。
(称さん) 2022/11/15(火) 06:39:33


コメント返信:

[ 一覧(最新更新順) ]


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