Vbscript 循环中的迭代太多

Vbscript 循环中的迭代太多,vbscript,Vbscript,此脚本收集文件夹中的所有文件,并通过在文件名后添加行数来重命名这些文件。所有文件都是.txt文件。方法(因为fso.MoveFile和fso.DeleteFile太特殊,会产生权限错误)是 创建文本文件 然后在文件夹中创建文件集合 然后用新名称将每个文件复制到同一文件夹中,然后 最后,删除复制的原始文件 除非集合中没有空文本文件,否则脚本工作正常。发生的情况是,使用新文件重建集合,脚本再次重命名这些文件。我知道我可以通过检查每个文件是否存在某些重复字符串来防止这种情况,但我想知道发生了什么?为什

此脚本收集文件夹中的所有文件,并通过在文件名后添加行数来重命名这些文件。所有文件都是.txt文件。方法(因为
fso.MoveFile
fso.DeleteFile
太特殊,会产生权限错误)是

  • 创建文本文件
  • 然后在文件夹中创建文件集合
  • 然后用新名称将每个文件复制到同一文件夹中,然后
  • 最后,删除复制的原始文件
  • 除非集合中没有空文本文件,否则脚本工作正常。发生的情况是,使用新文件重建集合,脚本再次重命名这些文件。我知道我可以通过检查每个文件是否存在某些重复字符串来防止这种情况,但我想知道发生了什么?为什么脚本重新生成文件集合并再次运行它们(重命名每个集合)?这会一直持续到我结束这个过程

    另一个有趣的factoid是,如果我碰巧捕获了一个空文本文件,我的消息会显示出来,脚本会停在那里,但仍然会再次重新处理集合中的第一个文件。请注意,空文件恰好是集合中的最后一个文件,但第一个文件将再次被处理

    因此,通过设计,创建的名为“ab0.txt”的文本文件将重命名为“ab0-15.txt”,因为其中包含15行文本。这个新重命名的文件看起来像“ab0-15-15-15-15-15-15-15-15-15-15-15.txt”

    问题:发生了什么事?有没有更好、更有效的方法来实现这一目标

    以下是与此问题相关的代码:

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set oFolder = fso.GetFolder(strSaveTo)
    Set colFiles = oFolder.Files
    
    ' Call Sub to copy and rename
    ChangeFileName colFiles
    MsgBox("File renaming complete.")
    ' Exit code
    
    Sub ChangeFileName(collectionSet)
      Const ForReading = 1
      Dim oFile
    
      For Each oFile In collectionSet
        Set LineCnt = fso.OpenTextFile(oFile, ForReading)
        If oFile.Size = 0 then
          'if this msg is not included, weird things happen
          MsgBox("The file named " & oFile & _
            " is empty.You may want to verify and manually delete it.")
          '[I had some code in here to delete the empty file, but nothing worked]
        Else
          Do While LineCnt.AtEndOfStream <> True
            LineCnt.SkipLine
          Loop
          lineVar = lineCnt.Line-1
          strNewFile = strSaveTo & Left(oFile.name, Len(oFile.name)-4) & _
                       "-" & lineVar & ".txt"
          fso.CopyFile oFile, strNewFile
          LineCnt.Close
          fso.DeleteFile oFile, True
        End If
      Next
    End Sub
    
    Set fso=CreateObject(“Scripting.FileSystemObject”)
    文件夹集=fso.GetFolder(strsavivot)
    设置colFiles=oFolder.Files
    '调用Sub以复制和重命名
    更改文件名
    MsgBox(“文件重命名完成”)
    “退出代码
    子更改文件名(集合集)
    常数ForReading=1
    淡色
    对于集合集中的每个文件
    设置LineCnt=fso.OpenTextFile(oFile,ForReading)
    如果oFile.Size=0,则
    如果不包括这个消息,就会发生奇怪的事情
    MsgBox(“名为“&oFile&_
    “为空。您可能需要验证并手动删除它。”)
    “[我这里有一些删除空文件的代码,但没有任何效果]
    其他的
    当LineCnt.AtEndOfStream为True时执行此操作
    斯基普林线
    环
    lineVar=lineCnt.Line-1
    strNewFile=strsavevot&Left(oFile.name,Len(oFile.name)-4)和_
    “-”&lineVar&“.txt”
    文件的fso.CopyFile,strNewFile
    直线闭合
    fso.DeleteFile文件,True
    如果结束
    下一个
    端接头
    
    我听说有传闻证明
    文件集是“活动”的,这意味着新创建的文件将被添加到集合中并进行迭代,但我找不到任何说明这种或那种方式的文档。在任何情况下,最好先将集合中的
    文件
    对象复制到数组中,然后再对其进行处理:

    Dim oFile
    Dim fileArray()
    Dim i
    
    ReDim fileArray(collectionSet - 1)
    i = 0
    For Each oFile in collectionSet
        Set fileArray(i) = oFile
        i = i + 1
    Next
    
    For Each oFile In fileArray
        ' Count lines and rename
    Next
    

    似乎
    collectionSet
    是您试图修改的文件夹中的文件集合。问题在于,每次通过
    for each
    循环时,都会将文件添加到此文件夹,其中一些文件会反馈到循环中。您需要做的是,在尝试遍历文件夹之前,找到一种获取文件夹快照的方法。实现这一点的方法是用字符串集合替换文件夹
    collectionSet
    ,这些字符串是迭代之前文件的名称,并修改代码以按名称打开文件(而不是通过文件对象)。这样,当您对集合进行迭代时,集合就不会扩展

  • 您应该在所使用的范围内创建变量(例如 文件/文件夹对象在子文件夹中使用
  • 始终显式(ly)声明变量
  • 您不需要复制文件并重命名它,然后执行删除操作。 只需使用
    FileObject.Name
    属性重命名它
  • 以下是一个例子:

    Option Explicit 'always declare your vars!
    
    Dim strFolder:    strFolder = "c:\temp\Rename Test"
    Dim strExtension: strExtension = "txt"
    
    ' Call Sub to rename the files in the folder
    ChangeFileName strFolder, strExtension
    
    Sub ChangeFileName(strFolder, strExtension)
        Const ForReading = 1
        Dim FSO:        set FSO = CreateObject("Scripting.FileSystemObject")
        Dim objFolder:  set objFolder = FSO.GetFolder(strFolder)
        Dim colFiles:   set colFiles = objFolder.Files
        Dim objFile
        Dim intCount
        Dim strFileName
        Dim objTextStream
    
        For Each objFile In colFiles
                msgbox "File: " & objfile.path & vbcrlf & FSO.GetExtensionName(objFile.path)
    
            if UCase(FSO.GetExtensionName(objFile.Path)) = UCase(strExtension) and _ 
               objFile.Size > 0 then
                'set LineCnt = FSO.OpenTextFile(objFile, ForReading)
                set objTextStream = objFile.OpenAsTextStream(ForReading,-2)
                intCount = 0
                strFileName = objFile.Name
                Do While objTextStream.AtEndOfStream <> True 
                    intCount = intCount + 1
                    objTextStream.ReadLine
                Loop
                objTextStream.Close
                objFile.Name = FSO.GetBaseName(objFile.Path) & "-" & _
                               intCount & "." & FSO.GetExtensionName(objFile.Path)
            end if
        Next
    End Sub
    
    Option Explicit'始终声明您的变量!
    Dim strFolder:strFolder=“c:\temp\Rename Test”
    Dim strExtension:strExtension=“txt”
    '调用Sub重命名文件夹中的文件
    更改文件名strFolder,strExtension
    子更改文件名(strFolder、strExtension)
    常数ForReading=1
    Dim FSO:set FSO=CreateObject(“Scripting.FileSystemObject”)
    Dim objFolder:设置objFolder=FSO.GetFolder(strFolder)
    Dim colFiles:set colFiles=objFolder.Files
    Dim objFile
    暗计数
    Dim strFileName
    暗淡的objTextStream
    对于colFiles中的每个objFile
    msgbox“文件:”&objfile.path&vbcrlf&FSO.GetExtensionName(objfile.path)
    如果UCase(FSO.GetExtensionName(objFile.Path))=UCase(strExtension)和
    objFile.Size>0则
    '设置LineCnt=FSO.OpenTextFile(objFile,ForReading)
    设置objTextStream=objFile.OpenAsTextStream(ForReading,-2)
    整数=0
    strFileName=objFile.Name
    当objTextStream.AtEndOfStream为True时执行此操作
    intCount=intCount+1
    objTextStream.ReadLine
    环
    objTextStream,关闭
    objFile.Name=FSO.GetBaseName(objFile.Path)&“-”和_
    intCount&“&&FSO.GetExtensionName(objFile.Path)
    如果结束
    下一个
    端接头
    
    什么是
    collectionSet
    ?我猜您在对集合进行迭代时正在修改集合,这可能会导致不可预测的结果。对固定的字符串集合进行迭代更有意义。很好的答案。OP对其问题的描述非常清楚地证明了
    文件
    对象,正如您所说,他们的代码没有挂在无限循环中,这是一个奇迹。