在循环文件时使用FileSystemObject重命名文件

时间:2013-08-08 15:32:57

标签: vba ms-access access-vba ms-access-2003 ms-access-2013

作为前言,我在Access 2003中编写代码,但是会让用户使用Access 2013,因此我需要它兼容两者。我有一个循环,它使用Application.FileSearch循环遍历目录中的许多文件。我的理解是,在较新版本的Access中不推荐使用它,因此我必须使用“For Each”来循环访问文件。

以下是我正在改变的代码:

strPath = CurrentProject.Path & "\Files\"

strFileName = "SourceCode.txt"

With Application.FileSearch
    .FileName = "*.txt"
    .LookIn = strPath
    .Execute
    intFileCount = .foundfiles.Count
    For x = 1 To intFileCount
        Set fs = CreateObject("Scripting.FileSystemObject")
        Set f = fs.GetFile(.foundfiles(x))
        strNewFileName = Right((.foundfiles(x)), Len((.foundfiles(x))) - (InStr((.foundfiles(x)), "Files\") + 5))
        fs.MoveFile f, strPath & strFileName
        'Run the Process() function
        Process
        FileCopy strPath & strFileName, strPath & "Processed\" & strNewFileName
        Kill strPath & strFileName
    Next x
End With

这是我用以下代码代替的代码:

strPath = CurrentProject.Path & "\Files\"

strFileName = "SourceCode.txt"

Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFolder(strPath)
Set fc = f.Files

For Each f1 In fc
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFile = objFSO.OpenTextFile(strPath & f1.Name, 1)
    strNewFileName = f1.Name
    f1.Name = strFileName
    'Run the Process() function
    Process
    FileCopy strPath & strFileName, strPath & "Processed\" & strNewFileName
    Kill strPath & strFileName
Next

此代码循环遍历每个文件,然后启动Process()函数,该函数对文件进行更改。所以我的工作方式是将活动文件更改为“SourceCode.txt”,然后Process()函数知道使用该名称的文件。然后它将文件移动到“已处理”子文件夹,并使用其原始文件名。

这在原始代码中运行良好。新代码似乎主要起作用,除了我在启动Process()之前找不到将文件重命名为“SourceCode.txt”的方法。我尝试了几种方法,但我一直在收到错误。在上面的代码中,我尝试了“f1.Name = strFileName”。这给了我一个“权限被拒绝”的错误。我尝试使用FileCopy,然后使用原始文件上的Kill命令,但Kill命令返回错误。我怀疑FileSystemObject正在锁定文件,因此无法移动或杀死它。但旧版本的代码能够毫无问题地移动它。

1 个答案:

答案 0 :(得分:2)

您获得“权限被拒绝”,因为您尝试在文件使用时重命名,即objFSO.OpenTextFile。这与fs.GetFile不同,而不是原始代码 - 您需要它吗?它返回您未随后使用的TextStream

无论如何,请在打开文件之前移动f1.Name = strFileName,或者在完成处理后,请致电objFile.Close然后重命名。