Excel. Mensaje mientras ejecuta macro para cancelarlo

Estoy buscando la manera de cuando inicio la ejecución de un macro pueda fácilmente anularlo. Mi intención es que salga un mensaje que diga que lo está ejecutando con un botón de cancelar por si se quiere salir en medio del proceso.

1 respuesta

Respuesta
2

Podrías hacerlo si poner la macro en un userform, por ejemplo:

En el botón Inicio pones tu código de la siguiente manera:

Private Sub CommandButton1_Click()
  'Inicio tu código
    'Supongo que tienes un ciclo
    'Inicio ciclo
      'instruciones
      '
      DoEvents
    'Fin ciclo
  'Fin tu código
End Sub

Y en el botón Cancelar el siguiente código:

Private Sub CommandButton2_Click()
  End
End Sub

Ahora, por qué quieres un botón para cancelar? Tu macro tarda mucho en ejecutarse?

¿Cuántos registros tienes que procesar?

Pon aquí tu macro para revisarla, también explica con una imagen qué debe hacer la macro; tal vez pueda mejorarla para que sea más rápida.

Hola, seguro que mi macro se puede mejorar. He ido construyéndolo poco a poco cogiendo cosas por internet. Hace un proceso de búsqueda que a veces puede tardar demasiado.Voy a intentar explicarlo:

-Funcionalidad:

Tengo una carpeta padre con muchas subcarpetas y dentro, otras tantas, y así muchos niveles. Tenemos unas carpetas llamadas "1. Despiece diseño" distribuidas dentro y mezcladas con el resto en distintos niveles dependiendo de los casos. Dentro tenemos unos Excel que listan una serie de referencias. Algunas de estas se asocian a unos archivos con extensiones pdf y dxf con el mismo nombre. Estos archivos están siempre dentro de carpetas llamadas "PDF" (extensiones pdf) y "Despiece" (Extensiones dxf) o en subcarpeta de estas llamada "Otros".

Mi intención es un macro que me saque las rutas de los archivos para poder hacer un hipervínculo en el Excel y poder abrirlos desde ahí ya que se pierde mucho tiempo si hay que buscarlos uno a uno. El problema es que la búsqueda puede tardar mucho si no encuentra los archivos rápido.

-Macro

Primero recorre todas las referencias en la columna M y dependiendo de los valores en columna J manda a buscar, o no, los archivos con las extensiones correspondientes.

Luego saca las rutas por separado en columnas N y O según su extensión. (Para separarlas cree una solución no muy fina).

Hay dos búsquedas. La primera hace un recorrido en la carpeta superior que contiene la subcarpeta "1. Despiece diseño" donde está el Excel ya que hay se encuentran bastantes archivos. Está búsqueda la hace muy rápido y funciona correctamente. La segunda, busca en toda la carpeta padre los archivos que no ha encontrado en la búsqueda anterior. Está búsqueda puede dar problemas cuando hay archivos que se encuentran en un nivel muy bajo de subcarpetas. Para agilizar, estas búsquedas se ha intentado limitar indicando que solo busque archivos en carpetas llamadas "PDF" o "Despiece" , o su subcarpetas que donde están los archivos.

El macro es el siguiente:

----------------

Dim dire As String
Sub AgregaRutas1()

'se establecen la ruta padre
Ruta = "V:\PADRE"

'se recorre la col M desde fila 8 hasta encontrar celda vacía. Fin de rango
[M8].Select
While ActiveCell <> "" And ActiveCell.Offset(0, -1) <> ""
    dato = ActiveCell.Value: dire = ""
    'se mira si en col L hay alguna clave
    If ActiveCell.Offset(0, -1) = "F1" Or ActiveCell.Offset(0, -1) = "F1S" Then   'pdf
        tipo = "pdf"
        Call buscarF(dato, Ruta, tipo)
    ElseIf ActiveCell.Offset(0, -1) = "F2" Or ActiveCell.Offset(0, -1) = "F2S" Then   'pdf
        tipo = "pdf"
        Call buscarF(dato, Ruta, tipo)
    ElseIf ActiveCell.Offset(0, -1) = "S" Or ActiveCell.Offset(0, -1) = "C" Then   'pdf
        tipo = "xlsx"
        dato = "Despiece " & dato
        Call buscarF(dato, Ruta, tipo)
    ElseIf ActiveCell.Offset(0, -1) = "T" Or ActiveCell.Offset(0, -1) = "TS" Then   'las 2
        tipo = "pdf"
        Call buscarF(dato, Ruta, tipo)
        tipo = "dxf"
        Call buscarF(dato, Ruta, tipo)

    End If
    ActiveCell.Offset(0, 1).ClearContents
    ActiveCell.Offset(0, 2).ClearContents
    'Saca las rutas separadas según sea pdf o dxf
    If dire <> "" And tipo = "pdf" Then ActiveCell.Offset(0, 1) = Trim(dire)
    If dire <> "" And tipo = "xlsx" Then ActiveCell.Offset(0, 1) = Trim(dire)
    If dire <> "" And tipo = "dxf" Then
    ActiveCell.Offset(0, 2) = Trim(dire)
    ActiveCell.Offset(0, 1) = Left(Trim(dire), InStrRev(Trim(dire), " V"))
    ActiveCell.Offset(0, 2) = Replace(Trim(dire), ActiveCell.Offset(0, 1), "")
    ActiveCell.Offset(0, 1) = Left(ActiveCell.Offset(0, 1), Len(ActiveCell.Offset(0, 1)) - 1)
    End If
    'continúa con el siguiente registro
    ActiveCell.Offset(1, 0).Select
Wend
MsgBox "Fin del proceso."
End Sub

----------------

Sub buscarF(refer, dir1, exten)

'Genera una ruta especifica donde se encontraran gran parte de los archivos antes de buscar en toda la carpeta padre
Ruta01 = ThisWorkbook.Path
Ruta02 = Left(Trim(Ruta01), InStrRev(Trim(Ruta01), "\"))
Ruta03 = Left(Trim(Ruta02), Len(Trim(Ruta02)) - 1)
Ruta04 = Left(Trim(Ruta03), InStrRev(Trim(Ruta03), "\"))
dir1 = Ruta04

Dim fs, Carpeta, subcarpeta, subcarpeta1, subcarpeta2, subcarpeta3, subcarpeta4
Set fs = CreateObject("Scripting.FileSystemObject")
Set Carpeta = fs.GetFolder(dir1)

'se buscan las subcarpetas dentro de carpeta
    For Each subcarpeta In Carpeta.SubFolders
    If subcarpeta Like "*PDF*" Or subcarpeta Like "*Despiece*" Or Carpeta Like "*PDF*" Or Carpeta Like "*Despiece*" Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece
        For Each Archi In subcarpeta.Files
            If Archi = subcarpeta & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta
            Exit Sub
        End If
        Next
    End If
    For Each subcarpeta1 In subcarpeta.SubFolders
    If subcarpeta1 Like "*PDF*" Or subcarpeta1 Like "*Despiece*" Or subcarpeta Like "*PDF*" Or subcarpeta Like "*Despiece*" Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece
        For Each Archi In subcarpeta1.Files
            If Archi = subcarpeta1 & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta1
            Exit Sub
        End If
        Next
    End If
    For Each subcarpeta2 In subcarpeta1.SubFolders
    If subcarpeta2 Like "*PDF*" Or subcarpeta2 Like "*Despiece*" Or subcarpeta1 Like "*PDF*" Or subcarpeta1 Like "*Despiece*" Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece
        For Each Archi In subcarpeta2.Files
        If Archi = subcarpeta2 & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta2
            Exit Sub
        End If
        Next
    End If
    For Each subcarpeta3 In subcarpeta2.SubFolders
    If subcarpeta3 Like "*PDF*" Or subcarpeta3 Like "*Despiece*" Or subcarpeta2 Like "*PDF*" Or subcarpeta2 Like "*Despiece*" Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece
        For Each Archi In subcarpeta3.Files
        If Archi = subcarpeta3 & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta3
            Exit Sub
        End If
        Next
        End If
   For Each subcarpeta4 In subcarpeta3.SubFolders
    If subcarpeta4 Like "*PDF*" Or subcarpeta4 Like "*Despiece*" Or subcarpeta3 Like "*PDF*" Or subcarpeta3 Like "*Despiece*" Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece
        For Each Archi In subcarpeta3.Files
        If Archi = subcarpeta4 & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta3
            Exit Sub
        End If
        Next
        End If
    Next
    Next
    Next
    Next
Next

----------------

Call buscarF1(refer, dir1, exten)

End Sub

Sub buscarF1(refer, dir2, exten)

dir2 = "V:\PADRE\"
Ruta01 = ThisWorkbook.Path
Ruta02 = Left(Trim(Ruta01), InStrRev(Trim(Ruta01), "\"))
Ruta03 = Left(Trim(Ruta02), Len(Trim(Ruta02)) - 1)
Ruta04 = Left(Trim(Ruta03), InStrRev(Trim(Ruta03), "\"))

Dim fs, Carpeta, subcarpeta, subcarpeta1, subcarpeta2, subcarpeta3, subcarpeta4
Set fs = CreateObject("Scripting.FileSystemObject")
Set Carpeta = fs.GetFolder(dir2)

'se busca el archivo. Si no está se recorren las subcarpetas
For Each Archi In Carpeta.Files
  If Archi = Carpeta & "\" & refer & "." & exten Then
      dire = dire & " " & Carpeta
      Exit Sub
  End If
Next
'se buscan las subcarpetas dentro de carpeta
    For Each subcarpeta In Carpeta.SubFolders
    If subcarpeta Like "*PDF*" Or subcarpeta Like "*Despiece*" Or Carpeta Like "*PDF*" Or Carpeta Like "*Despiece*" And subcarpeta <> Ruta04 Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece, menos en la buscada ya en llamada anterior
        For Each Archi In subcarpeta.Files
            If Archi = subcarpeta & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta
            Exit Sub
        End If
        Next
    End If
    For Each subcarpeta1 In subcarpeta.SubFolders
    If subcarpeta1 Like "*PDF*" Or subcarpeta1 Like "*Despiece*" Or subcarpeta Like "*PDF*" Or subcarpeta Like "*Despiece*" And subcarpeta1 <> Ruta04 Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece, menos en la buscada ya en llamada anterior
        For Each Archi In subcarpeta1.Files
            If Archi = subcarpeta1 & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta1
            Exit Sub
        End If
        Next
    End If
    For Each subcarpeta2 In subcarpeta1.SubFolders
    If subcarpeta2 Like "*PDF*" Or subcarpeta2 Like "*Despiece*" Or subcarpeta1 Like "*PDF*" Or subcarpeta1 Like "*Despiece*" And subcarpeta2 <> Ruta04 Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece, menos en la buscada ya en llamada anterior
        For Each Archi In subcarpeta2.Files
        If Archi = subcarpeta2 & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta2
            Exit Sub
        End If
        Next
    End If
    For Each subcarpeta3 In subcarpeta2.SubFolders
    If subcarpeta3 Like "*PDF*" Or subcarpeta3 Like "*Despiece*" Or subcarpeta2 Like "*PDF*" Or subcarpeta2 Like "*Despiece*" And subcarpeta3 <> Ruta04 Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece, menos en la buscada ya en llamada anterior
        For Each Archi In subcarpeta3.Files
        If Archi = subcarpeta3 & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta3
            Exit Sub
        End If
        Next
        End If
   For Each subcarpeta4 In subcarpeta3.SubFolders
    If subcarpeta4 Like "*PDF*" Or subcarpeta4 Like "*Despiece*" Or subcarpeta3 Like "*PDF*" Or subcarpeta3 Like "*Despiece*" And subcarpeta4 <> Ruta04 Then
    'a continuación se miran los archivos solo dentro de carpetas llamadas PDF o Despiece, menos en la buscada ya en llamada anterior
        For Each Archi In subcarpeta3.Files
        If Archi = subcarpeta4 & "\" & refer & "." & exten Then
            dire = dire & " " & subcarpeta3
            Exit Sub
        End If
        Next
        End If
    Next
    Next
    Next
    Next
Next

End Sub

----------------

Gracias por su atención

Prueba la siguiente macro:

Mi intención es un macro que me saque las rutas de los archivos para poder hacer un hipervínculo en el Excel y poder abrirlos desde ahí ya que se pierde mucho tiempo si hay que buscarlos uno a uno.

Supongo que los nombres de archivo están en la columna "M" y empiezan en la celda M8.

Los nombres de archivo no tienen extensión, como se muestra en el siguiente ejemplo:

La macro va a buscar en todas las carpetas, y si encuentra un archivo que existe en varias carpetas entonces te desplegará hacia la derecha las carpetas y el nombre del archivo con su extensión.


Solamente cambia en la macro la ruta inicial y el nombre de la hoja donde tienes tus referencias.

Dim rutas As New Collection
Sub Buscar_Archivos()
'DECLARACIÓN DE VARIABLES
  Dim sPath As String, sNombre As String, sCar As Variant
  Dim arch As Variant, sd As Variant, a As Variant, b() As Variant
  Dim sh1 As Worksheet, dic As Object
  Dim i As Long, n As Long, j As Long
  '
  Application.ScreenUpdating = False
  Application.DisplayAlerts = False
  '
'ENTRADA
  Set sh1 = Sheets("Referencias")
  sh1.Range("N8", sh1.Cells(Rows.Count, Columns.Count)).ClearContents
  'CARGA en a todas las referencias
  a = sh1.Range("M8", sh1.Range("M" & Rows.Count).End(3)).Value2
  ReDim b(1 To UBound(a), 1 To 2)
  Set dic = CreateObject("Scripting.Dictionary")
  'CARGA en rutas todas las carpetas
  Set rutas = Nothing
  sPath = "C:\trabajo\"
  rutas.Add sPath
  Call AddSubDir(sPath)
  '
'PROCESO
  For Each sd In rutas
    arch = Dir(sd & "\*.*")
    Do While arch <> ""
      If InStrRev(arch, ".") > 0 Then
        sNombre = Left(arch, InStrRev(arch, ".") - 1)
        'Carga en dic todos los archivos
        dic(sNombre) = dic(sNombre) & "|" & sd & IIf(Right(sd, 1) = "\", "", "\") & arch
      End If
      arch = Dir()
    Loop
  Next
  '
  'Busca las referencias en Dic
  For i = 1 To UBound(a)
    If dic.exists(a(i, 1)) Then
      sCar = Split(Mid(dic(a(i, 1)), 2), "|")
      For j = 0 To UBound(sCar)
        b(i, j + 1) = sCar(j)
      Next
    End If
  Next
'SALIDA
  sh1.Range("N8").Resize(UBound(b, 1), UBound(b, 2)).Value = b
End Sub
'
Sub AddSubDir(lPath As Variant)
  Dim SubDir As New Collection, DirFile As Variant, sd As Variant
  If Right(lPath, 1) <> "\" Then lPath = lPath & "\"
  DirFile = Dir(lPath & "*", vbDirectory)
  Do While DirFile <> ""
    If DirFile <> "." And DirFile <> ".." Then _
      If ((GetAttr(lPath & DirFile) And vbDirectory) = 16) Then SubDir.Add lPath & DirFile
    DirFile = Dir
  Loop
  For Each sd In SubDir
    rutas.Add sd
    Call AddSubDir(sd)
  Next
End Sub

Si tienes alguna duda o cambio, sería conveniente crear una nueva pregunta que hable sobre el tema de buscar archivos.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas