Cuando trabajamos en Excel, ya sea en la hoja mediante fórmulas o en el editor de VBA, es muy importante conocer todas las alternativas disponibles que tenemos a nuestra mano. No solo por el hecho de conocer (el saber no ocupa lugar) sino porque algunos métodos pueden resultar más o menos sencillos o más o menos rápidos.
Hoy quiero dar algunas pinceladas sobre varias alternativas para copiar datos de una hoja a otra hoja (u hojas) de nuestro libro.
Para empezar, vamos a crear los datos para realizar el ejemplo. Para crearlos, utilizaré una pequeña macro para generar una matriz de número aleatorios, una matriz bidimensional (compuesta por 25 líneas y 3 columnas):
Esta será la macro:
Sub Creamatriz()
Dim Matriz(1 To 25, 1 To 3)
Dim i, j As Double
For i = 1 To UBound(Matriz, 1)
For j = 1 To UBound(Matriz, 2)
Worksheets("Hoja1").Cells(i, j).Value = FormatNumber((Rnd() * 100), "0")
Next j
Next i
End Sub
En una vez que la ejecutamos ya tenemos nuestros datos, preparados para ser movidos a otra hoja, que será la “hoja2”.
Ya que hemos creado una macro que devuelve una matriz de 2 dimensiones, aprovechemos lo que hemos realizado para que esa misma matriz nos sirva para exportar los datos a otra hoja, por ejemplo así:
Sub Ejemplo_1()
Dim Matriz(1 To 25, 1 To 3)
Dim i, j As Double
Call limpiar_hoja2
With Sheets(2)
For i = 1 To UBound(Matriz, 1)
For j = 1 To UBound(Matriz, 2)
.Cells(i, j).Value = Sheets(1).Cells(i, j).Value
Next j
Next i
End With
End Sub
De esta forma, estamos pasando los datos mediante un bucle for/next de la hoja 1 a la hoja2.
Esta misma operación la podemos realizar solo con un bucle for/next y teniendo en cuenta dos variables, las filas y las columnas, donde es la propia macro la que controla los datos de filas y columnas y, en caso de que estos varíen, los recogerá (a diferencia de la macro anterior, que solo graba los datos declarados en la matriz):
Sub Ejemplo_2()
Dim i, j As Double
Call limpiar_hoja2
With Sheets(2)
Fin = Application.CountA(Sheets(1).Range("A:A"))
Fin2 = Application.CountA(Sheets(1).Range("1:1"))
For i = 1 To Fin
For j = 1 To Fin2
.Cells(i, j).Value = Sheets(1).Cells(i, j).Value
Next j
Next i
End With
End Sub
Otra forma y casi idéntica a la anterior, sería utilizando el mismo bucle, pero seremos nosotros los que indiquemos donde queremos colocar las columnas. Este tipo de macro es muy útil cuando queremos “formatear” los datos de alguna columna o cambiarlas de orden. Normalmente es el que yo suelo utilizar, dado que frecuentemente tengo que adaptar mis datos a diversas necesidades. Por supuesto, también recoge las variaciones de datos (en este caso en las filas).
Sub Ejemplo_3()
Dim i, j As Double
Call limpiar_hoja2
With Sheets(2)
Fin = Application.CountA(Sheets(1).Range("A:A"))
For i = 1 To Fin
.Cells(i, 1).Value = Sheets(1).Cells(i, 1).Value
.Cells(i, 2).Value = Sheets(1).Cells(i, 2).Value
.Cells(i, 3).Value = Sheets(1).Cells(i, 3).Value
Next i
End With
End Sub
Otra forma de hacerlo es directamente moviendo el rango entero o parcialmente, o varias columnas, aquí ya no trabajamos con bucles, utilizamos la instrucción SET que asigna valor a un objeto, en este caso Origen y Destino como worksheet, de tal forma que solamente tenemos que igualar los rangos de Origen y Destino y al ejecutar serán idénticos. Es muy útil cuando solo queremos mover determinadas columnas o rangos de una información.
Sub Ejemplo_4()
Dim Origen, Destino As Worksheet
Set Origen = Sheets(1)
Set Destino = Sheets(2)
Fin = Application.CountA(Sheets(1).Range("A:A"))
Call limpiar_hoja2
With Destino
.Range("A1:C" & Fin).Value = Origen.Range("A1:C" & Fin).Value
End With
End Sub
Por último, otra forma de hacerlo también (muy resumidamente) es grabar el rango de los datos que hemos creado en una matriz y luego igualarlos a un rango definido en la «hoja2», es idéntica que la anterior, pero usando matrices.
Sub Ejemplo_5()
Dim MiMatriz As Variant
Fin = Application.CountA(Sheets(1).Range("A:A"))
Call limpiar_hoja2
MiMatriz = Sheets(1).Range("A1:C" & Fin)
Sheets(2).Range("A1:C" & Fin) = MiMatriz
End Sub
Por último, en los cinco ejemplos utilizo un «Call» para limpias los datos de la hoja2. Creo que ayuda mucho a reducir el código y es más claro. La macro a la que llama el Call es la siguiente:
Sub limpiar_hoja2()
Sheets(2).Select
Columns("A:C").ClearContents
End Sub
Y estos han sido solo algunos de los ejemplos que más se usan a la hora de mover nuestros datos por las hojas de Excel. Se podrían añadir otros ejemplos, algunos muy sofisticados con bastante programación (SQL, ADO,… etc) pero sin duda, para el día a día, me quedo con algunos de estos. La clave está en la sencillez del proceso.
Descarga el archivo de ejemplo pulsando en: PROCEDIMIENTOS EN VBA PARA MOVER DATOS ENTRE HOJAS
Me ha parecido un excelente aporte ya que es muy rápido, tenia el problema de que con copy y paste duraba más en ejecutarse, solo que ahora me queda la duda, ¿si se quisiera hacer que en ves de sobre escribirse o borrarse la anterior entrada se pudiera poner Justo por debajo del último dato ingresado como sería?
Hola: Lo que preguntas no tiene que ver con el post, no obstante tienes entradas donde se responde a esa duda:
– https://excelsignum.com/2020/12/04/grabar-registros-en-excel-con-un-formulario-y-vba/
¿Este código de puede usar con filtros?