Foros del Web » Soporte técnico » Ofimática »

Excel: Pegar datos con bucle

Estas en el tema de Excel: Pegar datos con bucle en el foro de Ofimática en Foros del Web. Hola. Estoy aprendiendo a usar las macros. Para empezar estoy con la grabadora de macros. Lo primero que he hecho ha sido copiar una columna ...
  #1 (permalink)  
Antiguo 18/09/2008, 18:03
 
Fecha de Ingreso: octubre-2007
Mensajes: 22
Antigüedad: 16 años, 6 meses
Puntos: 0
Excel: Pegar datos con bucle

Hola.

Estoy aprendiendo a usar las macros. Para empezar estoy con la grabadora de macros. Lo primero que he hecho ha sido copiar una columna de una hoja e ir pegándola en otra hoja. Más o menos así:

Código:
Sub prueba()
'
' prueba Macro
'
' Acceso directo: CTRL+r
'
    Calculate
    Range("I5:I15").Select
    Selection.Copy
    Sheets("Rol").Select
    Range("A1").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Sheets("Creador").Select
    Application.CutCopyMode = False
    Calculate
    Selection.Copy
    Sheets("Rol").Select
    Range("B1").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Sheets("Creador").Select
    Application.CutCopyMode = False
    Calculate
    Selection.Copy
    Sheets("Rol").Select
    Range("C1").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
End Sub
En este caso he copiado y pegado 3 veces. Me gustaría saber si esta tarea repetitiva se puede hacer utilizando un bucle para copiar la misma columna (que es de valores aleatorios, por tanto las columnas pegadas serán diferentes) e ir pegándola en diferentes columnas en otra hoja tantas veces como quiera.

Muchas gracias.

Un saludo.
  #2 (permalink)  
Antiguo 18/09/2008, 20:41
Avatar de mrocf  
Fecha de Ingreso: marzo-2007
Ubicación: Bs.As.
Mensajes: 1.103
Antigüedad: 17 años
Puntos: 88
Busqueda Pegar datos con bucle

Hola! STDSTC. Puedes hacerlo de varios modos.
El siguiente código realiza lo mismo que el tuyo... pero sin moverse de la hoja "Creador":
Código:
Sub Prueba2()
  Application.ScreenUpdating = False
  Rangos = Array("A1", "B1", "C1")
For ii = 0 To 2
  Calculate
  Range("I5:I15").Copy
  Sheets("Rol").Range(Rangos(ii)).PasteSpecial Paste:=xlPasteValues
Next ii
  Application.ScreenUpdating = True
End Sub
Tienes varias cosas que mirar:
a) ScreenUpdating.
b) Array.
c) "Calculate" NUNCA fue necesario, realmente.

etc. etc. etc.

Saludos, Cacho.
  #3 (permalink)  
Antiguo 18/09/2008, 21:00
Avatar de mrocf  
Fecha de Ingreso: marzo-2007
Ubicación: Bs.As.
Mensajes: 1.103
Antigüedad: 17 años
Puntos: 88
Respuesta: Excel: Pegar datos con bucle

Hola! STDSTC.
Otra alternativa pero sin utilizar la información del rango I5:I15 de la hoja "Creador":
Código:
Sub Prueba3()
  Application.ScreenUpdating = False
  Rangos = Array("A", "B", "C")
For ii = 0 To 2
  With Sheets("Rol").Range(Rangos(ii) & "1:" & Rangos(ii) & "11")
    .Formula = "=RAND()": .Copy: .PasteSpecial xlPasteValues
  End With
Next ii
  Application.ScreenUpdating = True
End Sub
Saludos, Cacho.

  #4 (permalink)  
Antiguo 18/09/2008, 21:10
Avatar de mrocf  
Fecha de Ingreso: marzo-2007
Ubicación: Bs.As.
Mensajes: 1.103
Antigüedad: 17 años
Puntos: 88
De acuerdo Respuesta: Excel: Pegar datos con bucle

Y así es como yo lo haría:
Código:
Sub Prueba4()
  With Sheets("Rol").[A1:C11]
    .Formula = "=RAND()": .Copy: .PasteSpecial xlPasteValues
  End With
End Sub
Saludos, Cacho.
  #5 (permalink)  
Antiguo 19/09/2008, 03:59
 
Fecha de Ingreso: octubre-2007
Mensajes: 22
Antigüedad: 16 años, 6 meses
Puntos: 0
Respuesta: Excel: Pegar datos con bucle

Hola Cacho. Gracias por tus respuestas.

Pero me sirven a medias porque pegan 3 columnas o una solo en la otra hoja. Lo que yo quiero hacer es que la Columna de la hoja "Creador" se copie tantas veces como quiera (por ejemplo, si pongo un bucle de 100) que copie 100 veces los distintos resultados aleatorios de I5:I15 y los vaya pegando en la hoja "Rol" de modo que en A1:A11 quede el primer resultado, en B1:B11, el segundo, así hasta la décima columna (J1:J11). Y apartir de ahí continue por abajo. Es decir, el 11º resultado quedaría pegado en A12:A22, y de nuevo hasta la columna 10ª (J12:J22). Y siguiendo así hasta completar las 100 simulaciones.

A partir de tu código he intentado ampliar los rangos y bucles

Rangos = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")
For ii = 0 To 9

ó

[A1:J11]


para que hiciera más o menos lo que quiero pero no da resultado.

A ver si me puedes orientar un poco.

Un saludo. Gracias.
  #6 (permalink)  
Antiguo 19/09/2008, 10:34
Avatar de mrocf  
Fecha de Ingreso: marzo-2007
Ubicación: Bs.As.
Mensajes: 1.103
Antigüedad: 17 años
Puntos: 88
De acuerdo Respuesta: Excel: Pegar datos con bucle

Realmente no se entiende por qué deseas basarte en el contenido del rango I5:I15 como si ello tuviese algún tipo de significado o importancia...
Diría que no estás entendiendo el funcionamiento de la función ALEATORIO() (ó RAND() en inglés).

De modo que te dejaré el código que necesitas y te propongo que te pongas a investigar el tema con profundidad para que adviertas que estás aplicando -lo que se denomina- un pensamiento muy estructurado: ello no es siempre útil a la hora de programar:
Código:
Sub Prueba4()
  With Sheets("Rol").[A1:J22]
    .Formula = "=RAND()": .Copy: .PasteSpecial xlPasteValues
  End With
End Sub
Saludos, Cacho.

P.D.:
Desestructurar el pensamiento implica plantearte: 1º) cual es tu objetivo; 2º) cuales son tus alternativas; 3º) decidir cual es la mejor.

En este caso, me parece que estás partiendo de una única alternativa (que -encima- no es la mejor) y quieres buscar optimizarla: ojala se entienda esta sugerencia.
  #7 (permalink)  
Antiguo 19/09/2008, 13:15
 
Fecha de Ingreso: octubre-2007
Mensajes: 22
Antigüedad: 16 años, 6 meses
Puntos: 0
Respuesta: Excel: Pegar datos con bucle

Hola de nuevo.

Puede que no me haya explcado bien y por eso no me entiendes. Intentaré hacerlo mejor y con más detalles ahora.

El fondo de la cuestión es que yo quiero conseguir valores aleatorios comprendidos entre dos números. Para eso utilizo la función aleatorio. Pero hay un problema y es que la función aleatorio o aleatorio.entre arroja valores repetidos. Yo no quiero que se repitan los valores. Por esto, en la columna G tengo las siguiente fórmulas (en el rango G5:G15):

Para las 3 primeras filas (copiando y arrastrando la primera hasta G7) quiero números aleatorios entre 1 y 40:
=SI(SUMA($H$5:$H$15)<>11&SUMA($L$5:$L$15)>6500000& SUMA(I5:I15)>2;REDONDEAR(ALEATORIO()*(40-1)+1;0);REDONDEAR(ALEATORIO()*(40-1)+1;0))

Para las 4 siguientes filas (copiando y arrastrando la primera hasta G11) quiero números aleatorios entre 41y 106:
=SI(SUMA($H$5:$H$15)<>11&SUMA($L$5:$L$15)>6500000& SUMA(I5:I15)>2;REDONDEAR(ALEATORIO()*(106-41)+41;0);REDONDEAR(ALEATORIO()*(106-41)+41;0))

Para las 4 siguientes filas (copiando y arrastrando la primera hasta G15) quiero números aleatorios entre 107 y 182:
=SI(SUMA($H$5:$H$15)<>11&SUMA($L$5:$L$15)>6500000& SUMA(I5:I15)>2;REDONDEAR(ALEATORIO()*(182-107)+107;0);REDONDEAR(ALEATORIO()*(181-107)+107;0))

Luego, en la columna H tengo un Control cuya fórmula es:

=CONTAR.SI($G$5:$G$15;G5) (Y arrastramos hasta H15)

Éste mostrará todo 1 si no hay valores repetidos y 2 cuando los haya.

En la columna I tengo el identificador de los números aleatorios obtenidos en forma de nombres (esto como digo más abajo lo he desplazado hacia la columna K al realizar otras pruebas incluyendo condiciones). Es decir, en la columna G se generan los valores aleatorios y en I es donde los valores se convierten en nombres mediante un buscarv.

El procedimiento es generar 11 valores aleatorios pulso F9, copiar el resultado si no han repetidos y pegarlo en otra hoja. Y así cada vez que quiero otros 11 resultados. Entonces, lo que quiero hacer es una macro mediante la cual no tenga que estar todo el rato pulsando F9 para generar otros 11 valores, copiando esos valores y pegándolos en otra hoja. Quiero hacer todo eso automáticamente y el número de veces que yo elija. De modo que en otra hoja tendré bloques de 11 filas (que son los valores generados en cada tanda) unos junto a los otros sin pisarse.

El código que yo estaba utilizando era este:

Código:
Sub Creador()
'
' Creador Macro
'
' Acceso directo: CTRL+j
'
    Dim i As Integer
    Calculate
    Range("K5:K15").Select
    For i = 1 To 10
    If Sheets("Creador").Cells(19, 12) = "BIEN" And Sheets("Creador").Cells(17, 12) > 6000000 Then

    Selection.Copy
    Sheets("Rol").Select
    Range("A1").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    End If
    ActiveCell.Offset(0, 1).Select
    
    Calculate
    Range("K5:K15").Select
    Next i
    
End Sub
He desplazado los resultados de I hacia K y en esas dos columnas he introducido otras fórmulas que me sirven luego para establecer condiciones como uedes ver en el bucle if.

Con este código, a veces, se encuentran 11 resultados que cumplen las condiciones y se pegan en la hoja "Rol" en el rango A1:A11. Me gustaría que se pudieran ir pegando sucesivamente, por ejemplo, en A1:A11, 11 resultados, luego en B1:B11 otros 11 rresultados, así hasta la columna J. Después volvemos a la columna A. Debajo de los 11 anteriores pegamos otros 11, es decir, en A12:22. Otros 11 en B12:B22, otros 11 en C12:C22 y así hasta la columna J otra vez. Es decir, cada 2 tandas de filas de 11 serían 20 simulaciones. La cosa sería hacer como 100 o así por lo que el rango total sería A1:J110. Y habría 100 simulaciones de 11 cada una.

No se si ahora ha quedado algo más claro lo que quiero hacer.

Un saludo.
  #8 (permalink)  
Antiguo 19/09/2008, 14:37
Avatar de mrocf  
Fecha de Ingreso: marzo-2007
Ubicación: Bs.As.
Mensajes: 1.103
Antigüedad: 17 años
Puntos: 88
De acuerdo Respuesta: Excel: Pegar datos con bucle

Imagino que entre el contenido del archivo AleatoriosEnRangosSinRepe.xls y adaptando mi primer mensaje: resuelves tu problema.

Saludos, Cacho.
  #9 (permalink)  
Antiguo 20/09/2008, 06:04
 
Fecha de Ingreso: octubre-2007
Mensajes: 22
Antigüedad: 16 años, 6 meses
Puntos: 0
Respuesta: Excel: Pegar datos con bucle

Gracias por el archivo. Creo que es de más utilidad que lo que tenía antes. Me ha parecido muy curiosa la forma de obtener los números aleatorios sin repetición.

Ya he conseguido que me cree todas las simulaciones de 11 que quiera, eso si poniendo el rango a mano en el array, en este caso de la columna A1 hasta J1 (¿no hay forma de evitar tener que ponerlos todos a mano, algo del tipo A1:J1?)

Código:
Public Sub Genera_11_Numeros()
  Application.Calculate
  Rangos = Array("A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1", "I1", "J1")
  For i = 0 To 9
With Sheets("Generador")
  For ii = 0 To 6 Step 3
    .[A1].Offset(0, ii).CurrentRegion.Sort Key1:=.[B1].Offset(0, ii)
  Next ii
End With
Range("L1:L11").Copy
Sheets("Resultados").Range(Rangos(i)).PasteSpecial Paste:=xlPasteValues
Next i
End Sub
Y otra cosa importante, cuando obtengo las simulaciones de 11 en las X columnas que he definido en el primer bucle for algunas de ellas no son válidas por que no cumplen la condición que quiero mantener que es esta:

Código:
If Sheets("Generador").Cells(15, 13) = "BIEN" And Sheets("Generador").Cells(13, 13) > 6000000 Then

.
Yo esa condición la incluyo al final
Código:
Public Sub Genera_11_Numeros()
  Application.Calculate
  Rangos = Array("A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1", "I1", "J1")
  For i = 0 To 9
With Sheets("Generador")
  For ii = 0 To 6 Step 3
    .[A1].Offset(0, ii).CurrentRegion.Sort Key1:=.[B1].Offset(0, ii)
  Next ii
End With
  If Sheets("Generador").Cells(15, 13) = "BIEN" And Sheets("Generador").Cells(13, 13) > 6000000 Then
Range("L1:L11").Copy
Sheets("Resultados").Range(Rangos(i)).PasteSpecial Paste:=xlPasteValues
  End If
Next i
End Sub
Pero claro, esto hace que en la primera corrida de la simulación, si no se cumple la condición, la columna A1 quede vacía, si no se cumple en la segunda corrida, la columna B2 también queda vacía y así hasta la columna J. Es decir, sólo se rellena cuando se cumple la condición, por lo que casi siempre que pulso el botón van a quedar columnas vacías de las 10 que he definido (de la A a la J).

¿Cómo puedo introducir esa condición en el código de modo que cuando no se cumpla, no deje la columna vacía y pase a la siguiente, sino que continue en esa columna hasta que halle unos valores que cumplan la condición y cuando los halle siga hasta terminar de rellenar las columnas definidas, en este caso hasta la columna J?

Todo esto es para no tener que ir seleccionando los resultados que han salido correctos de los que no y que salgan todos correctos.

Un saludo.
  #10 (permalink)  
Antiguo 20/09/2008, 09:58
Avatar de mrocf  
Fecha de Ingreso: marzo-2007
Ubicación: Bs.As.
Mensajes: 1.103
Antigüedad: 17 años
Puntos: 88
Respuesta: Excel: Pegar datos con bucle

Para tu primera consulta: puedes reemplazar "Range(Rangos(i))" por "Cells(1, i+1)".
Y para tu segunda: lée sobre Do-Loop.

Saludos, Cacho.
  #11 (permalink)  
Antiguo 20/09/2008, 15:42
 
Fecha de Ingreso: octubre-2007
Mensajes: 22
Antigüedad: 16 años, 6 meses
Puntos: 0
Respuesta: Excel: Pegar datos con bucle

Muchas gracias Cacho por tu ayuda. Ya lo conseguí. Lo pongo aquí por si algún principiante como yo quiere verlo.

Código:
Public Sub Genera_11_Numeros()
  Application.Calculate
  Do While Sheets("Generador").Cells(17, 13) <> 100
  For i = 0 To 99
With Sheets("Generador")
  For ii = 0 To 6 Step 3
    .[A1].Offset(0, ii).CurrentRegion.Sort Key1:=.[B1].Offset(0, ii)
  Next ii
End With
  If Sheets("Generador").Cells(15, 13) = "BIEN" And Sheets("Generador").Cells(13, 13) > 6000000 Then
Range("L1:L11").Copy
Sheets("Resultados").Cells(1, i + 1).PasteSpecial Paste:=xlPasteValues
  End If
Next i
Loop
Call Apilar
End Sub
Un saludo.
  #12 (permalink)  
Antiguo 20/09/2008, 20:35
Avatar de mrocf  
Fecha de Ingreso: marzo-2007
Ubicación: Bs.As.
Mensajes: 1.103
Antigüedad: 17 años
Puntos: 88
Respuesta: Excel: Pegar datos con bucle

Gracias, STDSTC y hasta la próxima.

Saludos, Cacho.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 09:26.