プロが教えるわが家の防犯対策術!

エクセル2000です。
現在CSV形式のファイルをもらい、エクセルVBAで1行づつエクセルに取り込み、加工しています。(CODEは、かなり省略していますが下記の通り)
データは将来的には何万件におよぶことも考えられます。
ためしに65536を超えるデータを読み込ませたところ65536を超えたところでやはりエラーになりました。Workbooks.Openでエクセル形式で開いているので65536を超える部分は無視されるからだと思います。
このような場合には、どうやってCSVファイルからデータを読み込めばよいのでしょうか?(なお、エクセルは当分2007にはなりそうもありません。アクセスはまったく使えません。)

Sub TEST01()
Set cf = Workbooks.Open(Filename:=ThisWorkbook.Path & "\test.csv")
Set zerro = cf.Sheets(1).Range("A1:AX1")
ThisWorkbook.Sheets("Sheet1").Activate
Do Until zerro.Cells(1).Value = ""
ThisWorkbook.Sheets("Sheet1").Range("A1:AX1").Value = zerro.Value
'処理マクロ省略
Set zerro = zerro.Offset(1)
Loop
End Sub

このQ&Aに関連する最新のQ&A

A 回答 (10件)

一括で読み込もうとするからダメなのであって、1行ずつ読み込むようにすれば何行にでも対応できると思います。



こんなページを見つけました:
http://www.k1simplify.com/vba/tipsleaf/leaf291.h …

上記ページのプログラムは全行読み込んでいますが、ループのところをちょっと加工すれば(行数をカウントして65536を超えたら新しいシートを作ってそっちに書き込むなど)、長大なレコード数に対応できると思います。

ただ、処理の内容にもよりますがExcelでは65536行を超えるデータを1枚のワークシートに保持できませんから、たとえばピボットテーブルなどを作りたい場合はどうしようもありません。
合計を集計するだけとかなら問題ないですけど。

やはり最終的にはAccessを導入すべきかと思います。

この回答への補足

ご教示のページ、参考にしてなんとか出来ました。
有難うございました。

Sub CSV_Read3()

Dim FileNamePath As String
Dim textline, csvline() As String
Dim Rowcnt, ColumNum As Integer
Dim ch1 As Long

MsgBox "作業開始後、中断したい場合には、Ctrlキー+Breakキーを押してください。" _
, vbInformation, " (´^∇^)σ"

FileNamePath = ThisWorkbook.Path & "\test.csv"
ch1 = FreeFile '空いているファイル番号を取得

Open FileNamePath For Input As #ch1 'FileNamePath のファイルをオープン

On Error GoTo erLine 'エラーが発生したらファイルを閉じる
Application.EnableCancelKey = xlErrorHandler

Do While Not EOF(ch1) 'ファイルの終端かどうかを確認
Line Input #ch1, textline '1行読み込み
textline = Replace(textline, """", "") 'ダブルクォーテーションを削除
csvline() = Split(textline, ",") 'カンマで分離
Range(Cells(1, 1), _
Cells(1, UBound(csvline()) + 1)) = csvline() '配列渡しでセルに代入

'VBA処理省略

Application.StatusBar = Cells(1, 1)
Loop

erLine:

If Err.Number = 18 Then

MsgBox "中断キーが押されました。" & Chr(10) & _
"終了します。" _
& Chr(10) & "バイバイ。", vbCritical, " ( ; ゜Д゜)"
ElseIf Err.Number <> 0 Then
MsgBox Err.Number & ":" & Err.Description
End If

Close #ch1 'ファイルを閉じる
Application.StatusBar = ""
Application.EnableCancelKey = xlInterrupt

End Sub

補足日時:2007/08/07 16:10
    • good
    • 0
この回答へのお礼

ありがとうございます。
やりたいことは、いわば差込印刷に毛の生えたようなものなので、1行ずつ読みこみ、その分の処理が終われば消去して、また次の行を読み込んでくればいいのです。
ご教示のページ、参考にしてみます。

お礼日時:2007/08/07 14:39

こうなると、もうACCESSの世界では?

    • good
    • 0
この回答へのお礼

そうですよね。
ただわたしはまだアクセスは皆目分からないんです。
有難うございました。
お礼が遅くなり済みませんでした。

お礼日時:2007/08/09 16:51

#2 です。



>だから65,536行よりも大きいCSVをまるごとインポートすることではありません。

サイトを紹介しただけで、そのものズバリではありません。

細かな事情は分かりませんが、それをヒントにして、インポートして、Excelに表示しなくても、そのままOutput を組み合わせて出力してしまえば、ワークシートに出す必要もありませんね。また、外部オートメーションの必要もありませんね。

merlionXX さんなら、インポートが出来れば、エクスポートもお分かりになるかと思います。後は、ご自身でお考えください。
    • good
    • 0
この回答へのお礼

いつもお世話になり、有難うございます。
お礼が遅くなり済みませんでした。

お礼日時:2007/08/09 16:50

merlionXXさまのことですのでご存じとは思いますが、FileSystemObjectを利用する方法もありますね。


UNICODEなら OpenAsTextStream(1, 0) だったと思います

Sub TextImport()
 Dim FSO, buf As String
 Dim idx As Long
 Set FSO = CreateObject("Scripting.FileSystemObject")
 With FSO.GetFile("z:\OnDemandScanLog.txt").OpenAsTextStream(1, -2)
  Do
   buf = .ReadLine
   Cells(1, 1).Value = buf
'    差し込み印刷(?)処理 挿入
  Loop Until .AtEndOfStream
  .Close
 End With
 Set FSO = Nothing
End Sub
    • good
    • 0
この回答へのお礼

FileSystemObjectですか?
初めて聞きました。
有難うございました。
お礼が遅くなり済みませんでした。

お礼日時:2007/08/09 16:49

補足:



中途で読み込みを強制終了したい場合は、

FileRead "", True

でOKです。
    • good
    • 0
この回答へのお礼

補足まで有難うございました。

お礼日時:2007/08/09 16:48

エクセルの根本的制約事項として、不可能とはっきりしていることを、いまさら聞いても無駄でしょう。


>2007にはなりそうもありません
上司でも相談したの。新製品も出て、2万円前後の金で解決することではないの。ただ今のパソコンのスペックは問題だが。それに設計思想が100万行になっただけで、処理反応時間が快適かどうかはべつですが。
情報処理に、コストがかかることは認識されているのでしょうかね。
ーーー
もうひとつ
(1)6万の続きを、同一シート別列に読み込むと、後の処理の重大な障害になるか。
(2)6万の続きを、別シートに読み込むと、重大な障害になるか。
そういうことが、言及されてないが。
(1)(2)をやる場合、VBAでCSVファイルをよむプログラムを探すか作らないといけないが、旧BASICのころから行われている簡単なコードなので、WEBを照会すれば、沢山転がっている。
    • good
    • 0
この回答へのお礼

有難うございました。
お礼が遅くなり済みませんでした。

お礼日時:2007/08/09 16:47

<Book2.csv>



1,A
2,B
3,C
4,D
5,E
6,F
7,G

このような csv ファイルを1行づつ読み込んで、Sheet(1)、Sheet(2)、Sheet(3)等に2行づつ転記。

Private Sub CommandButton1_Click()
  Dim I      As Integer
  Dim N      As Integer
  Dim R      As Integer
  Dim intCount   As Integer
  Dim intSheet_New As Integer
  Dim intSheet_Now As Integer
  Dim Datas    As String
  Dim strValues() As String
  
  Do
    Datas = FileRead("C:\temp\Book2.csv")  ' 1行だけ読み込む
    If Len(Datas) > 2 Then             ' 終端の判断
      intCount = intCount + 1          ' カウントアップ
      intSheet_New = (intCount + 1) \ 2    ' シートインデックス確定
      If intSheet_New <> intSheet_Now Then ' ニューシート移行時の行インデックス(R)の初期化
        R = 0
        intSheet_Now = intSheet_New
      End If
      strValues() = Split(Datas, ",")       ' 各セルデータに分割
      R = R + 1                   ' 行カウントアップ
      N = UBound(strValues())          ' 列数取得
      For I = 0 To N
        Worksheets(intSheet_Now).Activate     ' シートアクティブ
        ActiveSheet.Cells(R, I + 1) = strValues(I)  ' データ転記
      Next I
    Else
      Exit Do
    End If
  Loop Until (0)
End Sub

ポイントは、1行づつ順次に読み込む FileRead関数を利用していることです。

<標準モジュール>

Option Explicit

Public Function FileRead(ByVal FileName As String, Optional isStop As Boolean = False) As String
On Error GoTo Err_FileRead
  Static isOpen As Boolean
  Static fso  As FileSystemObject
  Static fil  As File
  Static txs  As TextStream
  
  If Not isOpen Then
    isOpen = True
    Set fso = New FileSystemObject
    Set fil = fso.GetFile(FileName)
    Set txs = fil.OpenAsTextStream(ForReading, TristateUseDefault)
  End If
  FileRead = txs.ReadLine
Exit_FileRead:
  If Len(FileRead) = 0 Or isStop Then
    isOpen = False
    Set txs = Nothing
    Set fil = Nothing
    Set fso = Nothing
  End If
  Exit Function
Err_FileRead:
  Resume Exit_FileRead
End Function

※Microsoft scripting runtime 参照設定が必要。
    • good
    • 0
この回答へのお礼

FileRead関数ですか、勉強になります。
有難うございました。
お礼が遅くなり済みませんでした。

お礼日時:2007/08/09 16:47

基本的な考え方は#3さんと同意見です(OPENなど)


ただ、方法として次の方法も考えられます。
1.1行ずつ処理(加工)しているならその都度csvへ格納する。
2.フォームを作りリストボックスなどにAddして選んだものをシートへ返し加工する。リストボックスなどでは65536の制限はありません。

現在の内容が明確ではないのでハッキリと言えませんが、将来を見込んだロジックであるなら考えてみてください。
    • good
    • 0
この回答へのお礼

有難うございました。
お礼が遅くなり済みませんでした。

お礼日時:2007/08/09 16:44

エクセルにお任せで読み込む方法は無いので、全てをVBAで制御する必要があります。



ファイルの OPEN 文を使って指定ファイルを開き、
INPUT/LINEINPUT 文を使って1行ずつ読み込みます。
65536行を超える場合は、カウンターを使って設定した読込範囲をチェックしながら読み込む必要があります。

http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub0 …
    • good
    • 0
この回答へのお礼

ありがとうございました。
勉強になります。

お礼日時:2007/08/09 16:40

こんにちは。



以下でお分かりになると思いますが、

65,536行よりも大きいテキストファイルは、Excel97,Excel2000, Excel2002, Excel2003
では、インポートできません。
http://support.microsoft.com/default.aspx?scid=k …

Open FileName For Input As #FileNum

で、65,536行を越えたら、Worksheets.Add して、再びインポートしていきます。
    • good
    • 0
この回答へのお礼

ありがとうございます。
やりたいことは、いわば差込印刷に毛の生えたようなものなので、1行ずつ読みこみ、その分の処理が終われば消去して、また次の行を読み込んでくればいいのです。
だから65,536行よりも大きいCSVをまるごとインポートすることではありません。

お礼日時:2007/08/07 14:41

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qエクセル2000で65536行を超えるCSVファイルの読み込み方法

Windows2000、エクセル2000です。
今回、約10万行を超えるCSVファイルが送られてきました。
エクセルで開くと当然65536行で切れてしまいます。
やむをえず、拡張子を .txt に変え、メモ帳で開いて分割してエクセルの複数のシートに張ろうとしてみました。
拡張子を .txt に変えれば65536行で切れず、全件表示されます。しかし、このデータをコピーしようとCtrlを押したままマウスでスクロールをしたところ、スクロールはできるのですがデータが膨大なため遅々として先にすすんでくれません。
これじゃらちがあかないので、他の部署のAccsessを使える人にデータをわたして数ファイルのCSVファイルに分割していただきました。
今回はこれで事なきをえたのですが、これからまたこんなことがあった場合、わたしはAccsessを使ったことがないので困ってしまいます。(送付側からは分割したければそっちでやれといわれております。)

こんな場合、エクセルではどのような対応をすればいいのでしょうか?
(エクセル2007を使えという答えは勘弁してください。)

Windows2000、エクセル2000です。
今回、約10万行を超えるCSVファイルが送られてきました。
エクセルで開くと当然65536行で切れてしまいます。
やむをえず、拡張子を .txt に変え、メモ帳で開いて分割してエクセルの複数のシートに張ろうとしてみました。
拡張子を .txt に変えれば65536行で切れず、全件表示されます。しかし、このデータをコピーしようとCtrlを押したままマウスでスクロールをしたところ、スクロールはできるのですがデータが膨大なため遅々として先にすすんでくれません。
これじゃらちが...続きを読む

Aベストアンサー

別にexcelで開かなくても、wordで開いちゃえばいいじゃないですか。

word上で、適当な行数で切って「書式なし(*.txt)」で保存すれば
済む話です。ナンなら「メモ帳」でも同じことが出来ますよ。

QExcelで65536行以上の.txtを開く

エクセルにおいて65536行以上あるテキストファイルを開く方法は無いのでしょうか?
通常だと「表示の範囲を超えている」という趣旨のメッセージが表示され、規定行以上は表示されません。
例えばこれを規定行を超えた場合はSheet2等に分けて表示させる方法等は無いのでしょうか?

なぜ、そんな長い行を表示させたいのかと言うと、計測機の測定値がダンプされており、それをエクセルで開いて統計を取りたいのです。しかし、1ヶ月の記録がテキストファイルで約7000行となります。
これだと9か月分しかエクセル表示出来ません。
現在は計測機に添付されていたソフトを使っていますが、これの1回の変換限界は200行しか有りません。従って1ヶ月だけでも35回も操作を繰り返してエクセルに変換しています。
この手間を減らし、なおかつ長期分の統計処理をやりたいのです。
なにかいい方法は無いでしょうか?

なお、65536行以下の自作変換用マクロは作成済みで、添付ソフトのように変換限界もなく問題なく動作しています。

Aベストアンサー

さんこうに

http://oshiete1.goo.ne.jp/qa3235220.html

QExcel 2007で6万5536行以上のデータ

Excel 2007では、最大列数が従来の256列から1万6384列に,最大行数が従来の6万5536行から104万8576行に増えたと聞きました。私のExcelは、2007ですが、最大行数は6万5536行のままです。
どうしたら、6万5536行以上のデータを扱えるようになるのでしょうか?
何らかの設定変更で可能になるのでしょうか?

Aベストアンサー

>何らかの設定変更で

エクセルを素で起動させたときの設定方法は,画面左上の丸いOfficeボタンからExcelのオプションの「保存」欄で,ファイルの保存形式が「Excel 97-2003ブック」になっているので「Excelブック(*.xlsx)」に変更します。



すでにあるブックについては,
>どうしたら、6万5536行以上のデータを扱えるようになるのでしょうか?

画面左上の丸いOfficeボタンから「変換」を開始すると,ブックを一度保存する画面が開いて後に変わっています。

ちなみにxlsxブック形式だけでなく,xlsmやxlsbを選んでも変わります。

QVBAでの100万行以上のデータの取り込み

どなたかご教示お願いいたします。
VBAで100万行以上のCSVデータの取り込みは可能でしょうか?
初心者なのでファイルを開いてセルに入れてから範囲を指定し配列に
取り込み処理しておりましたが100万行以上だとデータがシートから出てしまいます。
なのでエクセルに展開せずに配列に取り込むなどということはできるのでしょうか?
もし可能であればあつかましいのですが、A列の120万行データを配列に取り込むサンプルをご教示いただけるとありがたいのですが・・・
よろしくお願いいたします。

Aベストアンサー

6割程度出来たかも?
データ数180万、項目数8個、最大・最少を求めるのは1項目、
100データ区切りで試した結果。
5分。
200データ区切りだと
4分。
最初の30秒ほど応答なし状態ですがその後にシート転記が始まりました。
700万だとExcelが落ちる可能性有りです。

ただ、まだ確認したいことがありますのでコードは差し控えます。
時間軸の項目名と書式(例 15:30:25 のようなもの)。
時間軸のデータは重複があり得ますか。
何の最大値・最小値なのでしょう?もしかして時間軸を除く16項目。
もしかして、200区切りでその範囲内なら時間軸の値は同じ?
(でないと16項目の最大・最少を求めても意味ないですよね)
200区切りで、もし一部分でも200に満たないものがあった場合に
考慮しないで常に200区切りとして処理しても構わない。

呑み込みが悪くてすみません。
出来ればデータを1行目から数行提示してもらえると助かります。
例えば3データ区切とした場合
時間軸|項目1|項目2|・|項目16
1:01:01  10   20    30
1:01:01  20   50    40
1:01:01  15   80    10
1:01:02  90   60    10
1:01:02  20   50    40
1:01:02  15   80    50

1:01:01  20   80    40
1:01:01  10   20    10
1:01:02  90   80    50
1:01:02  15   50    10
ということでしょうか?
横の方が良いのか
1:01:01 20/10  80/20  40/10
1:01:02 90/15  80/50  50/10

つまり、
時間軸が大体200区切りで値が同じ
その中でそれぞれの項目の最大・最少なら単純なのですけど。
冒頭のデータ量で2分程度でした。
(3年前の中堅スペックのPCです)
700万行だとやってみないことには…。
ヘッダー(タイトル行)は120も700のモノも同じ
でデータ部分が異なるだけ?
bin-chan さんにお任せして敵前逃亡しようかな。。。

6割程度出来たかも?
データ数180万、項目数8個、最大・最少を求めるのは1項目、
100データ区切りで試した結果。
5分。
200データ区切りだと
4分。
最初の30秒ほど応答なし状態ですがその後にシート転記が始まりました。
700万だとExcelが落ちる可能性有りです。

ただ、まだ確認したいことがありますのでコードは差し控えます。
時間軸の項目名と書式(例 15:30:25 のようなもの)。
時間軸のデータは重複があり得ますか。
何の最大値・最小値なのでしょう?もしかして時間軸を除く16項目。
...続きを読む

QエクセルVBA 大容量CSVファイルの読み込み

200万行のCSVファイルをエクセルに読み込みたいです。Rows.Countを超えるので、2回に分けて
半分読み込み
処理
残り半分読み込み
処理
のようにしたいのです。どうすればいいでしょうか?

参考までに、検索したところ下記のQ&Aは見つかりました。
https://oshiete.goo.ne.jp/qa/3407338.html
ただ、これは途中の任意の1行を読み込む方法です。

100万行のファイルを2個作る等のようなとんちの利いた回答はナシでお願いします。
他に無ければしますが。。。

Aベストアンサー

使えそうな項目が無いですね・・・。
ExcelでCSVファイルを読み込むときに頭を悩ませるデータ型の変更、
(電話番号の前ゼロ消失、
郵便番号が日付になったり計算されてしまう・・・が無さそうなのでマシかも)

CSVファイルのフルパスが
D:\SampleData\てすと.csv
で、
タイトル行が無い場合のコードです。パスとファイル名は適宜書き換えてください。
20行程度の小さなテストデータで問題なかったら本番でお試しを。
数分かかるかと思います。

Sub Test()
Dim Cn As Object
Dim Rs As Object
Dim i As Long, k As Long, j As Integer

Set Cn = CreateObject("ADODB.Connection")

With Cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = _
"Data Source=D:\SampleData;" _
& "Extended Properties='text;HDR=NO;" _
& "FMT=Delimited'"
.Open
End With

Set Rs = CreateObject("ADODB.Recordset")
Rs.CursorLocation = 3 'adUseClient
Rs.Open "SELECT * FROM てすと.csv", Cn, 0, 1, 1

MsgBox "項目数は" & Rs.Fields.Count _
& vbNewLine _
& "行数は" & Rs.RecordCount

Application.ScreenUpdating = False
Sheets(1).Range("A1").CopyFromRecordset Rs, 10 '←本番では1000000に

'残りはシート2に
Rs.absolutePosition = 11 '←本番では1000001に
Do Until Rs.EOF
k = k + 1
If k > 1048576 Then
MsgBox "最大行数を超えました。もう無理!"
Exit Do
End If
For j = 1 To Rs.Fields.Count
Sheets(2).Cells(k, j) = Rs.Fields(j - 1)
Next
Rs.movenext
Loop
Application.ScreenUpdating = True
Rs.Close: Set Rs = Nothing
Set Cn = Nothing
End Sub

使えそうな項目が無いですね・・・。
ExcelでCSVファイルを読み込むときに頭を悩ませるデータ型の変更、
(電話番号の前ゼロ消失、
郵便番号が日付になったり計算されてしまう・・・が無さそうなのでマシかも)

CSVファイルのフルパスが
D:\SampleData\てすと.csv
で、
タイトル行が無い場合のコードです。パスとファイル名は適宜書き換えてください。
20行程度の小さなテストデータで問題なかったら本番でお試しを。
数分かかるかと思います。

Sub Test()
Dim Cn As Object
Dim Rs As Object
Dim...続きを読む

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

QEXCEL VBAマクロ作成で、他のEXCELからデータを取り込みたい

メインプログラム(EXCEL VBA)より、
他のフォルダーにあるEXCELの項目の内容を取り込みたいです。
たとえば他のフォルダーのEXCELのRange("A2:A3").ValueをメインプログラムのRange("C2:C3").Valueにセットしたい時です。

・コマンドボタン押したら、どこのEXCELから取り込むかのポップアップ(?)は、表示はできてます。
・作業者が選んだパスとブックもMsgBoxで表示できてるので、もらう相手の場所も取得できてます。

・となると次はOPEN,INPUTですか?
テキストデータの取り込みですと、Inputでそのバッファを定義してるのですが、なんか違うような。。。

よろしくお願いします!

Aベストアンサー

私がやる方法です。

Dim writeSheet As Worksheet ' 自分自身の書き出し先シート
Set writeSheet = ThisWorkbook.Worksheets(1) ' Sheet1 を参照

Dim readBook As Workbook ' 相手ブック
Set readBook = Workbooks.Open(filename) ' 相手ブックを開いて参照
Dim readSheet As WorkSheet ' 相手シート
Set readSheet = readBook.Worksheets("sheetName") ' 相手シートを参照
' または Set readSheet = readBook.Worksheets(sheetIndex)

' 例えば
writeSheet.Cells(1, 1).Value = readSheet.Cells(2, 2).Value ' 相手シートの B2 の値を自分自身の A1 に書き込む

readBook.Close False ' 相手ブックを閉じる
Set readSheet = Nothing
Set readBook = Nothing

私がやる方法です。

Dim writeSheet As Worksheet ' 自分自身の書き出し先シート
Set writeSheet = ThisWorkbook.Worksheets(1) ' Sheet1 を参照

Dim readBook As Workbook ' 相手ブック
Set readBook = Workbooks.Open(filename) ' 相手ブックを開いて参照
Dim readSheet As WorkSheet ' 相手シート
Set readSheet = readBook.Worksheets("sheetName") ' 相手シートを参照
' または Set readSheet = readBook.Worksheets(sheetIndex)

' 例えば
writeSheet.Cells(1, 1).Value = readSheet.Ce...続きを読む

QエクセルVBA 大容量CSVファイルの読み込みが遅い

800万行、1.4GBのCSVファイルをLineにより100万行ずつシートに読み込み、処理してます。
100万行読み込み
コンマを区切り文字にして展開
データ処理
次の100万行読み込み
の手順です。

出だしは快調で1シート20秒程度で読み込みます。ところが、シートを重ねるごとにだんだん遅くなり、1シート5分、最後の方はメモリーオーバーでエラーとなり、最後まで行き着いてません。ウインドウ下枠に表示される「フィル」で時間がかかります。その後で表示される「区切り位置」以降、データ処理は普通です。おそらくLineによる読み込みで時間がかかっていると思います。なぜでしょうか?どうすればいいでしょうか?

エラー位置はDoの3行下です。
Sub Macro1()

Dim vFile As Variant
Dim WSdata As Worksheet
Dim ffn As Long
Dim vA() As Variant
Dim j As Long, k As Long

Const Half As Long = 500000 ' 1回の書き出し行数
Const CROWSZ As Long = 1000000 '1シートへの書き出し数
vFile = ThisWorkbook.Path & "\CSVconverted.CSV"

ReDim vA(1 To UnitRead, 1 To 1)

'100万行を入力するワークシート
Set WSdata = ThisWorkbook.Worksheets("CSV")

'CSVファイルを開く
ffn = FreeFile()
Open vFile For Input As #ffn

j = 1
k = 1
Do
Line Input #ffn, vA(j, 1)   '1行ずつ読み込み
If j >= Half Or EOF(ffn) Then
WSdata.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).Resize(UBound(vA), 1).Value = vA 'ここで止まる。vAにマウスを当てると「メモリーオーバー」と表示
ReDim vA(1 To UnitRead, 1 To 1)
j = 0

If k >= CROWSZ Or EOF(ffn) Then
      'コンマを区切り文字にして展開
With WSdata.Range(WSdata.Cells(2, "A"), WSdata.Cells(Rows.Count, "A").End(xlUp))
Application.DisplayAlerts = False
.TextToColumns .Cells(1), xlDelimited, Comma:=True
Application.DisplayAlerts = True
End With
k = 0


'データ処理がここに記載


WSdata.Cells.ClearContents
End If
End If
j = j + 1
k = k + 1
Loop While Not EOF(ffn)
Close #ffn 'CSV閉じる

End Sub

800万行、1.4GBのCSVファイルをLineにより100万行ずつシートに読み込み、処理してます。
100万行読み込み
コンマを区切り文字にして展開
データ処理
次の100万行読み込み
の手順です。

出だしは快調で1シート20秒程度で読み込みます。ところが、シートを重ねるごとにだんだん遅くなり、1シート5分、最後の方はメモリーオーバーでエラーとなり、最後まで行き着いてません。ウインドウ下枠に表示される「フィル」で時間がかかります。その後で表示される「区切り位置」以降、データ処理は普通です。おそら...続きを読む

Aベストアンサー

No.4ママチャリです。
まず①の件ですが、確かに Office 2013 and later となっていますね。でも、私の環境もExcel2010ですが、ヘルプにも掲載されているし、実際、StartRowで指定した行から読み込めています。各種ホームページを見ても2013より前のバージョンでも話題になっているので、問題ないと思います。

②の方ですが、OverTheGalaxyさんが書いたコード(Workbooks.OpenText Filename:=vFile, DataType:=xlDelimited, startrow:=ReadRow, comma:=True)を実際に動かしたところ、正常に動きました。確かにstartrowは大文字になりませんでしたが・・・。

試しに、[ファイル]ー[開く]の手順をマクロに記録し、それをベースに実験してみてはいかがでしょうか。各種HPを見ていて、「省略可能なパラメータと書いてあるくせに、省略したら問題が発生した」みたいな記事がありましたので・・・。

マクロを記録する際、列数が多いと FieldInfo パラメータがあふれることがあります。ただ、形式を指定する必要がなければ、不要なものなので捨てちゃってOKです。

では、ご検討をお祈りします。
それにしても、同じ環境(2010ではやっていないのでしたっけ?)で動作が異なるとは、Micr●s●ftらしいですね。

No.4ママチャリです。
まず①の件ですが、確かに Office 2013 and later となっていますね。でも、私の環境もExcel2010ですが、ヘルプにも掲載されているし、実際、StartRowで指定した行から読み込めています。各種ホームページを見ても2013より前のバージョンでも話題になっているので、問題ないと思います。

②の方ですが、OverTheGalaxyさんが書いたコード(Workbooks.OpenText Filename:=vFile, DataType:=xlDelimited, startrow:=ReadRow, comma:=True)を実際に動かしたところ、正常に動きました。確かにstar...続きを読む

Q大量のCSVデータを1つのエクセルデータにまとめる方法について

今仕事で、CSVファイルが400ファイル程あり、これを一つの
エクセルファイルにまとめなくて加工しなければならないのですが
うまいことVBAを活用して効率的にできないか思案中なのですが
うまい具合に行きません。
データの持ち方として
○CSVファイル1
1.AAA
2.BBB

○CSVファイル2
3.CCC
4.DDD

となっており、これを1つのエクセルファイル上で
1.AAA
2.BBB
3.CCC
4.DDD
としたいのですがなにかいい方法はないでしょうか?
1つのブックで外部データの取り込みでCSVを次々に選択して
いくVBAなんてあれば教えていただけないでしょうか?
よろしくお願いします。

Aベストアンサー

こんにちは。
昔書いた事があるサンプルです。
同一フォルダにあるcsvファイルをまとめて処理します。

Sub CSVまとめsample()
  Dim MyObj As Object
  Dim MyFol As String
  Dim MyFnm As String
  Dim MyStr As String
  Dim i   As Long
  Dim n   As Long
  Dim n1  As Long
  
  'フォルダを選択する
  Set MyObj = CreateObject("Shell.Application") _
    .BrowseForFolder(0, "SelectFolder", 0)
  '選択なければ処理を抜ける
  If MyObj Is Nothing Then Exit Sub
  MyFol = MyObj.self.Path & "\"
  MsgBox MyFol & "を処理します。"
  Set MyObj = Nothing
  Application.ScreenUpdating = False
  'ThisWorkbookにシートを追加して処理
  With Sheets.Add
    'Dir関数を使って指定フォルダ内csvファイルを順次処理
    MyFnm = Dir(MyFol & "*.csv")
    Do Until Len(MyFnm) = 0&
      i = i + 1
      'データエリアを取得してセット先を変更
      n = IIf(n = 0, 1, n + n1)
      '外部データ取り込みを利用
      With .QueryTables.Add(Connection:="TEXT;" & MyFol & MyFnm, _
                 Destination:=.Range("B" & n))
        .AdjustColumnWidth = False
        .TextFilePlatform = xlWindows
        .TextFileStartRow = 1
        .TextFileCommaDelimiter = True
        .Refresh False
        n1 = .ResultRange.Rows.Count
        .Parent.Names(.Name).Delete
        .Delete
      End With
      'ファイル名をA列にセット
      .Range("A" & n).Resize(n1).Value = MyFnm
      '次のファイルへ
      MyFnm = Dir()
    Loop
  End With
  If i > 0 Then
    MyStr = i & "個のファイルを処理しました。"
  Else
    '検索結果が0なら
    MyStr = "検索条件を満たすファイルはありません。"
  End If
  Application.ScreenUpdating = True
  MsgBox MyStr
End Sub

#シート行数をオーバーした時のエラー処理などはしてないので
#うまくいかなかったらごめんね^ ^;

こんにちは。
昔書いた事があるサンプルです。
同一フォルダにあるcsvファイルをまとめて処理します。

Sub CSVまとめsample()
  Dim MyObj As Object
  Dim MyFol As String
  Dim MyFnm As String
  Dim MyStr As String
  Dim i   As Long
  Dim n   As Long
  Dim n1  As Long
  
  'フォルダを選択する
  Set MyObj = CreateObject("Shell.Application") _
    .BrowseForFolder(0, "SelectFolder", 0)
  '選択なければ処理を抜ける
  If MyObj Is Nothi...続きを読む

QExel VBA 別ブックから該当データを検索し、必要なデータを取得する方法について

部品表というブックがあります
A列に商品名、B列に商品番号が入力してあります。C列のコードは未入力です。
A列     B列     C列      
商品名  商品番号  コード
モータ  U-1325-L  
ホルダ  R-134256

また、コード一覧表という別のブックには、A列に商品番号と、B列にコードが、何千件も入力されています。

やりたいことは
部品表のC列のコード欄に、コード一覧表ブックから商品番号と一致するコードを貼り付けしたいのです。

部品表は、何百種類もありますので、関数ではなく、マクロで処理を希望します。

自分では、部品表の商品番号をコピーして、コード一覧表で検索し、検索結果の右隣のセル(B列のコード)の値を部品表のC列に貼り付ければよいかと思い、書いてみたんですが…

Sub 別ブックから貼り付ける()
  Dim 検索する As Long
Windows("部品表.xls").Activate
検索する = cells(i,2).Value
Windows("コード一覧表.xls").Activate
ActiveWindow.SmallScroll Down:=-3
Selection.AutoFilter Field:=3, Criteria1:="=検索する", Operator:= xlAnd

と、してみたものの、検索しても、その検索結果の隣のセルのコードをどうやって取得すればいいのかが、わかりませんでした。

基本事項は本で学びましたが、呪文のようなコードはよく理解できません。懸命にネットで検索して、訳して理解する努力をしてはいますが。

どうぞよろしくお願いします。

部品表というブックがあります
A列に商品名、B列に商品番号が入力してあります。C列のコードは未入力です。
A列     B列     C列      
商品名  商品番号  コード
モータ  U-1325-L  
ホルダ  R-134256

また、コード一覧表という別のブックには、A列に商品番号と、B列にコードが、何千件も入力されています。

やりたいことは
部品表のC列のコード欄に、コード一覧表ブックから商品番号と一致するコードを貼り付けしたいのです。

部品表は、何百種類もありますので、関数...続きを読む

Aベストアンサー

こんにちは。
とりあえず実用性も踏まえました。
メインの動作はワークシート関数のVLOOKUPをVBA上で使用していますので理解はしやすいかと思います。
また、質問文から察するに「部品表.xls」と「コード一覧表.xls」の両方を開いて処理されていますが「コード一覧表.xls」はプログラム内で開いて閉じているので実行するときは「コード一覧表.xls」は閉じて置いてください。
Option Explicit
Sub Sample()
 Application.ScreenUpdating = False
 Dim I As Long
 Dim xlBook
 Set xlBook = Workbooks.Open("C:\★★\コード一覧表.xls") '★要変更★
 I = 2
 Do While Range("A" & I).Value <> ""
  ThisWorkbook.Worksheets("Sheet1").Range("C" & I).Value = Application.VLookup(ThisWorkbook.Worksheets("Sheet1").Range("B" & I).Value, xlBook.Worksheets("Sheet1").Range("A2:B65535"), 2, 0)
  I = I + 1
 Loop
 xlBook.Close
 Application.ScreenUpdating = True
 MsgBox ("完了")
End Sub

こんにちは。
とりあえず実用性も踏まえました。
メインの動作はワークシート関数のVLOOKUPをVBA上で使用していますので理解はしやすいかと思います。
また、質問文から察するに「部品表.xls」と「コード一覧表.xls」の両方を開いて処理されていますが「コード一覧表.xls」はプログラム内で開いて閉じているので実行するときは「コード一覧表.xls」は閉じて置いてください。
Option Explicit
Sub Sample()
 Application.ScreenUpdating = False
 Dim I As Long
 Dim xlBook
 Set xlBook = Workbooks....続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング