Generar listado a partir de varias hojas

12/12/2007 - 15:40 por mamo66 | Informe spam
Hola amigos

Felicidades a todos los que participan en el grupo, debo
comentarles que he aprendido mucho en este foro. Bueno, les explico.

Hace tiempo que estoy buscando una forma de automatizar este
procedimiento, si bien es sierto lo tengo solucionado en parte, pero,
lo que pasa que cada vez que cambio o agrego una linea a la seccion de
datos tengo que cambiar todo.

Tengo un Libro que tiene 31 hojas (Dia1, Dia2, Dia3etc),
que cada una representa un dia del mes, en cada una de ellas tengo
tres rangos con datos que corresponden a movimiento de tarjetas de
credito, los rango son:

1.- M45:Q94
2.- AM45:AQ94
3.- BM45:BQ94

estos datos estan en la misma posicion en todas las hojas (Dia 1.
al Dia 31).

Entonces, necesito, a traves de una macro, generar una nueva hoja, con
un listado de todos los movimientos desde el dia 1 al dia 31. Ojo, que
dentro de estos rangos, podrian haber menos datos no quiere decir que
los rangos estan llenos de datos podrian haber 10 mov. en otro
podrian haber 30 mov. etc.

Por favor, espero alguien me ayude.
Saludos

Preguntas similare

Leer las respuestas

#6 Ivan
15/12/2007 - 11:13 | Informe spam
se me olvidaba (como siempre)

dale a la columna A de resumen el formato de fecha que quieras en formato de celdas

un saludo
Ivan
Respuesta Responder a este mensaje
#7 Ivan
16/12/2007 - 00:16 | Informe spam
hola de nuevo, Manuel,

al fin me he podido parar un poco, y al revisar el otro codigo he encontrado al menos un fallo (seguia cargando la fecha
de las hojas aunque en estas no hubiese nada que cargar). En la modificacion que te pongo al final esto parece evitarse,
y en mis pruebas parece ir bien.

de todas formas te comento un poco mas tanto su funcionamiento como los supuestos para los que esta hecha:

1º. algunas cosas que debes tener en cuenta a la hora de ejecutar la macro, bien para evitarlas, bien para controlarlas
mediante algun tipo de control de errores

a) la macro presupone que en las hojas de los dias, los rangos de origen (m45:q94, am45:aq94 bm45:bq94) se
vacian en algun momento previo a comenzar a escribir las entradas correspondientes al nuevo mes. Es decir, que cuando
empiezas a rellenar los datos del dia 1, en el resto de las hojas dichos rnagos estan limpios/vacios, y por lo tanto
todo lo que haya en dichos rangos corresponde al mismo mes para todas las hojas

esto no quiere decir que tengas que ejecutarlo por fuerza el dia ultimo de cada mes, sino que cuando empieces a meter
los de uno nuevo, antes debes asegurarte de borrar dichos rangos en todas las hojas

b) otra cosa que debes asegurarte es de que la fecha sea la correcta en las celdas c1(dia), d1(mes) y e1(año a
ser posible con 4 cifras), tal y como comentabas, al menos para el dia 1 y para todo aquel que tenga algun dato en
m45:m94, am45:am94. y/o bm45:bm94 (por cierto he dado por hecho que en la fila 45 ya son datos y no titulos)

c) la macro te admite dias 'vacios/cerrados', pues recorre el mes completo (solo hasta su ultimo dia real en
funcion del mes/año)

OJO => si los rangos reales no fueran como los expuestos y pudieran ser 'mucho' mas extensos, quizas convendria evitar
esto para no ralentizar el proceso, pero con los rangos que expones, en el peor de los casos, con todos los rangos
llenos 100x100 no creo que demore mas alla de 2 o 3 segundos,

2º. dado que no comentas si tienes algun tipo de identificador unico (¿que hay en la 5ª columna <q, aq, bq> ?) para los
registros (una opcion ideal para esto seria pej. la hora, que podria unirse a la fecha y te daria un nº unico para cada
registro) , el recorrer todas las hojas te evita esta necesidad, pues solo te carga a partir del ultimo dia cargado, y
en este, para evitar duplicados, previamente descarga los existentes, por si, tras ejecutar la macro se hubiesen
realizado mas movimientos ese dia (los previos ya has comentado que no se modificarian).

tambien podrias añadir algun condicional mas para evitar que ciertas partes del codigo (pej. los copiados/pegados) se
ejecuten en los rangos vacios. Pero esto eres tu el que lo puede ver/saber

.- he añadido al finbal un formateo del rango de fecha, pero mira a ver si es el que deseas o si coincide con tu
configuracion

bueno, estos son los codigos ( las funciones son exactamente iguales pero les he cambiado el nombre, para acortar lineas
en el foro)

'' busca el dia de la fecha mas alta cargada en Resumen
'
Function UltCargado(rango As Range) As Byte
Dim maximo As Byte
On Error Resume Next
UltCargado = _
IIf(Application.Max(rango) = 0, 0, Day(Application.Max(rango)))
End Function
'
''--busca el ultimo dia del mes segun el mes y el año pasados--
'
Function UltDiaMes(mes As Byte, año As Integer) As Byte
Dim n As Integer, fch As Date
For n = 31 To 28 Step -1
On Error Resume Next
fch = DateValue(n & "/" & mes & "/" & año)
If Err.Number = 0 Then Exit For
On Error GoTo 0
Next
UltDiaMes = n
End Function
'
'carga los registros que falten en la hoja resumen -
'
Sub CargarDias_2()
Dim n As Long, ultD As Byte, ultDM As Byte, uF As Long, hj As Worksheet
Application.ScreenUpdating = False
With ThisWorkbook
With .Worksheets("1"): ultDM = UltDiaMes(.[d1], .[e1]): End With
Set hj = .Worksheets("Resumen")
With hj
ultD = UltCargado(.Range(.Range("a2"), .[a65536].End(xlUp).Offset(1)))
If ultD = 0 Then
ultD = 1
Else
.[a1].CurrentRegion.Sort key1:=.[a2], order1:=xlAscending, header:=xlYes
For n = hj.[a65536].End(xlUp).Row To 2 Step -1
If Day(.Cells(n, 1)) = ultD Then .Rows(n).Delete Else Exit For
Next
End If
End With
For n = ultD To ultDM
With .Worksheets(CStr(n))
.Range("m45:q94").Copy hj.[b65536].End(xlUp).Offset(1)
.Range("am45:aq94").Copy hj.[b65536].End(xlUp).Offset(1)
.Range("bm45:bq94").Copy hj.[b65536].End(xlUp).Offset(1)
uF = hj.[a65536].End(xlUp).Row + 1
If hj.Range("b" & uF) <> "" Then
hj.Range("a" & uF) = CLng(CDate(.[c1] & "/" & .[d1] & "/" & .[e1]))
hj.Cells(uF, 1).AutoFill hj.Range(hj.Cells(uF, 1), hj.Range("a" & _
hj.[b65536].End(xlUp).Row)), xlFillCopy
End If
End With
Next
.Save
End With
Application.CutCopyMode = False: hj.[a:a].NumberFormat = "dd/mm/yyyy"
hj.Columns.AutoFit: Set hj = Nothing
End Sub
'
'**************************************************************

si quieres comentas como te ha ido

un saludo
Ivan

PD: ojo a los posibles trunques de las lineas del codigo en el foro
Respuesta Responder a este mensaje
#8 mamo66
18/12/2007 - 14:29 | Informe spam
On 15 dic, 06:11, "Ivan" wrote:
hola Manuel,

disculpa la tardanza, pero ando liadillo

bueno, voy con prisa, pero si quieres prueba esto con copias:

supuestos:

a)la hoja resumen se llama "Resumen" y las de los dias "1","2","3",,"31"

b)en la hoja resumen pon en la 1ª fila los mismos titulos que tengas en los listado pero a partir de B1. En A1 pones
como titulo "Fechas" (o similar)

creo que si el resto es como yo te he entendido deberia valerte.

copia/pega en un modulo normal y llama a la macro "" cuando quieras actualizar

''--pega desde aqui
'
Function UltimoDiaCargado(rango As Range) As Byte
Dim maximo As Byte
On Error Resume Next
UltimoDiaCargado = _
IIf(Application.Max(rango) = 0, 0, Day(Application.Max(rango)))
End Function
Function UltimoDiaMes(mes As Byte, año As Integer) As Byte
Dim n As Integer, fch As Date
For n = 31 To 28 Step -1
On Error Resume Next
fch = DateValue(n & "/" & mes & "/" & año)
If Err.Number = 0 Then Exit For
On Error GoTo 0
Next
UltimoDiaMes = n
End Function
Sub CargarDias()
Dim n As Long, T As Long, ultD As Byte, ultDM As Byte, _
uF As Long, hj As Worksheet
Application.ScreenUpdating = False
With ThisWorkbook
Set hj = .Worksheets("Resumen")
With .Worksheets("1")
ultDM = UltimoDiaMes(.[d1], .[e1])
End With
ultD = UltimoDiaCargado(hj.Range(hj.Range("a2"), _
hj.[a65536].End(xlUp).Offset(1)))
If ultD = 0 Then
ultD = 1
Else
hj.[a1].CurrentRegion.Sort key1:=hj.[a2], _
order1:=xlAscending, header:=xlYes
For n = hj.[a65536].End(xlUp).Row To 2 Step -1
If Day(hj.Cells(n, 1)) = ultD Then _
hj.Rows(n).Delete Else Exit For
Next
End If
For n = ultD To ultDM
With .Worksheets(CStr(n))
uF = hj.[a65536].End(xlUp).Row + 1
hj.Range("a" & uF) = CLng(CDate(.[c1] & "/" & _
.[d1] & "/" & .[e1]))
.Range("m45:q94").Copy hj.[b65536].End(xlUp).Offset(1)
.Range("am45:aq94").Copy hj.[b65536].End(xlUp).Offset(1)
.Range("bm45:bq94").Copy hj.[b65536].End(xlUp).Offset(1)
hj.Cells(uF, 1).AutoFill hj.Range(hj.Cells(uF, 1), _
hj.Range("a" & hj.[b65536] _
.End(xlUp).Row)), xlFillCopy
End With
Next
hj.Columns.AutoFit: .Save
End With
Set hj = Nothing
End Sub
''
'-pega hasta aqui

no se si saldra muy chapuza, y atmpoco esta probada con todos tus 'posibles', pero creo que no va mal

si cualquier cosa si quieres comentas

un saludo
Ivan

"mamo66" escribió en el mensajenews:
On 12 dic, 23:39, Ivan wrote:> hola Manuel,

> la verdad es que no se si estare un poco espeso, pero creo que ahora
> tengo aun mas dudas que antes:

> 1º) comentas que tienes 31 hojas, una por dia del mes

> .- supongo que seran en unos casos 31, en otros 30 y en otros
> 28/29

R: En el archivo tengo 31 hojas... fijas.

> 2º) en la hoja de cada dia tienes

> a.-> tres rangos separados pero que tienen la misma estructura de
> datos: [Nº Tarjeta / Cod / Descripcion / Valor]

R: Si, efectivamente

> .-¿como quieres que sea la hoja/lista de destino? tambien con 3
> rangos/listas separadas o en una sola lista con encabezados comunes?.

R: Una sola lista con emcabezados comunes

> .-en cualquiera de los 2 casos ¿en que rango/s quieres que vaya/n
> la/s lista/s

R: Desde la Celda A1 en adelante

> b.-> si tu ej. responde +/- a la realidad en estos 3 rangos pueden
> darse registros exactamente iguales =>

> ' 10201 / 1 / Credito / 15.000 => se repite en 2 de los rangos
> ' 10202 / 1 / Credito / 5.000 => no se repite
> ' 32120 / 2 / Debito / 4.000 => se repite en los 3
> ' 32121 / 2 / Debito / 10.000 => se repite en 2
> '11020202 / 3 / Otras / 20.000 => se repite en los 3

> .-¿como quieres que se considere a estos registros repetidos?¿como
> diferentes o como uno solo? pej. si el mismo registro esta en los 3
> rangos ¿se cargaria 3 veces en la hoja de destino, o se cargaria solo
> 1?

R: Si, se debe cargar 3 veces...

> 3º) acabas diciendo=>

> >> NOTA Importante, esta macro debo ejecutarla las dias 15 + - de cada
> >> mes, entonces en la hoja de destino no me debe llevar los datos que ya
> >> han sido cargados.

> a) si la ejecutas +/- cada dia 15, supongo que cargas la ultima
> quincena del mes anterior y la 1ª del mes en curso

R: No, son los dias del mes en curso.

> .-¿es posible que una vez ejecutado el codigo vuelvan a modificarse
> las hojas de dias anteriores, o sea las ya cargadas?

R: No... eso es poco frecuente, y si pasa se modificaria manualmente
la hoja de Destino.

> .-¿indicas el mes correspondiente en algun sitio o de alguna
> forma?

R: En cada hoja tengo la fecha en esta posicion C2=Dia , D2=Mes,
E2=Año

> .-¿tienes intencion de poner algun campo mas, pej indicando la
> fecha a la que corresponden dichos registros?¿y/o algun nº/
> identificador unico por registro?

R: Exacto, debo sacar la fecha de cada dia desde las celdas comentadas
anteriormente. entonces en la Hoja de destino debe incluir esta campo

> .-¿se pueden borrar los datos de la hojas una vez cargados en el
> resumen, digamos que como para empezar de cero? ¿o es que cada nuevo
> mes vas añaiendo a cada dia los registro a acontinuacion de los ya
> existentes?

R: Bueno, al llegar el dia 31, debo ejecutar otra macro que e limpia
las hojas y comienzo un nuevo mes...

> ..-en cuanto a los datos ya cargados o no, [creo que] las
> posibilidades cambiarian mucho dependiendo de algunas de las cosas/
> dudas comentadas mas arriba

> bueno, de momento no me viene ninguna mas,peros eeguro que se me
> escapan unas cuantas

> siento no ser de gran ayuda

> un saludo
> Ivan

> PD: si quieres comentas algunos mas de estos detalles

Hola Ivan..

Mira, estas planillas son de una estacion de Servicio, y en
las estaciones de servicio, existen 3 turnos. (Mañana, Tarde, Noche),
y en los 3, los atendedores reciben pagos de combustibles con Tarjetas
de Credito, por lo tanto, un Cliente puede pasar a cargar combustible
en la mañana (paga con Tarjeta Rango M45:Q94) y puede pasar en la
Tarde o bien en la noche, por lo tanto seria el mismo Nº de tarjeta,
entonces sí, efectivamente, se puede repetir en el dia, en mas de un
rango.
Cuando digo que no se repitan es; que si ejecuto la macro y me
lee los dias del 1 a 15, y despues el 30 la ejecuto nuevamente, tengo
dos opciones; o bien limpio toda la hoja de destino y cargo desde el
dia 1 al 30, o bien me carga desde el dia 16 en adelante a
continuación de lo que ya se cargo (dia 1 al 15).
En cuanto a la fecha, se me olvido informartelo, y gracias por
tu aclaración, tengo que sacarla de tres celdas en las cuales tengo en
una el Mes en Otra el dia y en otro Año.. C2=Dia , D2=Mes, E2=Año.
Entonces al leer la hoja llamada Dia 1, la macro debe colocar la fecha
que se encuentra en estos rango (C2=Dia , D2=Mes, E2=Año), a todas las
tarjetas de ese dia..al pasar por la Hoja Dia 2, debe colocar la fecha
de ese dia a todas las tarjetas de ese dia.

Gracias nuevamente



Muchas gracias Iva

Lo provare y te cuento

Saludos
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida