Nhờ viết Code Copy toàn bộ các file excel từ 1 folder vào Folder khác. (2 người xem)

  • Thread starter Thread starter LinDan
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

LinDan

Thành viên tiêu biểu
Tham gia
8/2/12
Bài viết
412
Được thích
111
Tôi có 1 Folder trong đó chứa rất nhiều folder con, trong folder còn lại chưa rất nhiều loại khác nhau (.doc, xls, flv...), giờ tôi chỉ muốn Copy (lọc) tất cả các file excel (đuôi xls, xlsx) ra thì phải làm thế nào, nhờ các thày chỉ giúp cho Code thực hiện
 
Bạn sử dụng code này xem sao nhé. Giả sử thư mục đích là D:\Test
Lưu ý code chỉ chạy trong excel 2003, và nếu file nào đặt tên tiếng viết có dấu cũng không copy được
PHP:
Sub Copyfile()
Application.ScreenUpdating = 0
Dim i
Dim FN As String, sFN As String
    With Application.FileSearch
        .SearchSubFolders = True
        .LookIn = ThisWorkbook.Path
        .filename = "*.xls;*.xlsx"
        If .Execute() = 0 Then
            End
        ElseIf .Execute() > 0 Then
            For i = 1 To .FoundFiles.Count
                sFN = .FoundFiles(i)
                FN = Right(sFN, Len(sFN) - InStrRev(sFN, "\"))
                If FN <> ThisWorkbook.Name Then
                    FileCopy sFN, "d:\test\" & FN
                End If
            Next
        End If
    End With
Application.ScreenUpdating = 1
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi có 1 Folder trong đó chứa rất nhiều folder con, trong folder còn lại chưa rất nhiều loại khác nhau (.doc, xls, flv...), giờ tôi chỉ muốn Copy (lọc) tất cả các file excel (đuôi xls, xlsx) ra thì phải làm thế nào, nhờ các thày chỉ giúp cho Code thực hiện

Bạn đọc và tải File tại bài này xem có đúng ý bạn không (lấy tên file trong Folder bằng tiếng Việt, dung lượng File, phân loại File, ngày tạo, và cuối cùng là 1 Link để mở File).
http://www.giaiphapexcel.com/forum/...-lấy-tên-tất-cả-các-file-trong-1-folder/page2
 
Upvote 0
Đây là 1 cách tìm files để xử lý của anh NDU rất hay, up lên để các bạn tham khảo.
Trong bài này mình đặt tên thư mục cần copy files tại ô D1, có thể điều chỉnh tùy ý
 

File đính kèm

Upvote 0
Đây là 1 cách tìm files để xử lý của anh NDU rất hay, up lên để các bạn tham khảo.
Trong bài này mình đặt tên thư mục cần copy files tại ô D1, có thể điều chỉnh tùy ý

Cũng tương tự như bài đầu của bạn. Tức sẽ bị mất tất cả các tập tin có tên tiếng Việt và tất cả các tập tin (tiếng Việt hay không) trong thư mục tên tiếng Việt. Vì tên các đường dẫn trong mảng trả về không đúng nữa nên FileCopy không thành công
 
Upvote 0
Um mình cũng biết vậy nhưng khả năng chỉ có nhiêu đó nên chia sẽ bi nhiêu đó thôi. Có còn hơn không mà. Vậy theo bạn thì nên thêm bớt hay thay code nào để xử lý vấn đề trên.
 
Upvote 0
Đây là 1 cách tìm files để xử lý của anh NDU rất hay, up lên để các bạn tham khảo.
Trong bài này mình đặt tên thư mục cần copy files tại ô D1, có thể điều chỉnh tùy ý
Coi chừng copy vào chung 1 thư mục sẽ có trường hợp file bị trùng tên nha (tên trùng nằm riêng không sao, cho chung lại coi chừng cái này "đè" cái kia)
 
Upvote 0
Um mình cũng biết vậy nhưng khả năng chỉ có nhiêu đó nên chia sẽ bi nhiêu đó thôi. Có còn hơn không mà. Vậy theo bạn thì nên thêm bớt hay thay code nào để xử lý vấn đề trên.

code của bạn ndu đẹp rồi nên không có chuyện "thay code" ở đây. Ta chỉ cần trang điểm chút chút cho nó lộng lẫy hơn, tức hỗ trợ tiếng Việt. Ai thích tên thư mục, tên tập tin bằng tiếng Việt xin cứ mạnh dạn
Mã:
Function GetListFile(ByVal Folder As String, ByVal Search As String, ByVal InSub As Boolean)
  Dim sComm As String, tmpFile
  On Error GoTo ExitSub
  If Right(Folder, 1) <> "\" Then Folder = Folder & "\"
  Folder = """" & Folder & """"
  With CreateObject("Scripting.FileSystemObject")
    tmpFile = .GetTempName
    sComm = "DIR " & Folder & "*" & Search & "* /ON /B /A-D " & IIf(InSub, "/S", " ") & " >" & tmpFile
    CreateObject("Wscript.Shell").Run "cmd /c " & sComm, 0, True
    GetListFile = Split(.OpenTextFile(tmpFile, 1).ReadAll, vbCrLf)
  End With
  Kill tmpFile
ExitSub:
End Function

[COLOR=#0000ff]Ta sửa thành[/COLOR]

Function GetListFile(ByVal Folder As String, ByVal Search As String, ByVal InSub As Boolean)
    Dim sComm As String, tmpFile, text As String, m() As Byte
    On Error GoTo ExitSub
    If Right(Folder, 1) <> "\" Then Folder = Folder & "\"
    Folder = """" & Folder & """"
    With CreateObject("Scripting.FileSystemObject")
        tmpFile = .GetTempName
        sComm = "DIR " & Folder & "*" & Search & "* /ON /B /A-D " & IIf(InSub, "/S", " ") & " > " & tmpFile
        CreateObject("Wscript.Shell").Run "cmd [COLOR=#ff0000]/U[/COLOR] /c " & sComm, 0, True
        
        [COLOR=#ff0000]Open tmpFile For Binary As #1
        ReDim m(LOF(1))
        Get #1, , m
        Close #1
[/COLOR]  
        [COLOR=#ff0000]text = m
[/COLOR]  GetListFile = Split(text, vbCrLf)
    End With
    Kill tmpFile
ExitSub:
End Function

Và đây nữa

Mã:
Sub Get_Files()
Application.ScreenUpdating = False
On Error Resume Next
Dim arr, i, filename
arr = GetListFile(ThisWorkbook.Path, "*.xls;*xlxs", True)
For i = 0 To UBound(arr)
    filename = arr(i)
    filename = Right(filename, Len(filename) - InStrRev(filename, "\"))
    FileCopy arr(i), [D1] & "\" & filename
Next
[a1].Resize(i - 1, 1) = Application.Transpose(arr)
Application.ScreenUpdating = True
End Sub

[COLOR=#0000ff]Ta sửa thành[/COLOR]

Sub Get_Files()
    Application.ScreenUpdating = False
    On Error Resume Next
    Dim Arr, i, dest As String, filename As String, fso As Object
    Arr = GetListFile(ThisWorkbook.Path, "*.xls;*xlxs", True)
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    For i = 0 To UBound(Arr)
        filename = Arr(i)
        dest = [D1] & "\" & Right(filename, Len(filename) - InStrRev(filename, "\"))
        [COLOR=#ff0000]fso.CopyFile [/COLOR]filename, dest
    Next
    [a1].Resize(i - 1, 1) = Application.Transpose(Arr)
    Application.ScreenUpdating = True
    
    Set fso = Nothing
End Sub

Xin mời mọi người "mắt thấy tai nghe"


----------------
code đã được sửa thêm để giải quyết trường hợp không tìm thấy tập tin nào, và lược bỏ phần tử cuối cùng của mảng trả về do đó là chuỗi rỗng.
Do mảng trả về có thể chứa toàn tên tập tin chứ không phải đường dẫn đầy đủ (khi InSub = FALSE) nên Sub CopyFiles phục vụ cả trường hợp toàn tên và trường hợp là các đường dẫn đầy đủ. Ngoài ra hỗ trợ cả trường hợp các tập tin trùng tên.
code hoàn chỉnh (???) như dưới đây
Mã:
Option Explicit
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long


Function GetListFile(ByVal Folder As String, ByVal Search As String, ByVal InSub As Boolean)
'    neu InSub = False thi mang tra ve chi chua ten cac tap tin. Neu InSub = True thi mang tra ve chua toan bo duong dan
    Dim sComm As String, tmpFile, text As String, m() As Byte, Arr
    On Error GoTo ExitSub
    If Right(Folder, 1) <> "\" Then Folder = Folder & "\"
    Folder = """" & Folder & """"
    With CreateObject("Scripting.FileSystemObject")
        tmpFile = .GetTempName
        sComm = "dir " & Folder & "*" & Search & "* /b " & IIf(InSub, "/s", vbNullString) & " > " & tmpFile
        CreateObject("Wscript.Shell").Run "cmd /u /c " & sComm, 0, True
        
        Open tmpFile For Binary As #1
        ReDim m(LOF(1))
        Get #1, , m
        Close #1
        
        text = m
        Arr = Split(text, vbCrLf)
'        neu trong thu muc khong co tap tin nao thi UBound(Arr) = -1, ra khoi Sub
        If UBound(Arr) = -1 Then GoTo ExitSub
'        chac chan phan tu cuoi cung la rong, loai bo
        If Arr(UBound(Arr)) = "" Then ReDim Preserve Arr(0 To UBound(Arr) - 1)
        GetListFile = Arr
    End With
    
ExitSub:
    Kill tmpFile
End Function

Sub CopyFiles(Arr, ByVal srcDir As String, ByVal destDir As String)
'    mang Arr co the chi chua ten chu khong phai toan bo duong dan. Neu chi chua ten
'    thi ta dung srcDir de tao duong dan day du cho cac tap tin nguon
Dim k As Long, n As Long, tempArr, filename As String, src As String, fso As Object
On Error GoTo end_
    If Right(destDir, 1) <> "\" Then destDir = destDir & "\"
    If Right(srcDir, 1) <> "\" Then srcDir = srcDir & "\"
    Set fso = CreateObject("Scripting.FileSystemObject")
    If IsArray(Arr) Then
'        neu Arr la mang
        tempArr = Arr
        For k = LBound(tempArr) To UBound(tempArr)
            src = tempArr(k)
            filename = Right(src, Len(src) - InStrRev(src, "\"))
'            chi co ten tap tin, ta tao duong dan day du
            If filename = src Then src = srcDir & filename
'            neu o dich da co tap tin ten nhu the thi ta tao ten moi bang cach them prefix
            If fso.FileExists(destDir & filename) Then filename = CStr(GetTickCount) & "_" & filename
'            sao tap tin toi dich
            fso.CopyFile src, destDir & filename
        Next k
    Else
'        neu Arr la 1 tap tin
        src = Arr
        filename = Right(src, Len(src) - InStrRev(src, "\"))
        If filename = src Then src = srcDir & filename
        fso.CopyFile src, destDir & filename
    End If
end_:
    Set fso = Nothing
End Sub

Sub Get_Files()
'    vi du. Trong o D1 co thu muc dich
    Application.ScreenUpdating = False
    On Error Resume Next
    Dim Arr
    Arr = GetListFile(ThisWorkbook.path, "*.xls;*xlxs", True)
    If IsArray(Arr) Then
        CopyFiles Arr, ThisWorkbook.path, [D1]
        [a1].Resize(UBound(Arr) + 1, 1) = Application.Transpose(Arr)
        Application.ScreenUpdating = True
    End If
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
VB tôi còn kém nên có vài chổ chưa hiểu!
Bạn siwtom vui lòng giải thích giúp đoạn này:
Mã:
Open tmpFile For Binary As #1
ReDim m(LOF(1))
Get #1, , m
Close #1
text = m
Không biết dùng với mục đích gì?
Cảm ơn
 
Upvote 0
code của bạn ndu đẹp rồi nên không có chuyện "thay code" ở đây. Ta chỉ cần trang điểm chút chút cho nó lộng lẫy hơn, tức hỗ trợ tiếng Việt. Ai thích tên thư mục, tên tập tin bằng tiếng Việt xin cứ mạnh dạn
----------------
code đã được sửa thêm để giải quyết trường hợp không tìm thấy tập tin nào, và lược bỏ phần tử cuối cùng của mảng trả về do đó là chuỗi rỗng.
Do mảng trả về có thể chứa toàn tên tập tin chứ không phải đường dẫn đầy đủ (khi InSub = FALSE) nên Sub CopyFiles phục vụ cả trường hợp toàn tên và trường hợp là các đường dẫn đầy đủ. Ngoài ra hỗ trợ cả trường hợp các tập tin trùng tên.
code hoàn chỉnh (???) như dưới đây
Code hay quá nhưng cao siêu, nếu bạn Siwton có thể diễn "nôm" giúp.
Nếu mình dùng search *.xls và sau đó chọn hết file copy thì có ok?.
Cám ơn nhiều.
 
Upvote 0
Code hay quá nhưng cao siêu, nếu bạn Siwton có thể diễn "nôm" giúp.
Nếu mình dùng search *.xls và sau đó chọn hết file copy thì có ok?.
Cám ơn nhiều.

Đương nhiên được... nhưng code trên không chỉ có thể, nó cho phép Seach theo 1 từ khóa nào đó (chứ không riêng gì đuôi file) ---> Ví dụ Search các tên file có từ khóa *ChiThu* chẳng hạn
Toàn bộ giải thuật cho GetListFile là dùng DOS Command đấy ThuNghi à (tôi post lên diễn đàn lâu rồi mà)
 
Upvote 0
code của bạn ndu đẹp rồi nên không có chuyện "thay code" ở đây. Ta chỉ cần trang điểm chút chút cho nó lộng lẫy hơn, tức hỗ trợ tiếng Việt. Ai thích tên thư mục, tên tập tin bằng tiếng Việt xin cứ mạnh dạn
Mã:
Function GetListFile(ByVal Folder As String, ByVal Search As String, ByVal InSub As Boolean)
   .......
    CreateObject("Wscript.Shell").Run "cmd /c " & sComm, 0, True
   .......
End Function

[COLOR=#0000ff]Ta sửa thành[/COLOR]

Function GetListFile(ByVal Folder As String, ByVal Search As String, ByVal InSub As Boolean)
   .........
   CreateObject("Wscript.Shell").Run "cmd [B][COLOR=#ff0000]/U[/COLOR][/B] /c " & sComm, 0, True
   .........

Bạn siwtom cho mình hỏi thêm về tham số /U tí:
- Liệu nó có liên quan gì đến Unicode không? Vì tôi thí nghiệm thấy rằng nếu không có tham số này thì chuổi Unicode không hiển thị tốt trên file TXT
- Ngoài /U này ra, còn có những tham số nào "hay ho" nữa không?
 
Upvote 0
VB tôi còn kém nên có vài chổ chưa hiểu!
Bạn siwtom vui lòng giải thích giúp đoạn này:
Mã:
Open tmpFile For Binary As #1
ReDim m(LOF(1))
Get #1, , m
Close #1
text = m
Không biết dùng với mục đích gì?
Cảm ơn

Trong tập tin tmpFile do Dir trả về là text unicode.
Bạn thử giữ code cũ "GetListFile = Split(.OpenTextFile(tmpFile, 1).ReadAll, vbCrLf)" thì bạn sẽ thấy thế nào.
Còn code bạn hỏi thì nó đọc nội dung tập tin tmpFile vào text
Tôi thấy dùng OpenTextFile (không được) hay cái gì khác thay cho code của tôi cũng được. Miễn là khi thử thấy đúng.
 
Upvote 0
Bạn siwtom cho mình hỏi thêm về tham số /U tí:
- Liệu nó có liên quan gì đến Unicode không? Vì tôi thí nghiệm thấy rằng nếu không có tham số này thì chuổi Unicode không hiển thị tốt trên file TXT
- Ngoài /U này ra, còn có những tham số nào "hay ho" nữa không?

/u đúng là ám chỉ unicode
các tham số khác cũng chả có gì hay cả. Tôi chỉ giữ /b (để không có tiêu đề và các thứ khác) và /u, còn /s thì tùy
 
Upvote 0
Trong tập tin tmpFile do Dir trả về là text unicode.
Bạn thử giữ code cũ "GetListFile = Split(.OpenTextFile(tmpFile, 1).ReadAll, vbCrLf)" thì bạn sẽ thấy thế nào.
Còn code bạn hỏi thì nó đọc nội dung tập tin tmpFile vào text
Tôi thấy dùng OpenTextFile (không được) hay cái gì khác thay cho code của tôi cũng được. Miễn là khi thử thấy đúng.
Ah...
Nếu là .OpenTextFile(tmpFile, 1, , -2) thì.. hình như được đấy
(đang thí nghiệm)
--------------------------
/u đúng là ám chỉ unicode
các tham số khác cũng chả có gì hay cả. Tôi chỉ giữ /b (để không có tiêu đề và các thứ khác) và /u, còn /s thì tùy
Từ trước giờ tôi rất "kết" giải thuật dùng DOS Command, vì cảm giác nó cho tốc độ rất nhanh... Chỉ đáng tiếc là vẫn chưa xử lý được vụ Unicode text. Hôm nay với cái /U của bạn thì.. ngon lành rồi
Cảm ơn nhiều nhé
 
Upvote 0
Ah...
Nếu là .OpenTextFile(tmpFile, 1, , -2) thì.. hình như được đấy
(đang thí nghiệm)
--------------------------

Từ trước giờ tôi rất "kết" giải thuật dùng DOS Command, vì cảm giác nó cho tốc độ rất nhanh... Chỉ đáng tiếc là vẫn chưa xử lý được vụ Unicode text. Hôm nay với cái /U của bạn thì.. ngon lành rồi
Cảm ơn nhiều nhé

Đúng là OpenTextFile hỗ trợ unicode - tôi nhầm lẫn khi đưa thông số nên cứ "ngạc nhiên". Vì OpenTextFile cũng như những hàm khác là của thư viện scrrun.dll nên phải hỗ trợ unicode.
-------------------------------------
Tôi thấy các bạn rất chăm chỉ, đọc rất nhiều sách nhưng có quyển sách gần nhất thì thường không đọc.
Để xem có các lệnh nào sử dụng trong dòng lệnh thì mở cửa sổ dòng lệnh (Start --> Run) và: help --> ENTER.
Sau khi biết tên các lệnh rồi thì tìm hiểu cách dùng: tên /? --> ENTER, vd. dir /? --> ENTER
hoặc cmd /? --> ENTER. Lúc này các bạn sẽ thấy thông số /u (trong lệnh cmd) có nghĩa gì. Đại loại là với /u thì "dữ liệu" tuôn vào dòng (stream) hay tập tin là ở dạng unicode.
Bản thân lệnh dir thì không có gì cao siêu cả. Nó cũng như lệnh dir của hệ điều hành DOS xa xưa. Cái thú vị ở trong code của bạn ndu là ở chỗ " > tmpFile". Tức dữ liệu không được "tuôn" ra màn hình của cửa sổ dòng lệnh mà nó được "tuôn" vào tập tin. Và có thể chọn thông số /b để chỉ tuôn vào những cái ta cần. Không có /b thì sau khi ta có tập tin với cả tiêu đề và dung lượng, ngày tháng thì lại phải lọc.
Nếu có thời gian tôi sẽ viết thêm chút ít về các điều này
 
Lần chỉnh sửa cuối:
Upvote 0
Đúng là OpenTextFile hỗ trợ unicode - tôi nhầm lẫn khi đưa thông số nên cứ "ngạc nhiên". Vì OpenTextFile cũng như những hàm khác là của thư viện scrrun.dll nên phải hỗ trợ unicode.
-------------------------------------
Tôi thấy các bạn rất chăm chỉ, đọc rất nhiều sách nhưng có quyển sách gần nhất thì thường không đọc.
Để xem có các lệnh nào sử dụng trong dòng lệnh thì mở cửa sổ dòng lệnh (Start --> Run) và: help /? --> ENTER.
Sau khi biết tên các lệnh rồi thì tìm hiểu cách dùng: tên /? --> ENTER, vd. dir /? --> ENTER
hoặc cmd /? --> ENTER. Lúc này các bạn sẽ thấy thông số /u (trong lệnh cmd) có nghĩa gì. Đại loại là với /u thì "dữ liệu" tuôn vào dòng (stream) hay tập tin là ở dạng unicode.
Bản thân lệnh dir thì không có gì cao siêu cả. Nó cũng như lệnh dir của hệ điều hành DOS xa xưa. Cái thú vị ở trong code của bạn ndu là ở chỗ " > tmpFile". Tức dữ liệu không được "tuôn" ra màn hình của cửa sổ dòng lệnh mà nó được "tuôn" vào tập tin. Và có thể chọn thông số /b để chỉ tuôn vào những cái ta cần. Không có /b thì sau khi ta có tập tin với cả tiêu đề và dung lượng, ngày tháng thì lại phải lọc.
Nếu có thời gian tôi sẽ viết thêm chút ít về các điều này
Trước giờ tôi cũng thường dùng cách này để nghiên cứu lệnh DOS nhưng thật sự không để ý trong các lệnh DOS lại có lệnh cmd
Ẹc... Ẹc... mới thử xong ---> Cả 1 "rừng" luôn
-----------------
Người ta nói HỌC ĐI ĐỘI VỚI HÀNH... Vậy nên chỉ cần vài bài "hành" như ở đây đã bằng đọc mấy quyển sách rồi
Cảm ơn bạn!
 
Upvote 0
Đúng là OpenTextFile hỗ trợ unicode - tôi nhầm lẫn khi đưa thông số nên cứ "ngạc nhiên". Vì OpenTextFile cũng như những hàm khác là của thư viện scrrun.dll nên phải hỗ trợ unicode.
-------------------------------------
Tôi thấy các bạn rất chăm chỉ, đọc rất nhiều sách nhưng có quyển sách gần nhất thì thường không đọc.
Để xem có các lệnh nào sử dụng trong dòng lệnh thì mở cửa sổ dòng lệnh (Start --> Run) và: help --> ENTER.
Sau khi biết tên các lệnh rồi thì tìm hiểu cách dùng: tên /? --> ENTER, vd. dir /? --> ENTER
hoặc cmd /? --> ENTER. Lúc này các bạn sẽ thấy thông số /u (trong lệnh cmd) có nghĩa gì. Đại loại là với /u thì "dữ liệu" tuôn vào dòng (stream) hay tập tin là ở dạng unicode.
Bản thân lệnh dir thì không có gì cao siêu cả. Nó cũng như lệnh dir của hệ điều hành DOS xa xưa. Cái thú vị ở trong code của bạn ndu là ở chỗ " > tmpFile". Tức dữ liệu không được "tuôn" ra màn hình của cửa sổ dòng lệnh mà nó được "tuôn" vào tập tin. Và có thể chọn thông số /b để chỉ tuôn vào những cái ta cần. Không có /b thì sau khi ta có tập tin với cả tiêu đề và dung lượng, ngày tháng thì lại phải lọc.
Nếu có thời gian tôi sẽ viết thêm chút ít về các điều này

Cũng cần nói rõ là nếu lệnh không "tuôn ra" text ở dạng unicode thì thông số /u cũng không làm gì được (nếu tôi không lầm). lệnh dir trả về text unicode nhưng có những lệnh không trả về unicode. Vd. lệnh xcopy sẽ copy các tập tin và hiển thị danh sách những tập tin đã được copy nhưng danh sách đó không phải unicode. find.exe tìm trong những tập tin cho trước những đoạn text cần tìm và nó trả về nội dung những dòng tìm thấy. Những đoạn cần tìm có thể là unicode nó cũng tìm ra nhưng khi trả về danh sách các dòng tìm thấy thì danh sách lại không là unicode.
--------------------
Một vài thông tin về cửa sổ dòng lệnh, tức "dư âm" của hệ điều hành DOS xa xưa.
1. Chuyển hướng In / Out
Dòng dữ liệu vào In và dòng dữ liệu ra Out. DOS cho phép "tuôn" dữ liệu vào và ra tới các thiết bị In / Out hoặc từ / tới tập tin. Trong DOS có nhiều loại thiết bị In / Out như NUL, CON, AUX, PRN, COMx (COM1, COM2, COM3, COM4), LPTx (LPT1, LPT2, ...). Tôi sẽ giới thiệu về NUL và CON.
CON là thiết bị In / Out mặc định. CON có nghĩa là console - màn hình và bàn phím. Mọi dữ liệu vào được mặc định đưa lên màn hình thông qua bàn phím. Mọi dữ liệu ra (các thông báo, yêu cầu, kết quả) được mặc định đưa ra màn hình. Tóm lại COM là thiết bị mặc định. Nhưng DOS cho phép chuyển hướng In / Out và đưa dữ liệu sang thiết bị khác (vd. máy in - LPT, chú ý là ta đang nói về hđh DOS. Trong cửa sổ dòng lệnh có thể khác) hoặc từ / tới tập tin. Cụ thể như thế nào?
a. Chuyển hướng OUT. Ta dùng "... > tập tin hoặc thiết bị đích"
Mã:
vd. dir c:\*.txt > d:\files.txt --> ENTER
Kết quả là dữ liệu ra, tức danh sách các tập tin TXT trên C, không được "tuôn" ra màn hình mà được chuyển hướng vào tập tin d:\files.txt do dir tạo ra.
b. Chuyển hướng OUT. Ta dùng "... >> tập tin hoặc thiết bị đích"
Chú ý là nếu ta dùng trong vd. a ở trên " ... > tập tin" thì kết quả được ghi ở đầu tập tin files.txt do dir tạo ra nếu files.txt chưa tồn tại. Còn nếu tập tin đã tồn tại thì nội dung của nó bị thay bởi kết quả. Vậy nếu ta muốn dùng dir 2 lần để "tuồn" 2 danh sách khác nhau vào cùng 1 tập tin thì làm thế nào? Thì dùng " ... >> ..." thôi. ">>" có nghĩa là dòng dữ liệu ra sẽ được ghi vào cuối tập tin.
Mã:
vd. 
dir /b c:\*.txt >> d:\files.txt --> ENTER
dir /b c:\wincmd\*.txt >> d:\files.txt --> ENTER
Kết quả là trong d:\files.txt ta có danh sách các tập tin txt từ 2 thư mục khác nhau.
Thế nếu ta không muốn "tuôn" dòng dữ liệu vào màn hình cũng như vào tập tin thì làm thế nào?
vd. ta muốn copy các tập tin TXT từ c:\van_ban sang d:\luu_tru thì ta dùng
Mã:
copy c:\van_ban\*.txt d:\luu_tru --> ENTER
Nhưng nếu trong van_ban có 2000 tập tin TXT thì kết quả (tức thông báo của lệnh copy) "tuôn" ra màn hình sẽ là 2000 dòng tên các tập tin và dòng cuối là: Tổng số các tập tin được sao: 2000
Nếu ta thao tác lâu ở dòng lệnh thì 2001 dòng kia đúng là rác, làm phiền ta. Ta có thể chuyển hướng
để ghi 2001 dòng thông báo đó vào tập tin cho khuất mắt nhưng ta cũng có thể dùng NUL - tức chuyển hướng tới "chả là gì cả", tức chuyển vào "hư vô"
Mã:
copy c:\van_ban\*.txt d:\luu_tru > NUL
2. Chuyển hướng In "... < ..."
Bình thường thì dữ liệu vào được lấy thông qua bàn phím và hiển thị trên màn hình - thiết bị IN / Out mặc định CON.
Mã:
copy c:\*.txt d:\
vd. trên copy tất cả các tập tin TXT trong C:\ sang D:\. Thế nếu trên D:\ đã có 1 số tập tin TXT có tên như tập tin đang phải copy thì sao? Thì lúc đó copy sẽ hiển thị thông báo kiểu (ngôn ngữ tùy phiên bản Windows):
PHP:
c:\xyz.txt
Rewrite d:\xyz.txt? <Yes/No/All>
Lúc đó người dùng phải nhấn: y + ENTER (yes), n + ENTER (No), a + ENTER (all)
Thế nếu người dùng lười hoặc nếu là code viết trong VBA để chạy tự động thì sao? DOS cho phép lấy dữ liệu vào (ở đây là câu trả lời của người dùng) từ nguồn khác với nguồn bàn phím. Tức ta có thể soạn tập tin chứa câu trả lời của ta và cung cấp nó như là nguồn vào. Ví dụ ta muốn khi có những tập tin trùng thì ghi đè TẤT CẢ. Vậy ta phải cung cấp a và ENTER. Ta mở notepad và nhấn phím a, tiếp đó nhấn ENTER, sau đó ghi lại vd. trên C:\ với tên cau_tra_loi.txt. Trong cửa sổ dòng lệnh ta gõ
Mã:
copy c:\*.txt d:\ < c:\tra_loi.txt
Lúc này thì nếu có các tập tin trùng thì chúng sẽ bị ghi đè mà người dùng không phải nhấn phím a + ENTER nữa vì câu trả lời đã có trong tập tin c:\tra_loi.txt và " < c:\tra_loi.txt" thông báo là nguồn dữ liệu vào (ở đây là câu trả lời) là tập tin c:\tra_loi.txt
Ở trên là 1 câu trả lời. Có nhiều khi ta phải trả lời vài lần. Ví dụ trong DOS nếu ta format vd. đĩa mềm thì đầu tiên format thông báo là hãy chắc chắn là đã đút đĩa mềm vào ổ rồi nhấn ENTER để bắt đầu. Khi format xong thì format hỏi có đặt Label không, nếu ta đặt thì gõ tên rồi ENTER, nếu không thì chỉ ENTER. Khi đã xong xuôi rồi thì format còn nhì nhằng: có format tiếp các đĩa khác không. Nếu ta không format tiếp thì nhấn N. Như vậy phiền quá. Có 3 chỗ phải trả lời. Vậy ta mở notepad rồi nhấn liên tiếp: ENTER --> ENTER --> n (--> chỉ để minh họa, không gõ)
Sau đó ta ghi trên C:\ với tên tra_loi.txt. Trong dòng lệnh ta viết:
Mã:
format A: < c:\tra_loi.txt
Lúc này ta không phải nhấn phím 3 lần nữa.
------------
Cuối cùng ta bàn chút về việc copy nhưng giữ nguyên cấu trúc của thư mục nguồn. Có ai đó đã bỏ công ra sắp xếp các tập tin của mình vào từng thư mục con theo chủ đề. Bây giờ anh ta muốn copy một số tập tin nhưng vẫn giữ cấu trúc như cũ.
xcopy sẽ làm được việc đó. Nó có thể copy và giữ nguyên cấu trúc nguồn. Code như sau:
Mã:
Sub Xcopy(ByVal srcDir As String, ByVal destDir As String, ByVal Pattern As String, _
        Optional ByVal InSub As Boolean = True)
'    neu InSub  TRUE thi tim ca trong cac thu muc con.
'    cac tap tin tim duoc se duoc copy sang thu muc destDir va dam bao giu nguyen cau
'    truc nhu o thu muc goc srcDir. vd. thu muc goc la ...\bla co 2 thu muc con la bla\he1 va bla\he2. Trong \bla co tap tin
'    bla.txt, trong bla\he1 co he1.txt, trong bla\he2 co he2.txt thi khi tim va copy tat ca cac tap tin TXT thi tai thu muc
'    destDir se duoc tao 2 thu muc con la he1 va he2, va trong thu muc destDir se xuat hien tap tin bla.txt, trong
'    destDir\he1 - he1.txt, trong destDir\he2 - he2.txt
    Dim sCmd As String, tmpFile As String, text As String, k As Long, count As Long, argArr, tmpArr, Arr, sh As Object
    
    On Error GoTo ExitSub
    
    If Right(srcDir, 1) <> "\" Then srcDir = srcDir & "\"
    srcDir = """" & srcDir & """"
    If Right(destDir, 1) <> "\" Then destDir = destDir & "\"
    destDir = """" & destDir & """"
    argArr = Split(Pattern, ";")
    
    Set sh = CreateObject("Wscript.Shell")
  
'    copy lan luot cac tap tin khop voi pattern hien hanh
    For k = LBound(argArr) To UBound(argArr)
'        dong lenh
        sCmd = "xcopy " & srcDir & argArr(k) & " " & destDir & " /h /k /r /y " & IIf(InSub, "/s", vbNullString)
'        copy cac tap tin va ghi danh sach ra tmpFile
        sh.Run "cmd /c " & sCmd, 0, True
    Next k
ExitSub:
    Set sh = Nothing
End Sub
Có file đính kèm. Vd. sẽ copy tất cả các tập tin có dạng *.xls và *.xlxs có trong thư mục có xcopy.xls (tập tin ví dụ). Vậy để test thì phải tải xcopy.xls về thư mục có những tập tin như đã chỉ ở trên.
code đã được thử trên XP + Excel2007 và Win7 + Excel 2007
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Một vài thông tin về cửa sổ dòng lệnh, tức "dư âm" của hệ điều hành DOS xa xưa.

Nói ngoài lề chút: Có vẻ như bạn siwtom đã.. lớn tuổi?
Vì tôi để ý thấy các bạn trẻ bây giờ ít ai còn biết đến DOS Command, mà bạn thì lại rất siêu phần này
Tôi đoán đúng chứ?
---------------------------
Hy vọng khi nào rảnh rỗi, bạn mở hẳn 1 topic chuyên về DOS, nhất là những câu lệnh có thể "nhúng" vào VB, VBA (tôi cũng dùng DOS khá nhiều nhưng "biết" lại chẳng được bao nhiêu)
Cảm ơn trước nha!
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom