アプリ版:「スタンプのみでお礼する」機能のリリースについて

もし何か方法があったら教えていただきたいです。よろしくおねがいします(切実)。

Excel2010VBAで、100万行程度のCSVデータを、ADODBを使用して読み込み、
WHERE条件にヒットした行の次のヒットしていない行のデータを取得したいです。
サンプルとして、CSVが以下のようになっているとして、

F1,F2,F3
あ,い,う
え,お,か
き,く,け
こ,さ,し

※このようなデータがランダムに繰り返される

これに対して
Set DB = CreateObject("ADODB.Connection")
Set RS = CreateObject("ADODB.Recordset")
With DB
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Path & ";" _
& "Extended Properties='Text;HDR=YES;FMT=Delimited'"
.Open
End With
RS.Open "SELECT * FROM " & CSVFileName & " WHERE F1 = 'え'", DB, 1, 1
Debug.Print RS.Fields(0) & "," & RS.Fields(1) & "," & RS.Fields(2)

このコードは100万件でも処理時間はとてもいいのですが、
この時の"き,く,け"のデータが取得したいのです。

WHERE句なしで、
RS.Open "SELECT * FROM " & CSVFileName
としてから、MoveNext等でループしてF1に"え"があった次の行を取得すればできるのですが、データが多いと、非常に遅くなってしまいます。
RS.Findを使用する方法もありますが、WHERE句での検索よりも処理時間がかかりました。

別の方法として、CSVに行番号を付加し、WHERE句にヒットした行の行番号+1を条件にSELECT文を投げたらできるかな?と思い、

'行番号のあるテーブルを新たに作成
Set Ca = CreateObject("ADOX.Catalog")
Set DB = CreateObject("ADODB.Connection")
Ca.Create "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & DBFileName & "'"
DB.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & DBFileName & "'"

DB.Execute "CREATE TABLE TESTTB(ID INT IDENTITY(1,1) PRIMARY KEY ,F1 String,F2 String,F3 String)"

'CSVをインポート
DB.Execute "INSERT INTO " & TableName & " SELECT F1,F2,F3 FROM [Text;database=" & Path & "].[" & CSVFileName & "]"

とやってみましたが、Providerがおかしいせいか、エラーは発生しませんが、
ID列が自動採番されず、空になります。。。

一行づつINSERT INTOすればできますが、データが多いとやはり時間が非常にかかってしまいます。


何かいい方法はないのでしょうか??

質問者からの補足コメント

  • 補足:TableName="TESTTB"

      補足日時:2015/03/02 19:42
  • その読み込み方であれば基本的に順番通り(ファイルの上から下へ)に読み込まれると思いますが、
    時間がかかりすぎます。

    CSVをテーブルにインポートする時に順序が考慮されない事は知りませんでした。
    RecordSetの順序は保証されるかわかりませんが、インポートができないのであれば、
    質問の後半にあるやり方はできなくなります。

    そうなるとCSVに行番号が無いケースでは、レコードの順番を条件にした検索は、
    全くもって不可能ということでしょうか?
    何か方法はないのでしょうか?

    No.1の回答に寄せられた補足コメントです。 補足日時:2015/03/09 02:05

A 回答 (1件)

RecordSetで開いたときに


http://support.microsoft.com/kb/834927/ja
並び順が保証されるのか気になったので、ADODB ではありませんけども。

Sub Test01()
  Dim sLine As String
  Dim FF As Integer
  Dim B As Boolean
  Const CsvPath As String = "E:\Sample.CSV"
  Dim i As Long
  Dim t As Date
  
  t = Now
  FF = FreeFile
  '入力ファイルを開く
  Open CsvPath For Input Access Read As FF
  
  '入力ファイルがEOFになるまでのループ
  Do Until EOF(FF)
    i = i + 1 '行番号確認用
    Line Input #FF, sLine 'sLineに1行読み込み、行位置は自動的に次へ
    If B Then
      Debug.Print i, sLine  'イミディエイトウィンドウへ出力
    End If
    If InStr(sLine, "ピンポン") > 0 Then  
    'ここは実データに合わせてLeft(sLine,4)="ピンポン" とか適当に
      B = True
    Else
      B = False
    End If
  Loop
  
  Close 'ファイルをすべて閉じる
  DoEvents  'これを入れないと進まない場合があったので
  MsgBox CDate(Now - t)
End Sub

※複数行に渡って連続して、ピンポン(”え”) が出て来る場合は考えてません。
※結果報告をヨロシクね。
この回答への補足あり
    • good
    • 0

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

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