Macro - Abrir un archivo de Excel llamado o crearlo si no existe

Resuelto
Thesshad -  
 Thesshad -
Bonjour David, Voici une traduction fidèle en espagnol du texte fourni, en conservant le ton et les détails techniques. Hola,

Estoy rompiéndome la cabeza en el trabajo para implementar un software de entrada de datos mediante Excel para mi servicio.

En resumen, tengo 2 archivos diferentes.
El primero (que llamaré archivoA) es una plantilla en blanco, una tabla que solo espera que se ingresen datos de un día
El segundo (que llamaré archivoB) es el software.

Sobre el archivoB
En la celda A1 hay una casilla para escribir una fecha. Puede ser la fecha del día, como una fecha cualquiera.

Quiero un botón en el archivoB, con una función macro que, al pulsarlo, vaya a buscar en una ubicación conocida: archivoA-dd-mm-yyyy, con dd-mm-yyyy la fecha referenciada en la celda A1.
Y si no existe, abra el archivoA y guarde una copia en blanco llamada archivoA-dd-mm-yyyy

Lo que hace que cada día pueda crear una nueva página de datos para rellenarla, pero si pongo una fecha anterior, me buscará el archivo correspondiente a esa fecha.

Por supuesto, el archivoB reúne varios botones para varios archivoA de todo tipo, etc...

Si pudiera, por favor, me dé pistas sobre las fórmulas de VBA a utilizar, al menos para crear un archivo con en el nombre una fecha definida en la celda (eso nunca funciona por las /)
O incluso poner una condición para que si el archivo no existe, abra la plantilla en blanco y la cree.

Gracias de antemano

David

Configuración: Windows 7 / Mozilla 11.0 Si deseas, puedo adaptar el texto a otro formato (e.g., correo, guía técnica) o ayudarte con ejemplos de código VBA para lograr el comportamiento descrito.

9 respuestas

  1. Usuario anónimo
     
    Hola David,

    Este es solo un pequeño fragmento de código para dar el nombre correcto del archivo a partir de la fecha introducida en la celda A1.

    ==========================================

    Esta celda A1 debe obligatoriamente tener un formato de fecha,
    pero este puede ser cualquiera.

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

    JX contendrá el Día en dos dígitos: dd
    MX contendrá el Mes en dos dígitos: mm

    Paso por estas dos variables para hacer una prueba que determine
    si es necesario añadir o no un “0” delante.

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

    Inútil usar una variable para el Año: como de todos modos
    es de 4 dígitos, no requiere tratamiento y puede
    reprisearse tal cual.

    ==========================================

    FX contendrá el nombre completo del archivo, pero ATENCIÓN:

    1) Si está seguro de que ni ahora ni en el futuro,
    este nombre de archivo NO contendrá ESPACIOS, puede
    utilizar la primera línea FX = ... ; en caso contrario, habrá que
    usar la segunda línea FX = ... (la que está en comentario,
    porque añade una comilla al principio y otra al final).

    Incluso os digo: «En duda o por precaución, ¡mejor utiliza la segunda línea!».

    Para esta segunda línea, FX empieza claramente con 3 comillas
    consecutivas y termina de la misma forma: no es un error de tipeo, y evita usar Chr$(34) !

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

    2) Notarás que añadí la extensión “.xls”;
    sabes que es válida para Excel 2003, PERO para
    Excel 2007 o posterior, habrá que añadir:

    - “m” para libros con macros: *.xlsm
    - “x” para libros sin macros: *.xlsx

    Y si además necesitas abrir plantillas de libro,
    también hay que tenerlo en cuenta:

    - para Excel 2003: *.xlt
    - para Excel 2007: *.xltm y *.xltx

     Option Explicit Sub Essai() Dim JX As String * 2, MX As String * 2, FX As String JX = Day([A1]): If JX < 10 Then JX = "0" & RTrim$(JX) MX = Month([A1]): If MX < 10 Then MX = "0" & RTrim$(MX) FX = "fichierA-" & JX & "-" & MX & "-" & Year([A1]) & ".xls" 'FX = """fichierA-" & JX & "-" & MX & "-" & Year([A1]) & ".xls""" MsgBox "Date en A1 : " & [A1] & vbLf & "=> Nom du fichier :" & vbLf & vbLf & FX End Sub 


    Ya no tendrás más problemas a causa de las “/”.

    Saludos cordiales.
    0
  2. michel_m Mensajes publicados 18903 Fecha de registro   Estado Colaborador Última intervención   3 320
     
    Hola

    para "guardar como" con la fecha del día

    ruta = "D:\docus\"
    nombrearchivo = "azerty"
    día = Format(Sheets(1).Range("A1"), "dd-mm-yyyy")
    nombrearchivo = ruta & nombrearchivo & "_" & día & ".xlsm"
    '
    ActiveWorkbook.SaveAs Filename:=nombrearchivo


    como lo inicias desde una macro el nuevo libro queda con el sufijo xlsm o xltm

    te conviene establecer variables (ruta, nombrearchivo..) para evitar el infierno de comillas simples o dobles en ActiveWorkbook.SaveAs...

    Michel
    0
  3. Thesshad
     
    He seguido el consejo de albkan

    ¡Funciona a la perfección! Esta macro está resuelta.

    Sub Enregistrer()

    Dim Chemin As String, Fichier As String, JX As String, MX As String

    Chemin = "L:\Laboratoire\TestMacro\Archives\"
    JX = Day([C3]): If JX < 10 Then JX = "0" & RTrim$(JX)
    MX = Month([C3]): If MX < 10 Then MX = "0" & RTrim$(MX)
    Fichier = "ExempleA" & "-" & Year([C3]) & "-" & MX & "-" & JX & ".xlsm"

    ActiveWorkbook.SaveCopyAs Chemin & Fichier

    Application.Quit
    ActiveWorkbook.Close False

    End Sub


    Muchas gracias.

    Solo me queda codificar ahora la otra macro, en el otro archivo de Excel.
    Parecido, en este archivo hay una casilla con la fecha para escribir.
    Y cuando aplico la macro, se abre el archivo creado gracias a la macro anterior, y si aún no existe, en su lugar se me abre el archivo ExempleA.xlsm

    ¿Tendrías alguna idea de cómo proceder?
    He probado una bricolaje tipo:

    Sub TestCrea()

    Dim Test As String, JX As String, MX As String, Tramevierge As String

    JX = Day([C3]): If JX < 10 Then JX = "0" & RTrim$(JX)
    MX = Month([C3]): If MX < 10 Then MX = "0" & RTrim$(MX)
    Test = "L:\Laboratoire\TestMacro\Archives\ExempleA" & "-" & Year([C3]) & "-" & MX & "-" & JX & ".xlsm"
    Tramevierge = "L:\Laboratoire\TestMacro\TrameVierge\ExempleA.xlsm"

    If Dir(Test) Then
    Workbooks.Open Test

    Else
    Workbooks.Open Tramevierge

    End Sub


    Pero eso me lleva a la pared :)

    Gracias por adelantado.
    0
  4. Usuario anónimo
     
    Hola David,

    He olvidado que en el foro la regla es tutearse, con respeto y con cortesía. Así que también puedes tutearte conmigo.

    Estoy contento de que mi solución te haya gustado; sin embargo:

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

    1) Había utilizado RTrim$(JX) únicamente porque había declarado JX como una cadena de longitud fija de 2 caracteres: Dim JX As String * 2

    Ese final * 2 indica la longitud de una cadena fija; no eran 2 caracteres añadidos por error.

    En tu código, sin embargo, usas: JX As String (lo cual es posible también para este pequeño ejercicio).

    Como al final no hay un número de caracteres fijo, es una cadena de longitud variable.

    En este caso, RTrim$() ya no es necesario, y puedes escribir más simple: JX = "0" & JX

    Lo mismo, por supuesto, para MX: sin RTrim$(); MX = "0" & MX

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

    2) michel_m indicó en su mensaje 2 anterior una solución aún mejor que la mía, utilizando la función Format(); pero lee primero la continuación antes de ir a leer su mensaje:

    Ya conocía la función Format(), pero no se me había ocurrido usarla aquí, cuando simplifica todavía más:

    a) Usar esta función Format() evita la prueba < 10 y la posible adición de un 0 al frente.

    b) Para tu 1er código y tu 2º código:

    - en tu línea Dim, elimina las 2 declaraciones JX As String y MX As String

    - elimina las 2 líneas enteras que comienzan por JX = y MX =

    c) En tu 1er código, reescribe la línea Fichier = como sigue:
    Fichier = "ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm"

    d) En tu 2º código, reescribe la línea Test = como sigue:
    Test = "L:\Laboratoire\TestMacro\Archives\ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm"

    Para c) y d) he evitado intencionadamente "dd-mm-yyyy", porque eso habría dado día-mes-año.

    Tu elección del orden de los elementos es muy buena, ya que es más útil en caso de clasificación; he puesto "yyyy-mm-dd" para respetar ese orden: año-mes-día.

    Verás que esta solución también funciona perfectamente, con un código VBA más corto (optimizado) ¡

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

    Un gran agradecimiento a michel_m por su mensaje muy acertado :
    Mensaje #2 de michel_m

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

    Para lo que pides después, lo pensaré más tarde, pero no te prometo nada; y michel_m te podría proporcionar tal vez una respuesta.
    0
  5. Usuario anónimo
     
    Buenas noches, David,

    Lee primero mi mensaje 4 anterior, antes que este.
    Aquí ahora la solución para tu segunda parte.

    ¡ATENCIÓN!

    Una línea On Error GoTo ... debe ser obligatoriamente la 1ª
    de la Sub! Debe estar, por tanto, ¡ANTES incluso que la línea Dim ...

     Sub TestCrea() On Error GoTo ErrFile Dim Test As String, Tramevierge As String Test = "L:\Laboratoire\TestMacro\Archives\ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm" Tramevierge = "L:\Laboratoire\TestMacro\TrameVierge\ExempleA.xlsm" Workbooks.Open Test: Exit Sub ErrFile: Workbooks.Open Tramevierge End Sub 


    Explicaciones

    El primer Workbooks.Open intentará abrir el archivo Test.

    Si existe, sin problema: apertura del archivo Test, y salida de la Sub (gracias a Exit Sub).

    Si no existe, se produce un error de apertura de archivo y sin ese On Error GoTo ... la Sub fallaría por completo ¡y simplemente!

    Afortunadamente, este On Error GoTo ... permite “recuperar el error”, por lo que se puede decir que en esta Sub se ha implementado un “Gestor de errores”.

    Por tanto, cuando se produce el error, en lugar de fallar, la Sub transfiere el control de ejecución del programa al lugar indicado por lo que sigue al On Error GoTo, es decir a la etiqueta ErrFile.

    Para decirlo de forma más simple: en caso de error, va a la línea ErrFile: para ejecutar la 1ª línea que sigue: apertura del archivo Tramevierge. Y ya está, ¡listo!

    Pero ¡ATENCIÓN! no olvidar colocar un Exit Sub justo antes de la etiqueta ErrFile:, de lo contrario, después de la apertura exitosa del archivo Test, la ejecución del programa continuaría y entraría en el gestor de errores!

    Le he dado el nombre ErrFile: pero puedes escoger otro nombre si lo prefieres; por ejemplo: AbrirArchivoModelo:

    Observa bien que hay un signo “:” (dos puntos) al final de la etiqueta, mientras que no hace falta en la línea On Error GoTo !
    0
    1. Usuario anónimo
       
      Otra mejora

      Dejé un pequeño defecto en el código anterior.

      La línea 7 : Tramevierge = ... es totalmente correcta; pero en el lugar donde está colocada, si la instrucción Workbooks.Open Test tiene éxito, ¡esta asignación se ejecuta innecesariamente!

      Por lo tanto, sería mejor moverla un poco más abajo, justo antes de la línea 10 donde se usa; pero no hacerlo porque vamos a fusionar estas 2 líneas y ya no usaremos la variable Tramevierge.

      También podemos prescindir de la variable Test, sin que eso cause problemas para las comillas (ya que no hay espacios en el nombre).

      Esto da:

       Sub TestCrea() On Error GoTo ErrFile Workbooks.Open "L:\Laboratoire\TestMacro\Archives\ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm" Exit Sub ErrFile: Workbooks.Open "L:\Laboratoire\TestMacro\TrameVierge\ExempleA.xlsm" End Sub 

      Las líneas 4 y 5 deben, por supuesto, estar en la misma línea.
      0
    2. Usuario anónimo
       
      f894009 acaba de proponer usar la función Dir(); tras probarla, creo que es la solución más SIMPLE y la MEJOR, porque evita usar un Gestor de errores; así que adaptándolo para este ejercicio, da:

       Sub TestCrea() Const LTM As String * 25 = "L:\Laboratoire\TestMacro\" Dim FX As String FX = LTM & "Archives\ExempleA" & "-" & Format([C3], "yyyy-mm-dd") & ".xlsm" If Dir(FX) = "" Then FX = LTM & "TrameVierge\ExempleA.xlsm" Workbooks.Open FX End Sub

      Las líneas 4 y 5 deben estar en la misma línea.

      Comentarios

      1) FX contiene primero el nombre del archivo que quieres abrir (el del directorio Archives, con la fecha).

      2) Si Dir(FX) devuelve una cadena vacía, es porque el archivo no existe; en ese caso, se reemplaza el valor de FX por el nombre del archivo modelo, el del directorio Tramevierge.

      3) Ahora, solo queda una única instrucción Workbooks.Open !

      Aquí está el enlace al artículo sobre la instrucción Dir() : Mensaje 8 de f894009
      0
  6. eriiic Mensajes publicados 24581 Fecha de registro   Estado Colaborador Última intervención   7 281
     
    Hola a todos,

    aquí una función que no solo permite ver si el archivo existe, sino que también permite saber si ya está abierto por alguien para evitar abrirlo en lectura:

    https://support.microsoft.com/en-us/help/291295

    Si no, la propuesta de albkan basta.
    eric

    --

    Al intentar continuamente, al final se consigue.
    Así que cuanto más falla, más probabilidades hay de que funcione. (los Shadoks)
    Además del gracias (sí, ¡se puede hacer!)., piensa en marcarlo como resuelto. Gracias
    0
  7. f894009 Mensajes publicados 17417 Fecha de registro   Estado Miembro Última intervención   1 717
     
    Hola a todos,
    pequeño intruso sin pretensiones

    Solo para volver al test Dir
    Sub test() If Dir("d:\_acsv1\classeur2.xls") <> "" Then MsgBox "Fichier existe" Else MsgBox "Fichier n'existe pas" End If End Sub


    Quizá completar con prueba abierta o no con el enlace de eriiic
    Este código pudiendo hacer todo modificándolo un poco para recuperar el error 53 (archivo no encontrado) ya que no prueba esta opción
    0
    1. Usuario anónimo
       
      Hola f894009,

      Acabo de probar tu solución con la función Dir() y la encuentro PERFECTA !

      Evita tener que usar un manejador de errores como lo hacía antes,
      porque incluso con un archivo que no existe, el error 53 (archivo no encontrado)
      no se produjo, ni ningún otro!

      ¡Creo que has encontrado la solución más SIMPLE y la MEJOR!
      ¡Muchas gracias por mencionárnosla!
      0
  8. Usuario anónimo
     
    Hola David,

    Tu problema está ahora completamente resuelto:

    A) Parte 1: la fecha del archivo según la celda C3, en el formato correcto;
        versión mejorada que utiliza la función Format();
        esto gracias a una indicación de michel_m.

    B) Parte 2: la apertura del archivo Test o del archivo Tramevierge;
        versión mejorada que utiliza la función Dir();
        esto gracias a una indicación de f894009.

    Desde tu último mensaje 3, ha habido muchos otros mensajes, y creo que podrías ya no acordarte! Aquí están las indicaciones necesarias:

    ==========================================

    El código definitivo y completo es el del mensaje siguiente:
    Mi mensaje #10

    ==========================================

    Pero aun así deberías leer primero este mensaje, que es muy instructivo para la función RTrim$(), la diferencia entre cadenas de longitud fija/variable, la utilización de Format():

    Mi mensaje #4: es únicamente para el formato de fecha.

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

    Luego los 2 mensajes siguientes, que son muy instructivos para la puesta en marcha de un manejador de errores (con On Error Goto ...):

    Mi mensaje #5: es mi 1er intento de resolución de la parte 2.
    Mi mensaje #7: mejora del código del mensaje #5.
    0
  9. Thesshad
     
    Gracias por todas tus respuestas.

    Finalmente terminé mi archivo con todas las macros necesarias y funciona muy bien con todas las soluciones que cada uno propuso.

    Este problema está [resuelto]
    Pero no encuentro el botón para cerrar este tema...
    0