0

私は vbscripting を初めて使用し、これらのファイルを別のディレクトリに移動できるように、ファイル名に一致する文字列を含む 6 つのファイルを見つける必要があるというタスクを受け取りました。ファイル名内のすべての文字列を見つけるために、正規表現パターン「\d{8}-\d{6}」を使用しています。

ディレクトリで検索を行い、ファイル名に一致する文字列を持つ6つのファイルがあるかどうかを確認して、それらを配列に保存してからファイルを別のディレクトリに移動できるようにするにはどうすればよいですか?

これまでに書いたスクリプト:

Set objFS = CreateObject("Scripting.FileSystemObject")

strShareDirectory = "in\"
strDumpStorageDir = "out\"

Set objFolder = objFS.GetFolder(strShareDirectory)
Set colFiles = objFolder.Files

Set re = New RegExp
re.Global     = True
re.IgnoreCase = False
re.Pattern    = "-\d{8}-\d{6}"

Dim curFile, matchValue
Dim i: i = 0

For Each objFile in colFiles
   bMatch = re.Test(objFile.Name)
   curFile = objFile.Name

   If bMatch Then
      ReDim preserve matches(i)
      Matches(i) = curFile
      i = (i + 1)

      For Each objFile1 in colFiles
        If objFile1.Name <> objFile.Name Then
            For each match in re.Execute(objFile1.Name)
                matchValue = match.Value
                Exit For
            Next
            If (Instr(curFile, matchValue) > 0) Then
                matchCount = 1
                For Each match1 in re.Execute(objFile1.Name)
                    curFile1 = objFile1.Name
                    matchValue1 = match1.Value
                    Exit For
                    'If  Then

                Next
                'msgbox(curFile1)
            End If
     End If
    Next
   End If
Next

これが、私が使用しているサンプル ディレクトリの外観です。 ここに画像の説明を入力

4

2 に答える 2

3

@KekuSemau の提案はファイルのグループ化の (サブ) 問題に対処していないため、dweebles は完全なストーリーを提供しません (なぜ配列なのか? ファイルの完全な (サブ) セットを持つことを主張するのはなぜですか?)、および数値 (グループの 6、ファイル名の 3/4 の部分) は、基本的なタスクには実際には関係ありません - ファイル名の部分に基づいて、セットのファイルをフォルダーに配布します - 私は、タスクを解決する方法は取り除くことであると主張しますすべての配列、辞書、および正規表現の空想をシンプルに保ちます。

前:

tree /A /F ..\data
+---in
|       B-2
|       B-1
|       A-3
|       A-2
|       B-3
|       A-1
|
\---out

コード:

  Const csSrc = "..\data\in"
  Const csDst = "..\data\out"
  Dim f, n, d
  For Each f In goFS.GetFolder(csSrc).Files
      n = Split(f.Name, "-")
      If 1 = UBound(n) Then
         d = goFS.BuildPath(csDst, n(1))
         If Not goFS.FolderExists(d) Then goFS.CreateFolder d
         f.Move goFS.BuildPath(d, f.Name)
      End If
  Next

後:

tree /A /F ..\data
+---in
\---out
    +---3
    |       A-3
    |       B-3
    |
    +---1
    |       B-1
    |       A-1
    |
    \---2
            B-2
            A-2

PS この問題は、同じアプローチを使用して解決できます。

于 2013-01-18T21:07:51.680 に答える
1

ああ、今、私は理解しています。したがって、同じ一致する部分文字列を持つファイルが少なくとも 6 つある場合、パターンに一致するすべてのファイル名が必要です。わかった。次に、はい、ネストされた for..next ループで首を絞められる可能性があることを理解しています。その場合は、いくつかのコードを追加の関数に入れることをお勧めします。
このソリューションでは、辞書を使用していくつかの作業をはるかに簡単に行います (「exists」へのすべての呼び出しは、たとえば、すべての要素に対する別のネストされた反復であり、すべての割り当ても同様です)。
この例では、1 つのファイル名内の複数の一致は無視されます。

option explicit

dim objFS : dim strShareDirectory : dim strDumpStorageDir : dim objFolder : dim colFiles : dim re : dim objFile

dim dictResults ' dictionary of [filename] -> [matching substring]
dim dictResultsCount ' dictionary of [matching substring] -> [count]
dim dictResultsFinal ' only the valid entries from dictResults
dim keyItem 
dim strMatch

set dictResultsFinal = CreateObject("Scripting.Dictionary")
set dictResults = CreateObject("Scripting.Dictionary")
set dictResultsCount = CreateObject("Scripting.Dictionary")

Set objFS = CreateObject("Scripting.FileSystemObject")

strShareDirectory = "in\"
strDumpStorageDir = "out\"

Set objFolder = objFS.GetFolder(strShareDirectory)
Set colFiles = objFolder.Files

Set re = New RegExp
re.Global     = True
re.IgnoreCase = False
re.Pattern    = "-\d{8}-\d{6}"

Dim curFile, matchValue
Dim i: i = 0

For Each objFile in colFiles
    ' test if the filename matches the pattern
    if re.test(objFile.Name) then
        ' for now, collect all matches without further checks
        strMatch = re.execute(objFile.Name)(0)
        dictResults(objFile.Name) = strMatch
        ' and count
        if not dictResultsCount.Exists(strMatch) then
            dictResultsCount(strMatch) = 1
        else
            dictResultsCount(strMatch) = dictResultsCount(strMatch) +1
        end if
    end if
next

' for testing: output all filenames that match the pattern
msgbox join(dictResults.keys(), vblf)

' now copy only the valid entries into a new dictionary
for each keyItem in dictResults.keys()
    if dictResultsCount.Exists( dictResults(keyItem) ) then
        if dictResultsCount( dictResults(keyItem) ) >= 6 then
            dictResultsFinal(keyItem) = 1
        end if
    end if
next

' test output the final result
msgbox join(dictResultsFinal.keys(), vblf)

--- 私の最初の答え

さて、私はおそらくあなたが何を試したのか尋ねる必要がありますが... これがあなたの例です^^. これで開始するのに十分なはずです(あなたが言及した「6」の要件は無視しました)。さらに説明が必要かどうか尋ねます。

Option explicit
dim a
a = findFiles("G:\",  "\d{8}-\d{6}")
msgbox join(a, vblf)

function findFiles(path, pattern)
    dim rx
    dim fso
    dim fsoFolder
    dim fsoFiles
    dim results
    dim item
    set rx = new regexp
    rx.pattern =  pattern
    set results = CreateObject("Scripting.Dictionary")
    set fso = CreateObject("Scripting.FileSystemObject")
    set fsoFolder = fso.GetFolder(path)
    set fsoFiles = fsoFolder.Files
    for each item in fsoFiles
        if rx.test(item.name) then results(item.name) = 1
    next
    set fso = nothing
    set fsoFolder = nothing
    set fsoFiles = nothing
    findFiles = results.keys()
end function
于 2013-01-18T17:18:21.463 に答える