movimiento y ejecucion simultanea. Programacion emergente

10/09/2005 - 06:00 por luisf | Informe spam
Tengo programado ya la ejecucion del movimiento de distintos objetos en una
hoja de excel xp, pero lo hago a traves de un for each... next. El
movimiento es muy rapido para 10 objetos, pero para 100 empieza a ir a saltos.

¿como se les puede dar mejor movimiento? nota: la grabacion de macros del
power point no registra los movimientos de objetos, que aqui si se vmueven
con rapidez independientemente de su numero.

¿como puedo ejcutar dos macros de manera simultanea?, es decir mandar a un
objeto que se mueva segun la macro1 y, mientras se esta moviendo, mandar a
otro que ejecute la macro2. nota: si se hace medienta call (aunque sea con un
doevents) para la ejecucion de la macro1, hace toda la macro2, y
posteriormente finaliza la macro1.

Las dos preguntas tienen el mismo fin, la realizacion simultanea de tareas,
con el objetivo final de poder hacer un tipo de programacion emergente.

Preguntas similare

Leer las respuestas

#1 KL
10/09/2005 - 09:35 | Informe spam
Hola luis,

Creo que en este caso un codigo de ejemplo valdria mas que el mensaje entero
;-)

Me parece (muy) raro que el simple hecho de mover 100 objetos (no
especificas que clase de objetos , pero casi que da igual) pueda relentizar
o afectar de otra manera el codigo. Me suena mas bien a que por una lado
posiblemente abuses del metodo select y por otro no uses la propiedad
ScreenUpdating del objeto Application. De todas formas puede haber muchas
mas causas y es posible que me equivoque. ?Comentas?

Saludos,
KL


"luisf" wrote in message
news:
Tengo programado ya la ejecucion del movimiento de distintos objetos en
una
hoja de excel xp, pero lo hago a traves de un for each... next. El
movimiento es muy rapido para 10 objetos, pero para 100 empieza a ir a
saltos.

?como se les puede dar mejor movimiento? nota: la grabacion de macros del
power point no registra los movimientos de objetos, que aqui si se vmueven
con rapidez independientemente de su numero.

?como puedo ejcutar dos macros de manera simultanea?, es decir mandar a un
objeto que se mueva segun la macro1 y, mientras se esta moviendo, mandar a
otro que ejecute la macro2. nota: si se hace medienta call (aunque sea con
un
doevents) para la ejecucion de la macro1, hace toda la macro2, y
posteriormente finaliza la macro1.

Las dos preguntas tienen el mismo fin, la realizacion simultanea de
tareas,
con el objetivo final de poder hacer un tipo de programacion emergente.
Respuesta Responder a este mensaje
#2 luisf
12/09/2005 - 11:01 | Informe spam
Ante todo gracias por responder a mi peticion de ayuda.

Te mando el cogigo que mueve los objetos, que por cierto no son mas que
autoformas de excel (ya sabes, caras, corazones, ect...)

*************************************************
Sub movuniversal()
'Este programa mueve los objetos pintados en la hoja activa, pero antes:
'Primero redimensiono la hoja a cuadriculas de 13x13 pixeles
'Luego creo un marco (cuadrado) a base de pintar el fondo de las celdas del
marco en blanco
'Finalmente pongo una autoforma que ocupe toda una celda y la replico dentro
del marco, poniendo la celda que ocupan con el fondo blanco
'Y una vez hecho todo esto, ejecuto este programa

For i = 1 To 100 'para realizar el movimiento global 100 veces
For Each s In ActiveSheet.Shapes 'mueve cada objeto (en este caso suelo
poner autoformas)

s.Select

fil5 = Selection.TopLeftCell.Rows.Row ' para obtener la fila donde esta
el objeto
col5 = Selection.TopLeftCell.Columns.Column 'para la columna

Randomize ' gerero dos numeros que cada uno puede ser: 1 ,0, -1
x = (Int(3 * Rnd) - 1)
y = (Int(3 * Rnd) - 1)


If Cells(fil5 + x, col5 + y).Interior.ColorIndex = 2 Then 'Este if
controla que los objetos no se salgan del marco...
x = 0 'hecho a base de llenar el fondo de blanco(tambien evita las
posiciones ocupadas por otros objetos, ya que esta estan tambien pintadas de
blanco)
y = 0 'Lo que hace es que si la nueva posicion a ocupar tiene fondo
blanco, no se mueve (en esta vuelta i)
End If

Cells(fil5, col5).Interior.ColorIndex = 0 'quita el color blanco de la
antigua posicion
Cells(fil5 + x, col5 + y).Interior.ColorIndex = 2 ' pinta de color
blanco la nueva posicion

'Ahora muevo el objeto +1, 0 ó -1 (el *10 es por que en las celdas de
13x13 pixeles ...
'el desplazamiento de 10 en un objeto que ocupe toda la celda es justo
para pasar a otra celda)
'Esto es mas rapido que cortar y pegar
Selection.ShapeRange.IncrementLeft y * 10 'movimiento horizontal
Selection.ShapeRange.IncrementTop x * 10 'movimiento vertical

Next

Next
End Sub
************************************************
Este codigo es el cuarto o quito intento de depuracion, es decir que no me
salio asi a la primera, pero es el que mejor va (de momento).

No obstante, despues del primer mensaje, he podido averiguar que lo que
relentiza la ejecucion es el hecho de pintar en la hoja de excel (el intento
de escribir las posiciones en otra hoja y despues operar tiene el mismo
resultado), es decir, cualquier accion de pintar o escribir sobre la hoja
relentiza el proceso.

Ahora, y tras desempolvar los viejos recuerdos del BASIC, estoy atacando el
problema a base de crear una matriz con las posiciones de los objetos (esto,
ya lo he comprobado, no relentiza el proceso segun el numero de objetos).

De todas formas, agradeceria cualquier sugerencia, ya que cuando pase a
programar las interacciones entre objetos se me complicara algo la cosa si lo
tengo que hacer a base de matrices.

¿No hay algun tipo de objeto que se pueda programar y que se ejecute su
programa de forma independiente de otros objetos similares?

Lo suyo, para mi caso y el de la programacion emergente (o multiagente),
seria el poder programar cado objeto (¿hormiga?) y que luego el evolucionara
a la vez, e independientemente,que el resto de objetos (¿hormigas?).

No obstante, tal y como voy, podria obtener un efecto similar, aunque en
lugar de miniprogramas ejecutandose a la vez, se tendria un macroprograma que
se aplicaria a cada objeto secuencialmente pero de forma rapida.

Volviendo a agraceder tu primera respuesta, quedo esperando con impaciencia
la segunda.

Gracias.

luisf.


luisf


"KL" escribió:

Hola luis,

Creo que en este caso un codigo de ejemplo valdria mas que el mensaje entero
;-)

Me parece (muy) raro que el simple hecho de mover 100 objetos (no
especificas que clase de objetos , pero casi que da igual) pueda relentizar
o afectar de otra manera el codigo. Me suena mas bien a que por una lado
posiblemente abuses del metodo select y por otro no uses la propiedad
ScreenUpdating del objeto Application. De todas formas puede haber muchas
mas causas y es posible que me equivoque. ?Comentas?

Saludos,
KL


"luisf" wrote in message
news:
> Tengo programado ya la ejecucion del movimiento de distintos objetos en
> una
> hoja de excel xp, pero lo hago a traves de un for each... next. El
> movimiento es muy rapido para 10 objetos, pero para 100 empieza a ir a
> saltos.
>
> ?como se les puede dar mejor movimiento? nota: la grabacion de macros del
> power point no registra los movimientos de objetos, que aqui si se vmueven
> con rapidez independientemente de su numero.
>
> ?como puedo ejcutar dos macros de manera simultanea?, es decir mandar a un
> objeto que se mueva segun la macro1 y, mientras se esta moviendo, mandar a
> otro que ejecute la macro2. nota: si se hace medienta call (aunque sea con
> un
> doevents) para la ejecucion de la macro1, hace toda la macro2, y
> posteriormente finaliza la macro1.
>
> Las dos preguntas tienen el mismo fin, la realizacion simultanea de
> tareas,
> con el objetivo final de poder hacer un tipo de programacion emergente.



Respuesta Responder a este mensaje
#3 Luis Garcia
12/09/2005 - 13:27 | Informe spam
Hola:

Sin entrar en tema de que es lo que realmente quieres hacer, como
optimizacion yo probaria las siguientes:

1) Usar la variable 's' en vez de 'Selection'
2) Quitar el 's.Select'
3) Poner una comprobación para x<>0 o y<>0 para realizar los 'cambios' de
colores y posiciones solo cuando sea necesario.
4) Poner un Application.ScreenUpdating = False antes del For Each y = True
al salir.

Saludos

Luis


"luisf" escribió en el mensaje
news:
Ante todo gracias por responder a mi peticion de ayuda.

Te mando el cogigo que mueve los objetos, que por cierto no son mas que
autoformas de excel (ya sabes, caras, corazones, ect...)

*************************************************
Sub movuniversal()
'Este programa mueve los objetos pintados en la hoja activa, pero antes:
'Primero redimensiono la hoja a cuadriculas de 13x13 pixeles
'Luego creo un marco (cuadrado) a base de pintar el fondo de las celdas


del
marco en blanco
'Finalmente pongo una autoforma que ocupe toda una celda y la replico


dentro
del marco, poniendo la celda que ocupan con el fondo blanco
'Y una vez hecho todo esto, ejecuto este programa

For i = 1 To 100 'para realizar el movimiento global 100 veces
For Each s In ActiveSheet.Shapes 'mueve cada objeto (en este caso suelo
poner autoformas)

s.Select

fil5 = Selection.TopLeftCell.Rows.Row ' para obtener la fila donde


esta
el objeto
col5 = Selection.TopLeftCell.Columns.Column 'para la columna

Randomize ' gerero dos numeros que cada uno puede ser: 1 ,0, -1
x = (Int(3 * Rnd) - 1)
y = (Int(3 * Rnd) - 1)


If Cells(fil5 + x, col5 + y).Interior.ColorIndex = 2 Then 'Este if
controla que los objetos no se salgan del marco...
x = 0 'hecho a base de llenar el fondo de blanco(tambien evita las
posiciones ocupadas por otros objetos, ya que esta estan tambien pintadas


de
blanco)
y = 0 'Lo que hace es que si la nueva posicion a ocupar tiene fondo
blanco, no se mueve (en esta vuelta i)
End If

Cells(fil5, col5).Interior.ColorIndex = 0 'quita el color blanco de la
antigua posicion
Cells(fil5 + x, col5 + y).Interior.ColorIndex = 2 ' pinta de color
blanco la nueva posicion

'Ahora muevo el objeto +1, 0 ó -1 (el *10 es por que en las celdas de
13x13 pixeles ...
'el desplazamiento de 10 en un objeto que ocupe toda la celda es justo
para pasar a otra celda)
'Esto es mas rapido que cortar y pegar
Selection.ShapeRange.IncrementLeft y * 10 'movimiento horizontal
Selection.ShapeRange.IncrementTop x * 10 'movimiento vertical

Next

Next
End Sub
************************************************
Este codigo es el cuarto o quito intento de depuracion, es decir que no me
salio asi a la primera, pero es el que mejor va (de momento).

No obstante, despues del primer mensaje, he podido averiguar que lo que
relentiza la ejecucion es el hecho de pintar en la hoja de excel (el


intento
de escribir las posiciones en otra hoja y despues operar tiene el mismo
resultado), es decir, cualquier accion de pintar o escribir sobre la hoja
relentiza el proceso.

Ahora, y tras desempolvar los viejos recuerdos del BASIC, estoy atacando


el
problema a base de crear una matriz con las posiciones de los objetos


(esto,
ya lo he comprobado, no relentiza el proceso segun el numero de objetos).

De todas formas, agradeceria cualquier sugerencia, ya que cuando pase a
programar las interacciones entre objetos se me complicara algo la cosa si


lo
tengo que hacer a base de matrices.

¿No hay algun tipo de objeto que se pueda programar y que se ejecute su
programa de forma independiente de otros objetos similares?

Lo suyo, para mi caso y el de la programacion emergente (o multiagente),
seria el poder programar cado objeto (¿hormiga?) y que luego el


evolucionara
a la vez, e independientemente,que el resto de objetos (¿hormigas?).

No obstante, tal y como voy, podria obtener un efecto similar, aunque en
lugar de miniprogramas ejecutandose a la vez, se tendria un macroprograma


que
se aplicaria a cada objeto secuencialmente pero de forma rapida.

Volviendo a agraceder tu primera respuesta, quedo esperando con


impaciencia
la segunda.

Gracias.

luisf.


luisf


"KL" escribió:

> Hola luis,
>
> Creo que en este caso un codigo de ejemplo valdria mas que el mensaje


entero
> ;-)
>
> Me parece (muy) raro que el simple hecho de mover 100 objetos (no
> especificas que clase de objetos , pero casi que da igual) pueda


relentizar
> o afectar de otra manera el codigo. Me suena mas bien a que por una lado
> posiblemente abuses del metodo select y por otro no uses la propiedad
> ScreenUpdating del objeto Application. De todas formas puede haber


muchas
> mas causas y es posible que me equivoque. ?Comentas?
>
> Saludos,
> KL
>
>
> "luisf" wrote in message
> news:
> > Tengo programado ya la ejecucion del movimiento de distintos objetos


en
> > una
> > hoja de excel xp, pero lo hago a traves de un for each... next. El
> > movimiento es muy rapido para 10 objetos, pero para 100 empieza a ir a
> > saltos.
> >
> > ?como se les puede dar mejor movimiento? nota: la grabacion de macros


del
> > power point no registra los movimientos de objetos, que aqui si se


vmueven
> > con rapidez independientemente de su numero.
> >
> > ?como puedo ejcutar dos macros de manera simultanea?, es decir mandar


a un
> > objeto que se mueva segun la macro1 y, mientras se esta moviendo,


mandar a
> > otro que ejecute la macro2. nota: si se hace medienta call (aunque sea


con
> > un
> > doevents) para la ejecucion de la macro1, hace toda la macro2, y
> > posteriormente finaliza la macro1.
> >
> > Las dos preguntas tienen el mismo fin, la realizacion simultanea de
> > tareas,
> > con el objetivo final de poder hacer un tipo de programacion


emergente.
>
>
>
Respuesta Responder a este mensaje
#4 KL
12/09/2005 - 14:57 | Informe spam
Hola Luis,

Ahora veo que es una animacion (habia entendido mover como hacer un
desplaamiento unico de cada autoforma). Por tanto no podriamos deshabilitar
la actualizacion de pantalla que junto con seleccionar los objetos es lo que
mas tiempo lleva (no el hecho de pintar o escribir en si).

He intentado agilizar un poco el codigo ahorrandote memoria mediante la
declaracion de las variables (las variables no declaradas expresamente se
autodeclaran como tipo Variant que es el que mas memoria se lleva),
eliminacion de la accion de seleccionar (no es necesaria) y deshabilitando
los eventos y recalculo de formulas (por si tales existieran en tu libro).

Tambien veras que te he detectado un fallo que tendras que decidir como lo
manejas.

Prueba el codigo que te pongo a continuacion y me comentas.

Como una idea adicional - podrias pensar en generar una matriz de los 100
valores aleatorios para las variables "x" y "y" antes de ejecutar el bucle
principal.

Saludos,
KL

Sub movuniversal()
Dim s As Shape, c As Range
Dim x As Integer, y As Integer

'Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
For i = 1 To 100
For Each s In ActiveSheet.Shapes
With s
With .TopLeftCell
Set c = Cells(.Rows.Row, .Columns.Column)
End With

Randomize
x = (Int(3 * Rnd) - 1)
y = (Int(3 * Rnd) - 1)

On Error Resume Next
' si tu autoforma se encuentra en fila 1
' y x sale como -1 se produciria un error
'ya que saldria una referencia no valida
'lo mismo aplica a las columnas). Tendras
'que decidir como manejas el error (de
'momento he hecho que el codigo lo ignore)
If c.Offset(x, y).Interior.ColorIndex = 2 Then
x = 0: y = 0
End If
On Error GoTo 0

c.Interior.ColorIndex = 0
c.Offset(x, y).Interior.ColorIndex = 2
.IncrementLeft y * 10
.IncrementTop x * 10
End With
Next
Next
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
'Application.ScreenUpdating = True
End Sub
Respuesta Responder a este mensaje
#5 luisf
13/09/2005 - 14:01 | Informe spam
Hola KL

Gracias de nuevo por contestar.

Hoy solo tengo tiempo para enviarte este mensje. Mañana tatare de probar
algunas cosas de las de tu codigo, ya que hay cosas que ni sabia que existian
(el problema de ser autodidacta y aprender a base de grabar macros y leer la
ayuda en linea)

No obstante, te mando lo que hice ayer para que veas coma va la cosa.

Basicamente me he adelantado a alguna sugerencia tuya y me he basado en
matrices que guardan las posiciones de los objetos y comparacion con la
posiciones futuras a ocupar.

Por cierto, el error que comentas, no llega a darse en realidad ya que, lo
primero que hago es crear el marco (en blanco: colorindex=2) donde se mueven
los objetos, hay un if que si se va a mover al blanco deja x e y a cero (es
dcir, no se mueve esta vuelta. De todas formas te añado las macros de crear
el marco y generar objetos (muy sencillitas evidentemente) ya que mas vale un
codigo que mil palabras.

++++++++++++++++++++++++++++++++++++++++++++++++++

codigo para animacion por matrices (ahora va muy rapido)

Sub movunimatriz()

Dim matrizpos() As Integer
Dim matrizcom(1 To 2, 1) As Integer
Dim conta As Integer
Dim fil5, col5 As Integer
Dim x, y As Integer
Dim i, j, k As Integer

For Each s In ActiveSheet.Shapes 'cuenta los objetos que hay
conta = conta + 1
Next
ReDim matrizpos(2, conta)
For i = 1 To conta ' guarda las primeras posiciones

matrizpos(1, i) = ActiveSheet.Shapes(i).TopLeftCell.Rows.Row
matrizpos(2, i) = ActiveSheet.Shapes(i).TopLeftCell.Columns.Column
Next


For j = 1 To 100 'repite el proceso 100 veces
i = 0
For i = 1 To conta 'hace la accion para los i objetos



fil5 = ActiveSheet.Shapes(i).TopLeftCell.Rows.Row
col5 = ActiveSheet.Shapes(i).TopLeftCell.Columns.Column


Randomize
x = (Int(3 * Rnd) - 1)
y = (Int(3 * Rnd) - 1)

If Cells(fil5 + x, col5 + y).Interior.ColorIndex = 2 Then 'no se sale
del marco
x = 0
y = 0
End If

If x <> 0 And y <> 0 Then 'si se va a mover...
matrizcom(1, 1) = fil5 + x
matrizcom(2, 1) = col5 + y
For k = 1 To 20 '... compara para ver si esta ocupado
If matrizcom(1, 1) = matrizpos(1, k) And matrizcom(2, 1) =
matrizpos(2, k) Then
GoTo fin1
End If
Next


ActiveSheet.Shapes(i).IncrementLeft y * 10 'se mueve
ActiveSheet.Shapes(i).IncrementTop x * 10


matrizpos(1, i) = ActiveSheet.Shapes(i).TopLeftCell.Rows.Row 'guarda
nueva posicion
matrizpos(2, i) = ActiveSheet.Shapes(i).TopLeftCell.Columns.Column

End If
fin1:

Next
Cells(1, 1).Select 'para que se vea el movimiento (sin parpadeos)
''Application.ScreenUpdating = True'se ve el movimientos con parpadeos de
pantalla
Next


End Sub


++++++++++++++++++++++++++++++++++++++++++++++++

**************************************************

Aqui esta la macro que genera el marco (dode se moveran), recuerda que las
hojas de calculo las redimensiono a 13x13 pixeles

Sub blanco2()
'
' Macro44 Macro
' Macro grabada el 10/09/2005 por luis
'

'
Range("A1:B40,B39:BV40,BU1:BV39,B1:BV2").Select
Range("BV1").Activate
Selection.Interior.ColorIndex = 2
Range("A1").Select
End Sub


************************************************
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Y ahora la macro que genera 10 objetos como el primero que hagas

Sub llenado2()

For m = 1 To 10
Randomize
a = Int((36 - 4 + 1) * Rnd + 4)
b = Int((70 - 4 + 1) * Rnd + 4)

ActiveSheet.Shapes(1).Select
Selection.Copy
Cells(a, b).Select
ActiveSheet.Paste
Cells(a, b).Interior.ColorIndex = 0
Next

End Sub

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

de nuevo gracias y ya te ire contando.

luisf





Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida