*はじめにフォーマットをインポート
インデックスマッチでインポート
このVBAコードは、ExcelファイルやCSVファイルを指定されたフォルダから一括して読み込んで、指定された形式に変換して、同一のフォーマットで集計します。
1.指定されたファイルからデータを読み取り、指定された形式に変換します。
2.読み取ったデータを、同じ形式のExcelファイルにコピーします。
3.次のファイルに移動して、ステップ1および2を繰り返します。
4.最後に、集計されたExcelファイルを保存します。
最初に、新しいシートを追加し、このシートをws1変数に割り当てます。次に、ユーザーに対話的にファイルを選択するように求め、選択されたファイルがExcelファイルまたはCSVファイルである場合は、このファイルを開き、1つ目のシートをws1000変数に割り当てます。
次に、ws1000の1列目をテキスト形式に変換し、ws1にコピーします。その後、ディレクトリ内のファイルを処理するループが始まります。
このループでは、まずbuf変数にDir関数を使用してフォルダ内のファイル名を取得します。bufが空でない場合、bufに格納されたファイルを開き、ws2に割り当てます。
次に、ws2の1列目をテキスト形式に変換し、ws1の1列目にコピーします。さらに、元のシートから、社名と項目名のディクショナリを作成し、それぞれdicギョウコウモクとdicRetukoumokuに割り当てます。ここで、Scripting.Dictionaryオブジェクトを使用しています。
最後に、buf変数に再びDir関数を使用して、次のファイル名を取得し、ループを続行します。
Sub フォーマットインポート_フォルダの全て_エクセルファイルとCSVファイルを処理() '列行指定(インデックスマッチ)
Worksheets.Add(After:=ActiveSheet).Name = "import_"
'Worksheets.Add(After:=ActiveSheet).Name = ActiveSheet.Name & "_" & VBA.Format(Now(), "h時mm分ss秒")
'このファイル
Dim ws1 As Worksheet 'Set ws1 = ActiveSheet
Set ws1 = ThisWorkbook.Worksheets("import_")
'対象ファイル(フォーマットファイルをインポート)
Dim FName As String
Dim wb1000 As Workbook
Dim ws1000 As Worksheet
MsgBox "「ファイル」選択"
FName = Application.GetOpenFilename("Microsoft ExcelブックorCSV,*.*") ' "\*.*")
If FName <> "False" Then
Set wb1000 = Workbooks.Open(FName)
Set ws1000 = wb1000.Worksheets(1)
Else
MsgBox "File未指定 "
End
End If
'表示系列変換
ws1000.Activate
ws1000.Range("A2:A" & Cells(Rows.Count, "A").End(xlUp).Row).Select
Selection.TextToColumns Destination:=Range("A2"), DataType:=xlDelimited, FieldInfo:=Array(1, xlTextFormat)
Selection.NumberFormatLocal = "@"
'インポート
ws1000.Cells.Copy ThisWorkbook.Worksheets("import_").Range("A1")
'コピーモード解除
Application.CutCopyMode = False
'閉じる
wb1000.Close savechanges:=False
Set wb1000 = Nothing
Set ws1000 = Nothing
'-------------------------------------------------------------------------------------------------
'まとめたいデータの入っているディレクトリのパスを代入
Const path As String = "C:\Users\y1ban\OneDrive\デスクトップ\Sampleフォルダ\"
'ディレクトリ内の全てのファイル名を取得
Dim buf As String
buf = Dir(path & "\*.*")
'ループ処理--------------------------------------------------------------------------------------
Dim i As Long
Do While buf <> ""
i = i + 1
'相手シート
Dim wb2 As Workbook
Set wb2 = Workbooks.Open(path + buf)
Dim ws2 As Worksheet
Set ws2 = wb2.Worksheets(1)
'表示系列変換
ws2.Range("A2:A" & Cells(Rows.Count, "A").End(xlUp).Row).Select
Selection.TextToColumns Destination:=Range("A2"), DataType:=xlDelimited, FieldInfo:=Array(1, xlTextFormat) 'おかしい
Selection.NumberFormatLocal = "@"
ActiveCell.Select
ws2.Cells(1, 1) = ws1.Cells(1, 1).Value
'ディクショナリ作成-----------------
'Dictionaryオブジェクトの宣言
Dim dicGyoukoumoku As Object '元表の社名行番号ディクショナリ
Dim dicRetukoumoku As Object '元表の項目名列番号ディクショナリ
Set dicGyoukoumoku = CreateObject("Scripting.Dictionary")
Set dicRetukoumoku = CreateObject("Scripting.Dictionary")
Const ws2_KEY_CLM As Long = 1 '「元表」シートのキー列(社名列:C列)
Const ws2_KEY_ROW As Long = 1 '「元表」シートのキー行(項目見出し行:1行目)
Dim iRRow As Long '元表シートの読込行(ws2)
Dim iRCol As Long '元表シートの読込列(ws2)
'あいて表シート(2行目から最終行)から社名のディクショナリを作成
For iRRow = 2 To ws2.Cells(Rows.Count, 1).End(xlUp).Row
'For iRRow = 2 To ws2.Cells(2, ws2_KEY_CLM).End(xlDown).Row
DoEvents
'社名をキーとして行番号をディクショナリに保管(同じ社名が複数存在した場合、後勝ちで行番号が上書きされます)
dicGyoukoumoku(ws2.Cells(iRRow, "A").Value) = iRRow '(ws2)
Next
'あいて表シート(2列目から最終列)から項目名のディクショナリを作成
For iRCol = 2 To ws2.Cells(1, Columns.Count).End(xlToLeft).Column
'For iRCol = 2 To ws2.Cells(ws2_KEY_ROW, 1).End(xlToRight).Column
DoEvents
'項目名をキーとして列番号をディクショナリに保管
dicRetukoumoku(ws2.Cells(1, iRCol).Value) = iRCol
Next
'転記処理----------------------------
Const ws1_CLM As Long = 1 '「転記先」シートA列(社名列:C列)
Const ws1_ROW As Long = 1 '「転記先」シート1行目(項目見出し行:1行目)
Dim iWRow As Long '転記先シートの出力行(ws1)
Dim iWCol As Long '転記先シートの出力列(ws1)
'あいて転記先シート(5行目から最終行)の社名ループ
For iWRow = 2 To ws1.Cells(Rows.Count, 1).End(xlUp).Row '社名から元表の行番号を取得
DoEvents
If dicGyoukoumoku.Item(ws1.Cells(iWRow, ws1_CLM).Value) = "" Then '社名から行番号が取得できない場合は何もしない
Else
iRRow = dicGyoukoumoku.Item(ws1.Cells(iWRow, ws1_CLM).Value) '元表の行番号を取得
End If
'あいて転記先シートの項目ループ-------------
For iWCol = 1 To ws1.Cells(1, Columns.Count).End(xlToLeft).Column '項目名から元表の列番号を取得
DoEvents
If dicRetukoumoku.Item(ws1.Cells(ws1_ROW, iWCol).Value) = "" Then '項目名から列番号が取得できない場合は何もしない
Else
iRCol = dicRetukoumoku.Item(ws1.Cells(ws1_ROW, iWCol).Value) '元表の列番号を取得
ws1.Cells(iWRow, iWCol).Value = ws2.Cells(iRRow, iRCol).Value '「元表」シートの取得行・取得列のセルの値を、「転記先」シートの出力行・出力列に出力する
End If
Next iWCol
Next iWRow
ActiveWorkbook.Close savechanges:=False 'ActiveWorkbook.Close savechanges:=True
buf = Dir()
Loop '----------------------DO LOOP
ThisWorkbook.Activate
'ws1.Range("A1").Select
MsgBox "完了"
End Sub
解説
1行目:このマクロは「フォーマットインポート_フォルダの全て_エクセルファイルとCSVファイルを処理」という名前で定義されています。
2〜5行目:新しいワークシートを作成し、それを「import_」という名前にします。
7〜13行目:対象のファイルを選択します。ExcelブックまたはCSVファイルを選択できます。
14〜22行目:選択されたファイルからデータを読み取り、指定された形式に変換します。
23〜25行目:読み取ったデータを、同じ形式のExcelファイルにコピーします。
27〜34行目:指定されたディレクトリからファイルを取得し、各ファイルについて以下の処理を行います。
35〜38行目:ファイルを開き、ワークシートを設定します。
40〜47行目:読み取ったデータを指定された形式に変換します。
49行目:「元表」シートから、キー列(社名列:C列)およびキー行(項目見出し行:1行目)を設定します。
50〜53行目:元表シートの各行について、社名のディクショナリを作成します。
54〜57行目:元表シートの各列について、項目名のディクショナリを作成します。
コメント