• 締切済み

VBA 複数のファイルの特定の列だけ取得してマージ

お世話になっております。 VBAで、複数のCSVファイルの特定の列だけを抽出して別のCSVファイルにマージする方法を探しています。 例えば、マージフォルダに1000のCSVファイルがあります。 1000あるファイルのA列とC列だけを抽出して、 それを別の「マージ.CSV」というファイルにA列とB列にマージして一つにしたいのです。 1000のファイルにはA~Qまで値が入っていて、A~Q列の値全て取り込みマージするとデータが重くなってしまうのです。 Unionメソッドを仕様して列を選択するのかなと思うのですが。。。 現在、こちらのコードを参考にしています。 わかる方いましたらよろしくお願いいたします。 Sub csvmerge() wpath = Range("B3") wfile = Dir(wpath & "\") flag = 0 Do While wfile <> "" If InStr(wfile, ".csv") Then flag = flag + 1 If flag = 1 Then FileCopy wpath & "\" & wfile, ThisWorkbook.Path & "\output.csv" Open ThisWorkbook.Path & "\output.csv" For Output As #1 Close #1 End If Open ThisWorkbook.Path & "\output.csv" For Append As #1 Open wpath & "\" & wfile For Input As #2 Do Until EOF(2) Line Input #2, w_str Print #1, w_str Loop Close #2 Close #1 End If wfile = Dir() Loop MsgBox "マージ完了", vbInformation End Sub

みんなの回答

  • Prome_Lin
  • ベストアンサー率42% (201/470)
回答No.3

「VBScript」による回答ですので、「Windows限定」です。 このプログラムは、プログラムファイルの存在するフォルダ内のすべての「csv」ファイルの列「A」と列「C」のみを抽出し、同じフォルダ内に「Merge.csv」という結果ファイルを作成します。 以下のプログラムを、メモ帳またはテキストエディタに貼り付け、「~.vbs」という名前で保存します(保存する際は、必ず、「文字コード」を「Shift-JIS(ANSI)」で保存してください)。 「~」の部分は、何でもかまいませんが、「.vbs」の部分は、必ず、半角です。 できたプログラムファイル(「~.vbs」ファイル)を、これから処理したい「csv」ファイル群の存在するフォルダに放り込んで、ダブルクリック(「シングルクリック」→「Enter」の方が確実)するだけです。 実行すると、最初に「Start!」と表示しますので、「OK」を押して、スタートしてください。 また、最後に「Finished!」と表示しますので、「OK」を押して、終了してください。 注意事項 4行目、「m = "Shift-JIS" '"UTF-8" "Unicode"」で、「csv」ファイルの文字コードを指定しています。 今は、「Shift-JIS(ANSI)」ですが、ここを、「m = "UTF-8"」とすれば、「UTF-8(BOM付き)」に、「m = "Unicode"」とすれば、「UTF-16LE(BOM付き)」にそれぞれ対応できます(それ以外のプログラムを変更する必要はありません)。 なお、一応、ファイル名を使って、「小さい順」にソートしていますが、「Test_1.csv」、「Test_2.csv」、・・・「Test_10.csv」、「Test_11.csv」のような場合、思ったようにはソートされません。 すなわち、「Test_1.csv」、「Test_10.csv」、「Test_11.csv」、「Test_2.csv」となってしまいます。 「Test_0001.csv」のように、桁数が揃っていれば、もちろん問題なくソートされます。 Option Explicit Dim a, ai, ao, c, f, gf, m, i, j, so, x MsgBox("Start!") m = "Shift-JIS" '"UTF-8" "Unicode" Set so = CreateObject("Scripting.FileSystemObject") Set gf = so.GetFolder(so.GetParentFolderName(WScript.ScriptFullName)) c = - 1 For Each f In gf.Files If LCase(so.GetExtensionName(f)) = "csv" Then c = c + 1 ReDim Preserve n(c) n(c) = f.Name End If Next For i = 0 to c - 1 For j = i + 1 to c If n(i) > n(j) Then x = n(i) n(i) = n(j) n(j) = x End If Next Next Set ao = CreateObject("ADODB.Stream") ao.Type = 2 ao.Charset = m ao.Open For i = 0 to c Set ai = CreateObject("ADODB.Stream") ai.Type = 2 ai.Charset = m ai.Open ai.LoadFromFile gf & "\" & n(i) Do Until ai.EOS x = ai.ReadText(-2) a = Split(x, ",") ao.WriteText a(0) & "," & a(2), 1 Loop ai.Close Set ai = Nothing Next ao.SaveToFile gf & "\Merge.csv", 2 ao.Close Set ao = Nothing Set gf = Nothing Set so = Nothing MsgBox("Finished!") 説明が必要でしたら、言ってください。

  • kkkkkm
  • ベストアンサー率65% (1614/2452)
回答No.2

No1の補足です A列B列C列のデータにカンマが存在する場合は正しい結果になりません。 12,324みたいなデータがある場合などです。

  • kkkkkm
  • ベストアンサー率65% (1614/2452)
回答No.1

カンマ区切りのCSVだと考えた場合です。変更する部分だけ記載しますので部分変更して試してみてください。 FileCopy wpath & "\" & wfile, ThisWorkbook.Path & "\マージ.csv" Open ThisWorkbook.Path & "\マージ.csv" For Output As #1 Close #1 End If Open ThisWorkbook.Path & "\マージ.csv" For Append As #1 Open wpath & "\" & wfile For Input As #2 w_str2 = "" Do Until EOF(2) Line Input #2, w_str w_str2 = Split(w_str, ",")(0) w_str2 = w_str2 & "," & Split(w_str, ",")(2) Print #1, w_str2 Loop

関連するQ&A

  • Excel 2010 VBA:ファイル名を読み込む

    下は複数のcsvファイルを一つに合体するVBAです。これにシートの右端に読み取ったファイル名を追加するにはどうしたらよいでしょうか。 よろしくお願いします。 Sub macro1() Dim myPath As String Dim myFile As String Dim s As String myPath = ThisWorkbook.Path & "\" On Error Resume Next Kill myPath & "合体版.csv" On Error GoTo 0 myFile = Dir(myPath & "*.csv") If myFile = "" Then Exit Sub Open myPath & "合体版.csv" For Output As #1 Do Until myFile = "" Open myPath & myFile For Input As #2 Do Until EOF(2) Line Input #2, s Print #1, s Loop Close #2 myFile = Dir() Loop Close #1 End Sub

  • VBA:2つのCSVファイルを開きたいです。

    エクセル2010のVBAにてCSVファイルを開き結合させるプログラムを組もうとしているのですが、2つ目のCSVファイルを開こうとすると、何故かエラーが出てしまいます。 -------------------------------------------------------------------------------- 1つ目 Sub mobile_FileSearch(Path As String) 'test.csvのデータを検索して開く Dim FSO As Object, Folder As Variant, File As Variant Set FSO = CreateObject("Scripting.FileSystemObject") For Each Folder In FSO.GetFolder(Path).SubFolders Call mobile_FileSearch(Folder.Path) Next Folder For Each File In FSO.GetFolder(Path).Files If File.Name = "test.csv" Then Workbooks.Open ("test.csv") End If Next File End Sub ---------------------------------------------------------------------------- 2つ目 Sub local_FileSearch(Path As String) 'bbb.csvのデータを検索して開く Dim FSO As Object, Folder As Variant, File As Variant Set FSO = CreateObject("Scripting.FileSystemObject") For Each Folder In FSO.GetFolder(Path).SubFolders Call local_FileSearch(Folder.Path) Next Folder For Each File In FSO.GetFolder(Path).Files If File.Name = "bbb.csv" Then Workbooks.Open ("bbb.csv")'←ここでエラー End If Next File End Sub ------------------------------------------------------------------------ まったく同じプログラムで、csvファイル名だけ変えただけで実行時エラー1004が出てしまいます。 一体全体何が問題なのでしょうか?

  • ファイル名のわからない複数のファイルをひとつにまとめる

    エクセル2000で以下のマクロを作成したいです。 1.フォルダ内のCSVファイルを開き、中のデータをひとつにまとめる。 (フォルダ名とファイル名、ファイル数はその時によって変わってきます。ファイル数はだいたい10個くらいです。ひとつのデータは20列50行くらいで列の項目を基準にまとめたいです。) 2.列を1列目に挿入し、2列目と3列目のデータを1列目に統合する。 3.1列目のデータを使用し、重複を調べる。重複がある場合はどちらかひとつを削除する。(できれば4列目のデータを比較し数値が少ないほうを削除したいです。) まだ途中までですが、マクロ作成してみました。 わたしとしては、フォルダ内のCSVファイルを開いてセルA1からデータの入った範囲をコピーし、testエクセルファイルのアクティブセルに貼り付け ↓↓↓ 次のファイルのデータをその下に貼り付けたいのでtestファイルのデータが入ったセルの下を選択し、ファイルを開くへ繰り返し。 のつもりなのですが…、うまく作動しません。 マクロのテキストを片手にネットでも検索しながら作ったのですが、まだ記述の仕方などがわかってなくどこがおかしいのかもわかりません。 わかる方がいたらよろしくお願いします! ----------------------------------- Sub ファイルのデータを統合() Dim filename As String Dim openedbook As Workbook Dim isbookopen As Boolean Dim myworksheet As Worksheets Dim myrange As Range filename = Dir(ThisWorkbook.Path & "\*.csv") Do While filename <> "" isbookopen = False For Each openedbook In Workbooks If openedbook.Name = filename Then isbookopen = True Exit For End If Next Range("A1").CurrentRegion.Copy Destination:=Workbooks("test.xls").Worksheets("sheet1").ActiveCell Workbooks("test.xls").Worksheets("sheet1").Range("A1").End(xlDown).Offset(1).Select If isbookopen = False Then Workbooks.Open (ThisWorkbook.Path & "\" & filename) End If filename = Dir() Loop End Sub

  • 【VBA】【複数ファイルの読み込み】

    23歳OLです。 会社でマクロを組むことになったのですが、 どうしてもわからないところがあったので質問させていただきます。 ご回答いただけると嬉しいです。。 ============================ ▼問題点 問題(1) Line input にしているのですが、 一行ずつ入力されず、読み込んだファイルが一つのセルの中にすべて入ってしまいます。 問題(2) 複数ファイルを1、2、3、と読み込んだ際A列,B列,C列と違う列に 入って行ってほしいのですが現在同じ列に入ってしまいます。 どうやったら改善できるのでしょうか? 以上です。 よろしくお願いします。 ※読み込みたいファイルはlogファイルとvファイルです。※ ==========該当マクロ============== ■VBAコード Sub ReadMultiFiles() ' [[ 変数定義 ]] Dim varFileName As Variant Dim VWorkSheet As Worksheet Dim NewWorkSheet As Worksheet Dim SheetName As String Dim Filename As Variant ' [[ ファイルパスからファイル名を取得 ]] SheetName = Dir(ThisWorkbook.FullName) ' [[ ファイル名で新しいシート作成 ]] Set NewWorkSheet = CreateWorkSheet(SheetName) ' [[ 複数ファイルパス名を取得 ]] varFileName = Application.GetOpenFilename(FileFilter:="(*.*),*.*", _ Title:="CSVファイルの選択", MultiSelect:=True) ' [[ ファイルパス取得できなかったら ]] If IsArray(varFileName) = False Then Exit Sub End If ' [[ ファイルパス取得できたら ]] For Each Filename In varFileName   ' [[ CSVファイルを開く ]]   Dim buf As String, n As Long   Open Filename For Input As #1   Do Until EOF(1)   Line Input #1, buf   n = n + 1   Cells(n, 1) = buf   Loop      ' [[ CSVファイルを閉じる(保存無し) ]]   Close #1 Next Filename End Sub ' [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ' [[ ]] ' [[ ワークシート名を指定したワークシートの作成 ]] ' [[ ]] ' [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] Function CreateWorkSheet(WorkSheetName As String) As Worksheet ' 変数定義 Dim NewWorkSheet As Worksheet Dim iCheckSameName As Integer ' ワークシートの作成 ' ※一番最後に挿入 Set NewWorkSheet = Worksheets.Add(After:=Worksheets(Worksheets.Count)) ' 同じ名前ワークシートが無いか確認 iCheckSameName = 0 For Each WS In Sheets If WS.Name = WorkSheetName Then MsgBox "ワークシート名:" + WorkSheetName + " この名前は既に使われています。" iCheckSameName = 1 End If Next '同じ名前のワークシートがなければ If iCheckSameName = 0 Then NewWorkSheet.Name = WorkSheetName Set CreateWorkSheet = NewWorkSheet End If End Function ==========================

  • VBAで、ExcelシートにCSVファイルのデータを取り込みたいのです

    VBAで、ExcelシートにCSVファイルのデータを取り込みたいのですが、 1行目しか取り込めません。 取り込む項目数は32個です。 以下のコードでは、Excelシートの1行目のみ取り込みができますが、 1行目32列目のセルには、2行目のA列に表示されるべきデータも表示されます。 2行目以下は取り込みできていません。 Sub CSV取込() Dim OpenFileName As String Dim MyString As String Dim MyVar As Variant Dim i As Long, j As Long OpenFileName = Application.GetOpenFilename("CSVファイル,*.csv") If OpenFileName = "False" Then MsgBox "キャンセルされました。" Else Open OpenFileName For Input Access Read As #1 i = 1 While Not EOF(1) Line Input #1, MyString MyVar = Split(MyString, ",") If MyVar(0) <> "" Then For j = 0 To 31 ThisWorkbook.ActiveSheet.Cells(i + 10, j + 1) = MyVar(j) Next j i = i + 1 End If Wend Close #1 End If End Sub おそらく、改行が判別できないためかと思いますが、 どこが間違っているのかがわかりません。 アドバイスをよろしくお願いします。

  • accessVBAで特定の文字列を削除

    以前頼んで作ってもらったVBAを少し改造しようと思っていますが、上手くいきませんので質問します。よろしくお願いします。 csvファイルを分割するVBAを作ってもらいました。 1001,a12345678 1001,b15467863546789 1001,b25463254875698 1001,c23564879 1005,a23456753 1005,b25647565823653 1005,c26546875 1007,a23456789 1007,b23659856325632 1007,b46785215468523 1007,c12546873 というcsvファイルを 1001.csvというファイルで中身は 1001,a12345678 1001,b15467863546789 1001,b25463254875698 1001,c23564879 と 1005.csvというファイルで中身は、 1005,a23456753 1005,b25647565823653 1005,c26546875 と 1007.csvというファイルで中身は、 1007,a23456789 1007,b23659856325632 1007,b46785215468523 1007,c12546873 の3つのcsvファイルに分けます。 今回は仕様変更で、 1001.csvというファイルで中身は a12345678 b15467863546789 b25463254875698 c23564879 と 1005.csvというファイルで中身は、 a23456753 b25647565823653 c26546875 と 1007.csvというファイルで中身は、 a23456789 b23659856325632 b46785215468523 c12546873 の3つに分けなくてはならなくなりました。 今使っているVBAは Private Sub DOQUERY_Click() Dim IN_FNO As Integer Dim OUT_FNO As Integer Dim BREAK_OLD As String Dim BREAK_NEW As String Dim HEADLINE As String Dim TEXTLINE As String Dim ARY() As String Dim OUTNAME As String Dim ARYNAME() As String Dim CNT As Integer Dim MSG As String '============================================ On Error GoTo err If IsNull(InputFile) Or IsNull(OutputFile) Then Exit Sub End If If InputFile = "" Or OutputFile = "" Then MsgBox "ファイル名が正しく指定されていません。", vbCritical Exit Sub End If ラベル5.Visible = True DoEvents '読込みCSV OPEN IN_FNO = FreeFile Open InputFile For Input As #IN_FNO '見出し読込み Line Input #IN_FNO, HEADLINE$ '1レコード目読込み Line Input #IN_FNO, TEXTLINE$ '発注番号 ARY() = Split(TEXTLINE$, ",") BREAK_NEW = Replace(ARY(0), """", "") BREAK_OLD = BREAK_NEW '出力CSVファイル名作成 OUTNAME = OutputFile & BREAK_NEW & ".csv" '出力CSVファイル名保存 CNT = 1 ReDim Preserve ARYNAME(CNT) ARYNAME(CNT) = OUTNAME '出力CSV OPEN OUT_FNO = FreeFile Open OUTNAME For Output As #OUT_FNO '見出し書込み Print #IN_FNO, HEADLINE$ '1レコード目書込み Print #IN_FNO, TEXTLINE$ Do While Not EOF(IN_FNO) '次レコード目読込み Line Input #IN_FNO, TEXTLINE$ '発注番号 ARY() = Split(TEXTLINE$, ",") BREAK_NEW = Replace(ARY(0), """", "") '発注番号が変わったとき新しいCSVを開く If BREAK_OLD <> BREAK_NEW Then CNT = CNT + 1 BREAK_OLD = BREAK_NEW '旧書込みCSVをクローズ Close #OUT_FNO '新出力CSVファイル名作成 OUTNAME = OutputFile & BREAK_NEW & ".csv" '新出力CSVファイル名保存 ReDim Preserve ARYNAME(CNT) ARYNAME(CNT) = OUTNAME '新出力CSV OPEN OUT_FNO = FreeFile Open OUTNAME For Output As #OUT_FNO End If '次レコード書込み Print #OUT_FNO, TEXTLINE$ Loop '出力CSVクローズ Close #OUT_FNO '入力CSVクローズ Close #IN_FNO '出力したCSV名称一覧 Dim I As Integer For I = 1 To UBound(ARYNAME()) MSG = MSG & ARYNAME(I) & vbCrLf Next MsgBox CNT & "個のファイルに分割しました。" & vbCrLf + vbCrLf & MSG, vbInformation, "CSV分割" ラベル5.Visible = False Exit Sub err: MsgBox err.Description, vbCritical, "エラー" ラベル5.Visible = False End Sub です。 ファイル名がBREAK_NEWでそれを消せればいいと思うのですが・・・ 以上長くなりましたが、よろしくお願いします。

  • VBAフォルダ内ファイル入出力について

    Accessで特定のフォルダ内にあるcsvファイルを全て読み込み、別のcsvファイルへ 出力するという処理を作りたいのですが、最近からVBAを始めたばかりで どうすればよいか分かりません。 とりあえず、特定のファイルをひとつ読み込み、別ファイルへ出力することはできました。 Option Compare Database Private Sub Button_Click() Dim No As Integer Dim buf No = FreeFile Open "C:\test1.csv" For Input As #1 Open "C:\test2.csv" For Output As #2 Do Until EOF(No) Line Input #1, buf Print #2, buf Loop MsgBox "処理終了" Close #1 Close #2 End Sub 読み込み対象を「特定のフォルダ内のファイル全て」 にする方法が知りたいです。 ちなみに出力先のファイルはひとつにまとめてもそれぞれ別のファイルに 出力でもどちらでも構いません。 できれば両方教えていただければ有難いです。 宜しくお願いします。

  • 【VBA】ExcelマクロでCSVファイルに保存したデータが""で囲まれてしまう

    添付図のような、Excel2003で作成した表内のデータを CSVで保存するマクロを作成したのですが、 図のように、CSVファイルに「""」で値が囲まれた状態で、 保存されてしまいます。 下記にマクロを記載しますので、 どうすれば文字列が「""」で囲まれずに、 カンマ区切りだけのデータで出力されるのか、 ご存知の方おられましたら、ご教示お願い致します。 Sub csv保存() Dim フォルダ名 As String Dim パス名 As String Dim ファイル名 As String Dim データ As Variant Dim 行数 As Long, 列数 As Integer Dim i As Integer, j As Long, k As Long ファイル名 = "test.csv" フォルダ名 = "csv" パス名 = ActiveWorkbook.Path & "\" & _ フォルダ名 'csvフォルダが存在しなければ作成する If Dir(パス名, vbDirectory) = "" Then MkDir パス名 End If ChDir パス名 Open ファイル名 For Output As #1 For i = 1 To Worksheets.Count Worksheets(i).Activate Worksheets(i).Cells(1, 1).Select ActiveCell.CurrentRegion.Select 行数 = Selection.Rows.Count 列数 = Selection.Columns.Count For j = 1 To 行数 For k = 1 To 列数 - 1 データ = Selection.Cells(j, k) _ .Value Write #1, データ; Next k Write #1, Selection.Cells(j, 列数) _ .Value Next j Next i Close #1 End Sub

  • VBAよりCSVファイルの任意の行を取得

    お世話になります。 Access2010 VBAよりCSVファイルの2行目の文字列を取得したいのですが、とりあえず下記で取得することができました。 path = CurrentProject.path cnt = 1 Open path & "\test.csv" For Input As #1 Do Until cnt > 2   Line Input #1, buf   If cnt = 2 Then     MsgBox buf   End If   cnt = cnt + 1 Loop Close #1 例えば、 1行目 xxxxx 2行目 フィールド1,フィールド2,フィールド3,・・・ 3行目 データ1,データ2,データ3・・・ という内容のCSVがあり、上記のVBAを実行すると、2行目の『フィールド1,フィールド2,フィールド3,・・・』を表示できます。 で、実際のCSVファイルは数十万行あるのですが、そのファイルを指定し上記VBAを実行すると、Line Input #1, bufの箇所で「実行時エラー14 文字列領域が不足しています。」と表示されてしまいます。 何かよい方法はございますでしょうか。 なお、当該Accessはユーザーへ配布するものであり、Runtime環境で実行します。 よって、CreateObjectは使えない状況です。 勉強不足で申し訳ございませんが、ご教授の程よろしくお願い致します。

  • 複数のCSVを1つのファイルにまとめる

    リモートからダウンロードしたCSVファイルをひとつにまとめる処理をしています。 ダウンロードするリストファイルとCSVファイルのダウンロードはできたのですが、最後にダウンロードしてきたCSVファイルをひとつにまとめるところがうまくいきません。 こちらの過去ログから下記記述してみたのですが、うまくいきません。 if(open(OUT,">$path/$year$mon$mday$csv")){      for my $fname (sort @dirs){        if(open(IN,"$path/$fname")){          my @lines = <IN>;          print OUT @lines;          close(IN);        }     }     close(OUT);   } for my $fname (sort @dirs){の記述で、Unrecognized characterといったエラーが出てうまくいきません。 項目の設定に誤りがあるのでしょうか?perl初心者でよくわかりません。 $fnameや@dirsはどのように設定すればいいのでしょうか?

    • ベストアンサー
    • Perl

専門家に質問してみよう