Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3384 / 13645 ツリー ←次へ | 前へ→

【56405】巨大なCSVファイルの読み込みに関して アヒルペンギン 08/6/16(月) 15:36 質問[未読]
【56406】Re:巨大なCSVファイルの読み込みに関して kanabun 08/6/16(月) 15:56 発言[未読]
【56408】Re:巨大なCSVファイルの読み込みに関して アヒルペンギン 08/6/16(月) 16:22 回答[未読]
【56432】Re:巨大なCSVファイルの読み込みに関して Yuki 08/6/17(火) 10:58 発言[未読]
【56434】Re:巨大なCSVファイルの読み込みに関して アヒルペンギン 08/6/17(火) 13:01 お礼[未読]
【56438】Re:巨大なCSVファイルの読み込みに関して Yuki 08/6/17(火) 15:50 発言[未読]
【56440】Re:巨大なCSVファイルの読み込みに関して アヒルペンギン 08/6/17(火) 16:28 お礼[未読]
【62580】Re:巨大なCSVファイルの読み込みに関して kosuke 09/8/1(土) 16:42 質問[未読]
【62581】Re:巨大なCSVファイルの読み込みに関して kanabun 09/8/1(土) 19:27 発言[未読]
【62582】Re:巨大なCSVファイルの読み込みに関して kosuke 09/8/2(日) 10:52 発言[未読]
【62585】Re:巨大なCSVファイルの読み込みに関して kanabun 09/8/2(日) 19:15 発言[未読]
【62587】Re:巨大なCSVファイルの読み込みに関して kanabun 09/8/2(日) 23:22 発言[未読]
【62589】Re:巨大なCSVファイルの読み込みに関して kosuke 09/8/3(月) 10:09 発言[未読]
【62590】Re:巨大なCSVファイルの読み込みに関して kanabun 09/8/3(月) 11:00 発言[未読]
【62591】Re:巨大なCSVファイルの読み込みに関して kosuke 09/8/3(月) 11:40 発言[未読]
【62592】Re:巨大なCSVファイルの読み込みに関して kanabun 09/8/3(月) 12:00 発言[未読]
【62593】Re:巨大なCSVファイルの読み込みに関して kosuke 09/8/3(月) 13:07 お礼[未読]

【56405】巨大なCSVファイルの読み込みに関して
質問  アヒルペンギン  - 08/6/16(月) 15:36 -

引用なし
パスワード
   Excelだと、横方向にはFFまでしか項目を読む事ができないようですが今回取り扱っているCSVは横方向に2000以上項目があります。シートを分割してもかまわないのでどうにかExcelで読み込む必要があるのですが、VBAでそういった処理をする事が可能でしょうか?先人の方々教えていただけると幸いです。

【56406】Re:巨大なCSVファイルの読み込みに関して
発言  kanabun  - 08/6/16(月) 15:56 -

引用なし
パスワード
   ▼アヒルペンギン さん:
こんにちは。

>CSVは横方向に2000以上項目があります。

回答ではないのですが、
ちなみに縦方向には何行くらいあるのでしょうか?
また、読み込んで、どういった処理をすることが目的なんでしょうか?

【56408】Re:巨大なCSVファイルの読み込みに関して
回答  アヒルペンギン  - 08/6/16(月) 16:22 -

引用なし
パスワード
   返信ありがとうございます。縦方向に関しては6万5千以上にはなりません。
横方向に関しては、FF(255)まで達したら次の項目は次のシート描画するように
したいのです。(その項目以下の縦方向データも)縦方向もなぜこんなに大きいのかというと扱っているCSVデータがレコーダからはき出されるログデータだからです。縦方向の行数に関しては手動で値を設定してもかまわないのですが、横は可変で対応させたいのです。

長文で申し訳ありませんが回答して頂けると助かります。


▼kanabun さん:
>▼アヒルペンギン さん:
>こんにちは。
>
>>CSVは横方向に2000以上項目があります。
>
>回答ではないのですが、
>ちなみに縦方向には何行くらいあるのでしょうか?
>また、読み込んで、どういった処理をすることが目的なんでしょうか?

【56432】Re:巨大なCSVファイルの読み込みに関して
発言  Yuki  - 08/6/17(火) 10:58 -

引用なし
パスワード
   ▼アヒルペンギン さん:
>Excelだと、横方向にはFFまでしか項目を読む事ができないようですが今回取り扱っているCSVは横方向に2000以上項目があります。シートを分割してもかまわないのでどうにかExcelで読み込む必要があるのですが、VBAでそういった処理をする事が可能でしょうか?先人の方々教えていただけると幸いです。

XL2007だったら一つのシートでいけますね。
数万行のデータだったらすごく時間がかかりそうです。

Sub TEXT_CSV2K_READ()
  Dim FSO   As Object  ' File System Obj
  Dim FsoTS  As Object  ' FSO.TextStream Obj
  Dim File  As Object  ' FSO.file Obj
  Dim strFN  As String  ' File Name
  Dim eLN   As Long   ' CSVファイルの行数
  Dim CLM   As Long   ' シート数
  Dim strD  As String  ' 一行データ
  Dim vD   As Variant ' 一行分配列
  Dim vA()  As Variant ' シート用配列
  Dim vX()  As Variant ' セル用
  Dim i    As Long
  Dim j    As Long
  
  strFN = "D:\Excel\Test.csv"
  
  Set FSO = CreateObject("Scripting.FileSystemObject")
  
  Set FsoTS = FSO.OpenTextFile(strFN, 8)
  eLN = FsoTS.Line - 1
  FsoTS.Close
  
  Set File = FSO.GetFile(strFN)
  Set FsoTS = File.OpenAsTextStream(1)
  
  ' 前処理
  strD = FsoTS.ReadLine
  
  vD = Split(strD, ",")
  If UBound(vD) > 255 Then
    CLM = Int(UBound(vD) / 256) + 1
  Else
    CLM = 1
  End If
  ' シート不足分追加
  If Worksheets.Count < CLM Then
    Worksheets.Add Count:=CLM - Worksheets.Count
  End If

  ReDim vX(1 To CLM)
  ReDim vA(1 To eLN, UBound(vD) - 1)
  
  For i = 1 To CLM
    vX(i) = vA
  Next
  
  j = 1
  For i = 0 To UBound(vD)
    vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
  Next
  
  '本処理
  Do While Not FsoTS.AtEndOfStream
    DoEvents
    strD = FsoTS.ReadLine
    vD = Split(strD, ",")
    j = j + 1
    For i = 0 To UBound(vD)
      vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
    Next
  Loop
  
  ' シートに貼り付け
  For i = 1 To CLM
    DoEvents
    With Worksheets(i)
      .Cells.ClearContents
      .Range("A1").Resize(j, 256).Value = vX(i)
    End With
  Next
  FsoTS.Close
  Set FsoTS = Nothing
  Set FSO = Nothing
End Sub

【56434】Re:巨大なCSVファイルの読み込みに関して
お礼  アヒルペンギン  - 08/6/17(火) 13:01 -

引用なし
パスワード
   返信ありがとうございます。さきほどのソースで読み込みを行いファイル名等の
変更も行ったあと実行したのですが、なぜか
  j = 1
  For i = 0 To UBound(vD)
    vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
  Next
の部分でエラーが起こります。インデックスが有効範囲にありませんというエラーなのですが何が原因でしょうか?たびたび申し訳ありませんが回答頂けるとうれしいです。


▼Yuki さん:
>▼アヒルペンギン さん:
>>Excelだと、横方向にはFFまでしか項目を読む事ができないようですが今回取り扱っているCSVは横方向に2000以上項目があります。シートを分割してもかまわないのでどうにかExcelで読み込む必要があるのですが、VBAでそういった処理をする事が可能でしょうか?先人の方々教えていただけると幸いです。
>
>XL2007だったら一つのシートでいけますね。
>数万行のデータだったらすごく時間がかかりそうです。
>
>Sub TEXT_CSV2K_READ()
>  Dim FSO   As Object  ' File System Obj
>  Dim FsoTS  As Object  ' FSO.TextStream Obj
>  Dim File  As Object  ' FSO.file Obj
>  Dim strFN  As String  ' File Name
>  Dim eLN   As Long   ' CSVファイルの行数
>  Dim CLM   As Long   ' シート数
>  Dim strD  As String  ' 一行データ
>  Dim vD   As Variant ' 一行分配列
>  Dim vA()  As Variant ' シート用配列
>  Dim vX()  As Variant ' セル用
>  Dim i    As Long
>  Dim j    As Long
>  
>  strFN = "D:\Excel\Test.csv"
>  
>  Set FSO = CreateObject("Scripting.FileSystemObject")
>  
>  Set FsoTS = FSO.OpenTextFile(strFN, 8)
>  eLN = FsoTS.Line - 1
>  FsoTS.Close
>  
>  Set File = FSO.GetFile(strFN)
>  Set FsoTS = File.OpenAsTextStream(1)
>  
>  ' 前処理
>  strD = FsoTS.ReadLine
>  
>  vD = Split(strD, ",")
>  If UBound(vD) > 255 Then
>    CLM = Int(UBound(vD) / 256) + 1
>  Else
>    CLM = 1
>  End If
>  ' シート不足分追加
>  If Worksheets.Count < CLM Then
>    Worksheets.Add Count:=CLM - Worksheets.Count
>  End If
>
>  ReDim vX(1 To CLM)
>  ReDim vA(1 To eLN, UBound(vD) - 1)
>  
>  For i = 1 To CLM
>    vX(i) = vA
>  Next
>  
>  j = 1
>  For i = 0 To UBound(vD)
>    vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
>  Next
>  
>  '本処理
>  Do While Not FsoTS.AtEndOfStream
>    DoEvents
>    strD = FsoTS.ReadLine
>    vD = Split(strD, ",")
>    j = j + 1
>    For i = 0 To UBound(vD)
>      vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
>    Next
>  Loop
>  
>  ' シートに貼り付け
>  For i = 1 To CLM
>    DoEvents
>    With Worksheets(i)
>      .Cells.ClearContents
>      .Range("A1").Resize(j, 256).Value = vX(i)
>    End With
>  Next
>  FsoTS.Close
>  Set FsoTS = Nothing
>  Set FSO = Nothing
>End Sub

【56438】Re:巨大なCSVファイルの読み込みに関して
発言  Yuki  - 08/6/17(火) 15:50 -

引用なし
パスワード
   ▼アヒルペンギン さん:
貴方のデータが分からないのでチョット分かりません。
テストに使用したデータ作成は

Sub CSVWrite()
  Dim strD  As String
  Dim i    As Long
  Dim j    As Long
  Dim intF  As Integer
  intF = FreeFile
  Open "D:\Excel\Test.csv" For Output As #intF
  For j = 1 To 20
    DoEvents
    For i = 1 To 2000
      strD = strD & Chr(64 + j) & Format(Hex(i), "00000") & ","
    Next
    strD = Left(strD, Len(strD) - 1)
    Print #intF, strD
    strD = ""
  Next
  Close #intF
End Sub

シート分割
Sub TEXT_CSV2K_READ()
  Dim FSO   As Object  ' File System Obj
  Dim FsoTS  As Object  ' FSO.TextStream Obj
  Dim File  As Object  ' FSO.file Obj
  Dim strFN  As String  ' File Name
  Dim eLN   As Long   ' CSVファイルの行数
  Dim CLM   As Long   ' シート数
  Dim strD  As String  ' 一行データ
  Dim vD   As Variant ' 一行分配列
  Dim vA()  As Variant ' シート用配列
  Dim vX()  As Variant ' セル用
  Dim i    As Long
  Dim j    As Long
  
  strFN = "D:\Excel\Test.csv"
  
  Set FSO = CreateObject("Scripting.FileSystemObject")
  
  Set FsoTS = FSO.OpenTextFile(strFN, 8)
  eLN = FsoTS.Line - 1
  FsoTS.Close
  
  Set File = FSO.GetFile(strFN)
  Set FsoTS = File.OpenAsTextStream(1)
  
  ' 前処理
  strD = FsoTS.ReadLine
  
  ' 一行目をカンマでスプリット
  vD = Split(strD, ",")
  
  ' 配列数を256で割ってシート数を計算
  If UBound(vD) > 255 Then
    CLM = Int(UBound(vD) / 256) + 1
  Else
    CLM = 1
  End If
  ' シート不足分追加
  If Worksheets.Count < CLM Then
    Worksheets.Add Count:=CLM - Worksheets.Count
  End If
  
  ' シート数分の配列を確保
  ReDim vX(1 To CLM)
  ’セル数分の配列を確保
  ReDim vA(1 To eLN, UBound(vD) - 1)
  ’訂正してください ↓
  ReDim vA(1 To eLN, 255)
  
  ' シートの中にセルの配列を組み込む
  For i = 1 To CLM
    vX(i) = vA
  Next
  
  ’一行目のデータをセット
  ’こちらではエラーにならないのですが
  ' 貴方のデータがどのようなものか分かりませんので
  ' 下記の説明でデバッグしてみて下さい。
  j = 1
  For i = 0 To UBound(vD)
    Debug.Print i       ' を追加してエラー時にチェック
    ’vX(Int(i / 256) + 1)はvX(1)です。
    '(j, i Mod 256)は(1, i Mod 256)のはずです。
    vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
  Next
  
  '本処理 2行目以降の処理
  Do While Not FsoTS.AtEndOfStream
    DoEvents
    strD = FsoTS.ReadLine
    vD = Split(strD, ",")
    j = j + 1
    For i = 0 To UBound(vD)
      vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
    Next
  Loop
  
  ’シートにデータをセットする
  For i = 1 To CLM
    DoEvents
    With Worksheets(i)
      .Cells.ClearContents
      .Range("A1").Resize(j, 256).Value = vX(i)
    End With
  Next
  FsoTS.Close
  Set FsoTS = Nothing
  Set FSO = Nothing
End Sub

【56440】Re:巨大なCSVファイルの読み込みに関して
お礼  アヒルペンギン  - 08/6/17(火) 16:28 -

引用なし
パスワード
   Yukiさんありがとうございます。
正常に動作致しました。改行されていなかったのが原因だったようです。
1行目の項目だけが入力してある状態で実行していた為実行できなかった
ようです。テストデータまで公開して頂き感謝致します。まさにこの様な
動作を期待していました。本当にありがとうございました^−^


▼Yuki さん:
>▼アヒルペンギン さん:
>貴方のデータが分からないのでチョット分かりません。
>テストに使用したデータ作成は
>
>Sub CSVWrite()
>  Dim strD  As String
>  Dim i    As Long
>  Dim j    As Long
>  Dim intF  As Integer
>  intF = FreeFile
>  Open "D:\Excel\Test.csv" For Output As #intF
>  For j = 1 To 20
>    DoEvents
>    For i = 1 To 2000
>      strD = strD & Chr(64 + j) & Format(Hex(i), "00000") & ","
>    Next
>    strD = Left(strD, Len(strD) - 1)
>    Print #intF, strD
>    strD = ""
>  Next
>  Close #intF
>End Sub
>
>シート分割
>Sub TEXT_CSV2K_READ()
>  Dim FSO   As Object  ' File System Obj
>  Dim FsoTS  As Object  ' FSO.TextStream Obj
>  Dim File  As Object  ' FSO.file Obj
>  Dim strFN  As String  ' File Name
>  Dim eLN   As Long   ' CSVファイルの行数
>  Dim CLM   As Long   ' シート数
>  Dim strD  As String  ' 一行データ
>  Dim vD   As Variant ' 一行分配列
>  Dim vA()  As Variant ' シート用配列
>  Dim vX()  As Variant ' セル用
>  Dim i    As Long
>  Dim j    As Long
>  
>  strFN = "D:\Excel\Test.csv"
>  
>  Set FSO = CreateObject("Scripting.FileSystemObject")
>  
>  Set FsoTS = FSO.OpenTextFile(strFN, 8)
>  eLN = FsoTS.Line - 1
>  FsoTS.Close
>  
>  Set File = FSO.GetFile(strFN)
>  Set FsoTS = File.OpenAsTextStream(1)
>  
>  ' 前処理
>  strD = FsoTS.ReadLine
>  
>  ' 一行目をカンマでスプリット
>  vD = Split(strD, ",")
>  
>  ' 配列数を256で割ってシート数を計算
>  If UBound(vD) > 255 Then
>    CLM = Int(UBound(vD) / 256) + 1
>  Else
>    CLM = 1
>  End If
>  ' シート不足分追加
>  If Worksheets.Count < CLM Then
>    Worksheets.Add Count:=CLM - Worksheets.Count
>  End If
>  
>  ' シート数分の配列を確保
>  ReDim vX(1 To CLM)
>  ’セル数分の配列を確保
>  ReDim vA(1 To eLN, UBound(vD) - 1)
>  ’訂正してください ↓
>  ReDim vA(1 To eLN, 255)
>  
>  ' シートの中にセルの配列を組み込む
>  For i = 1 To CLM
>    vX(i) = vA
>  Next
>  
>  ’一行目のデータをセット
>  ’こちらではエラーにならないのですが
>  ' 貴方のデータがどのようなものか分かりませんので
>  ' 下記の説明でデバッグしてみて下さい。
>  j = 1
>  For i = 0 To UBound(vD)
>    Debug.Print i       ' を追加してエラー時にチェック
>    ’vX(Int(i / 256) + 1)はvX(1)です。
>    '(j, i Mod 256)は(1, i Mod 256)のはずです。
>    vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
>  Next
>  
>  '本処理 2行目以降の処理
>  Do While Not FsoTS.AtEndOfStream
>    DoEvents
>    strD = FsoTS.ReadLine
>    vD = Split(strD, ",")
>    j = j + 1
>    For i = 0 To UBound(vD)
>      vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
>    Next
>  Loop
>  
>  ’シートにデータをセットする
>  For i = 1 To CLM
>    DoEvents
>    With Worksheets(i)
>      .Cells.ClearContents
>      .Range("A1").Resize(j, 256).Value = vX(i)
>    End With
>  Next
>  FsoTS.Close
>  Set FsoTS = Nothing
>  Set FSO = Nothing
>End Sub

【62580】Re:巨大なCSVファイルの読み込みに関して
質問  kosuke  - 09/8/1(土) 16:42 -

引用なし
パスワード
   下記VBAを活用させていただいていますが、
"東京都,中央区","銀座",と書かれたCSVを読み込んだとき
東京都 中央区 銀座 三つのセルに分かれます。
東京都中央区 銀座 二つのセルに分ける、つまり
" "内の,を無視する方法を教えてください


Sub TEXT_CSV2K_READ()
  Dim FSO   As Object  ' File System Obj
  Dim FsoTS  As Object  ' FSO.TextStream Obj
  Dim File  As Object  ' FSO.file Obj
  Dim strFN  As String  ' File Name
  Dim eLN   As Long   ' CSVファイルの行数
  Dim CLM   As Long   ' シート数
  Dim strD  As String  ' 一行データ
  Dim vD   As Variant ' 一行分配列
  Dim vA()  As Variant ' シート用配列
  Dim vX()  As Variant ' セル用
  Dim i    As Long
  Dim j    As Long
  
  strFN = "D:\Excel\Test.csv"
  
  Set FSO = CreateObject("Scripting.FileSystemObject")
  
  Set FsoTS = FSO.OpenTextFile(strFN, 8)
  eLN = FsoTS.Line - 1
  FsoTS.Close
  
  Set File = FSO.GetFile(strFN)
  Set FsoTS = File.OpenAsTextStream(1)
  
  ' 前処理
  strD = FsoTS.ReadLine
  
  vD = Split(strD, ",")
  If UBound(vD) > 255 Then
    CLM = Int(UBound(vD) / 256) + 1
  Else
    CLM = 1
  End If
  ' シート不足分追加
  If Worksheets.Count < CLM Then
    Worksheets.Add Count:=CLM - Worksheets.Count
  End If

  ReDim vX(1 To CLM)
  ReDim vA(1 To eLN, UBound(vD) - 1)
  
  For i = 1 To CLM
    vX(i) = vA
  Next
  
  j = 1
  For i = 0 To UBound(vD)
    vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
  Next
  
  '本処理
  Do While Not FsoTS.AtEndOfStream
    DoEvents
    strD = FsoTS.ReadLine
    vD = Split(strD, ",")
    j = j + 1
    For i = 0 To UBound(vD)
      vX(Int(i / 256) + 1)(j, i Mod 256) = vD(i)
    Next
  Loop
  
  ' シートに貼り付け
  For i = 1 To CLM
    DoEvents
    With Worksheets(i)
      .Cells.ClearContents
      .Range("A1").Resize(j, 256).Value = vX(i)
    End With
  Next
  FsoTS.Close
  Set FsoTS = Nothing
  Set FSO = Nothing
 End Sub

【62581】Re:巨大なCSVファイルの読み込みに関して
発言  kanabun  - 09/8/1(土) 19:27 -

引用なし
パスワード
   ▼kosuke さん:
こんにちは。

>"東京都,中央区","銀座",と書かれたCSVを読み込んだとき
>東京都 中央区 銀座 三つのセルに分かれます。
>東京都中央区 銀座 二つのセルに分ける、つまり
>" "内の,を無視する方法を教えてください

別の質問なので、新たにスレッドを立てられたほうがいいかと思いますが、

ちなみに、kosuke さんのばあい、
一行の列数はいかほどあるのですか?

【62582】Re:巨大なCSVファイルの読み込みに関して
発言  kosuke  - 09/8/2(日) 10:52 -

引用なし
パスワード
   ▼kanabun さん:
こんにちは。

>"東京都,中央区","銀座",と書かれたCSVを読み込んだとき
>東京都 中央区 銀座 三つのセルに分かれます。
>東京都中央区 銀座 二つのセルに分ける、つまり
>" "内の,を無視する方法を教えてください
>
>別の質問なので、新たにスレッドを立てられたほうがいいかと思いますが、
>
>ちなみに、kosuke さんのばあい、
>一行の列数はいかほどあるのですか?

初めての質問でしたので、失礼しました。
次回からは、そのように致します。

列数は、287です。今回質問のデータは、22列にありましたが、
今後、他の列にも発生する可能性があります。
また、" "内に,があったり、なかったりします。
よろしくお願いいたします。

【62585】Re:巨大なCSVファイルの読み込みに関して
発言  kanabun  - 09/8/2(日) 19:15 -

引用なし
パスワード
   ▼kosuke さん:
こんにちは。

>列数は、287です。今回質問のデータは、22列にありましたが、
>今後、他の列にも発生する可能性があります。
>また、" "内に,があったり、なかったりします。

Input#ステートメントで 1項目ずつ読んでみました。
なので、超低速です。

Sub 超256列CSV読み込み()
  Dim myCSV As String
  myCSV = Application.GetOpenFilename("287列CSV,*.csv")
  If myCSV = "False" Then Exit Sub
  
  '------- テキストファイルの全行数取得
  Dim io As Integer
  Dim buf() As Byte
  Dim maxRow As Long
  Dim maxCol As Long
  Dim i As Long, j As Long, n As Long
  
  io = FreeFile()
  Open myCSV For Binary As io
   n = LOF(io)
   ReDim buf(1 To n)
   Get #io, , buf
  Close io
  maxRow = UBound(Split(StrConv(buf, vbUnicode), vbCrLf))
      
  '------- テキストファイルの列数取得
  For i = 1 To n
    If buf(i) = 13 Then
      If buf(i + 1) = 10 Then
        maxCol = i + 1
        Exit For
       End If
    End If
  Next
  Dim S As String
  Open myCSV For Input As io
  j = 0
  Do While Seek(io) < maxCol
    j = j + 1
    Input #io, S
    Debug.Print j, S
  Loop
  Close io
  maxCol = j
  
  '------- 配列に読み込み
  ReDim v(1 To maxRow, 1 To maxCol)
  Open myCSV For Input As io
  For i = 1 To maxRow
    For j = 1 To maxCol
      Input #io, v(i, j)
    Next
  Next
  Close io
  
  '------- シートに展開
  Dim nOld As Long
  Dim nSheet As Long, maxSheet As Long
  Dim m As Long, mz As Long, mCol As Long
  Const mm = &H100    'シート最大列数
  Dim v2()
  maxSheet = maxCol \ mm - (maxCol Mod mm > 0)
  With Application
    nOld = .SheetsInNewWorkbook
    .SheetsInNewWorkbook = maxSheet  '◆必要なシート枚数のBookを
    .Workbooks.Add          '新規追加
    .SheetsInNewWorkbook = nOld
  End With
  For m = 1 To maxCol Step mm
    nSheet = nSheet + 1
    mz = m + mm - 1
    If mz > maxCol Then mz = maxCol
    mCol = mz - m + 1
    If nSheet = 1 Then
      Worksheets(1).Cells(1).Resize(maxRow, mCol).Value = v
    Else
      ReDim v2(1 To maxRow, 1 To mCol)
      For i = 1 To maxRow
        For j = 1 To mCol
          v2(i, j) = v(i, m + j - 1)
        Next
      Next
      Worksheets(nSheet).Cells(1).Resize(maxRow, mCol) _
        .Value = v2
    End If
  Next
  
  MsgBox maxSheet & "つのシートに読み込みました"
  
End Sub

【62587】Re:巨大なCSVファイルの読み込みに関して
発言  kanabun  - 09/8/2(日) 23:22 -

引用なし
パスワード
   あと、
>  '------- 配列に読み込み
の部分↓ですが、

>  ReDim v(1 To maxRow, 1 To maxCol)
>  Open myCSV For Input As io
>  For i = 1 To maxRow
>    For j = 1 To maxCol
>      Input #io, v(i, j)
>    Next
>  Next

このままですと、
"0123" のような文字列は シートに展開したとき 数値化されて 123 になって
しまいますので、そういうデータがあるときは、
以下のようにしてください。

  For i = 1 To maxRow
    For j = 1 To maxCol
      Input #io, v(i, j)
      If VarType(v(i, j)) = vbString Then
        If IsNumeric(v(i, j)) Then
          v(i, j) = "'" & v(i, j)
        End If
      End If
    Next
  Next

【62589】Re:巨大なCSVファイルの読み込みに関して
発言  kosuke  - 09/8/3(月) 10:09 -

引用なし
パスワード
   ▼kanabun さん:
あと、
>>  '------- 配列に読み込み
>の部分↓ですが、
>
>>  ReDim v(1 To maxRow, 1 To maxCol)
>>  Open myCSV For Input As io
>>  For i = 1 To maxRow
>>    For j = 1 To maxCol
>>      Input #io, v(i, j)
>>    Next
>>  Next
>
>このままですと、
>"0123" のような文字列は シートに展開したとき 数値化されて 123 になって
>しまいますので、そういうデータがあるときは、
>以下のようにしてください。
>
>  For i = 1 To maxRow
>    For j = 1 To maxCol
>      Input #io, v(i, j)
>      If VarType(v(i, j)) = vbString Then
>        If IsNumeric(v(i, j)) Then
>          v(i, j) = "'" & v(i, j)
>        End If
>      End If
>    Next
>  Next

ご教示ありがとうございます。
当初、ご教示いただいたVBAで実行しましたが、下記→の箇所で、
インデックスが有効範囲にありません。と表示されました。

  '------- 配列に読み込み
→ ReDim v(1 To maxRow, 1 To maxCol)
  Open myCSV For Input As io
  For i = 1 To maxRow
    For j = 1 To maxCol
      Input #io, v(i, j)
    Next
  Next

再度、ご教示いただいたVBAを実行しましたが、下記→の箇所で、
コンパイルエラー。SubまたはFunctionが定義されていません。
と表示されました。


 For i = 1 To maxRow
    For j = 1 To maxCol
→     Input #io, v(i, j)
      If VarType(v(i, j)) = vbString Then
        If IsNumeric(v(i, j)) Then
          v(i, j) = "'" & v(i, j)
        End If
      End If
    Next
  Next

ご連絡が遅くなり、申し訳ありません。
VBAは勉強中の初心者ですので、よろしくお願いいたします。

【62590】Re:巨大なCSVファイルの読み込みに関して
発言  kanabun  - 09/8/3(月) 11:00 -

引用なし
パスワード
   ▼kosuke さん:

>当初、ご教示いただいたVBAで実行しましたが、下記→の箇所で、
>インデックスが有効範囲にありません。と表示されました。
>
>  '------- 配列に読み込み
> → ReDim v(1 To maxRow, 1 To maxCol)
デバッグして、maxRow や maxCol の値がこのRedim宣言時点で
いくつになっているか、確認してください。0 になってたりしてませんか?

>再度、ご教示いただいたVBAを実行しましたが、下記→の箇所で、
>コンパイルエラー。SubまたはFunctionが定義されていません。
>と表示されました。
> For i = 1 To maxRow
>    For j = 1 To maxCol
> →     Input #io, v(i, j)
こちらはちょっと分かりません。
この行のどこが反転していますでしょうか?


>VBAは勉強中の初心者ですので、よろしくお願いいたします。


もう一つ、別の方法があります。
>"東京都,中央区","銀座",と書かれたCSVを読み込んだとき
>東京都中央区 銀座 二つのセルに分ける、つまり
>" "内の,を無視する
このように、文字列データがダブルクォートで囲まれていたとき、
正しく「文字列データ」として読み込んだり、
"00123" のような文字列を 数値123 でなく 00123 と読んだり、
日付データを本来の日付形式で読み込むためには、
[データ]-[外部データの取り込み]-[テキストファイルの
インポート]メニュ−を使うといいです。

新規シートを2枚追加して、以下の操作をお試しください。

[テキストファイルのインポート]メニューを使うと、テキストファイ
ル(*.txt など)を[ファイル]-[開く]から開くときと同じように、
テキストファイルウィザードが開きます。
そこで ファイルの種類を *.csv にして、
> 列数は、287
のようなCSVファイルを指定して、
ウィザードの 1/3 で 「元のデータ形式」を
  ●カンマやタブなどの区切り文字によって....
のほうを選択し、
ウィザードの 2/3 で「区切り文字」の「カンマ」にだけチェック
をいれ、
ウィザードの 3/3 「データのプレビュー」で
  まず、
  ■256列目以降の列を選択して「列のデータ形式」から
   ●削除する
  とします。
  つぎに、256列までの各列について数値データ以外の「列の
  データ形式」を、
  ●文字列型 (例1:「東京都,中央区」 の列)
        (例2:「00012」 の列)
  とし、もし日付の列があれば、列のデータ形式から
  ●日付 〔YMD形式〕または〔MDY形式?〕などを指定します。

設定が終了したら、[完了]ボタンを押すと、どこにインポート
するか尋ねてきますので、新規シートの[A1]セルなどを指定しますと
そこに指定したとおりのデータが展開されます。

残りの列も上の操作と同様に(ただし、今度は 先ほどインポート
しなかった後半の列に対して列のデータ型を指定して)2枚目の
シートに読み込みます。

インポート後の利用目的によっては、
256列を上回るCSVのうち、必要な列だけ取捨選択して、
256列内に収め1シートに展開することもできます。

文章で書くと長ったらしいですが、一度だけ操作をマクロ記録し
ておけば、あとは同じタイプのCSVファイルに対しては ファイル
名を変更するだけで、マクロで一気にシートに展開することが
可能となります。
参考までに、こちらでとったマクロ記録です。

'Excel2002
' マクロ記録日 : 2009/8/3 ユーザー名 : kanabun

  With ActiveSheet.QueryTables.Add( _
      Connection:="TEXT;D:\(Data)\LongField.csv", _
      Destination:=Range("A1"))
    .Name = "LongField"
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .TextFilePromptOnRefresh = False
    .TextFilePlatform = 932
    .TextFileStartRow = 1
    .TextFileParseType = xlDelimited
    .TextFileTextQualifier = xlTextQualifierDoubleQuote
    .TextFileConsecutiveDelimiter = False
    .TextFileTabDelimiter = False
    .TextFileSemicolonDelimiter = False
    .TextFileCommaDelimiter = True
    .TextFileSpaceDelimiter = False
    .TextFileColumnDataTypes = Array(2, 1, 2, 5, 1, 2, 1, 1, 1, _
     1, 2, 1, 2, 5, 1, 2, 1, 2, 2, 2, 2, _
     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, _
     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 _
     , 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 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, 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, 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, 9, 9, 9, 9, 9, 9, _
    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 2)
    .TextFileTrailingMinusNumbers = True
    .Refresh BackgroundQuery:=False
  End With

 このばあい、最初の76列とお尻の4列だけを1シートにインポートしています。
 それ以外は DataTypesのパラメータを 9(削除) にしてあります。

こちらなら、手動操作をマクロの記録して、それを基にVBA化できますから、
初心者の方にも手をつけやすいのではないかと思います。

【62591】Re:巨大なCSVファイルの読み込みに関して
発言  kosuke  - 09/8/3(月) 11:40 -

引用なし
パスワード
   ▼kanabun さん:

早々のご連絡、ありがとうございます。

>▼kosuke さん:
>
>>当初、ご教示いただいたVBAで実行しましたが、下記→の箇所で、
>>インデックスが有効範囲にありません。と表示されました。
>>
>>  '------- 配列に読み込み
>> → ReDim v(1 To maxRow, 1 To maxCol)
>デバッグして、maxRow や maxCol の値がこのRedim宣言時点で
>いくつになっているか、確認してください。0 になってたりしてませんか?

 0 になっていました。

>
>>再度、ご教示いただいたVBAを実行しましたが、下記→の箇所で、
>>コンパイルエラー。SubまたはFunctionが定義されていません。
>>と表示されました。
>> For i = 1 To maxRow
>>    For j = 1 To maxCol
>> →     Input #io, v(i, j)
>こちらはちょっと分かりません。
> この行のどこが反転していますでしょうか?


  v(i, j)のvが反転していました。


別の方法は、これから試してみます。

【62592】Re:巨大なCSVファイルの読み込みに関して
発言  kanabun  - 09/8/3(月) 12:00 -

引用なし
パスワード
   ▼kosuke さん:

> 0 になっていました。

変数 maxRowも maxCol も両方とも、ですか?
もしそうだとしたら、その前の 行数取得や 列数取得のルーティンが
うまく動作しなかったということになります。
テキストファイルの構造がこちらが想定している形式でなかった可能性が
あります。

>  v(i, j)のvが反転していました。

ReDim v(1 To maxRow, 1 To maxCol)
の行がないのでは?

こういう構文エラーを見つけやすくするためにも、各モジュール(標準
モジュールとか、シートモジュールとか)の最初に、必ず
Option Explicit
の一行を入れておいてください。

これから作るモジュールに 自動でOption Explicitが入るようにするには、
以下の設定をしておくといいです。

◆VBE [ツール] メニューの [オプション] をクリックし、
[編集] タブの [変数の宣言を強制する] チェック ボックスをON にする。


いずれにしても、基本的な Debugの方法を身につける必要がありそうですね?

【62593】Re:巨大なCSVファイルの読み込みに関して
お礼  kosuke  - 09/8/3(月) 13:07 -

引用なし
パスワード
   ▼kanabun さん:

ご教示いただきました別の方法で対応できました。

ありがとうございました。

勉強します・・・。

3384 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free