Kích hoạt chế độ FileSystemObject trong VBA

Liên hệ QC

hoahuongduong1986

Thành viên thường trực
Tham gia
14/11/18
Bài viết
346
Được thích
40
Em muốn làm việc với việc Copy dữ liệu giữa các Folder nên em dùng FileSystemObject trong VBA. Nhưng đang bị lỗi, anh chi xem giúp em với ạ.
Em không muốn vào Tool => Chọn Refer => Microsoft Scripting Runtime. Nên em chọn cách khai báo nó là một dạng biến như vầy

Dim MyFSO As Object

Dim MyFile As File


Dim SourceFolder As String

Dim DestinationFolder As String

Dim MyFolder As Folder

Dim MySubFolder As Folder

ThisWorkbook.Activate

SourceFolder = Range("LINK1")

DestinationFolder = Range("LINK2")

Set MyFSO = CreateObject("Scripting.FileSystemObject")

Set MyFolder = MyFSO.GetFolder(SourceFolder)

For Each MyFile In MyFolder.Files

MyFSO.CopyFile Source:=MyFSO.GetFile(MyFile), _
Destination:=DestinationFolder & "\" & MyFile.Name, Overwritefiles:=True

Next MyFile

End Sub


Nhưng nó báo lỗi User define type not defined với đoạn Dim MyFile As File là sao ạ.
 
Em muốn làm việc với việc Copy dữ liệu giữa các Folder nên em dùng FileSystemObject trong VBA. Nhưng đang bị lỗi, anh chi xem giúp em với ạ.
Em không muốn vào Tool => Chọn Refer => Microsoft Scripting Runtime. Nên em chọn cách khai báo nó là một dạng biến như vầy

Dim MyFSO As Object

Dim MyFile As File


Dim SourceFolder As String

Dim DestinationFolder As String

Dim MyFolder As Folder

Dim MySubFolder As Folder

ThisWorkbook.Activate

SourceFolder = Range("LINK1")

DestinationFolder = Range("LINK2")

Set MyFSO = CreateObject("Scripting.FileSystemObject")

Set MyFolder = MyFSO.GetFolder(SourceFolder)

For Each MyFile In MyFolder.Files

MyFSO.CopyFile Source:=MyFSO.GetFile(MyFile), _
Destination:=DestinationFolder & "\" & MyFile.Name, Overwritefiles:=True

Next MyFile

End Sub


Nhưng nó báo lỗi User define type not defined với đoạn Dim MyFile As File là sao ạ.
Xin chào, bạn thử thay as File = as Object xem sao
 
Upvote 0
Xin chào, bạn thử thay as File = as Object xem sao
Nó lại báo lỗi như vầy với MyFolder As Folder bạn ạ. Mình nghĩ không phải as File = as Object được ấy, vì bản chất là phải Copy dạng File mà. Không rõ thiếu gì nữa.
Bài đã được tự động gộp:

Lý do tại sao không add reference vậy bạn?
Em không muốn cứ gửi một File lại bắt người khác họ vào kích hoạt chế độ đó thôi mà. Có làm theo kiểu Record Mac các bước này mà không được.
 
Upvote 0
Nếu đã kg add reference thì VBA kg hiểu type File hay Folder là gì
 
Upvote 0
Nó lại báo lỗi như vầy với MyFolder As Folder bạn ạ. Mình nghĩ không phải as File = as Object được ấy, vì bản chất là phải Copy dạng File mà. Không rõ thiếu gì nữa.
Bài đã được tự động gộp:


Em không muốn cứ gửi một File lại bắt người khác họ vào kích hoạt chế độ đó thôi mà. Có làm theo kiểu Record Mac các bước này mà không được.
bạn lại thử as Object xem sao.
mình không biết dùng FileSystemObject nên cũng chịu.
mình xin phép phán bừa 1 câu là: khi bạn add reference thì mới sài được as Folder, File. còn nếu dùng create scripting thì phải sài Object
nếu mình sai bạn bỏ quá cho nha. :)
 
Upvote 0
Vậy thì add refernce bằng code đi bạn. Diễn đàn có đó, chịu khó search 1 chút
 
Upvote 0
Nó lại báo lỗi như vầy với MyFolder As Folder bạn ạ. Mình nghĩ không phải as File = as Object được ấy, vì bản chất là phải Copy dạng File mà. Không rõ thiếu gì nữa.
Bài đã được tự động gộp:


Em không muốn cứ gửi một File lại bắt người khác họ vào kích hoạt chế độ đó thôi mà. Có làm theo kiểu Record Mac các bước này mà không được.


Hình thức bạn đang làm gọi là "Late Binding", không muốn tham chiếu đến thư việc trước trong code.
Muốn như vậy thì bạn khai báo báo bằng tên cách đối tượng của thư viện đó mà chỉ khai báo chung chung là Variant như anh VetMini đã nói hoặc nếu nó là đối tượng thì khai báo " As Object" luôn (bạn ducdoom chỉ bạn đúng rồi đó).
Đã MyFile As Object thì
MyFolder As Object luôn

Tôi nghĩ bạn nên kiếm trong diễn đàn, trong các ví dụ, nhiều người đã viết sẳn các bộ hàm hay thủ tục phục vụ một nhu cầu nào đó, bạn lấy về ngâm cứu đọc hiểu rồi áp dụng vô ứng dụng của mình, khỏi phải đi viết lại cho mất công.

Demo cái hàm tôi hay dùng để liệt kê tên file (dùng FSO với late binding). Nhớ nên giải phóng biến đối tượng sau khi xài xong nhé.

Mã:
Function ListFilesInFolder(ObjBox As Object, strFolderPath As String, Optional strFilter As String) As Boolean
    On Error GoTo ErrorHandler
    Dim strFileExt As String, strFullPath As String
    Dim objFSO As Object, objFolder As Object, objFile As Object
    Dim rstADO As Object

    If strFolderPath = vbNullString Then Exit Function

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFolder = objFSO.GetFolder(strFolderPath)
    Set rstADO = CreateObject("ADODB.RecordSet")

    'Dung ADO tao recordset tren memory
    Const adLongVarWChar = 203
    Const adFldMayBeNull = &H40
    Const adOpenForwardOnly = 0
    Const adUseClient = 3
    Const adLockPessimistic = 2

    With rstADO
        .Fields.Append "TenFile", adLongVarWChar, 255, adFldMayBeNull
        .Fields.Append "DuongDanFile", adLongVarWChar, 255, adFldMayBeNull
        .CursorType = adOpenForwardOnly
        .CursorLocation = adUseClient
        .LockType = adLockPessimistic
        .Open
    End With


    For Each objFile In objFolder.Files
        strFullPath = objFolder.path & "\" & objFile.Name
        If strFilter = vbNullString Then    'Khong loc file có ext nhu yeu cau
            rstADO.AddNew
            rstADO![TenFile] = objFile.Name
            rstADO![DuongDanFile] = strFullPath     'Phuc vu cho viec Delete file
        Else
            strFileExt = Mid$(objFile.Name, InStrRev(objFile.Name, ".") + 1)    'Dôi cheu ext cua tung file, neu có thì mói add
            If InStr(strFilter, strFileExt) > 0 Then
                rstADO.AddNew
                rstADO![TenFile] = objFile.Name
                rstADO![DuongDanFile] = strFullPath
            End If
        End If
    Next

    If rstADO.BOF And rstADO.EOF Then
        ListFilesInFolder = False
        Exit Function
    End If

    Dim i As Long
    rstADO.MoveFirst
    i = 0
    With ObjBox
        .Clear
        Do
            .AddItem
            .List(i, 0) = rstADO![TenFile]
            .List(i, 1) = rstADO![DuongDanFile]
            i = i + 1
            rstADO.MoveNext
        Loop Until rstADO.EOF
    End With

    ListFilesInFolder = True

Exit_ErrorHandler:
    Set objFSO = Nothing
    Set objFolder = Nothing
    Set objFile = Nothing
    Set rstADO = Nothing
    Exit Function

ErrorHandler:
    ListFilesInFolder = False
    MsgBox "Err Number: " & Err.Number & vbCrLf & Err.Description, , "Error: ListFilesInFolder"
    Resume Exit_ErrorHandler
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Tậu nghiệp cho VBA, với Object thì còn đỡ đỡ chút, chơi luôn Variant thì ông VBA gồng mình check VA_TYPE, convert, predict mệt nghĩ.
 
Upvote 0
Tậu nghiệp cho VBA, với Object thì còn đỡ đỡ chút, chơi luôn Variant thì ông VBA gồng mình check VA_TYPE, convert, predict mệt nghĩ.
Em cảm ơn anh đã cho ý kiến ạ. Em dùng ObJect cho đỡ ạ.
Bài đã được tự động gộp:

Hình thức bạn đang làm gọi là "Late Binding", không muốn tham chiếu đến thư việc trước trong code.
Muốn như vậy thì bạn khai báo báo bằng tên cách đối tượng của thư viện đó mà chỉ khai báo chung chung là Variant như anh VetMini đã nói hoặc nếu nó là đối tượng thì khai báo " As Object" luôn (bạn ducdoom chỉ bạn đúng rồi đó).
Đã MyFile As Object thì
MyFolder As Object luôn

Tôi nghĩ bạn nên kiếm trong diễn đàn, trong các ví dụ, nhiều người đã viết sẳn các bộ hàm hay thủ tục phục vụ một nhu cầu nào đó, bạn lấy về ngâm cứu đọc hiểu rồi áp dụng vô ứng dụng của mình, khỏi phải đi viết lại cho mất công.

Demo cái hàm tôi hay dùng để liệt kê tên file (dùng FSO với late binding). Nhớ nên giải phóng biến đối tượng sau khi xài xong nhé.

Mã:
Function ListFilesInFolder(ObjBox As Object, strFolderPath As String, Optional strFilter As String) As Boolean
    On Error GoTo ErrorHandler
    Dim strFileExt As String, strFullPath As String
    Dim objFSO As Object, objFolder As Object, objFile As Object
    Dim rstADO As Object

    If strFolderPath = vbNullString Then Exit Function

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFolder = objFSO.GetFolder(strFolderPath)
    Set rstADO = CreateObject("ADODB.RecordSet")

    'Dung ADO tao recordset tren memory
    Const adLongVarWChar = 203
    Const adFldMayBeNull = &H40
    Const adOpenForwardOnly = 0
    Const adUseClient = 3
    Const adLockPessimistic = 2

    With rstADO
        .Fields.Append "TenFile", adLongVarWChar, 255, adFldMayBeNull
        .Fields.Append "DuongDanFile", adLongVarWChar, 255, adFldMayBeNull
        .CursorType = adOpenForwardOnly
        .CursorLocation = adUseClient
        .LockType = adLockPessimistic
        .Open
    End With


    For Each objFile In objFolder.Files
        strFullPath = objFolder.path & "\" & objFile.Name
        If strFilter = vbNullString Then    'Khong loc file có ext nhu yeu cau
            rstADO.AddNew
            rstADO![TenFile] = objFile.Name
            rstADO![DuongDanFile] = strFullPath     'Phuc vu cho viec Delete file
        Else
            strFileExt = Mid$(objFile.Name, InStrRev(objFile.Name, ".") + 1)    'Dôi cheu ext cua tung file, neu có thì mói add
            If InStr(strFilter, strFileExt) > 0 Then
                rstADO.AddNew
                rstADO![TenFile] = objFile.Name
                rstADO![DuongDanFile] = strFullPath
            End If
        End If
    Next

    If rstADO.BOF And rstADO.EOF Then
        ListFilesInFolder = False
        Exit Function
    End If

    Dim i As Long
    rstADO.MoveFirst
    i = 0
    With ObjBox
        .Clear
        Do
            .AddItem
            .List(i, 0) = rstADO![TenFile]
            .List(i, 1) = rstADO![DuongDanFile]
            i = i + 1
            rstADO.MoveNext
        Loop Until rstADO.EOF
    End With

    ListFilesInFolder = True

Exit_ErrorHandler:
    Set objFSO = Nothing
    Set objFolder = Nothing
    Set objFile = Nothing
    Set rstADO = Nothing
    Exit Function

ErrorHandler:
    ListFilesInFolder = False
    MsgBox "Err Number: " & Err.Number & vbCrLf & Err.Description, , "Error: ListFilesInFolder"
    Resume Exit_ErrorHandler
End Function
Em đã thêm đoạn giải phóng biến sau khi xong lệnh rồi ạ. Em cảm ơn anh đã chỉ bảo ạ !
 
Lần chỉnh sửa cuối:
Upvote 0
Code copy file bằng FileSystemObject, dùng For Each để duyệt collection mà cũng sợ mệt.
Đi xe bò mà cũng sợ đường đất. Hết chỗ nói.
 
Upvote 0
Web KT

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

Back
Top Bottom