Macros distintos libros

Tenemos un gran problema y nos urge resolverlo
Problema:
Tenemos una hoja dentro de un libro de excel llamada "BASE DE DATOS" y queremos copiar en ella una fila que hay en una hoja de excel llamada "H1EXCEL", que está en un libro distinto. Esta fila se tiene que copiar inmediatamente después de la última fila escrita en la hoja "BASE DE DATOS", por lo tanto se deberá buscar esta última fila. Utilizamos excel 2003
La función que tendrá este macro sera:
Tendremos siempre abierta la hoja de excel "BASE DE DATOS"; habriremos el libro que es distinto, y en el, la hoja "H1EXCEL", ejecutaremos el macro y automatimente la fila "H1EXCEL" se copiara en la última fila de la hoja "BASE DE DATOS". Así lo haremos sucesivamente con varias "H2EXCEL, H3EXCEL, H4EXCEL, ..." con las que iremos actualizando la "BASE DE DATOS", por lo tanto, en todas las "H1EXCEL" se deberá identificar la última fila escrita de la hoja "BASE DE DATOS" para escribir a continuación.
Es básicamente un macro para actualizar la base de datos sin tener que seleccionar la fila de H1EXCEL, copiarla y después insertarla a continuación de la ultima fila con datos de la hoja"BASE DE DATOS", esto lo hacemos al día un numero elevado de veces y agilizaría bastante el proceso.
Decirle que ya hemos probado a grabar macro con la función automática de excel, pero como es en distintos libros no sabemos como hacer para que el libro en el que está "BASE DE DATOS" reconozca el otro

2 respuestas

Respuesta
1
El problema se puede enfocar de 2 modos distintos.
1. Crear una macro en "BASE DE DATOS" que controle el resto de de libros, los abra, capture la línea, la agregue al final de los datos y los cierre
2. Crear una macro en cada libro que lance la información hacia "BASE DE DATOS", en el lugar que corresponda, es decir, al final de los datos.
Es preferible la primera opción. Vosotros decidís.
Por otro lado, surge la siguiente cuestión: la fila de datos que se debe copiar en los libros "H1EXCEL"... se encuentra siempre en la misma posición (por ejemplo, ¿A1) o es variable?
Se lo explico lo más detalladamente posible:
Tenemos un libro llamado "BASEDATOS" que es el que contiene en su "hoja1" la base de datos que queremos actualizar y que siempre estará abierto.
Los libros de donde queremos sacar la información son :
"cb_001" con tres hojas, la que tiene la fila que nos interesa copiar es "cbs", y tiene el rango O35:w35.
"hc_001" con otras tres hojas, la que tiene la información que nos interesa copiar es "hcs" y el rango A297: J297.
En el futuro tendremos más libros de donde actualizar.
El proceso que más o menos tenia pensado que hiciera la macro es:
-Doy al botón posicionandome en el libro "BASEDATOS"
-Selecciono el libro que contiene los datos a copiar
-Ejecuto la macro y la base de datos queda actualizada.
Los datos se copiaran en la siguiente fila a la ultima escrita en "hoja1" de "BASEDATOS".
Por lo tanto ya nos habíamos decantado por la primera opción, ya que nos parece más eficiente y menos engorrosa.
Y respondiendo a su otra pregunta, los futuros libros que nos den, tendrán el rango a297:j297.
Muchas gracias por tu ayuda.
Queda claro. Una pregunta más: las bases de datos cb_001, hc_001, etc, ¿se encuentran dentro de la misma carpeta o en diferentes rutas?
Los dos libros de los que queremos sacar la información tendrán la misma ruta, es decir, estarán en el mismo sitio, en concreto, por si fuera importante, los libros, cb_001 y hc_001 estarán en el escritorio del ordenador, y "BASE DE DATOS" también.
De nuevo, muchas gracias por tu ayuda
Bien, en realidad no importa que estén en la misma carpeta pero sí es fundamental que, al menos, haya una carpeta con los libros o bien accesos directos a los mismos para que funcione bien la siguiente rutina.
1. Crear un UserForm; dentro pondremos un ListBos y un CommandButton
2. Copiar el siguiente código:
Const sRuta = "C:\bases de datos\"
Private Sub CommandButton1_Click()
UserForm1.Hide
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Workbooks.Open (sRuta & ListBox1.List(ListBox1.ListIndex))
AgregarDatos (ListBox1.List(ListBox1.ListIndex))
End Sub
Private Sub UserForm_Activate()
Dim OFS As Object
Dim Carpeta As Object
Dim oExcel As Object
Set OFS = CreateObject("scripting.FileSystemObject")
Set Carpeta = OFS.GetFolder(sRuta)
ListBox1.Clear
For Each oExcel In Carpeta.Files
ListBox1.AddItem oExcel.Name
Next
End Sub
Sub AgregarDatos(ByVal NombreFichero As String)
ActiveSheet.Select
Select Case NombreFichero
Case Is = "cb_001.xls": Range("O35:W35").Select
Case Is = "hc_001.xls": Range("a297:j297").Select
End Select
Selection.Copy
ActiveWorkbook.Close
ActiveSheet.Cells(UltimaFila, 1).Select
ActiveSheet.Paste
End Sub
Function UltimaFila()
Dim fila As Integer
fila = 1
While ActiveSheet.Cells(fila, 1) <> ""
fila = fila + 1
Wend
UltimaFila = fila
End Function
Ya me comentaréis que tal fue.
Hola! Muchas gracias por todo, de verdad te estamos muy agradecidos, ya casi lo hemos conseguido.
Nos hemos creado en C una carpeta llamada td, y dentro hemos metido los 3 libros:
BASEDATOS.xls(en este libro tenemos insertado el macro), cb_001.xls, hc_001.xls
Al ejecutarlo nos aparece el siguiente error:

Se ha producido el error "5" en tiempo de ejecución
Argumento o llamada al procedimiento no valida
Y el código lo tenemos hasta ese punto lo tenemos puesto así:
Private Sub ListBox1_Click()
Const sRuta = "C:\td\"
Private Sub CommandButton1_Click()
UserForm1.Hide
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Workbooks.Open (sRuta & ListBox1.List(ListBox1.ListIndex))
AgregarDatos (ListBox1.List(ListBox1.ListIndex))
End Sub
Private Sub UserForm_Activate()
Dim OFS As Object
Dim Carpeta As Object
Dim oExcel As Object
Set OFS = CreateObject("scripting.FileSystemObject")
Set Carpeta = OFS.GetFolder(sRuta)
ListBox1.Clear
For Each oExcel In Carpeta.Files
ListBox1.AddItem oExcel.Name
Next
End Sub

Bueno esperamos tu respuesta y muchas gracias de veras.
Perdona se nos ha olvidado decirte donde estaba el error, esta en:
Set Carpeta = OFS.GetFolder(sRuta) 
Muchas gracias otra vez.
Ok. Si os fijáis el valor de sRuta en la línea que os da el problema es NULL, es decir, que no contiene ningún valor y por tanto el método GetFolder no puede abrir la carpeta. Por eso hemos puesto la constante sRuta FUERA DEL CÓDIGO, para que se pueda leer desde cualquier procedimiento.
Quitad la línea Const sRuta... y la pegáis al principio de todo el código, que no quede entre medias de ningún sub...end sub.
Con eso ya debería funcionar.
Hola de nuevo, sentimos muchísimo las molestias, pero es que como no entendemos nada de esto, cada vez que nos da un error no sabemos solucionarlo; el error que nos da ahora es el siguiente:
Primero nos salia un error que consistía en que si poníamos la constante fuera de las 2 lieneas que aparecen, ponía que necesitábamos un end sub para la función que englobaba todo, pero no lo cogía en ningún sitio, y si la teníamos dentro, nos salia el error que antes te dijimos, asique pa pusimos fuera de todo y el código lo pegamos fuera de las 2 lienas y así si complila y funciona, pero hay otro problema:
Cuando se copian los datos para el libro "cb_001.xls" no se nos copia nada, y para el libro "hc_001.xls" si se nos copia todo. ¿Por qué puede ocurrirnos esto? Ya hemos revisado todo y está perfectamente
Muchas gracias de antemano
Ok. Si me enviáis el fichero a [email protected] revisaré el código. O bien, proporcionadme una dirección de e-mail para que os envíe un fichero demo...
Hola, ya esta todo arreglado, muchísimas gracias.
Ya no le vamos a molestar más, pero nos preguntábamos si nos podría aclarar una cuestión que nos ha surgido:
¿Hay alguna manera de que no haga falta copiar el rango dentro del macro?, es porque en el futuro tendremos más libros que actualizar, y además creemos que siempre va a ser el mismo rango y que la hoja donde está dicho rango dentro de cada libro es en la segunda
Muchísimas gracias por todo y ya no le molestamos más.
Si el rango no va a cambiar en función del libro seleccionado podéis eliminar la sentencia
Select Case
...
End Select
y sustituirla por una sentencia del tipo
Range("A297:O297").Select
Pero en el caso de seleccionar un libro con otro rango de datos fallará. Id probando con las condiciones de la sentencia Select para adaptarlas a vuestras necesidades. Si tenéis dudas, contactad de nuevo.
Muchas gracias por todo, gracias a su ayuda todo funciona perfectamente, pero todavía tenemos un pequeño problema porque queremos mejorarlo un poco.
Resulta que para que los datos se copien en "BASE DE DATOS" hemos observado que tenemos que guardar los libros con la hoja abierta donde esta la información que queremos copiar, porque como en cada libro tenemos 2 hojas si no lo hacemos así y el libro se abre por la otra hoja, los datos no se copian porque no los encuentra, es decir, como están en la otra hoja pues nos copia algo que no queremos.
La cuestión es ¿cómo podemos hacer para que siempre se seleccionen los datos de la "hoja2"?, cabe decir que en cada libro esta "hoja2" tendrá un nombre diferente.
Muchísimas gracias
Se puede acceder al valor de una celda ubicada en una hoja anteponiendo el nombre de esta, por ejemplo:
Sheets("hoja2").Cells(1,1).value
También se puede acceder mediante un índice:
Sheets(2).Cells(1,1).Value
Ambas expresiones son equivalentes. La ventaja de la segunda es que no se necesita conocer el nombre de la hoja
¿Ya os funciona correctamente la hoja de cálculo? Si es así, no olvidéis cerrar la pregunta
Hola, gracias por preocuparte.
He quedado con mi compañero el lunes por la manaña para intentar hacer que nos funcione, asique ya te contaremos que tal.
Muchas gracias
Bueno, ya por fin hemos terminado nuestro arduo trabajo gracias a tu inestimable ayuda, de verdad que nos has sido de gran ayuda.
Muchísimas gracias por todo y hasta siempre.
Respuesta
1
Pienso que puede usarse la macro, pero debes tener en cuenta que esta debe estar guardada en el libro de macros Personal.xls, ya que de lo contrario, tendrías que grabar esta macro en cada una de las hojas HXEXCEL.
Sub Copiar()
    Selection. Copy
    Windows("BASE DE DATOS"). Activate
    x = LTrim(Str(Range("A1").End(xlDown).Row))
    Range("A" & x).Select
    ActiveSheet.Paste
End Sub
Lo primero es que copies esta macro como te digo en el libro de macros Personal.xls en un módulo.
La idea de la macro es que una vez hayas seleccionado la fila que vas a pegar en la base de datos, ejecutas la macro (pero debe hacer una fila seleccionada). La macro se encargará de encontrar la siguiente fila disponible.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas