Access

Buscar el archivo más reciente con un nombre similar en una carpeta

Estaba trabajando en un proyecto y me encontré con un pequeño problema. Verás, creé un programa que procesa archivos generados por una aplicación web y que se descargan en la PC del usuario. El problema es que si el archivo ya existe, Windows agrega un prefijo numérico para diferenciar los archivos.


Entonces, digamos que los archivos originales se llamaban ‘DataArchive.zip’, las descargas posteriores dan como resultado

  • Archivo de datos.zip’
  • Archivo de datos (1).zip’
  • Archivo de datos (2).zip’
  • Archivo de datos (3).zip’

Bueno, eso es en Windows 10. Microsoft intentó ayudarnos y en Windows 11 ahora agrega un espacio adicional, por lo que obtenemos:

  • Archivo de datos.zip’
  • Archivo de datos (1).zip’
  • Archivo de datos (2).zip’
  • Archivo de datos (3).zip’

Ya sabes, sólo para darle un poco de vida a nuestra vida de codificación.

Busqué en Google, pensando que no sería el primer desarrollador que necesitara hacer este tipo de cosas, pero no encontré nada. Mi GoogleFu no estaba a la altura.

Por eso, me propuse crear algo por mi cuenta. Quería idear una forma «sencilla» de buscar en una carpeta, en este caso la carpeta de descargas, el último archivo descargado con un patrón de nombre determinado.

¿Cómo se podría hacer?

Bueno, terminé recurriendo al objeto del sistema de archivos (FSO). Esperaba poder usar simplemente Dir(), pero no me proporcionó acceso a las propiedades de archivo necesarias que sí ofrecía FSO.

Esto es lo que se me ocurrió:

'---------------------------------------------------------------------------------------
' Procedure : FindLatestFile
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : 
' Purpose   : Find the latest (DateCreated) file based on a search pattern
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - 
' Req'd Refs: Late Binding  -> none required
' References:
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPath             : Directory to search through
' sSearchPattern    : Search pattern to use to identify matching files
'
' Usage:
' ~~~~~~
' FindLatestFile("C:\Users\Dev\Downloads\", "DataArchive (*).zip")
'   Returns -> DataArchive (4).zip
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2024-07-15              Initial Public Release
'---------------------------------------------------------------------------------------
Function FindLatestFile(ByVal sPath As String, _
                        ByVal sSearchPattern As String) As Variant
On Error GoTo Error_Handler
    Dim oFSO                  As Object    'Scripting.FileSystemObject
    Dim oFolder               As Object    'Scripting.Folder
    Dim oFile                 As Object    'Scripting.File
    Dim dtCurrFileDt          As Date
    Dim dtFileDt              As Date
    Dim CurrentRow            As Long
    Dim sOutputFile           As String

    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oFolder = oFSO.GetFolder(sPath)

    For Each oFile In oFolder.Files
        If oFile.Name Like sSearchPattern Then
            dtCurrFileDt = oFile.DateCreated
            If CurrentRow = 0 Then
                dtFileDt = oFile.DateCreated
                sOutputFile = oFile.Name
            Else
                If dtCurrFileDt > dtFileDt Then
                    dtFileDt = oFile.DateCreated
                    sOutputFile = oFile.Name
                End If
            End If
            CurrentRow = CurrentRow + 1
        End If
    Next oFile

    If sOutputFile = "" Then
        FindLatestFile= Null
    Else
        FindLatestFile= sOutputFile
    End If
 
Error_Handler_Exit:
    On Error Resume Next
    Set oFile = Nothing
    Set oFolder = Nothing
    Set oFSO = Nothing
    Exit Function
 
Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Source: FindLatestFile" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl  0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

y un ejemplo de su uso podría ser:

sArchive = FindLatestFile("C:\Users\Dev\Downloads\", "DataArchive(*).zip") 'Windows 10 Search Pattern
If IsNull(sArchive) Then sArchive = FindLatestFile("C:\Users\Dev\Downloads\", "DataArchive (*).zip") 'Windows 11 Search Pattern
If IsNull(sArchive) Then sArchive = "DataArchive.zip" 'If none found fall back to the original filename
'Check if sArchive Exist ...

y esto se puede utilizar para todo tipo de otros escenarios, todo lo que tienes que hacer es cambiar sSearchPattern por el patrón que satisfaga tus necesidades.

En una versión futura, permitiré múltiples patrones en lugar de requerir procesar una carpeta varias veces, para mejorar el rendimiento, pero eso será para otro día.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Mira también
Cerrar
Botón volver arriba