• 締切済み

VBA 複数ファイルを読み込んで、抽出

VBA初心者です。どうぞよろしくお願いいたします。 <やりたいこと> 同じフォルダにある複数ファイル(logファイル)を順番に読み込み、 特定の文字が含まれている行だけを、別ファイル(sum.csv)に保存していきたい。 ファイルが多数あるため、VBAで処理できればと思っています。 急いでおり、今回は丸投げになりますが、どなたかコードを教えていただけますと 非常に助かります。 コードを見て、勉強させていただきます。 どうかよろしくお願いいたします。

みんなの回答

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.7

ありゃ,前に引っかかったのと同じですね。 修正: sub macro3()  :  loadlogfile2 mypath & myfile, myout  : end sub 失礼しました。

marimaria22
質問者

補足

本当にありがとうございます。思い通りの動きになりました! 図々しくも、さらにお伺いしたいことがあります。もし可能であれば教えてください。 今のコードは、解凍したいファイルと、プログラムが同じフォルダに入っていますが、 実際は、解凍したいファイルの入っているフォルダも複数あります。 できれば、下記のようにしたいのです。 logというフォルダの直下にプログラムをおく。 logフォルダの中の複数フォルダ内の複数ファイル(解凍対象)の特定文字の入っている行を、logフォルダ直下のsum.csvに書き込む。 log¥program.xlsx log¥sum.csv log¥201501¥g002.httpd-access_log ←解凍対象       ¥g003.httpd-access_log    log¥201502¥g010.httpd-access_log       ¥g011.httpd-access_log できましたら、ご回答いただけますと有り難いです。      

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.6

ほとんどそのまま流用してみると sub macro3()  dim myPath as string  dim myFile as string  dim myOut as string  mypath = thisworkbook.path & "\"  myfile = dir(mypath & "*.*log")  open mypath & "sum.csv" for output as #1  close #1  myout = mypath & "sum.csv"  do until myfile = ""   loadlogfile2 myfile, myout   myfile = dir()  loop end sub Sub loadLogFile2(ByRef fileName As Variant, outName as variant) Dim rowNo As Integer Dim readString As String Dim st As Object Set st = CreateObject("ADODB.Stream") 'ADODB.Stream生成 st.Type = 2 'オブジェクトに保存するデータの種類を文字列型に指定する st.Charset = "utf-8" '文字コード(Shift_JIS, Unicodeなど) st.LineSeparator = 10 '改行LF(10) st.Open 'Streamのオープン st.LoadFromFile (fileName) 'ファイル読み込み  open outname for append as #1 rowNo = 5 Do While Not st.EOS ' rowNo = rowNo + 1 readString = st.ReadText(-2) 'テキストを1行読み込む。 ' Cells(rowNo, 2).Value = readString '読み込んだ文字列をセルにセットする   if instr(readstring, "特定の文字列") > 0 then print #1, readstring Loop  close #1 st.Close 'Streamのクローズ Set st = Nothing End Sub

marimaria22
質問者

補足

ご回答ありがとうございます。本当にここまでおつきあいいただき恐縮です。 いただいたコードですが、下記のコード部分で「ファイルを開けませんでした」という エラーがでました。fileNameには、ちゃんとフォルダ内のファイル名が入っています。 st.LoadFromFile (fileName) 'ファイル読み込み  ←ここでエラー 長々ととおつきあいいだだき恐縮ですが、 おわかりになりましたら、教えてください。 宜しくお願いいたします。

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.5

>本当のlogファイル(多いものは80,000KB位あります。) 今のマクロだと,その4分の1ぐらいのサイズが仕様的な限度ですね。 実用的にはもっと小さくしないと使えないと思います。 手っ取り早い対処法としては「改行コードの違いで全体を一度に読み込んでしまう」のが原因なので,テキストエディタ等で改行コードを標準ウィンドウズテキストのvbcrlfに置換(改行コードを変換して保存)してやれば,最初のマクロで(一行ずつ読みながら)問題なく処理することはできます。 たとえばTeraPadなど。 http://www5.ocn.ne.jp/~m-shin/other/terapad-return.html

marimaria22
質問者

補足

ご回答いただきありがとうございます! ログファイルは大量にあるので、1ファイルごとテキストエディタで変更することはとても大変な事情があります。なにかプログラムで対応できないかと調べてみたら、 ADODB.Streamというのを使うとできるように思えたのですが、自分ではコードが かけません もしお願いできるのであれば、ADODB.Streamを使ったコードを教えていただけないでしょうか。 http://www.hiihah.info/index.php?Excel%EF%BC%9AVBA%EF%BC%9AUTF-8%EF%BC%8FLF%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80 お願できれば、大変助かります。

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.4

>logファイルのデータを、改行のない、1行と判断している 実際にステップ実行してみてそのように動作しているのでしたら,そのlogファイルの「改行コード」が,ウィンドウズテキストファイルの標準改行コードとは異なっているのが原因です。 具体的に何が改行コードとして利用されているのか,あなたのlogファイルの実際の構造をご自分で把握してください。 例:vblfが改行コードだった場合 sub macro2()  dim myPath as string  dim myFile as string  dim buf as string  dim a as variant  dim ax as variant  mypath = thisworkbook.path & "\"  myfile = dir(mypath & "*.*log")  open mypath & "sum.csv" for output as #1  do until myfile = ""   open mypath & myfile for input as #2   do until eof(2)    line input #2, buf    a = split(buf, vblf)  ’他にvbcrとかで試す    for each ax in a     if instr(ax, "特定の文字列") > 0 then print #1, ax    next   loop   close #2   myfile = dir()  loop  close #1 end sub

marimaria22
質問者

補足

ありがとうございます!思い通りの動きになりました。 ただ、 動きの検証用のファイルはファイル容量が小さかったので、問題なかったのですが、 本当のlogファイル(多いものは80,000KB位あります。)を3ファイル、フォルダにいれて、プログラムを動かしたところ、line input #2, bufのところで、応答無しに なってしまいました。強制的にファイルを閉じる時に、「文字列領域が不足」と出ていました。 ファイルの容量が大きすぎるということでしょうか?

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.3

>最初のコードに戻して、下記のようにしたのですが、やはり、open myfile for input as #2 の部分で、「ファイルが見つかりません」とでて止まります。 とりあえず Sub macro1()  Dim myPath As String  Dim myFile As String  Dim buf As String  myPath = ThisWorkbook.Path & "\"  myFile = Dir(myPath & "*.*log")  ’←ここだけ変えました。  Open myPath & "sum.csv" For Output As #1  Do Until myFile = "" ’←ここで「g002.httpd-access_log」が見えてるなら   Open mypath & myFile For Input As #2    'ここも変更する   Do Until EOF(2)    Line Input #2, buf    If InStr(buf, "特定の文字列") > 0 Then Print #1, buf   Loop   Close #2   myFile = Dir()  Loop  Close #1 End Sub スミマセン、 >今度は、myfileの中身が空になってしまいました。 のご説明と >Do Until myFile = ""  のmyfileには、ちゃんとlogのファイル名「g002.httpd-access_log」が見えました。 のご説明が矛盾します。 デバッグしてみるとmyfileの中身は「空ではなかった」という事ですから、「今度は空になってしまいました」はどういうマクロのどういう状況でそういうご判断になったのか判らず、どこが間違えているのか絞れません。

marimaria22
質問者

補足

説明が悪く申し訳ありませんでした。 <矛盾点についてのお答え> 最初にいただいたコード myfile = dir(mypath & "*.log")・・・・open myfile for input as #2 では、Do Until myFile = "" の中身にファイル名が見えた。 myfile = dir("*.*_log")・・・・open mypath & myfile for input as #2 と変更しましたら、Do Until myFile = "" の中身が空になった。 最後にいただいたコード myFile = Dir(myPath & "*.*log") ・・・Open mypath & myFile For Input As #2では、Do Until myFile = "" の中身にファイル名が見えました。 -------------------------------------- <新たな問題> 最後にいただいたコードで、ためしてみたところ、時間は結構かかりましたが、 コードは最後まで動きました。 しかし、sum.csv の中身をみると、logファイルの中身がすべてそのまま転記されていて、 抽出が行われていませんでした。 logファイルのデータを極端に少なくして、プログラムの動きを見たところ、 Line Input #2, buf If~を、1つのlogファイルにつき1回しかしていないようでした。 logファイルのデータを、改行のない、1行と判断しているのかなと思いましたが、 どうしたらよいでしょうか? 本当にお手数おかけして申し訳ございませんが、 教えていただけますと助かります。 どうぞよろしくお願いいたします。

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.2

>「ファイルが見つかりません」とでて止まります。 はて、とりあえず丁寧に myfile = dir(*.*_log)  : open mypath & myfile for input as #2 としてみます。

marimaria22
質問者

補足

ご回答いただきありがとうございます! ご指示のとおり、変更したのですが、今度は、myfileの中身が空になってしまいました。 ※myfile = dir(*.*_log)の部分は、エラーになったので、myfile = dir("*.*_log")と  書き換えて試してみました。 最初のコードに戻して、下記のようにしたのですが、やはり、open myfile for input as #2 の部分で、「ファイルが見つかりません」とでて止まります。 コードを1行づつ動かして、myfile の中身をみると、 Do Until myFile = ""  のmyfileには、ちゃんとlogのファイル名「g002.httpd-access_log」が見えました。 お手数かけてすみません。どうしたら、よいか教えていただけますと助かります。 Sub macro1() Dim myPath As String Dim myFile As String Dim buf As String myPath = ThisWorkbook.Path & "\" myFile = Dir(myPath & "*.*log")  ←ここだけ変えました。 Open myPath & "sum.csv" For Output As #1 Do Until myFile = "" Open myFile For Input As #2 Do Until EOF(2) Line Input #2, buf If InStr(buf, "特定の文字列") > 0 Then Print #1, buf Loop Close #2 myFile = Dir() Loop Close #1 End Sub

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.1

sub macro1()  dim myPath as string  dim myFile as string  dim buf as string  mypath = thisworkbook.path & "\"  myfile = dir(mypath & "*.log")  open mypath & "sum.csv" for output as #1  do until myfile = ""   open myfile for input as #2   do until eof(2)    line input #2, buf    if instr(buf, "特定の文字列") > 0 then print #1, buf   loop   close #2   myfile = dir()  loop  close #1 end sub ブックをlogファイルと同じフォルダに放り込んでからマクロを実行する。

marimaria22
質問者

補足

keithin さん ご回答いただきありがとうございます! 教えていただいたコードで試してみたのですが、 open myfile for input as #2 の部分で、「ファイルが見つかりません」とでて止まります。 下記の部分を変更しています。これが原因でしょうか? ※ログファイルのファイル名が、201505g0002.httpd-access_log のような形なので、 *.log →*_log  に変更。 お手数おかけいたしますが、教えていただきますと非常にありがたいです。 どうぞよろしくお願いいたします。

関連するQ&A

  • フォルダ内の複数ファイルから抽出(vbs)

    web のログファイルの集計のため、以下が可能なコードを教えていただきたい。 そのまま使えるコードですと非常に助かります。 (vbs または vba) logというフォルダに、複数のログファイルが入っています。 ファイルの文字コードは、UTF8  改行は、LFです。 この複数のファイルから、特定の文字列の入っている行を抜き出して、 1つのCSVファイルに書き出したい。(文字コードをShift-Jis 改行は、CRLFに変えたい) どうかお助けください。宜しくお願いいたします。

  • 複数のcsvファイルをマクロ(VBA)で取り込みたい

    複数のcsvファイルをマクロ(VBA)で取り込みたい csvファイルの中身が、 20090507 120508 osaka 項目1,項目2,項目3,・・・・・,項目10 a1,a2,a3,・・・・・,a10 b1,b2,b3,・・・・・,b10 c1,c2,c3,・・・・・,c10 や 20090507 132529 hokkaido 項目1,項目2,項目3,・・・・・,項目10 d1,d2,d3,・・・・・,d10 e1,e2,e3,・・・・・,e10 f1,f2,f3,・・・・・,f10 となっているcsvファイルが特定のフォルダの中に100以上あります。 このcsvふぁいるの5行目だけをaccessに書き込んでテーブルに追加していきたいと思っています。 項目1,項目2,項目3,・・・・・,項目10 a1,a2,a3,・・・・・,a10 d1,d2,d3,・・・・・,d10 このようなテーブルができればいいのですが・・・ csvファイルを開く→5行目をテーブルに追加→csvファイルを閉じる(削除する)→次のcsvファイルを開く→5行目をテーブルに追加→csvファイルを閉じる(削除する) この流れでいいと思うのですが方法が分かりません。 丸投げですがよろしくお願いします。

  • エクセルVBAでCSVを読み込んで別ファイルにまとめたいです。

    エクセルVBA初心者の者です。 マクロの記録でできたコードをいじって、 なんとか動くものができるレベルです。 Aというフォルダに20~40行程度の内容のCSVファイルが 数百個あります。開けてみないと何行あるのかわかりません。 そのAフォルダのCSVの内容をエクセルで開いて、別のエクセルファイルの一枚のシートにまとめたいのです。 最初にCSVファイル名を一枚のシートのA列に書き出すところ まではやれたのですが、それを順番に読み込んでコピペの 流れができません。 CSVファイル名読み込み 読み込んだファイル1つめCSV開く CSVの20~40行をコピー 別のエクセルファイルのシートに貼り付け 1つめCSV閉じる ↓ 読み込んだファイル2つめCSV開く 繰り返し こういうやり方じゃない方がいいのかもわかりません。 もしかして考え方も違うのでしょうか? サンプルコード教えていただけるとありがたいです。 よろしくお願いします。

  • フォルダ内のファイル読み込み

    エクセル2003のVBAを使って、特定のフォルダ内の複数のCSVファイル全てを「順番」に読み込む(ファイルを開く)方法を教えて下さい。 フォルダの中には「0.csv」~「12.csv」が入っています。 (しかし、間の番号が無い場合があります。例えば、0~4と6~10のファイルがあり、間に「5」がない。 必ず「0」から始まるないし、最後のファイル名の数字も違う。) よろしくお願いします。

  • VBA 複数ブックへ書き込み

    VBA初心者です。 1つのフォルダ内にある100(ファイル名001から100)個のエクセルファイル(ブック)の特定の場所(すべてのエクセル ファイルはファイル名は違うが、同一のシート名で同一のセルの構造になっている。 以上に対して、1つのもとになるファイルA(ブック、シート)の特定のセル(同一列の行を上から順次下る)セルの値を先の同一フォルダ内のエクセルファイル100(001~100)個に対して、ブックオープン、特定セルのデリート、特定セルへの書き込み、ブック保存という一連の作業を行いたいです。 多数のファイルから1つの集計ファイルに値を読み込んできて書き込むサンプルはあるようですが、逆に1つのファイルから同一フォルダ内の多数のファイル(ブック)の特定場所に書き込むためのサンプルコードを教えていただけると大変助かります。 以上よろしくお願いいたします。

  • 他のExcelファイルのVBAコードを検索したい

    他のExcelファイルに書かれたVBAコードに、ある特定のキーワード(パス名など)が使われているかを自動的に調べるためのVBAを書きたいと思っています。 仕事で使っているマクロが書かれたExcelファイルからある特定の処理をしているマクロを含むものを検索したいのですが、検索するExcelファイルが膨大なため、順番にExcelファイルを開いてVBAコードをチェックしていく工程をマクロ化したいのです。ファイルを順に開いていく処理はマクロ化できるのですが、書かれたVBAコードのチェックをどうしたらよいか悩んでいます。 「VBAコードに対して検索する」または「VBAコードを1行ずつ変数に代入する」、「モジュールシートをテキストファイルに出力する」などの処理が自動化できれば対応できそうなのですが、そのような処理をExcelVBAで作成できるでしょうか。 なお環境はWindowsXPのExcel2003です。 よろしくお願いいたします。

  • VBAで複数ファイルからのデータ抽出を行いたい。

    すみません、知恵をお貸しください。 VBA初心者です。 一つの同じフォルダ内にあるエクセルの同じ形式の複数ファイル(*.xls)から、データを抽出し(例.A2:k2)一つのファイルを作成したいのですが、どうにか一行目だけを抽出することができました。 しかし、データ抽出をしたい複数ファイルの中には(A2:k2)だけではなく、複数行に渡りデータが入っているもの(A3:k3まで、やA5:k5までなど)があり、それら全てを抽出したいのです。 何らかの条件付けの上でループをさせればいいのかな?とも考えたのですが、うまくいきません。 どうかご教授お願いします。

  • excel vbaで複数のcsvファイルの読み込み

    100シート分のcsvファイルのデーターを一つずつ読み込んでexcelにコピーして使用してますが莫大な時間がかかって困ってます。 vbaを使用して作業を簡素化出来る事は出来ないでしょうか? ------------------------------------------ ※ csvの概要 excelで1枚のcsvファイルを開くとA列の11行目から65536行まで数値データがあります。 ※ vbaできたらよいなと思う仕様 そこで、複数のcsvファイルを選択して読み込むとCSV_データと言うSeetのA列の10行目から1枚目のcsvファイル、B列の10行目から2枚目のcsvファイルと言う風に選択した分のcsvを列に続けて数値データを貼り付けしてくれるvbaをご教授していただけると大変助かります。 不躾で申し訳ございませんが宜しくお願い致します。 excel2003 ------------------------------------------

  • 複数のEXCELファイルより一部の行を自動でマージするマクロ

    「(1)複数のEXCELファイル」より、「(2)特定のシート」の中のさらに「(3)特定の行」をコピーし、あるEXCELファイルの1シートに挿入していくマクロ(VBA)か、ソフトが掲載されているサイト、もしくは、やりかたを教えてください。 1.EXCELは、2003 2.「(1)複数のEXCELファイル」は、一つのフォルダにあり、データ形式は一緒。  そのフォルダにはEXCELファイルしか置きません。 3.「(2)特定のシート」について、シート名はどれも一部のみ一致します。  または位置(順番)は一緒です。 4.「(3)特定の行」はどのファイルも作りが一緒です。 VBA初心者ですが、ヒントをいただければ頑張りたいと考えています。

  • 複数のtxtの特定部分を抽出し、一つのxlsファイルにまとめたいです。

    複数のtxtの特定部分を抽出し、一つのxlsファイルにまとめたいです。 皆様のお知恵をお借りできませんでしょうか? 現在約1000行からなる同一体裁のtxtファイルを多数所持しております。 中身はタブで区切ってあったので、タブをコンマに変換し、CSVファイルを作りました。 これらのファイルを15~20ファイルごとにフォルダ分けしてあります。 このCSVファイルをエクセルで開いたところ、 うちB601:B802に必要な情報が入っていました。 この情報を以下のような要領で入力したまとめxlsファイルを作りたいです。 A列 1行目 一つ目のCSVのファイル名(フォルダ内のCSVを名前順で並べたときに1番上のもの) 2行目~203行目 一つ目のCSVのファイルのB601:B802 B列 1行目 2つ目のCSVのファイル名(名前順で2番目のもの) 2行目~203行目 2つ目のCSVのファイルのB601:B802 (以後15~20ファイル分、O~T列まで。20ファイル以上にも対応できると嬉しいです。) このxlsファイルを最低でも20個作る予定です。 VBAマクロできっと出来るはずと思い、昨日9時間ほど調べたのですが、習得には至ってません。 例えば1つのCSVのB601:B802をコピーするマクロは作成できますが、 それをまとめファイルのA2に貼り付け、 まとめファイルのA1にCSVのファイル名を挿入し、 さらに同様の抽出をフォルダ内の別のファイルに連続して行い、 挿入部位が被らないようにまとめファイルB列以降に貼り付けさせることができません。 http://www.asahi-net.or.jp/~zn3y-ngi/YNxv252.htmlや http://oshiete1.goo.ne.jp/kotaeru.php3?q=359726や http://www.excel.studio-kazu.jp/kw/20080428180002.htmlなどを 応用できないか試してみましたが結局よくわからない状態です。 おそらくこちらの説明が不十分で答えにくい質問なのではないかと思いますが、 どなたかお答えいただければ幸いです。 また、勉強してから出直せ!的なことであれば勉強したいとおもいますので、 お勧めの書籍、サイトを教えていただければ幸いです。 どうかよろしくお願いいたします。

専門家に質問してみよう