VBA100本ノック 89本目:2つのフォルダの統合
2つのフォルダをサブフォルダも含めて統合する問題です。
同一フォルダに同じファイル名が存在する場合は更新日時のより新しいファイルを採用します。
ツイートでの見やすさを考慮して、ブック・シート指定等を適宜省略しています。
出題
全サブフォルダの全ファイルを対象としてください。
同一フォルダに同一ファイル名となる場合は、より更新日時の新しいファイルを採用してください。
同一更新日時の場合はどちらでも良い。
※パスは任意
VBA作成タイム
この下に頂いた回答へのリンクと解説を掲載しています。
途中まででも良いので、できるだけ自分でVBAを書いてみましょう。
他の人の回答および解説を見て、書いたVBAを見直してみましょう。
頂いた回答
解説
フォルダ、ファイル、再帰、これらの復習問題です。
最初のフォルダ「A」はフォルダごとコピーしています。
フォルダ「B」コピー時にファイルが既に存在していた場合に更新日付を確認してからコピーしています。
Sub VBA100_89_01()
Dim sPathA As String: sPathA = ThisWorkbook.Path & "\A"
Dim sPathB As String: sPathB = ThisWorkbook.Path & "\B"
Dim sPathC As String: sPathC = ThisWorkbook.Path & "\C"
Dim fso As New FileSystemObject
If fso.FolderExists(sPathC) Then Call fso.DeleteFolder(sPathC, True)
Call fso.CopyFolder(sPathA, sPathC, True)
Call copyFile(fso, fso.GetFolder(sPathB), sPathB, sPathC)
Set fso = Nothing
End Sub
Sub copyFile(ByVal fso As FileSystemObject, ByVal fromFolder As Folder, ByRef fromRoot As String, ByRef toRoot As String)
Dim sToPath As String
sToPath = repFolderName(fromFolder.Path, fromRoot, toRoot)
If Not fso.FolderExists(sToPath) Then
Call fso.CopyFolder(fromFolder, sToPath, True)
Exit Sub
End If
Dim oFile As File, sFilePath As String
For Each oFile In fromFolder.Files
sFilePath = repFolderName(oFile.Path, fromRoot, toRoot)
If fso.FileExists(sFilePath) Then
If oFile.DateLastModified > fso.GetFile(sFilePath).DateLastModified Then
Call fso.copyFile(oFile.Path, sFilePath, True)
End If
Else
Call fso.copyFile(oFile.Path, sFilePath, True)
End If
Next
Dim oFolder As Folder
For Each oFolder In fromFolder.SubFolders
Call copyFile(fso, oFolder, fromRoot, toRoot)
Next
End Sub
Function repFolderName(ByVal sFromFolder As String, ByRef sFromFolderR As String, ByRef sRootToR As String) As String
repFolderName = sRootToR & Mid(sFromFolder, Len(sFromFolderR) + 1)
End Function
この処理内容は、DOSコマンドのxcopyで/d指定した場合と同じです。
そこで、WshShellでxcopyを実行するサンプルVBAを記事補足に掲載しました。
補足
xcopy /d /i /e /y "元フォルダ" "先フォルダ"
これを「A」「B」それぞれについて行った結果と同じになります。
ExecまたはRunでコマンドを実行できます。
以下では2通りを紹介しておきます。
「Windows Script Host Object Model」
Dim wsh As New IWshRuntimeLibrary.WshShell
Dim wExec As WshExec
Dim wsh As Object: Set wsh = CreateObject("Wscript.Shell")
Dim wExec As Object
Sub VBA100_88_02()
Dim sPathA As String: sPathA = ThisWorkbook.Path & "\A"
Dim sPathB As String: sPathB = ThisWorkbook.Path & "\B"
Dim sPathC As String: sPathC = ThisWorkbook.Path & "\C"
Dim fso As New FileSystemObject
If fso.FolderExists(sPathC) Then Call fso.DeleteFolder(sPathC, True)
Set fso = Nothing
Dim sLogFile As String
sLogFile = ThisWorkbook.Path & "\VBA100_88_" & Format(Now(), "yyyymmddhhmmss") & ".log"
Call execXcopy(sPathA, sPathC, sLogFile)
Call execXcopy(sPathB, sPathC, sLogFile)
ThisWorkbook.FollowHyperlink sLogFile
End Sub
Sub execXcopy(ByVal fromPath As String, ByVal toPath As String, ByVal aLogFile As String)
Dim wsh As New IWshRuntimeLibrary.WshShell
Dim wExec As WshExec
Dim sCmd As String
sCmd = "xcopy /d /i /e /y """ & fromPath & """ """ & toPath & "\"" >> """ & aLogFile & """"
Set wExec = wsh.Exec("%ComSpec% /c " & sCmd)
Do While wExec.Status = 0
DoEvents
Loop
Set wsh = Nothing
End Sub
DOS窓が一瞬表示されます。
戻り値のオブジェクトを使う事で、標準出力も取得できます。
詳細は以下のMS公式ページを参照してください。
WshScriptExec オブジェクト
StdOut プロパティ (WshScriptExec)
Sub VBA100_88_03()
Dim sPathA As String: sPathA = ThisWorkbook.Path & "\A 1"
Dim sPathB As String: sPathB = ThisWorkbook.Path & "\B 2"
Dim sPathC As String: sPathC = ThisWorkbook.Path & "\C 3"
Dim fso As New FileSystemObject
If fso.FolderExists(sPathC) Then Call fso.DeleteFolder(sPathC, True)
Set fso = Nothing
Dim sLogFile As String
sLogFile = ThisWorkbook.Path & "\VBA100_88_" & Format(Now(), "yyyymmddhhmmss") & ".log"
Call runXcopy(sPathA, sPathC, sLogFile)
Call runXcopy(sPathB, sPathC, sLogFile)
ThisWorkbook.FollowHyperlink sLogFile
End Sub
Sub runXcopy(ByVal fromPath As String, ByVal toPath As String, ByVal aLogFile As String)
Dim wsh As New IWshRuntimeLibrary.WshShell
Dim sCmd As String
sCmd = "xcopy /d /i /e /y """ & fromPath & """ """ & toPath & "\"" >> """ & aLogFile & """"
Call wsh.Run("%ComSpec% /c " & sCmd, 0, True)
Set wsh = Nothing
End Sub
WshShellオブジェクト.Run(strCommand, [intWindowStyle], [bWaitOnReturn])
object | WshShell オブジェクトです。 | ||||||||||||||||||||||||
strCommand | 実行するコマンド ラインを示す文字列値です。 この引数には、実行可能ファイルに渡すべきパラメータをすべて含める必要があります。 |
||||||||||||||||||||||||
intWindowStyle | 省略可能です。 プログラムのウィンドウの外観を示す整数値です。
|
||||||||||||||||||||||||
bWaitOnReturn | 省略可能です。 スクリプト内の次のステートメントに進まずにプログラムの実行が終了するまでスクリプトを待機させるかどうかを示すブール値です。 TRUE を指定すると、プログラムの実行が終了するまでスクリプトの実行は中断され、Runメソッドはアプリケーションから返される任意のエラー コードを返します。 bWaitOnReturnにFALSE を指定すると、プログラムが開始するとRunメソッドは即座に復帰して自動的に 0 を返します。 |
詳細は以下のMS公式ページを参照してください。
WshShell オブジェクトのプロパティとメソッド
Run メソッド
サイト内関連ページ
同じテーマ「VBA100本ノック」の記事
86本目:全シートの総当たり表を作成
87本目:数式のシート間の依存関係
88本目:クロスABC分析作成
89本目:2つのフォルダの統合
90本目:セルに重なっている画像の削除
91本目:時間計算(残業時間の月間合計)
92本目:セルの色を16進で返す関数
93本目:複数ブックを連結して再分割
94本目:表範囲からHTMLのtableタグを作成
95本目:図形のテキストを検索するフォーム作成
96本目:Accessデータを取得(マスタ結合&抽出)
新着記事NEW ・・・新着記事一覧を見る
第5章:AI×VBAでつまづかない!トラブルシューティングとAIとの付き合い方
|生成AI活用研究(2025-05-20)
第4章:【事例で学ぶ】AIとVBAでExcel作業を劇的に効率化する!
|生成AI活用研究(2025-05-20)
第3章:AIを「自分だけのVBA先生」にする!質問・相談の超実践テクニック|生成AI活用研究(2025-05-19)
第2章 VBAって怖くない!Excelを「言葉で動かす」(超入門)|生成AI活用研究(2025-05-18)
第1章:AIって一体何?あなたのExcel作業をどう変える?(AI超基本)|生成AI活用研究(2025-05-18)
AI時代のExcel革命:AI×VBAで“書かない自動化”超入門|生成AI活用研究(2025-05-17)
Geminiと100本ノック 23本目:シート構成の一致確認|生成AI活用研究(5月16日)
AIが問う出版の未来は淘汰か進化か:AIと書籍の共存の道とは|生成AI活用研究(2025-05-16)
Geminiと100本ノック 22本目:FizzBuzz発展問題|生成AI活用研究(5月15日)
すぐに使える!生成AI プロンプト作成 実践ガイド|生成AI活用研究(2025-05-15)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
5.ひらがな⇔カタカナの変換|エクセル基本操作
6.RangeとCellsの使い方|VBA入門
7.メッセージボックス(MsgBox関数)|VBA入門
8.セルのクリア(Clear,ClearContents)|VBA入門
9.FILTER関数(範囲をフィルター処理)|エクセル入門
10.条件分岐(Select Case)|VBA入門
- ホーム
- マクロVBA入門編
- VBA100本ノック
- 89本目:2つのフォルダの統合
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。