试图了解您的问题/规格。假设对 .pdf 文件夹的文件进行循环会导致:
Looking at "0000000000012345.20120402.pdf"
Looking at "0000000000012345.20120502.pdf"
Looking at "0000000000012348.20121702.pdf"
Looking at "0000000000012346.20120802.pdf"
Looking at "0000000000012347.20121002.pdf"
Looking at "0000000000012348.20121602.pdf"
Looking at "0000000000012347.20121302.pdf"
Looking at "0000000000012347.20121202.pdf"
Looking at "0000000000012345.20120202.pdf"
Looking at "0000000000012348.20121502.pdf"
Looking at "0000000000012346.20120602.pdf"
Looking at "0000000000012346.20120902.pdf"
Looking at "0000000000012348.20121402.pdf"
Looking at "0000000000012346.20120702.pdf"
Looking at "0000000000012347.20121102.pdf"
Looking at "0000000000012345.20120302.pdf"
会
Last file for 0000000000012345 is 0000000000012345.20120502.pdf
Last file for 0000000000012348 is 0000000000012348.20121702.pdf
Last file for 0000000000012346 is 0000000000012346.20120902.pdf
Last file for 0000000000012347 is 0000000000012347.20121302.pdf
确定要正确复制的文件?如果是,请说出来,我会在此处发布代码。
首先,您需要一个类来获取并存储放入文件名中的信息:
' cut & store info about file(names) like "0000000000012347.20121202.pdf"
Class cCut
Private m_sN ' complete file name
Private m_sG ' group/number prefix part
Private m_dtF ' date part; converted to ease comparisons
Public Function cut(reCut, sFiNa)
Set cut = Me ' return self/this from function
Dim oMTS : Set oMTS = reCut.Execute(sFiNa)
If 1 = oMTS.Count Then
m_sN = sFiNa
Dim oSM : Set oSM = oMTS(0).SubMatches
m_sG = oSM(0)
m_dtF = DateSerial(oSM(1), oSM(3), oSM(2))
Else
' Err.Raise
End If
End Function ' cut
Public Property Get G() : G = m_sG : End Property ' G
Public Property Get D() : D = m_dtF : End Property ' D
Public Property Get N() : N = m_sN : End Property ' N
End Class ' cCut
然后只需遍历 .Files 并检查存储在字典中的每个组的日期部分(数字前缀部分用作键):
' The one and only .pdf folder - no recursion into subfolders!
Dim sTDir : sTDir = "..\data\test"
' dictionary to store the last/most recently used file for each group
Dim dicG : Set dicG = CreateObject("Scripting.Dictionary")
' RegExp to cut/parse file names like "0000000000012345.20120402.pdf"
Dim reCut : Set reCut = New RegExp
reCut.Pattern = "^(\d{16})\.(\d{4})(\d{2})(\d{2})\.pdf$"
Dim oFile
For Each oFile In goFS.GetFolder(sTDir).Files
WScript.Echo "Looking at", qq(oFile.Name)
' an oCut object for each file name
Dim oCut : Set oCut = New cCut.cut(reCut, oFile.Name)
If Not dicG.Exists(oCut.G) Then
' new group, first file, assume this is the latest
Set dicG(oCut.G) = oCut
Else
' found a better one for this group?
If dicG(oCut.G).D < oCut.D Then Set dicG(oCut.G) = oCut
End If
Next
WScript.Echo "-----------------------"
Dim sG
For Each sG In dicG.Keys
WScript.Echo "Last file for", sG, "is", dicG(sG).N
Next
WRT cmets:
我所有的(临时/概念证明)脚本都以
开头
Option Explicit
Dim goFS : Set goFS = CreateObject( "Scripting.FileSystemObject" )
并包含一些处理不同方面/策略的函数,以解决常见问题/主题。当我在这里发布代码时,我会从函数框架的中间复制/粘贴工作/测试代码,例如
' ============================================================================
goXPLLib.Add _
"useDic02", "use a dictionary (Mark II)"
' ----------------------------------------------------------------------------
' ============================================================================
Function useDic02()
useDic02 = 1 ' assume error
' The one and only .pdf folder - no recursion into subfolders!
...
Next
useDic02 = 0 ' success
End Function ' useDic02
(是的,有一个第一次尝试函数“useDic()”,它存储了每个组的所有 oCuts,以便在第二个循环中处理;是的,我需要一个函数“createTestData()”设置/填写我的 TDir)。有时我很马虎,忘记了goFS,请接受我的道歉。
变量名称是实验的一部分。我曾经提倡以类型为前缀的长变量名,包括
Dim nIdx
For nIdx = 0 To UBound(aNames)
aNames(nIdx) = ...
Next
其他人认为 nIdx-alikes 变量只是添加了一些字母以错误输入,但对 i 没有其他含义,并且 aNames-alikes 不能在没有上下文的情况下被理解,如果你有这个,aN 会一样好“当前处理文件中要与数据库中的名称进行比较的波斯国王的名字”的余数。
所以我想:鉴于文件名有 3 个有趣的方面(要复制的全名、要复制的全名、要分组的数字前缀、要比较/决定的日期部分)并且之间有半个屏幕
Private m_sN ' complete file name
和
Public Property Get N() : N = m_sN : End Property ' N
假设您只需要 Cut 对象的这 3 个属性就可以在其中使用它
Dim oCut : Set oCut = New cCut.cut(reCut, oFile.Name)
If Not dicG.Exists(oCut.G) Then
' new group, first file, assume this is the latest
Set dicG(oCut.G) = oCut
Else
' found a better one for this group?
If dicG(oCut.G).D < oCut.D Then Set dicG(oCut.G) = oCut
平均短时记忆能否应对 oCut.D?
显然不是。
复制所选文件:
假设您希望将文件复制到现有文件夹“..\data\latest”,请使用
goFS.CopyFile goFS.BuildPath(sTDir, dicG(sG).N), "..\data\latest\", True
代替/除了线
WScript.Echo "Last file for", sG, "is", dicG(sG).N
我没有预料到 .CopyFile 会在相对源路径上阻塞;所以考虑用 *P*ath 属性替换 cCut 类的 *N*ame 属性。
尝试使用
dicG(sG).Copy "..\data\latest\", True
结果:
Microsoft VBScript runtime error: Object doesn't support this property or method: 'dicG(...).Copy'
因为存储的对象不是文件(有 .Copy 方法),而是 cCuts(没有)。