copiar de una hoja y pegarlo en otra con macro

16/03/2006 - 15:12 por KM**VE | Informe spam
hola amigos, tengo una hoja de excel de una lista de productos, tiene los
siguente campos,


Hoja1

A B C D E
F J
1 Nombre: Jose perez
2Direccion: miami
3Telf: 305-6294521
4 Pedi. Cod. Nombre Cant Precio Costo
Total
5 10 101 Art1 200 5 4
800.00
6 102 Art2 350 10 6
2,100.00
7 100 103 Art3 650 25 20
13,000.00
8 200 104 Art4 1000 45 36
36,000.00
9 105 Art5 80 1.5
0.80 64.00
10 Pirsa 1380 Total
costo, 51,964.00
-
es posible alguen que hacer esto, en la columna (A) es colocar la cantidad
que uno queres y segun la cantidad colocada se copian por orden en la nueva
hoja segun el nombre de (B1)pedido, tener un boton para que se genera la
nueva hoja y limpia la columna (A) y si es posible que se resta la cantidad
y que recalcula el costo total de la (hoja1) seguin cada pedido.


Hoja2 Jose perez

A B C D E
1 Nombre: Jose
2Direccion: miami
3Telf: 305-6294521
4 Pedi. Cod. Nombre Precio Total
5 10 101 Art1 5 50.00
6 100 103 Art3 25 250.00
7 200 104 Art4 45 900.00
8 Total pieza 310 Total 1,200.00
9
-



Gracias
KM**VE

Preguntas similare

Leer las respuestas

#6 Héctor Miguel
19/03/2006 - 07:00 | Informe spam
hola, Ivan !

... gracias por tus palabras de animo.



[en realidad]... creo que todas las respuestas equivalen a 'palabras de animo' :))
[solo que pocas veces se expresan de manera tan...'expresa'] :D
[ademas de que tu 'auto-critica'... NO 'encaja' con el codigo que expusiste] ;)

... el codigo que expones abre, para mi, una nueva dimension... por la sintaxis... el uso de autofiltro, resize y otros
... en cuanto a la sintaxis... no he encontrado ayuda clara sobre el uso que tu le das. Si no te importa... unas consultas.
1-... "corchetes": supongo por tu ej. que se usan sustituyendo a range (o a cualquier objeto?) dentro de un grupo With, o lo permite el... autofiltro?
2-... Offset(1) sin separador de argumentos(,): creo intuir que representa el primer rango del campo por el cual se a filtrado o estoy equivocado?
3-... with anidados... No estaba seguro de que se pudieran usar. Supongo... que su ambito va de dentro a fuera. no tienen ningun condicionante?



1) los corchetes son una 'evaluacion' TEXTUAL de lo que pudiera ser una 'expresion normal' para el ambito de excel/vba
a) se llama 'notacion abreviada' y puedes consultar al respecto en la ayuda de vba
b) es muy util para 'recortar' expresiones anque pudiera resultar en un ligero 'demerito' en la rapidez de ejecucion de algunos codigos :-(
c) bajo otros criterios [o estructuras de codigo diferentes] es mejor hacer la referencia completa y explicita al objeto al que se refieren [p.e.]
la primera 'aparicion' en el ejemplo: -> .Range(.[a4], .[a65536].End(xlUp))
es el 'equivalente normal' de la expresion: -> .Range(.Range("a4"), .Range("a65536").End(xlUp))
igual se podria sustituir la linea anterior del ejemplo:
de -> With Worksheets("Hoja1")
a: -> With [Hoja1]
o cambiar una referencia completamente 'explicita' [p.e.]
de: -> Worksheets("Hoja1").Range("a1")
a: -> [Hoja1!a1]
OJO: SON referencia a los objetos EN la interfase con el usuario [no confundir con el uso de los 'Code Names']

2) el 'uso' de Offset [que en castellano equivale a la funcion de hoja de calculo DesRef y que 'sirve' para DESplazar una REFerencia]
es una referencia 'directa' a la celda 'desplazada' n_filas/columnas de su referencia 'original' -> de la sintaxis: Offset(Filas, Columnas) [p.e.]
al decir: Range("a1").Offset(2, 4) [realmente] estas haciendo una referencia a 2_filas_abajo y 4_columnas_despues de 'A1' [es decir]: -> 'E3'
al omitir algun argumento [fila o columna] se asume que el 'desplazamiento' [en esa direccion] sera de cero [es decir. la misma fila o columna] ;)

3) los 'with' anidados [al igual que bucles, o if's anidados] efectivamente se desarrollan desde el interior hacia el exterior
en cuanto a 'condicionantes'... [supongo que] solo NO 'perder de vista' en cual estas 'trabajando' para estar cierto del objeto al que estas afectando :))

4) por otras -posibles- 'sintaxis' utilizadas en el ejemplo... los caracteres que le indican [a vba] como debe tratar [p.e.]:
-> 'salto de linea' [dos puntos seguidos de un espacio] significan que la siguiente instruccion 'debiera' leerse como 'la linea de abajo' [ejemplo]
With Worksheets("Hoja1"): If .AutoFilterMode Then .Cells.AutoFilter
seria lo mismo que 'haber escrito' en dos lineas separadas +/- lo mismo...
With Worksheets("Hoja1")
If .AutoFilterMode Then .Cells.AutoFilter

espero no 'enrrollarte' con tanto 'rollo' :))
si cualquier duda... comentas ?
saludos,
hector.
Respuesta Responder a este mensaje
#7 klomkbock
20/03/2006 - 19:38 | Informe spam
Hola KM*VE…….(y Héctor Miguel, y todos los demás)

discúlpame porque me equivoque al enviar el ultimo código y mande el que
no era, y creo que tenia varios errores. En cualquier caso mando otro que,
aunque con varias limitaciones, creo que se podría adaptar a lo que
quieres.

Aunque no estoy seguro de entender del todo lo que quieres hacer, te
explico las adaptaciones para ver si te valen. Por otro lado, ahora no se
si tendré tiempo, pero estoy trabajando en algo parecido a lo que creo que
quieres y pienso que hay algunas cosas que quizás seria mejor ( o mas
cómodo, …o mas practico..) que hicieras de otra manera (discúlpame si me
entrometo o me paso de listo, al fin y al cabo es solo una opinión), si
puedo te las explico al final de este mensaje y si no te las mando por
correo cuando pueda. Vaya por delante lo que ya te he dicho: no soy ningún
experto, y, tanto los códigos que te estoy enviando, como las opiniones
que pueda darte pueden tener (tienen de hecho) bastantes errores, que
espero que con la ayuda del foro se puedan subsanar. Paso a explicarte los
cambios que he hecho en tus hojas.

La hoja del listado (Hoja1) quedaría como sigue:

En las celdas:
-A1=”Nombre” pero como titulo -B1aquí introduces el nombre del cliente
-A2=”Direccion” como titulo -B2aquí la dirección
-A3=”Tlf” como titulo -B3aquí el teléfono
-D1=”NºPedido” como titulo -E1aquí el nº de pedido (numérico o
alfanumérico pero único/no repetido al menos para cada cliente)
-D2=”Fecha” -E2aquí la fecha del pedido

-La fila cuatro se deja vacía, con todas sus celdas en blanco, para
facilitar a Excel reconocer la lista.

-Las celdas: A5, B5, C5, D5, E5, F5 y G5 contendrían respectivamente los
títulos de campo: Pedi, Cod, Nombre, Cant, Precio, Costo y Total

La hoja del cliente(NombreCliente) quedaría así:

-El rango A1:B3 igual que en la Hoja1 -Fila 4 = vacía
-Las celdas A5, B5, C5, D5, E5, F5 y G5 respectivamente: Pedi, Cod,
Nombre, Precio, Total, NºPedi, y Fecha

El motivo de introducir el nº de pedido y la fecha es para que puedas
distinguir los artículos correspondientes a cada pedido, además de poder
filtrarlos con más criterios.

Aunque estoy intentado adaptar el código de H.M. todavía no lo he
conseguido, así que mando una adaptación del mío recogiendo algunas de sus
ideas.

El código copia los registros de la hoja1 de los cuales se hace un pedido
(campo Pedi) en la hoja del cliente ( si no existe la crea) y los va
añadiendo a los ya existentes(como registros independientes, no añadiendo
las cantidades al articulo si ya ha sido pedido anteriormente) y los
ordena por numero de pedido colocando arriba el ultimo realizado y luego
por Cod.

IMPORTANTE: SIEMPRE DEBE HABER AL MENOS UN ARTICULO CON CANTIDADES
PEDIDAS (campo Pedi). De no ser así se generara un desbarajuste que aun no
he sido capaz de resolver.

PD: en cuanto a los consejos de que te he hablado en cuanto pueda, y si te
interesan, te los mando.

Un saludo y hasta pronto.
Ivan.

Este es el código, antes de usarlo haz las modificaciones indicadas arriba
en la hoja1 (listado), y recuerda introducir al menos una cantidad en
Pedi. Pruébalo sobre copias.

Con las dudas seguimos en contacto.

Sub GuardarPedidoCasiOk()
Dim Cliente As String, Celda As Range, i As Integer
Application.ScreenUpdating = False
With Worksheets("Hoja1")
Cliente = .[b1]
On Error Resume Next
If IsError(ActiveWorkbook.Sheets(Cliente)) Then
Worksheets.Add After:=Worksheets("Hoja1")
ActiveSheet.Name = Cliente
.[a1:c3].Copy
With Worksheets(Cliente): .[a1].PasteSpecial xlPasteValues
.[a5:h5] = Array _
("Pedi", "Pedi", "Cod", "Nombre", "Precio", "Total", "NºPedi",
"Fecha")
End With
End If
With Worksheets(Cliente)
.[a1].Offset(.[a65536].End(xlUp).Row - 1, 0).Delete
i = .[a65536].End(xlUp).Row
End With
.Range(.[a6], .[e65536].End(xlUp)).Sort (.[a6])
For Each Celda In .Range(.[a6], .[a65536].End(xlUp))
Range(Celda, Celda.Offset(, 2)).Copy
With Worksheets(Cliente)
.Range(.[a1].Offset(i, 0), .[c1] _
.Offset(i, 0)).PasteSpecial xlPasteValues
Celda.Offset(0, 4).Copy
.[d1].Offset(i, 0).PasteSpecial xlPasteValues
.[e1].Offset(i, 0) = Celda.Offset(0, 4) * Celda
.[f1].Offset(i, 0) = Worksheets("Hoja1").[e1]
.[g1].Offset(i, 0) = Worksheets("Hoja1").[e2]
Celda.Offset(0, 3) = Celda.Offset(0, 3) - Celda
Celda.ClearContents
i = i + 1
End With
Next Celda
With Worksheets(Cliente)
.Range(.[a6], .[g65536].End(xlUp).Address) _
.Sort Key1:=.[g6], Order1:=xlDescending, _
Key2:=.[b6], Order2:=xlAscending
.[a1].Offset(.[a65536].End(xlUp).Row, 0) = _
Application.Sum(.Range(.[a6], .[a1].Offset(.[a65536] _
.End(xlUp).Row - 1, 0)))
.[e1].Offset(.[e65536].End(xlUp).Row, 0) = _
Application.Sum(.Range(.[e6], .[e1].Offset(.[e65536] _
.End(xlUp).Row - 1, 0)))
End With
.Range(.[a6], .[e65536].End(xlUp).Address).Sort (.[b6])
End With
End Sub
Respuesta Responder a este mensaje
#8 klomkbock
20/03/2006 - 19:46 | Informe spam
Hola Hector Miguel y muchas gracias por tu ayuda.

Le he enviado un nuevo codigo a KM*VE basandome un poco en tus premisas
pero no he conseguido usar autofilter (he ordenado por Pedi antes de For
Each para trabajar solo con los registros utiles) pero estoy en ello.
Tambien he usado la notacion .[], para practicar y para los vagos como yo
parece ideal (siempre y cuando consiga descubrir las contraindicaciones.

Muchas gracias de nuevo, y si puedes echar un vistazo al codigo esta en el
otro post. Tiene cosas que he apañado por que no he tenido tiempo de
hacerlo en condiciones (y la verdad es que tampoco doy mucho mas de si).

Un saludo y hasta pronto.
Ivan
Respuesta Responder a este mensaje
#9 KM**VE
20/03/2006 - 21:32 | Informe spam
Hola Ivas de verdad te mando un gran saludo y te agradezco mucho por su
atención.



Lo único que falta a esta cuando hay un pedido del mismo nombre ya lo esta
haciendo bien que se pega en la mismo hoja al final de lo que hay pero es
mejor si puede que a cada pedido lleva un sub total de ventas y sub total
de cantidad de pieza y un gran total de todo de monto y cantidad de pieza a
los pedido.



Gracias
KM**VE

"Ivan" escribió en el mensaje
news:%
Hola KM*VE…….(y Héctor Miguel, y todos los demás)

discúlpame porque me equivoque al enviar el ultimo código y mande el que
no era, y creo que tenia varios errores. En cualquier caso mando otro que,
aunque con varias limitaciones, creo que se podría adaptar a lo que
quieres.

Aunque no estoy seguro de entender del todo lo que quieres hacer, te
explico las adaptaciones para ver si te valen. Por otro lado, ahora no se
si tendré tiempo, pero estoy trabajando en algo parecido a lo que creo que
quieres y pienso que hay algunas cosas que quizás seria mejor ( o mas
cómodo, …o mas practico..) que hicieras de otra manera (discúlpame si me
entrometo o me paso de listo, al fin y al cabo es solo una opinión), si
puedo te las explico al final de este mensaje y si no te las mando por
correo cuando pueda. Vaya por delante lo que ya te he dicho: no soy ningún
experto, y, tanto los códigos que te estoy enviando, como las opiniones
que pueda darte pueden tener (tienen de hecho) bastantes errores, que
espero que con la ayuda del foro se puedan subsanar. Paso a explicarte los
cambios que he hecho en tus hojas.

La hoja del listado (Hoja1) quedaría como sigue:

En las celdas:
-A1=”Nombre” pero como titulo -B1aquí introduces el nombre del cliente
-A2=”Direccion” como titulo -B2aquí la dirección
-A3=”Tlf” como titulo -B3aquí el teléfono
-D1=”NºPedido” como titulo -E1aquí el nº de pedido (numérico o
alfanumérico pero único/no repetido al menos para cada cliente)
-D2=”Fecha” -E2aquí la fecha del pedido

-La fila cuatro se deja vacía, con todas sus celdas en blanco, para
facilitar a Excel reconocer la lista.

-Las celdas: A5, B5, C5, D5, E5, F5 y G5 contendrían respectivamente los
títulos de campo: Pedi, Cod, Nombre, Cant, Precio, Costo y Total

La hoja del cliente(NombreCliente) quedaría así:

-El rango A1:B3 igual que en la Hoja1 -Fila 4 = vacía
-Las celdas A5, B5, C5, D5, E5, F5 y G5 respectivamente: Pedi, Cod,
Nombre, Precio, Total, NºPedi, y Fecha

El motivo de introducir el nº de pedido y la fecha es para que puedas
distinguir los artículos correspondientes a cada pedido, además de poder
filtrarlos con más criterios.

Aunque estoy intentado adaptar el código de H.M. todavía no lo he
conseguido, así que mando una adaptación del mío recogiendo algunas de sus
ideas.

El código copia los registros de la hoja1 de los cuales se hace un pedido
(campo Pedi) en la hoja del cliente ( si no existe la crea) y los va
añadiendo a los ya existentes(como registros independientes, no añadiendo
las cantidades al articulo si ya ha sido pedido anteriormente) y los
ordena por numero de pedido colocando arriba el ultimo realizado y luego
por Cod.

IMPORTANTE: SIEMPRE DEBE HABER AL MENOS UN ARTICULO CON CANTIDADES
PEDIDAS (campo Pedi). De no ser así se generara un desbarajuste que aun no
he sido capaz de resolver.

PD: en cuanto a los consejos de que te he hablado en cuanto pueda, y si te
interesan, te los mando.

Un saludo y hasta pronto.
Ivan.

Este es el código, antes de usarlo haz las modificaciones indicadas arriba
en la hoja1 (listado), y recuerda introducir al menos una cantidad en
Pedi. Pruébalo sobre copias.

Con las dudas seguimos en contacto.

Sub GuardarPedidoCasiOk()
Dim Cliente As String, Celda As Range, i As Integer
Application.ScreenUpdating = False
With Worksheets("Hoja1")
Cliente = .[b1]
On Error Resume Next
If IsError(ActiveWorkbook.Sheets(Cliente)) Then
Worksheets.Add After:=Worksheets("Hoja1")
ActiveSheet.Name = Cliente
.[a1:c3].Copy
With Worksheets(Cliente): .[a1].PasteSpecial xlPasteValues
.[a5:h5] = Array _
("Pedi", "Pedi", "Cod", "Nombre", "Precio", "Total", "NºPedi",
"Fecha")
End With
End If
With Worksheets(Cliente)
.[a1].Offset(.[a65536].End(xlUp).Row - 1, 0).Delete
i = .[a65536].End(xlUp).Row
End With
.Range(.[a6], .[e65536].End(xlUp)).Sort (.[a6])
For Each Celda In .Range(.[a6], .[a65536].End(xlUp))
Range(Celda, Celda.Offset(, 2)).Copy
With Worksheets(Cliente)
.Range(.[a1].Offset(i, 0), .[c1] _
.Offset(i, 0)).PasteSpecial xlPasteValues
Celda.Offset(0, 4).Copy
.[d1].Offset(i, 0).PasteSpecial xlPasteValues
.[e1].Offset(i, 0) = Celda.Offset(0, 4) * Celda
.[f1].Offset(i, 0) = Worksheets("Hoja1").[e1]
.[g1].Offset(i, 0) = Worksheets("Hoja1").[e2]
Celda.Offset(0, 3) = Celda.Offset(0, 3) - Celda
Celda.ClearContents
i = i + 1
End With
Next Celda
With Worksheets(Cliente)
.Range(.[a6], .[g65536].End(xlUp).Address) _
.Sort Key1:=.[g6], Order1:=xlDescending, _
Key2:=.[b6], Order2:=xlAscending
.[a1].Offset(.[a65536].End(xlUp).Row, 0) = _
Application.Sum(.Range(.[a6], .[a1].Offset(.[a65536] _
.End(xlUp).Row - 1, 0)))
.[e1].Offset(.[e65536].End(xlUp).Row, 0) = _
Application.Sum(.Range(.[e6], .[e1].Offset(.[e65536] _
.End(xlUp).Row - 1, 0)))
End With
.Range(.[a6], .[e65536].End(xlUp).Address).Sort (.[b6])
End With
End Sub


Respuesta Responder a este mensaje
#10 klomkbock
23/03/2006 - 03:09 | Informe spam
Hola KM*VE

Aquí te mando otro código que creo que resuelve la mayoría de los errores
del anterior y realiza lo último que comentas. La hoja del listado sigue
siendo como la ultima que te comente pero en la hoja del cliente pasa a
reflejar (al ejecutar la macro) los totales de venta y de piezas en las
celdas E1 y E2, y los totales de cada pedido en las celdas a la derecha de
la primera fila de cada pedido. El nombre del cliente y el nº de pedido es
obligatorio introducirlos (en la hoja Listado).

Espero que este te sea más útil, aunque probablemente sea muy mejorable en
su estructura. Como siempre, ve con cuidado.

Si puedes me confirmas que lo has visto y si te ha sido útil.

Por otro lado, lo que te comentaba el otro dia es que yo lo que hago
(intento) en un caso parecido al tuyo (pero con proveedores en vez de
clientes) es un libro por cliente, guardados en la misma carpeta. En la
primera hoja estarian los datos del cliente, en la segunda un listado de
todos los pedidos (un registro por pedido) con los totales y todos los
datos/campos que quiera reflejar de cada pedido, y las restantes serian
una hoja para cada pedido con el detalle.

Tambien intentaria introducir el pedido mediante un formulario o una hoja
que hiciera las funciones del mismo y que podria ir en el libro del
listado, aunque si trabajas con pocos articulos quizas no te haga falta.

En cualquier caso es cuestion de las necesidades de cada uno y de la forma
de trabajar o las preferencias.

Con las dudas hablamos.
Un saludo y hasta pronto
Ivan

Sub GuardarPedidoCasiCasiOk()
Dim Cliente As String, i As Long
Dim Celda As Range, Celda2 As Range
Dim Total As Long, Piezas As Long
Application.ScreenUpdating = False
With Worksheets("Hoja1"): Cliente = .[b1]
If .[b1] = "" Or .[e1] = "" Then
MsgBox ("Faltan datos del pedido, revisalos")
.[b1].Select: Exit Sub: End If
On Error Resume Next
If IsError(ActiveWorkbook.Sheets(Cliente)) Then
Worksheets.Add After:=Worksheets("Hoja1")
ActiveSheet.Name = Cliente
.[a1:c3].Copy: Application.CutCopyMode = False
With Worksheets(Cliente): .[a1].PasteSpecial xlPasteValues
.[a5:g5] = Array _
("Pedi", "Cod", "Nombre", "Precio", "Total", "NºPedi", "Fecha")
.[d1] = "PIEZAS": .[d2] = "TOTAL $": End With: End If
With .[a65536].End(xlUp)
If .Row = 5 Then
MsgBox ("No has introducido la cantidad pedida.")
.Offset(1, 0).Select: Exit Sub
ElseIf .Row > 5 And Not IsNumeric(.Value) Then
MsgBox ("El dato introducido no es valido, revisalo.")
.Select: Exit Sub: Range(Range("a6"), .Range).Sort (.[a6])
End If: End With
For Each Celda In .Range(.[a6], .[a65536].End(xlUp))
Range(Celda, Celda.Offset(, 2)).Copy
With Worksheets(Cliente): i = .[a65536].End(xlUp).Row
.Range(.[a1].Offset(i, 0), .[c1] _
.Offset(i, 0)).PasteSpecial xlPasteValues
Celda.Offset(0, 4).Copy
.[d1].Offset(i, 0).PasteSpecial xlPasteValues
.[e1].Offset(i, 0) = Celda.Offset(0, 4) * Celda
.[f1].Offset(i, 0) = Worksheets("Hoja1").[e1]
.[g1].Offset(i, 0) = Worksheets("Hoja1").[e2]
.[g1].Offset(i, 0) = FormatDateTime(.[g1].Offset(i, 0))
Celda.Offset(0, 3) = Celda.Offset(0, 3) - Celda
Celda.ClearContents: i = i + 1: End With: Next Celda
With Worksheets(Cliente)
.Range(.[a6], .[g65536].End(xlUp).Address) _
.Sort Key1:=.[f6], Order1:=xlDescending, _
Key2:=.[b6], Order2:=xlAscending
.[e1] = Application.Sum(.Range(.[a6], _
.[a1].Offset(.[a65536].End(xlUp).Row - 1, 0)))
.[e2] = Application.Sum(.Range(.[e6], _
.[e1].Offset(.[e65536].End(xlUp).Row - 1, 0)))
Range(.[h6], .[k1].Offset(.[f65536].End(xlUp).Row, 0)).Delete
For Each Celda2 In .Range(.[f6], .[f65536].End(xlUp))
With Celda2: Total = .Offset(0, -1).Value
Piezas = .Offset(0, -5).Value
If .Value <> .Offset(-1, 0) Then
.Offset(0, 2) = "TT PedNº" & .Value & "="
.Offset(0, 3) = Total
.Offset(0, 4) = "Pzs PedNº" & .Value & "="
.Offset(0, 5) = Piezas
ElseIf .Value = .Offset(-1, 0) Then
.Offset(0, 3).End(xlUp) = .Offset(0, 3).End(xlUp) + Total
.Offset(0, 5).End(xlUp) = .Offset(0, 5).End(xlUp) + Piezas
End If: End With: Next Celda2: .Columns.AutoFit
End With
.Range(.[a6], .[e65536].End(xlUp).Address).Sort (.[b6])
.Range(.[b1], .[b3]).ClearContents
.Range(.[e1], .[e2]).ClearContents
End With
End Sub
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida