Excel VBA質問箱 IV

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

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


18502 / 76736 ←次へ | 前へ→

【63675】Re:膨大のテキストファイルを読み込みたい
お礼  黄身  - 09/11/29(日) 5:42 -

引用なし
パスワード
   ▼Hirofumi さん:
天才ですね!!!!!

あとは自分のほしい形に直してみます。

また壁にぶちあたったらコメントお願いします。

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


>>Excel初心者です。
>>今大学の研究で3,000,000行×4列のテキストファイルを、50,000×4列に分けて横に60個並べて読み込もうとしているんですが、どうしたらいいかわかりません。
>>
>>助言お願いします。
>>
>>あと2002を使っています。
>
>如何しても、やって見るなら
>Csvで4列×3,000,000行で下記の様なデータ
>
>11903.57 15449.86   .000   .647
>11826.67 15412.91   .000  5.266
>11764.66 15382.12  2.974  5.266
>11705.12 15345.17   .000  5.266
>
>なら、時間が掛かりますが何とか行けるかも?
>Vista 2.3G メモリ2G Excel2007で約60秒ぐらいかな?
>
>Option Explicit
>
>Public Sub ReadCsvExt()
>
>'  指定行数分出力版(データ抽出)
>
>  '出力行数のサイズを設定
>  Const clngOutputSize = 50000
>
>  Dim lngWrite As Long
>  Dim lngRow As Long
>  Dim lngColumn As Long
>  Dim lngColumns As Long
>  Dim rngResult As Range
>  Dim vntResult() As Variant
>  Dim vntFilename As Variant
>  Dim dfn As Integer
>  Dim strBuff As String
>  Dim strRec As String
>  Dim blnMulti As Boolean
>  Dim strPrompt As String
>  
>  Dim sngTime1 As Single
>  Dim sngTime2 As Single
>  
>  '結果用配列の列初期値を設定
>  lngColumns = 3
>  
>  If Not GetReadFile(vntFilename, ThisWorkbook.Path) Then
>    strPrompt = "マクロがキャンセルされました"
>    GoTo Wayout
>  End If
>  
>  sngTime2 = Timer
>  
>  '結果出力位置の指定
>  Set rngResult = ActiveSheet.Range("A1")
>  
>  '画面更新を停止
>  Application.ScreenUpdating = False
>  
>  '空きファイルバファ番号を取得
>  dfn = FreeFile
>  'ファイルをInputモードでOpen
>  Open vntFilename For Input As dfn
>  
>  ReDim vntResult(1 To clngOutputSize, lngColumns)
>  Do Until EOF(dfn)
>    'ファイルより、1行読み込み
>    Line Input #dfn, strBuff
>    '論理レコードに物理レコードを追加
>    strRec = strRec & strBuff
>    '出力用配列を作成
>    lngRow = lngRow + 1
>    SplitCsv strRec, vntResult, lngRow, lngColumns, vbCrLf, blnMulti
>    If blnMulti Then
>      lngRow = lngRow - 1
>      strRec = strRec & vbLf
>    Else
>      strRec = ""
>      '★抽出条件(抽出の場合以下のコメントアウトを活かす)
>'      If (Val(vntResult(lngRow, 0)) <= 12000 _
>'          Or 15000 <= Val(vntResult(lngRow, 0))) _
>'              Or (Val(vntResult(lngRow, 1)) <= 17000 _
>'                  Or 19000 <= Val(vntResult(lngRow, 1))) Then
>'        lngRow = lngRow - 1
>'      End If
>    End If
>    If lngRow = clngOutputSize Then
>      '結果をシートに出力
>      rngResult.Offset(lngWrite, lngColumn).Resize(lngRow, _
>            lngColumns + 1).Value = vntResult
>      lngColumn = lngColumn + 4
>      lngRow = 0
>    End If
>  Loop
>  
>  'ファイルを閉じる
>  Close #dfn
>    
>  '文字列バファにデータが残っている場合、配列に出力
>  If lngRow > 0 Then
>    '結果をシートに出力
>    rngResult.Offset(lngWrite, lngColumn).Resize(lngRow, lngColumns + 1).Value = vntResult
>  End If
>
>  strPrompt = "処理が完了しました"
>  
>Wayout:
>
>  '画面更新を再開
>  Application.ScreenUpdating = True
>  
>  Set rngResult = Nothing
>  
>  sngTime1 = Timer
>  
>  MsgBox strPrompt & vbLf & (sngTime1 - sngTime2), vbInformation
>  
>End Sub
>
>Private Sub SplitCsv(strLine As String, _
>            vntData() As Variant, _
>            lngRow As Long, _
>            lngColumns As Long, _
>            strRet As String, _
>            Optional blnMulti As Boolean)
>
>  Const strDelimiter As String = ","
>  Const strQuote As String = """"
>  
>  Dim i As Long
>  Dim lngDPos As Long
>  Dim lngStart As Long
>  Dim lngEnd As Long
>  Dim strField As String
>  Dim lngRowMax As Long
>  Dim strTmp As String
>  
>  lngRowMax = UBound(vntData, 1)
>  
>  '配列の添え字の初期値
>  i = 0
>  'Delimiter探索の開始位置
>  lngStart = 1
>  '分割元の文字列の長さ
>  lngEnd = Len(strLine)
>  '複数行Flagを初期化
>  blnMulti = False
>  '探索開始位置が分割元の文字列の長さを超えるまで分割
>  Do
>    'もし、開始位置の文字がstrQuoteと違う場合
>    If Mid$(strLine, lngStart, 1) <> strQuote Then
>      'Delimiterの位置を取得
>      lngDPos = InStr(lngStart, strLine, strDelimiter, vbBinaryCompare)
>      'Delimiterがある場合
>      If lngDPos > 0 Then
>        '開始位置からDelimiterの前までを取得
>        strField = Mid$(strLine, lngStart, lngDPos - lngStart)
>        '開始位置をDelimiterの後ろに更新
>        lngStart = lngDPos + 1
>      Else
>        '開始位置以降を取得
>        strField = Mid$(strLine, lngStart)
>        '開始位置を分割元の文字列の長さを超える位置に
>        lngStart = lngEnd + 1
>      End If
>    '開始位置の文字がstrQuoteと同じ場合
>    Else
>      '開始位置をstrQuoteの後ろに設定
>      lngStart = lngStart + 1
>      Do
>        'strQuoteの位置を取得
>        lngDPos = InStr(lngStart, strLine, strQuote, vbBinaryCompare)
>        'strQuoteがある場合
>        If lngDPos > 0 Then
>          '取得済みの文字列にstrQuote以降の文字列を加算
>          strField = strField & Mid$(strLine, lngStart, lngDPos - lngStart)
>          '開始位置をstrQuote以降に更新
>          lngStart = lngDPos + 1
>          '分割元の文字列の開始位置から1文字取得し
>          strTmp = Mid$(strLine, lngStart, 1)
>          'Delimiterなら
>          If strTmp = strDelimiter Then
>            '開始位置を1つ進める
>            lngStart = lngStart + 1
>            'Doを抜ける
>            Exit Do
>          '空白の文字列なら
>          ElseIf strTmp = "" Then
>            'Doを抜ける
>            Exit Do
>          'strQuoteなら
>          ElseIf strTmp = strQuote Then
>            '開始位置を1つ進める
>            lngStart = lngStart + 1
>            '取得済みの文字列にstrQuoteを加算
>            strField = strField & strQuote
>          End If
>        'strQuoteが無い場合
>        Else
>          '複数行Flagを立てる
>          blnMulti = True
>          strField = Mid$(strLine, lngStart) & strRet
>          '開始位置を分割元の文字列の長さを超える位置に
>          lngStart = lngEnd + 1
>          'Doを抜ける
>          Exit Do
>        End If
>      Loop
>    End If
>    '配列を確保
>    If i > lngColumns Then
>      lngColumns = lngColumns + 1
>      ReDim Preserve vntData(1 To lngRowMax, lngColumns)
>    End If
>    '配列に取得文字列を代入
>    vntData(lngRow, i) = strField
>    '取得文字列を初期化
>    strField = ""
>    '配列の添え字を更新
>    i = i + 1
>  Loop Until lngEnd < lngStart
>  
>End Sub
>
>Private Function GetReadFile(vntFileNames As Variant, _
>            Optional strFilePath As String, _
>            Optional blnMultiSel As Boolean _
>                    = False) As Boolean
>
>  Dim strFilter As String
>  
>  'フィルタ文字列を作成
>  strFilter = "CSV File (*.csv),*.csv," _
>        & "Text File (*.txt),*.txt," _
>        & "CSV and Text (*.csv; *.txt),*.csv;*.txt," _
>        & "全て (*.*),*.*"
>  '読み込むファイルの有るフォルダを指定
>  If strFilePath <> "" Then
>    'ファイルを開くダイアログ表示ホルダに移動
>    ChDrive Left(strFilePath, 1)
>    ChDir strFilePath
>  End If
>  'もし、ディフォルトのファイル名が有る場合
>  If vntFileNames <> "" Then
>    SendKeys vntFileNames & "{TAB}", False
>  End If
>  '「ファイルを開く」ダイアログを表示
>  vntFileNames _
>      = Application.GetOpenFilename(strFilter, 1, , , blnMultiSel)
>  If VarType(vntFileNames) = vbBoolean Then
>    Exit Function
>  End If
>  
>  GetReadFile = True
>  
>End Function

0 hits

【63664】膨大のテキストファイルを読み込みたい 黄身 09/11/28(土) 15:17 質問
【63665】Re:膨大のテキストファイルを読み込みたい 超初心者 09/11/28(土) 15:34 発言
【63666】Re:膨大のテキストファイルを読み込みたい 黄身 09/11/28(土) 16:13 質問
【63667】Re:膨大のテキストファイルを読み込みたい 超初心者 09/11/28(土) 16:57 発言
【63670】Re:膨大のテキストファイルを読み込みたい 黄身 09/11/28(土) 18:50 お礼
【63673】Re:膨大のテキストファイルを読み込みたい kanabun 09/11/28(土) 20:43 質問
【63674】Re:膨大のテキストファイルを読み込みたい 黄身 09/11/29(日) 5:15 発言
【63676】Re:膨大のテキストファイルを読み込みたい よろずや 09/11/29(日) 7:15 発言
【63672】Re:膨大のテキストファイルを読み込みたい Hirofumi 09/11/28(土) 20:23 発言
【63675】Re:膨大のテキストファイルを読み込みたい 黄身 09/11/29(日) 5:42 お礼
【63714】Re:膨大のテキストファイルを読み込みたい Hirofumi 09/12/2(水) 17:57 回答
【63730】Re:膨大のテキストファイルを読み込みたい 黄身 09/12/3(木) 23:27 お礼
【63668】Re:膨大のテキストファイルを読み込みたい よろずや 09/11/28(土) 18:10 発言
【63671】Re:膨大のテキストファイルを読み込みたい 黄身 09/11/28(土) 18:52 お礼

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