●処理元データCSVファイル:約30万件
1)列項目名は3行目にあり1~2行目データはメモ項目で全列数80~85列に対して5~9列で一定になっていません。
2)列項目は時期に応じ若干の差があり3タイプに分類。
3)分析に使用するデータは全行約600行の内4~5行目のデータのみ。
■分析前処理
1)処理元データを列項目別に4~5行目のデータを集計する。
●分析
過去経験で対応可能。
マクロ記録「外部データ取込」を利用してその他の処理を加えデータのまとめ分析作業自動化をと考えています。
■分析前処理に関し、CSVを1件ずつ呼出た上で分析に必要な行を切出・・・・と過去経験での処理も可能とは考えていますが、従来アウトプットに迫られ勉強が出来ていない配列やCSVデータの直接処理を使い処理時間を短縮できないものかと考えています。
上記CSVファイルからの指定行3~5行目のデータ取得に関しご教授をお願いします。
No.6
- 回答日時:
私も、一言・二言・三言。
なぜ、アップロードを早めたかからですが、このまま頭の中だけに入れておくと忘れてしまうからです。
#5さんのご指摘のことは、一応は織り込み済みですが、
どこかでエラーが出たら、続きができるようにした方がよいでしょうね。
そのために、先にファイル名を取得しました。
途中で休むようにすればよいものですが、プロシージャ外にしても、エラートラップに引っかかれば、その記録は残せます。ただし、全体的なエラーを出せば、myArray の中身自体も飛んでしまいます。
'//
そのために、こんなところに切れ目を入れたのです。
本来は、
Sub CSVImportPro()
Dim myArray
ではなく、
Private myArray
Sub CSVImportPro()
です。
Dimの宣言の下あたりに、On Error Goto ErrHandler
の一行を加えます。
当然、ルールの一番出し入れの大きい部分に、
DoEvents
は入れておいたほうが安全です。
それとこの部分です。失敗したら、その次の番号を下記に入れます。
For i = LBound(myArray) To UBound(myArray)
↓
For i = (リテラルな数字) To UBound(myArray)
On Error GoTo ErrHandler
Exit Sub
ErrHandler:
Debug.Pring i; myArray(i)
End Sub
としたら、良いかと考えています。
自分の力ではまだ付いていけませんが
nicotinismさん WindFallerさん
論議ありがとうございました。
再度質問をさせて頂くかもしれませんがよろしくお願いします。
ベストアンサーは保留とさせてください。
No.5
- 回答日時:
軽く
>Dir関数などで30万回呼び出すとか・・・
と言ってしまいましたが、
30万個もあると何処かでエラーになって止まるかも知れない。
例えばですが、コマンドプロンプトで、Dir e:\tmp /s /b > check.txt 等々で
書き出してこれをシートに取り込み、対象ファイルのリストを作成。
一個処理が終わるごとに隣のセルに1。
途中から再開する場合にやりやすい・エラーファイルが分かりやすい「かも」?
ループ処理中にカウンタを入れて
if i mod 100 = 0 then
beep
do events とかにすると途中で止めやすく「応答なし」が避けられます。
beep 五月蠅いから却下?
取得自体は出来たとして、
出力をどのようにするかは、今のところ保留です。
恥ずかしながら30万件のファイルの一括処理は未経験ですので
興味津々です。(なかば野次馬根性?です。すみません。)
自分の力ではまだ付いていけませんが
nicotinismさん WindFallerさん
論議ありがとうございました。
再度質問をさせて頂くかもしれませんがよろしくお願いします。
ベストアンサーは保留とさせてください。
No.4
- 回答日時:
この時期にアップロードしないほうがよかったかもしれません。
Excelのシートへ出力のタイミングをどこでするかによって変わるような気がします。それ以外は、どうあがいても、まともな作り方をすれば、#3さんのものと大きく変わるわけではありませんが、それを、あえて別な方法にしてしまいました。
Dir のファイル名データを、最初配列の中で蓄えてから処理するという方法から、すべて配列の中で処理していく方法は、私のやり方にしても、その後のテキストインポートを、FileSystemObject を使ってしまいました。
以下の最大の問題点は、コードが読みにくいということでしょうね。
'//
Sub CSVImportPro()
Dim myArray
Dim FName As String, myPath As String
Dim objFS As Object
Dim objText As Object
Dim i As Long
Dim Culs, arCul
'出力の項目
Culs = "2,3,5,6"
myPath = "C:\Temp\Test1\" '末尾は"\"
ReDim myArray(400000)
Set objFS = CreateObject("Scripting.FilesystemObject")
FName = Dir(myPath & "*.csv", vbNormal)
Do While FName <> ""
If FName <> "." And FName <> ".." Then
If (GetAttr(myPath & FName) And vbNormal) = vbNormal Then
'If FileLen(myPath & FName) > 10 Then ' ファイルサイズ
myArray(i) = FName
i = i + 1
'End If
End If
End If
FName = Dir
Loop
If i = 0 Then
MsgBox "データが見つかりませんでした。", vbExclamation
Exit Sub
End If
'//
ReDim buf(3) '4個まで
Dim arBuf(4) '5個まで
Dim k As Long, j As Long, v
Dim n As Long, l As Long, m As Long
Dim buf1 As Variant
k = 1
For i = LBound(myArray) To UBound(myArray)
If myArray(i) = "" Then Exit For
Set objText = objFS.OpenTextFile(myPath & myArray(i))
n = 0
For j = 1 To 5 '1行目から5行目まで
If objText.AtEndofStream = True Then Exit For
If j > 2 Then
arBuf(n) = objText.ReadLine
n = n + 1
Else
objText.SkipLine
End If
Next
objText.Close
For n = LBound(arBuf) To UBound(arBuf)
buf1 = Split(arBuf(n), ",")
m = UBound(buf1)
If m > -1 Then
k = k + 1
'列の項目別
'Cells(k, 1).Resize(, m + 1).Value = Buf1 '全部
arCul = Split(Culs, ",")
l = 0
For Each v In arCul
If UBound(buf1) >= v - 1 Then
Cells(k, 1 + l).Value = buf1(v - 1)
l = l + 1
End If
Next v
End If
Next n
Erase arBuf
Next i
End Sub
ありがとうございました
現在出張中で動作確認できませんが、来週帰社したらダミーファイルで早速ステップ動作を確認しながら本件に合わせ修正を加えてなんとかやってみるつもりですが・・・
関連部署との打合せでやはり結果を急かされてしまい、システム部にロギングデータサブファイルの再細分化を依頼しました、今回は「力づく」で「おまじない【doevent】連発」処理しながら、サブファイルリスト作成⇒ファイルリスト作成⇒全体呼出/必要行切出⇒分析集計・・・・となってしまいそうですが、
自分のレベルアップも含め「力づく」からの脱却を目指します。
その際自分の力不足もあり再度質問をさせて頂くかもしれませんがよろしくお願いします。
No.3ベストアンサー
- 回答日時:
こんな関数を作成して、Dir関数などで30万回呼び出すとか・・・
確認用にイミディエイトウィンドウに出力しています。
例:mygetrows("ファイルのフルパス",2,5,7) で2・5・7項目めを選択
3~5行目を取り出しています。
Function myGetRows(ByVal myFilePath As String, _
ParamArray cAry() As Variant) As String
Dim FF As Integer
Dim i As Integer, j As Integer
Dim v As Variant, vr As Variant
FF = FreeFile
Open myFilePath For Input As #FF
Do Until EOF(FF)
i = i + 1
Line Input #FF, v
If i > 2 Then 'データの始まり
vr = Split(v, ",")
myGetRows = myGetRows & v & vbCrLf '取りあえず全項目 (^_^;))
'Debug.Print v
For j = LBound(cAry) To UBound(cAry)
'最左項目を1として指定した項目だけ取り出したい時の参考に
Debug.Print , j, vr(cAry(j) - 1)
Next
End If
If i > 4 Then '
myGetRows = Left(myGetRows, Len(myGetRows) - 2) '最後の改行削除
Close FF
Exit Do
End If
Loop
End Function
そのCSVファイルの文字コード次第ではご破算かも、
変なところに余計なカンマがあると×無くても。。。
投稿用にタブインデントを全角スペースに変換しています。
ご参考まで。
ありがとうございました
現在出張中で動作確認できませんが、来週帰社したらダミーファイルで早速ステップ動作を確認しながら本件に合わせ修正を加えてなんとかやってみるつもりです。
自分の力不足もあり再度質問をさせて頂くかもしれませんがよろしくお願いします。
追記
CSVファイルの文字コードの件は、エクセル「外部データ取込」で問題ないことは確認できています。
No.1
- 回答日時:
こんばんは。
とても興味を持ちました。
私の乏しい経験からすると、オーソドックスな方法が一番のような気がします。
しかし、VBAマクロとして読むと、具体性がない点がいくつかあります。
人によっては、このまま作ってしまうことが可能だと思いますが、
・処理元データを列項目別に4~5行目のデータを集計する。(集計とは合計の計算と考えます)
・CSVファイルからの指定行3~5行目のデータ取得に
つまり項目名を含むというとこです。
ここら辺で、ちょっとどちらだろうか、どうするのだろうか、そもそもファイルの一部のデータを取り出すということで、そのデータ名などは、どこかに必要なのかなとか、そして、結果としては、30万ファイルなら、60~90万行になるということです。それでは、管理もできないだろうなとかなど。
とりとめもなくいろんな疑問が湧いてきてしまいます。
どのようなスタイルにするか、ひな形でもあるとよいのですが。
ありがとうございました。
以下言葉が足りませんでした。
集計:4行目5行目データを切り出し項目タイプ別に行を追加していく事です、データ処理系で何と呼ぶのか知識が無くやむなく「集計」としました。
3~5行目:項目タイプ別に振り分けるため項目行を含めています。
データ名:項目の中に年月日時分秒の情報製品SNが含まれているため後の分析につなげる事が可能です。
データの用途他:対象は設備管理用にロギングしているデータです、本来は項目ごとに集計/バッチ分析している物で事足りるはずでしたが・・・・、事情があり生データからの再分析が必要になってしまいました。
『このまま・・・可能だと思いますが』に関し
従来手法「呼出⇒切出⇒「集計」⇒分割保存」でデータ量/処理量かなり重くなり「おまじない【doevent】連発」になりそうですが、分割保存まで行けばなんとかなるとの感触は持っています。
今回自分の勉強/レベルアップを含めてもう少しスマートに出来ないかと質問をさせて頂いた次第です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 【困っています】VBA 追加処理の記述を教えてください。 1 2022/08/25 22:54
- Visual Basic(VBA) 指定月分の顧客データファイルを統合して並べ替え、所定の場所に貼り付ける 3 2022/09/10 07:55
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- システム CSVファイルのマッピング処理の省力化 1 2022/11/24 00:01
- Excel(エクセル) CSVファイルがカンマ区切りにならない。対処法を教えていただきたいです。 仕事でSMS一斉送信ができ 2 2022/07/01 21:24
- Visual Basic(VBA) 【困っています2】VBA 追加処理の記述を教えてください。 2 2022/08/26 11:42
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) エクセルでcsvファイルを開いてVBAを使いたい 7 2022/04/28 11:12
- その他(プログラミング・Web制作) Windowsのバッチファイルについてご教示ください 5 2023/07/25 20:23
- Visual Basic(VBA) マクロを教えてください。 7 2023/06/01 19:47
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAでCSVファイルを途中行まで...
-
VBAでCSVファイルの特定行を書...
-
openした後、closeしないでプロ...
-
JavaでCSVファイルを高速に読む...
-
__DATA__の意味
-
vNoteのBODY部の取得(長めです)
-
MATLABでのwhile文の条件について
-
VB6.0でDB接続する際に切断時の...
-
CSVが可変長の場合の検索方法
-
拡張子 ”log” と ” dat” の違い
-
ExcelをCSV書き出す場合のシー...
-
プログラミング(流れ図とコー...
-
バッチファイルの作り方(CSV→...
-
close()で例外が投げられる理由
-
batファイルでrenameができませ...
-
VBAコードを張り付け後のエクセ...
-
ListBoxのデータを高速でファイ...
-
至急お願いします。C言語で.img...
-
タブの色を変更する方法
-
vba dir の相対パス
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAでCSVファイルの特定行を書...
-
ExcelをCSV書き出す場合のシー...
-
openした後、closeしないでプロ...
-
VBAでCSVファイルを途中行まで...
-
VBAで巨大なファイルの途中から...
-
ReadLineでの読み出し行を指定する
-
JavaでCSVファイルを高速に読む...
-
MATLAB グローバル変数の宣言
-
エクセルVBA コードが同じでも...
-
Perlの変数に文字数制限(容量...
-
perlで、後ろの行を読んで、前...
-
C言語でのファイルのデータ更...
-
2つのCSVファイルをマッチング
-
VB6.0でDB接続する際に切断時の...
-
CSVが可変長の場合の検索方法
-
perlで容量の大きいCSVファイル...
-
1ファイルずつ読み込みたい
-
VBScriptでファイル保存先のデ...
-
perl で googleAPIを呼び出す...
-
C#でCSVファイルを逐一更新したい
おすすめ情報