Copiar determinadas celdas de una hoja a otra

Tengo una hoja llamada "REGISTRO", en la cual en la columna A registro los números de identificación de unos empleados; en otra hoja llamada "NOVEDADES", en la columna E, están registrados los números de identificación de algunos de esos empleados; necesito una macro que haga una búsqueda de cada registro existente en la columna A de la hoja REGISTRO, en la columna E de la hoja NOVEDADES, y cada vez que el dato coincida, algunos datos de la fila de la hoja "NOVEDADES" sean copiados a la hoja llamada SANCIONES, luego de ello que se repita el proceso buscando el próximo registro de la fila A "REGISTRO".

La macro es la siguiente:

Sub ProductoEnsamblado()
finfil = ActiveSheet.Range("A20").End(xlUp).Row 'recorre hoja activa desde A20 hacia arriba
ActiveSheet.Range("A2").Select 'luego se ubica en la celda A2
While ActiveCell <> "" 
dato = ActiveCell.Value 
'luego busco el dato en la columna E de la hoja NOVEDADES
Set busco = Sheets("NOVEDADES").Range("E2:E1048576").Find(dato, LookIn:=xlValues, LookAt:=xlWhole)

'si encuentra el dato, copia algunos datos de la fila a la hoja "SANCIONES"
If Not busco Is Nothing Then
libre = Sheets("REPORTE").Range("A1048576").End(xlUp).Row + 1
busco.Offset(0, -4).Copy Destination:=Sheets("SANCIONES").Range("A2")
busco.Offset(0, -3).Copy Destination:=Sheets("SANCIONES").Range("B2")
busco.Offset(0, 0).Copy Destination:=Sheets("SANCIONES").Range("C2")
busco.Offset(0, 1).Copy Destination:=Sheets("SANCIONES").Range("D2")
busco.Offset(0, 3).Copy Destination:=Sheets("SANCIONES").Range("E2")
End If
Set busco = Nothing

'luego pasa a la siguiente fila de la hoja "REGISTRO"
ActiveCell.Offset(1, 0).Select
Wend
End Sub

El problema que tengo es que la hoja "SANCIONES" está protegida con la contraseña "xx", y necesito que los datos de la próxima búsqueda se copien a la hoja "SANCIONES" después de la ultima fila utilizada.

¿Qué datos debería agregar a la macro para que se pueda llevar a cabo el proceso según lo indicado?

2 respuestas

Respuesta
1

H o l a:

Te anexo la macro con otro estilo de programar, utilizando los objetos de las hojas. Las ventas que se tienen al utilizar los objetos h1, h2 y h3, son: puedes ejecutar la macro desde cualquier hoja, el proceso es más rápido, es más práctico escribir el objeto que todo el nombre de la hoja.

Sub CopiarCeldas()
'Por.Dante Amor
    Set h1 = Sheets("REGISTRO")
    Set h2 = Sheets("NOVEDADES")
    Set h3 = Sheets("SANCIONES")
    '
    h3.Unprotect "xx"
    For i = 2 To h1.Range("A" & Rows.Count).End(xlUp).Row
        Set b = h2.Columns("E").Find(h1.Cells(i, "A"), lookat:=xlWhole)
        If Not b Is Nothing Then
            u = h3.Range("A" & Rows.Count).End(xlUp).Row + 1
            h3.Cells(u, "A") = b.Offset(0, -4)  'A
            h3.Cells(u, "B") = b.Offset(0, -3)  'B
            h3.Cells(u, "C") = b.Offset(0, 0)   'E
            h3.Cells(u, "D") = b.Offset(0, 1)   'F
            h3.Cells(u, "E") = b.Offset(0, 3)   'H
        End If
    Next
    h3.Protect "xx"
    MsgBox "Fin"
End Sub

Si tienes menos registros en la hoja "NOVEDADES", entonces la búsqueda debería ser al revés, es decir, empezar en la hoja "NOVEDADES" y buscar en la hoja "REGISTRO", si se encuentra en la hoja "REGISTRO", entonces copiar datos de "NOVEDADES" a "SANCIONES".

En tal caso la macro sería así:

Sub CopiarCeldas2()
'Por.Dante Amor
    Set h1 = Sheets("REGISTRO")
    Set h2 = Sheets("NOVEDADES")
    Set h3 = Sheets("SANCIONES")
    '
    h3.Unprotect "xx"
    For i = 2 To h2.Range("E" & Rows.Count).End(xlUp).Row
        Set b = h1.Columns("A").Find(h2.Cells(i, "E"), lookat:=xlWhole)
        If Not b Is Nothing Then
            u = h3.Range("A" & Rows.Count).End(xlUp).Row + 1
            h3.Cells(u, "A") = h2.Cells(i, "A")
            h3.Cells(u, "B") = h2.Cells(i, "B")
            h3.Cells(u, "C") = h2.Cells(i, "E")
            h3.Cells(u, "D") = h2.Cells(i, "F")
            h3.Cells(u, "E") = h2.Cells(i, "H")
        End If
    Next
    h3.Protect "xx"
    MsgBox "Fin"
End Sub

':)
':)

Hola, gracias por responder, he probado la primera macro que es el caso que más se ajusta, pero no me funciona, revisando las líneas encuentro que hay un dato "For i = 2", no sé a que hace referencia el numero 2, pienso que ahí se presenta el inconveniente.

Los datos de la columna A de la hoja "REGISTROS" van desde A10 hasta A59, y cada uno de los datos que se encuentre en dicha columna (desde A10 hacia abajo) los busca en la columna E de la hoja "NOVEDADES", y cada vez que encuentre una coincidencia, de la fila del hallazgo, copia algunos datos a la hoja "SANCIONES"; luego pasa al siguiente registro de la hoja "REGISTROS" y repite el proceso.

He revisado línea a línea la instrucción del primer ejemplo y realmente no sé porqué no funciona, ya que lo único que hace se mostrar el mensaje "Fin", pero no realiza nada en la hoja "SANCIONES".

Agradezco alguna aclaración.

Revisando los datos, creo que el error se genera porque el rango de la hoja "REGISTRO" (A1:A59), no siempre está diligenciado en su totalidad, es decir, en ocasiones hay solamente 2 registros (A10 y A11), en ese caso creo que sería bueno colocarle una instrucción que indique que si la celda "REGISTRO" A10, A11, etc, están vacías, que no repita la macro, es decir que solamente que la búsquedas se ejecute si la celda no está vacía.

Quedo pendiente, disculpa tanta molestia.

H o l a:

Esta instrucción es para indicar que empiece en la fila 2 de la hoja "registro"

For i = 2 To h1.Range("A" & Rows.Count).End(xlUp).Row

Puse que empezara en la fila 2, porque eso es lo que tienes en tu macro:

ActiveSheet. Range("A2").Select 'luego se ubica en la celda A2


Pero para saber cómo debe funcionar, mejor envíame tu archivo con la macro que te envié y me explicas con un ejemplo el resultado que esperas.

Mi correo [email protected]

En el asunto del correo escribe tu nombre de usuario “LORENA706” y el título de esta pregunta.

Gracias Dante, acabo de enviarte el correo con el ejemplo con el asunto LORENA706, quedo pendiente.

Te anexo la macro actualizada

Sub CopiarCeldas()
'Por.Dante Amor
    Set h1 = Sheets("FACTURA")
    Set h2 = Sheets("ENSAMBLE")
    Set h3 = Sheets("SALIDA")
    '
    h3.Unprotect "xx"
    h3.UsedRange.Offset(1, 0).ClearContents
    For i = 10 To h1.Range("A" & Rows.Count).End(xlUp).Row
        Set r = h2.Columns("A")
        Set b = r.Find(h1.Cells(i, "A"), lookat:=xlWhole)
        If Not b Is Nothing Then
            ncell = b.Address
            Do
                'detalle
                u = h3.Range("A" & Rows.Count).End(xlUp).Row + 1
                h3.Cells(u, "A") = h2.Cells(b.Row, "C")
                h3.Cells(u, "B") = h2.Cells(b.Row, "D")
                h3.Cells(u, "C") = h1.Cells(i, "C") * h2.Cells(b.Row, "E")
                h3.Cells(u, "D") = h1.Cells(3, "F")
                h3.Cells(u, "E") = h1.Cells(4, "E")
                h3.Cells(u, "F") = h2.Cells(b.Row, "F")
                h3.Cells(u, "G") = h3.Cells(u, "C") * h3.Cells(u, "F")
                Set b = r.FindNext(b)
            Loop While Not b Is Nothing And b.Address <> ncell
        End If
    Next
    h3.Protect "xx"
    h3.Select
    MsgBox "Fin"
End Sub

':)
':)
Respuesta
1

Prueba con la función BuscarV, si deseas algo más sistematizado puedes crear una base de datos en Access, migrar los datos y en Excel crear un botón para que te traiga los datos de búsqueda.

acabo de dar con otra respuesta aplicando solo el VBA de Excel, limite la busqueda de la columna 1 de la hoja1 hasta 104 registros (filas), por que si lo hago para todas (con Rows.Count.End(xlUp).Row), me muestra desbordamiento de memoria en mi equipo, si deseas prueba remplazando For i = 3 To 104 por For i = 3 To Rows.Count.End(xlUp).Row .

Dim i, j, k As Integer
j = 3
k = 3
For i = 3 To 104      'Aqui remplazar por For i = 3 To Rows.Count.End(xlUp).Row
If Hoja1.Cells(j, 1) = Hoja2.Cells(i, 5) Then
Hoja3.Cells(k, 1) = Hoja1.Cells(j, 1)
k = k + 1
j = j + 1
End If

Next i

Éxitos!, me comentas como te fue.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas