- ベストアンサー
VB及びエクセルのVBAにて、
VB及びエクセルのVBAにて、 300000行のCSVデータを読み込もうと試みました。 ファイルOpenで、Line InputやInputBを使用しましたが、 どちらもあまり処理速度は変わらないようです。 高速で1行ずつCSVデータを読み込む方法をご存じないでしょうか。 ご存知でしたら、関連するサイトを教えていただければ助かります。 お手数をおかけしますが、よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 郵便番号のCSVを、Excel のADODB で試してみましたが、死ぬほど遅かったです。私は、少し甘く見すぎたようです。郵便番号CSVは、8M程度、13万行ですから、比べ物にならないほど小さいですね。 >アクセスインポートしてみたのですが、10分ほどかかりました。 悪くはないですね。その後で、mdb ファイルに変更すれば、データとしても生き返ることになるだろうと思います。他にも、専用のツールもあった覚えがありますし、SQLサーバーを使った方法もあるだろうと思います。もう少し、こちらも試してみます。ただ、私のSQLサーバーはスペックの関係で完全に稼働してはいません。 それと、最終的な目的によって変わってくるのではないかと思います。
その他の回答 (4)
- Wendy02
- ベストアンサー率57% (3570/6232)
ハングしますか? myData = String(4 * 10 ^ 7, vbNullChar) これは、最高値に近いので、2桁~3桁減らすか、この行を外してみたら、どうなりますか? String型は、2Gまであるはずですから、そのまま代入しても、問題は発生しないと思っています。
お礼
何度もすみません。 myData = String(4 * 10 ^ 7, vbNullChar) をはずしても、桁を減らしてもだめでした。 6万行のファイル拡張子を.csv⇒.txtに変更したらデータの中身が見れるので、 30万行のファイル拡張子も同じく変更してみたところ、 「このファイルは大きすぎてメモ帳で扱えません。」とエラーがでました。 テキストファイルの容量限界をこえているような気がします。 643MBで、1500万行のcsvファイルもあったので、 アクセスインポートしてみたのですが、10分ほどかかりました。 アクセスだと処理できるのかもしれません。 今から勉強してちょっと試してみます。
- Wendy02
- ベストアンサー率57% (3570/6232)
##2補足 >myData = objText.ReadAll 'できるだけ、String 型などの方が安全? 思い出しましたが、String型で、サイズを確保したほうが速いずです。 上記の行の前に、バッファを取ります。 myData = String(4 * 10 ^ 7, vbNullChar) PCの論理的なキャッシュサイズに依存すると思います。
お礼
いつも回答ありがとうございます。 コードもよい勉強となるので助かります。 軽いファイル(6万行)で試しましたら正常に動作しました。 重いファイル(30万行)を処理すると、パソコンがフリーズしてしまいます。 タスクマネージャーで状態を見たところ、応答なしとなっていました。 もう少しあれこれやってみます。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 いつも、難問を出しますね。 >ご存知でしたら、関連するサイトを教えていただければ助かります。 私は、サイトは、MSサポートならともかく、よその掲示板は分からないです。ここは、VBAの専門掲示板ではありませんから、ここの回答者のVBA信頼度は低いのかしら? 私のではダメはダメかもしれませんが、自分の頭で考えてやってみないと、やっぱり自分自身が覚えないように思っています。 Set objFS = CreateObject("Scripting.FileSystemObject") Set objText = objFS.OpenTextFile(FileName) myData = objText.ReadAll 'できるだけ、String 型などの方が安全? 確か、String型の容量は、2Gだったと思いますから、十分だと思います。つまり、オブジェクトの読み出しの繰り返しを減らせば速度は速くなるような気がします。 それで、それぞれのLine を、Split関数で、切り分けたら良いような気がします。列幅の最大値が決まっていさえすれば、もう少し別な方法もあるかもしれません。 ただし、30万桁ですから、そのままではExcel 2007 に限ります。それ以下のバージョンでは、シートを変えていかなくてはなりません。 '------------------------------------------- Sub TestCSVInport() Dim objFS As Object Dim objText As Object Dim myData As String Dim ArData As Variant Dim Ar2 As Variant Dim v As Variant Dim i As Long, j As Long Dim FileName As String Const ReadOnly As Integer = 1 '------------------------------------------- 'ファイル名 FileName = Application.DefaultFilePath & "\test1.csv" '------------------------------------------- Set objFS = CreateObject("Scripting.FileSystemObject") Set objText = objFS.OpenTextFile(FileName, ReadOnly) myData = objText.ReadAll 'できるだけ、String 型などの方が安全? objText.Close ArData = Split(myData, vbCrLf) i = 0 Application.ScreenUpdating = False For Each v In ArData Ar2 = Split(v, ",") j = UBound(Ar2) If j > -1 Then '空行を飛ばす ActiveSheet.Cells(i + 1, 1).Resize(, j + 1).Value = Ar2 End If i = i + 1 Next v Application.ScreenUpdating = True End Sub
- end-u
- ベストアンサー率79% (496/625)
>関連するサイトを... 『大きなサイズのCSVファイルを高速に読み込むには?』 http://park7.wakwak.com/~efc21/cgi-bin/exqalounge.cgi?print+200911/09110054.txt 実際のコードと様々な検証結果が載ってますから参考になると思います。 抽出して読み込む事も検討するなら以下も。 『CSVファイルから条件抽出する処理速度を上げるには?』 http://park7.wakwak.com/~efc21/cgi-bin/exqalounge.cgi?print+200807/08070107.txt
お礼
よいサイト紹介をありがとうございます。 現状、重いファイルを処理しようとすると、 VB・VBAではパソコンが止まってしまいます。 ADOの勉強をして、SQLで処理してみようとおもいます。
お礼
いろいろやっていただいてすみません。もう十分です。 ADODBでもパソコンが止まったようになります。 VB・エクセルでは無理で、他のソフトを使用しないといけないのかもしれません。 mdbファイルにすると1.7GBになりました。 時間がものすごくかかりそうですが、アクセスでデータを間引いてから、処理しようと思います。