同樣是來自網友的提問:
如何用Excel VBA將資料夾內的特定檔案移動到特定資料夾
我的思路是
1.先取得資料夾內的檔案
這有2種方式
1種是直接打在試算表內
再用程式去讀取儲存格
但是檔案多就沒效率
所以第2種是用FileSystemObject 物件建立Folder物件
再來取得資料夾內的所有 File 物件
可以參考微軟的線上說明
1 2 3 4 5 6 7 8 9 10 11 |
Sub ShowFileList(folderspec) Dim fs, f, f1, fc, s Set fs = CreateObject("Scripting.FileSystemObject") Set f = fs.GetFolder(folderspec) Set fc = f.Files For Each f1 in fc s = s & f1.name s = s & vbCrLf Next MsgBox s End Sub |
2.找出特定的檔案
由於不是每個檔案都要移動,而是特定副檔名的檔案
因此,可以用 File 物件的name屬性來取得檔案名稱
再用Split() 以 . 來分割完整檔案名稱
這樣得到的陣列的第1個值就是檔案名稱
第2個值則是副檔名
ps.用File 物件的type屬性,回傳的是Microsoft Excel 工作表
再用判斷式,符合的才進行操作
ps.如果不是所有相同副檔名都要移動??
如果檔案名稱是有規則的就可以依照規則來取出檔案
不然最好還是事前排除不要的檔案
3.判斷式:符合的檔案移動到特定資料夾
特定的資料夾名稱可以自訂
例如:根據檔案名稱
ps.如果只是要部份的檔案名稱
假如名稱是有規則的,例如:123-XXX .xlsx 456-XXX.xlsx
這樣就可以用Split() 來分割檔案名稱,取出要的部分再組成
如果沒有規則的話,就自己找規則…
4.之後再用一個判斷式:資料夾是否存在
如果資料夾已經存在就執行移動檔案的指令
假如不存在,則先建立資料夾,再執行移動檔案的指令
這邊移動檔案的指令式利用shell函數執行CMD(也就是DOS)的move指令
move [{/y|-y}] [<source>] [<target>]
Chr(32)是為了產生空格
完整程式碼如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
Public Sub 移動特定檔案到特定資料夾2() Dim oFSO As Object Dim oFolder As Object Dim oFile As Object Dim xlsx As Variant Dim filePath As String Dim oldPath As String Dim newPath As String filePath = ThisWorkbook.Path Debug.Print filePath ' 建立 FileSystemObject 物件 Set oFSO = CreateObject("Scripting.FileSystemObject") ' 建立目錄物件 Set oFolder = oFSO.GetFolder(filePath & "\") ' 以迴圈列出所有檔案 For Each oFile In oFolder.Files xlsx = Split(oFile.Name, ".") '用.來分割完整檔案名稱 Debug.Print xlsx(1) 'xlsx(0)檔案名稱 xlsx(1)副檔名 If xlsx(1) = "xlsx" Then '只取副檔名為xlsx的檔案 oldPath = oFile.Path newPath = ThisWorkbook.Path & "\" & xlsx(0) & "-資料夾" '自訂目標資料夾路徑 If Dir(newPath, vbDirectory) <> "" Then '判斷資料夾是否存在 Debug.Print "cmd.exe /c move /Y " & Chr(32) & oldPath & Chr(32) & newPath Shell "cmd.exe /c move /Y " & Chr(32) & oldPath & Chr(32) & newPath '執行cmd的move Else MkDir newPath '不存在則建立 Debug.Print "cmd.exe /c move /Y " & Chr(32) & oldPath & Chr(32) & newPath Shell "cmd.exe /c move /Y " & Chr(32) & oldPath & Chr(32) & newPath '執行cmd的move End If End If Next oFile End Sub |
後記
看程序名稱可以知道還有第1個版本
在第1個版本中,我是先將讀取到的檔案資料
分別寫入試算表中
再用迴圈分別讀取儲存格來執行shell函數
好處是可以判斷資料是否正確
缺點就是多餘了點
不過這是順著原本的思路一路修改來的
仔細看程式碼
其實用了兩種方式來操作檔案系統
1種是FileSystemObject
另1種是shell執行cmd指令
而FileSystemObject本身就有移動檔案的MoveFile方法
因此程式碼可以如下修改
If xlsx(1) = "xlsx" Then '只取副檔名為xlsx的檔案 oldPath = oFile.Path newPath = ThisWorkbook.Path & "\" & xlsx(0) & "-資料夾" '自訂目標資料夾路徑 If Dir(newPath, vbDirectory) <> "" Then '判斷資料夾是否存在 'Debug.Print "cmd.exe /c move /Y " & Chr(32) & oldPath & Chr(32) & newPath 'Shell "cmd.exe /c move /Y " & Chr(32) & oldPath & Chr(32) & newPath '執行cmd的move oFSO.MoveFile oldPath, newPath & "\" Else MkDir newPath '不存在則建立 'Debug.Print "cmd.exe /c move /Y " & Chr(32) & oldPath & Chr(32) & newPath 'Shell "cmd.exe /c move /Y " & Chr(32) & oldPath & Chr(32) & newPath '執行cmd的move oFSO.MoveFile oldPath, newPath & "\" End If End If
當然,也可以都用shell+cmd的方式
只是會比較麻煩,至少我目前想到的方法…