【问题标题】:Check directories for file containing cell data then add text to another cell检查包含单元格数据的文件的目录,然后将文本添加到另一个单元格
【发布时间】:2022-08-08 20:10:14
【问题描述】:

在我看来,这听起来很简单,但我很快发现我对如何进行的问题比我最初想象的要多。例如,我如何循环它通过几个目录?如何让它不在 LogNumber \"1001\" 中包含 LogNumber \"1\"? ETC

我会尽量保持简单,以后可以更改单元格和文件夹等。

假设,我在 A 和 B 列中有一张表格,标题在第 1 行;

Log Number Document Tracker
1001 NBI
101001 Authorized
2001 NBI
202001 Authorized
2003 Awaiting Check
3004 Rejected

在这种情况下,我在几个文件夹中有文件,以反映表格。

\"1001 Supplier A.pdf\" 位于文件夹 \"C:\\Documents\\Files\\NBI\"

\"101001 Supplier A.pdf\" 位于文件夹 \"C:\\Documents\\Files\\Authorized\"

\"2001 Supplier B.pdf\" 位于文件夹 \"C:\\Documents\\Files\\NBI\"

\"202001 Supplier C.pdf\" 位于文件夹 \"C:\\Documents\\Files\\Authorized\"

\"2003 Supplier B.pdf\" 位于文件夹 \"C:\\Documents\\Files\\Awaiting Check\"

\"3004 Supplier F.pdf\" 位于文件夹 \"C:\\Documents\\Processed\\Rejected\"

我希望 vba 脚本在上面的文件夹位置中搜索包含匹配日志编号的文件。然后,如果存在这样的文件,它将在 Document Tracker 列中放入一些相关文本,不一定是文件夹名称。因此,如果它在文件夹 \"NBI\" 中,它会在相关单元格中显示 \"NBI\"。

有任何想法吗?

  • “1001 Supplier A.pdf”是通用名称吗?我的意思是,应该以所谓的长号(LN)开头,或者这个 LN 必须只是它的一部分?那么,LN 后面会跟字符串 \"Supplier\" 吗?
  • This answer 应该提供一些入门帮助。
  • @FaneDuru 是的,文件以 LN 开头,然后是供应商,然后是与此主题无关​​的另一个数字。
  • 我调整了我的答案以处理上述评论中描述的情况。它应该适用于所有人......
  • @PeterT 感谢我将研究它的链接,它似乎与我所问的内容有关,而且我还看到了其他一些相关的内容,例如.. stackoverflow.com/questions/53443778/… 这似乎也很接近。

标签: excel vba


【解决方案1】:

假设文件名以 Long Number 开头,后跟“Suppl”,请尝试下一个代码。它将通过在arrFin 中添加“确定”返回所有文件确认的路径。 arrFin 的内容在 C:C 列中被删除,但可以在任何需要的地方删除:

Sub MatchFileExistence()
 Dim sh As Worksheet, lastR As Long, arr, arrFin, i As Long
 Const comPath As String = "C:\Documents\Files\"
 
 Set sh = ActiveSheet
 lastR = sh.Range("A" & sh.rows.count).End(xlUp).row 'last row in column A:A
 
 arr = sh.Range("A2:B" & lastR).Value2
 ReDim arrFin(1 To UBound(arr), 1 To 1) 'redim the array to keep the existence confirmation
 
 For i = 1 To UBound(arr)
    If Dir(comPath & arr(i, 2) & "\" & arr(i, 1) & " Supp*.pdf") <> "" Then
        arrFin(i, 1) = "OK" 'use here what confirmation string you need...
    End If
 Next i
 'drop the processed array result:
 sh.Range("C2").Resize(UBound(arrFin), 1).Value2 = arrFin
End Sub

请在测试后发送一些反馈。

已编辑

请测试下一个版本。它将检查 arrFolders 数组中所有文件夹中 A:A 列中的所有长数字,并返回找到该文件的子文件夹。如果在很多地方找到它,它将返回以“|”分隔的位置:

Sub MatchFileExistence()
 Dim sh As Worksheet, lastR As Long, arr, arrFin, El, arrFolders, i As Long
 Const comPath As String = "C:\Teste VBA Excel\Folders\"  '"C:\Documents\Files\"
 arrFolders = Split("NBI,Authorized,Awaiting Check,Rejected", ",") 'place subfolders in a list
 
 Set sh = ActiveSheet
 lastR = sh.Range("A" & sh.rows.count).End(xlUp).row 'last row in column A:A
  'in case of placing the necessary folders in column B:B, please uncomment the next line
 'arrFolders = sh.Range("B2", sh.Range("B" & sh.rows.count).End(xlUp)).Value2

 arr = sh.Range("A2:A" & lastR).Value2
 ReDim arrFin(1 To UBound(arr), 1 To 1) 'redim the array to keep the existence confirmation
 
 For Each El In arrFolders
        For i = 1 To UBound(arr)
           If Dir(comPath & El & "\" & arr(i, 1) & " *.pdf") <> "" Then
               If arrFin(i, 1) = "" Then
                    arrFin(i, 1) = El
                Else
                    arrFin(i, 1) = arrFin(i, 1) & "|" & El
                End If
           End If
        Next i
 Next El
 'drop the processed array result:
 sh.Range("C2").Resize(UBound(arrFin), 1).Value2 = arrFin
End Sub

它将处理结果从第二行开始放在同一 C:C 列中。

如果您打算将文件夹放在一个范围内(在一列上,让我们说 B:B),请取消注释行 'arrFolders = sh.Range("B2", sh.Range("B" &amp; sh.rows.count).End(xlUp)).Value2... 如果不是 B:B,请更新代码以匹配实际使用的列。

已编辑

请测试下一个版本。它将首先返回根文件夹及其所有子文件夹的出现数组,然后将评估该数组以提取文件夹:

Sub MatchFileExistenceX()
 Dim sh As Worksheet, lastR As Long, arr, arrFin, i As Long, arrFiles, El, arrFld
 Const comPath As String = "C:\Documents\Files\"
 
 Set sh = ActiveSheet
 lastR = sh.Range("A" & sh.rows.count).End(xlUp).row 'last row in column A:A
 
 arr = sh.Range("A2:B" & lastR).Value2
 ReDim arrFin(1 To UBound(arr), 1 To 1) 'redim the array to keep the existence confirmation
 
 For i = 1 To UBound(arr)
   If Not IsError(arr(i, 1)) Then
     arrFiles = getAllFls(comPath, arr(i, 1) & " *.pdf")
     If UBound(arrFiles) > -1 Then
        For Each El In arrFiles
             arrFld = Split(El, "\")
             If arrFin(i, 1) = "" Then
                    arrFin(i, 1) = arrFld(UBound(arrFld) - 1)
             Else
                    arrFin(i, 1) = arrFin(i, 1) & "|" & arrFld(UBound(arrFld) - 1)
             End If
        Next El
     End If
   End if
 Next i
 'drop the processed array result:
 sh.Range("C2").Resize(UBound(arrFin), 1).Value2 = arrFin
End Sub

Private Function getAllFls(strFold As String, Optional strExt As String = "*.*") As Variant
    getAllFls = filter(Split(CreateObject("wscript.shell").exec("cmd /c dir """ & strFold & strExt & """ /b/s").StdOut.ReadAll, vbCrLf), "\")
End Function

请使用 comPath 作为包含所有其他子文件夹的根文件夹...

现在我要离开我的办公室了。如果有不清楚的地方,请要求澄清,但我会在家时回答。

【讨论】:

  • 嗨,Fane,这实际上效果很好,谢谢你。有一些相关的反馈,你确实已经触及了一点,但我会在这里展开。首先,我注意到它只能搜索 1 个文件夹,即 comPath 中提供的文件夹。但它需要检查文件的多个位置。其次,如前所述,如果有“1”和“101”,两者都会被“1”触发。这可能不是什么大问题,因为我相信这些文件的处理速度相对较快,而且数量已经很大,所以这种情况很少发生。作为如何文件的示例
  • 贴上标签,会是这样的; “2000182 Google 2918.pdf” “2000183 Apple 3896.pdf” “2000184 Currys 1239.pdf” 第二个数字与此任务无关。电子表格中的供应商名称 IS 是必需的,位于单独的列中。第三,脚本所需的一项最重要任务是,它不只是说“确定”,而是将文本插入与它找到文件的文件夹相关的单元格中。如果它在文件夹“NBI”中找到它,它应该说“NBI”如果它在文件夹“Tony”中找到它需要说“等待授权”我希望这是有道理的?我很感激到目前为止的帮助
  • @InvkrMainr 恐怕,这没有更多意义......你说“是的,文件以 LN 开头,然后是供应商”,但我可以看到,现在将文件命名为“2000182 Google ...” , “2000184 Currys ...”,不尊重模式的一致性。那么,“文档跟踪器”应该是什么?找到文件的文件夹?我知道它是搜索路径的一部分......所以,如果我要说你想要搜索所有长号码,后跟一个空格一些文件夹,会是正确的理解吗?如果是这样,从哪里获取文件夹列表?
  • 抱歉,我的意思是“供应商”作为变量。我只是使用“供应商”,因为我不想提供具体名称。 “Document Tracker”将是文本,与在哪个文件夹中找到文件有关。例如,如果在“NBI”中找到文件,则单元格应显示“NBI”,如果在“Tony”中找到,则应显示“等待授权” " 如果在“已拒绝”中找到,则应显示“已拒绝”。如果有我可以添加的框架,我可以解决这个问题。您的理解似乎是正确的,如果这样更容易,我可以将文件夹列表放入电子表格本身。只需将它指向一个列/范围,我就可以修改。
  • @InvkrMainr 是否理解所有文件夹根目录都是我用作常量的目录,是否正确?然后,我不明白为什么如果在“托尼”中找到它应该说“等待授权”而不是“托尼”,根据你之前设定的规则......
猜你喜欢
  • 1970-01-01
  • 2017-04-29
  • 2017-06-12
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多