Perfeccionar Macro que copie de Hoja 1 filas de diversas columnas a Hoja 2 según condición y que las ordene agrupando por nombre

Investigando encontré la siguiente Macro realizada por Dan. Lo que hace está perfecto pero necesitaría que al ir ingresando registros en la Hoja 1, si se repite el nombre (que puede estar en una columna) y se cumple la condición de la columna "B", me copie a la Hoja 2 pero siempre me vaya agrupando los registros debajo del nombre correspondiente insertando una fila nueva con ese nuevo registro.

Algo también interesante y muy útil podría ser que al editar uno de los registros también se copie este nuevo cambio de edición a la Hoja 2 (como un nuevo registro agrupando debajo del mismo nombre) y en alguna columna se registre la fecha y hora. Muchas gracias.

Sub copiar()
    Set h1 = Sheets("Hoja1")
    Set h2 = Sheets("Hoja2")
    For i = 3 To h1.Range("B" & Rows.Count).End(xlUp).Row
        If h1.Cells(i, "B") = "si" Then
            u = h2.Range("A" & Rows.Count).End(xlUp).Row + 1
            h1.Range("A" & i & ",C" & i & ",D" & i & ",E" & i & _
                     ",F" & i & ",G" & i & ",H" & i & ",K" & i & _
                     ",X" & i & ",Y" & i & ",Z" & i & ",AH" & i & _
                     ",AI" & i & ",AJ" & i & ",BK" & i & ",BL" & i & _
                     ",BM" & i & ",BN" & i).Copy h2.Range("A" & u)
        End If
    Next
End Sub

1 respuesta

Respuesta
1

Podrías utilizar la macro para copiar a continuación todo lo que haga falta y luego ordenar la tabla por la columna donde se encuentra el nombre... y quizás también por fecha/hora.

Para desarrollar la macro comentame;

- En qué col está el nombre y si el criterio está en "B" (o luego sabrás modificar la macro)

-Si se copia la fila completa o se seleccionan solo algunas col, como está ahora.

Elsa, muchas gracias por responder!.

De lo consultado:

- En qué col está el nombre y si el criterio está en "B" (o luego sabrás modificar la macro)

El nombre está en la columna H de la Hoja1 y el criterio en columna "D" y es "Abierto"

-Si se copia la fila completa o se seleccionan solo algunas col, como está ahora.

Se seleccionan diversas columnas ya que no todas las que requiero copiar a la Hoja2 son contiguas.

Doy mas detalle de lo que necesito:

En Hoja 1 se van ingresando registros (fila 23 sería la proxima fila a recibir datos). Pero tambien existe la posibilidad que el registro ya existente se pueda editar. 

Lo que necesitaría que suceda es según la siguiente imagen de Hoja2:

Notar que los registros en "H" se van agrupando en este caso por Nombre y CTO, que puede ser orden alfabético ascendente y a su vez se añade en columna "P" la fecha y hora del movimiento. Es decir, para el caso "Nombre1" de fila 4 sería el primer registro de Hoja1 y la fecha corresponde al momento de su creación (que puede almacenarse en alguna columna de la Hoja1 o bien ser tomado de la columna "G" en donde fue ingresada manualmente la fecha). Al momento de ingresar nuevamente un registro que contenga "Nombre1" y además tambien coincida el dato de col "C", me inserte la fila 5 en la Hoja2 y ahora sí debe figurar en col "P" la hora y fecha del registro.

Ahora bien, notar qué sucede para el caso de "Nombre2" en la fila 6 y 7. Sería un caso en donde en Hoja1 no fué creado un nuevo registro pero sí fue editado sobre el existente, entonces me copió a Hoja2 el primer registro (ahora no visible en Hoja1) y a su vez el segundo correspondiente al editado (Aclaro que no sé si es esto posible pero siempre es bueno intentarlo).

Y para el caso de "Nombre3", observar que existe en Hoja1 un registro que no fue copiado ya que aún no se cumple la condición.

En definitiva la idea es llevar un historico de cada nombre y CTO por cada acción que se va realizando.

Espero haber sido lo más claro posible. Valoro mucho su esfuerzo y dedicación.

Quedo atento a cualquier consulta.

Saludos.

Entonces la macro original no te sirve porque te copia toda la hoja1 nuevamente. Y lo que necesitás es actualizar cada fila cuando tenga algún cambio, ya sea que se registre o que se modifique.

Entonces las siguientes 2 macros colocalas en un módulo del Editor.

Para ejecutarlas podrías tener un botón o utilizar algún Evento de Hoja como podría ser un Doble clic sobre alguna celda de la fila modificada.

Te invito a mirar el video 45 de mi canal donde dejo explicado este evento.

Sub ACTUALIZAR()
'x Elsamatilde
'se ejecuta una vez hecho un ingreso o modificación a la hoja 1
'se pasan datos de la fila activa
Set h1 = Sheets("Hoja1")
Set h2 = Sheets("Hoja2")
'fila disponible en Hoja2 según col Cliente
u = h2.Range("H" & Rows.Count).End(xlUp).Row + 1
'celdas a copiar de la fila activa
i = ActiveCell.Row
h1.Range("A" & i & ",C" & i & ",D" & i & ",E" & i & _
         ",F" & i & ",G" & i & ",H" & i & ",K" & i & _
         ",X" & i & ",Y" & i & ",Z" & i & ",AH" & i & _
         ",AI" & i & ",AJ" & i & ",BK" & i & ",BL" & i & _
         ",BM" & i & ",BN" & i).Copy h2.Range("B" & u)
'colocar la fecha/hora en col P   '*evaluar si ya está en col G
h2.Range("P" & u) = Now
h2.Range("P" & u).NumberFormat = "dd-mm-yy hh:mm"
'ordenar la hoja2 x Nombre-Cto- col P
Call OrdenaHoja2
'opcional: regresar a Hoja1
h1.Select
End Sub
Sub OrdenaHoja2()
'x Elsamatilde
Sheets("Hoja2").Select
'el fin de rango lo da la col de Cliente (H)
X = Range("H" & Rows.Count).End(xlUp).Row
If X = 3 Then Exit Sub
    ActiveWorkbook.Worksheets("Hoja2").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Hoja2").Sort.SortFields.Add2 Key:=Range("H4:H" & X), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("Hoja2").Sort.SortFields.Add2 Key:=Range("B4:B" & X), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("Hoja2").Sort.SortFields.Add2 Key:=Range("P4:P" & X), _
        SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Hoja2").Sort
        .SetRange Range("A3:P" & X)
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
Range("A3").Select
End Sub

Lo que hace la macro es pasar las celdas necesarias de la fila activa (ajustar referencias), coloca la fecha/hora en col P y ordena la Hoja2 (ajustar rango) por col: Cliente, Cto, Fecha.

Si la vas a colocar en algún evento de hoja (BeforeDobleClic, BeforeRightClic o SelectionChange te sirven para esto), la llamada quedaría así:

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'solo se ejecuta si se llama desde col D y fila 17 en adelante
If Target.Column <> 4 Or Target.Row < 17 Then Exit Sub
If Target.Value = "Abierto" Then Call ACTUALIZAR   'ajustar texto
Target.Offset(0, 1).Select
End Sub

Elsa, ante todo estoy muy contento y agradecido por los resultados que estoy obteniendo con esta macro. Desde ya mi calificación es Excelente!.

Solo me queda ajustar algunos detalles que estoy intentado aunque prefiero plantearlos igualmente.

El primero es la posibilidad de que no copie los formatos de la Hoja1 a la Hoja2 ya que en algunos hay listas desplegables que también se copian.

Luego la macro se detiene en la siguiente etapa del filtro en Hoja2 y no logro hasta el momento solucionarlo, me gustaría entender a que puede deberse.

Muy agradecido por brindar su conocimiento.

Saludos!

Resolví lo de error 438, solo era remplazando

.Add2

por Add

Unicamente me queda que copie sin los formatos.

Muchas gracias!.

Hay muchas maneras de copiar datos. Podés leer más en mi Guía Temática N° 3.

Tu macro tenía la instrucción h1. Copy con destino h2 ... y de ese modo se va con todo.

Para tomar solo el valor debes hacerlo al revés:

H2.Range("B" & u) = h1. Range("A" & i)

Y así con cada celda. Otro modo sería copiar... luego pegar especial, solo valores o solo formatos o lo que necesites. Así que ante la duda, mejor con h2...= h1....

Sdos!

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas