jueves, 3 de noviembre de 2016

VBA: Función FileCopy para copiar y mover ficheros desde Excel

Tocaremos un tema interesante y recurrente. La gestión de ficheros y carpetas desde Excel.
En particular hoy aprenderemos a usar la función VBA FileCopy.

Esta función se engloba en un conjunto de funciones de 'archivo/carpeta' como pueden ser (algunas ya vistas en el blog):
ChDir
ChDrive
Dir
FileCopy
FileDateTime
FileLen
GetAttr
Kill
MkDir
SetAttr
(en orden alfabético).


La que toca hoy FileCopy realiza un trabajo simple: copia un archivo desde una ubicación a otra.

Imaginemos el siguiente trabajo. Tenemos un listado en nuestra hoja de Excel donde disponemos de las equivalencias de una serie de archivos. Esta equivalencia responde a 'ubicación original' vs 'ubicación destino':

VBA: Función FileCopy para copiar y mover ficheros desde Excel



Notemos que al rango de celdas D2:D4 se le ha asignado un nombre definido 'origen', con el fin de facilitar el trabajo, y resulte más visual.

En un módulo estándar de nuestro proyecto de VB insertamos la siguiente macro 'CopiarARchivos':

Sub CopiarArchivos()
'recorremos cada celda del rango 'origen'
For Each celda In Range("origen")
    'determinamos la ruta original
    origen = celda.Value
    'y cuál es el destino
    destino = celda.Offset(0, 1).Value
    'con la función FileCopy copiamos de un lugar a otro
    FileCopy origen, destino
Next celda
End Sub



Tras ejecutar nuestro procedimiento, comprobaremos el resultado... ambos archivos ha sido pegados en su ubicación definitiva... incluso con el nuevo nombre de archivo.

VBA: Función FileCopy para copiar y mover ficheros desde Excel

Nota importante: Las rutas deben existir!!


OJO!!, no confundir con el método CopyFile, muy similar (casi idéntico en su composición), pero requiere la creación del objeto.

Sub CopiaArchivo()

Dim fso As Object
Set fso = VBA.CreateObject("Scripting.FileSystemObject")
'recorremos cada celda del rango 'origen'
For Each celda In Range("origen")
    'determinamos la ruta original
    origen = celda.Value
    'y cuál es el destino
    destino = celda.Offset(0, 1).Value
    'empleamos el método CopyFile
    fso.CopyFile origen, destino
Next celda
End Sub



El resultado es el mismo, la ventaja (según la documentación de Microsoft) es que el método es más eficiente y de mejor rendimiento...

22 comentarios:

  1. Muy bueno Ismael, permiteme felicitarte por tus aportes en esta maravilla de programa Excel.

    Necesito tu ayuda, para desarrollar un libro Mayor de contabilidad, con los siguientes requerimientos:

    Fecha - N° de cuenta - Nombre de Cuenta -Glosa - Detalle - Debe Haber - Saldo.

    De antemano.

    Atte.

    Aldo Moreno.

    ResponderEliminar
    Respuestas
    1. Gracias Aldo,
      Entiedno tienes ya u libro diario con todos los movimientos, y necesitas obtener el mayor de una u otra cuenta.
      Lo más simple sería aplicar un filtro avanzado sobre este libro diario, y emplear la opción de 'copiar a otro lugar' y así obtener el mayor de la cuenta deseada.

      Revisa la categoría de filtros del blog, y verás algunos ejemplos:
      http://excelforo.blogspot.com.es/search/label/Filtros

      Un saludo

      Eliminar
  2. Gracias por enseñar a las personas que necesitamos tus conocimientos.

    Me permiti compartir tu publicación en los Grupos de Facebook donde soy Administradora y los seguire compartiendo si me permites.

    ResponderEliminar
  3. Según tu último párrafo es mejor usar FileCopy que CopyFile, lo he entendido bien?

    ResponderEliminar
    Respuestas
    1. Hola,
      al revés, según MS es mejor usar el método CopyFile
      Saludos

      Eliminar
  4. amigo si quisiera agregarle un msgbox para saber por pantalla cuando copia o cuando no puede copiarlo donde debo colocarlo

    ResponderEliminar
    Respuestas
    1. Hola Danny,
      por ejemplo, justo antes del next celda, podría ser un buen sitio.

      Saludos

      Eliminar
    2. La pregunta más bien sería como estructuró un condicional para controlar mensaje de copia con exito y cuando no pudo copiar ya que no encontró el archivo en la ruta

      Eliminar
  5. Gracias ya le coloque
    msgbox "archivo copiado con exito"
    Justo donde me dijiste y funciona bien. ahora quisiera controlar el mensaje cuando no se pueda copiar el archivo.

    ResponderEliminar
    Respuestas
    1. Hola,
      podrías optar, por ejemplo, por un On Error GoTo ...,
      o quizá un condicional dentro de tu macro:
      If Dir("la ruta y nombre de tu fichero")<>"" Then
      ' tu código...
      Else
      MsgBox "El fichero no existe."
      End If

      Saludos

      Eliminar
  6. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  7. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  8. Ismael excelente aporte, te pregunto como podría crear una carpeta dependiendo cada linea es decir:

    ORIGEN ______________________DESTINO _____________________CARPETA A CREAR
    X:\2017\16\123\eje.txt_______C:\NUEVO\123\eje.txt_________123
    X:\2017\16\124\eje2.txt______C:\NUEVO\124\eje2.txt________124

    ResponderEliminar
    Respuestas
    1. Hola Juan,
      para generar carpetas se suele emplear la función MkDir
      Echa un vistazo a este post:
      http://excelforo.blogspot.com.es/2011/05/vba-como-generar-una-carpeta-o.html

      Espero te sirva
      Slds

      Eliminar
    2. Mil gracias Ismael por tu colaboracion, montare el codigo con la recomendacion que medas

      Eliminar
  9. Buenos dias,

    El codigo no me esta funcionando, es porque tengo excel 2013 ?

    el error que me salta es "Error en el metodo "Range" de objeto _Global"

    ResponderEliminar
    Respuestas
    1. Hola Jose Carlos,
      es probable hayas olvidado definir el nombre definido que se emplea:
      'Notemos que al rango de celdas D2:D4 se le ha asignado un nombre definido 'origen', con el fin de facilitar el trabajo, y resulte más visual.'

      Saludos

      Eliminar
  10. Hola,

    Al momento de ejecutar el codigo me aparece el error "Se ha producido el error '53' en tiempo de ejecución:

    Archivo no encontrado

    Mis datos estan en las columnas A y B

    Solo modifique el codigo en esta linea
    For Each celda In Range("A2:A500")

    Los archivos están en una sola carpeta y debo copiarlos o moverlos a diferentes carpetas, todo los tengo listado en las 2 columnas pero no he logrado que se copien o muevan a ese destino

    ResponderEliminar
    Respuestas
    1. Hola,
      asegúrate que las rutas existen..
      no importa que sean diferentes mientras existan.

      No debería fallar en ningún otro caso
      Saludos

      Eliminar
  11. Por favor me puedes ayudar con la misma progración pero limitando a que solo llame las rutas de los archivos .xml de la carpeta seleccionada?? Gracias

    ResponderEliminar
    Respuestas
    1. Hola Carlos,
      en realidad bastaría que te aseguraras que tu listado en la hoja de cálculo detallara solo archivos .xml
      Si quieres controlarlo desde la programación deberías añadir un control con un IF
      por ejemplo algo así:
      IF right(origen,4)=".xml" then
      ...'resto del código de duplicado
      END IF

      Espero te oriente
      Saludos

      Eliminar

Nota: solo los miembros de este blog pueden publicar comentarios.