Evaluate

Solo consultas sobre macros y código VBA Excel.

Reglas del Foro
1. Antes de hacer tu pregunta intenta con el buscador de este foro (muchas preguntas ya fueron respondidas antes!)
2. Si haces una nueva pregunta, es muy recomendable que adjuntes el ejemplo Excel para poder comprenderla mejor!
3. Realiza tu pregunta de forma clara, explicando bien cada paso de lo que haces y tendrás más probabilidad de respuesta!
Compartir en:
     

Evaluate

Notapor pacocp » 08 Ene 2010 20:21

Hola a todos,

No me queda claro qué hace y cómo funciona la instrucción "Evaluate". En la ayuda del VBA dice: "Convierte un nombre de Microsoft en un objeto o un valor", pero no me queda claro el concepto. ¿Alguien me puede explicar con peras y manzanas esto?

Saludos
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
pacocp
Miembro Frecuente
Miembro Frecuente
 
Registrado: 21 Dic 2009 14:52

Re: Evaluate

Notapor mjrofra » 08 Ene 2010 22:25

bueno, yo no soy ningún experto, pero ya que responder tu pregunta me puede ayudar un poco a mi mismo a respondérmela también, pues acá va una explicación, que espero sea de beneficio tuyo, mio y del que lea (en todo caso no me creas mucho y has algunas pruebas tú también, jejej).

Seguro que has visto que mucha gente escribe, en lugar de range("a1"), algo así [a1].

Bueno, los [ ] son una abreviación del método evaluate. [a1] es equivalente a evaluate("a1"), lo que, en este caso, como bien citas tu, convierte un nombre: "a1", en un objeto: celda A1. Por esto puedes escribir: evaluate("a1").select o abreviando, [a1].select.

Yo, personalmente, evito usar [a1] porque tiene un efecto significativo en el rendimiento (al menos eso es lo que he leído) y acá hago una prueba muy torpe de esto:

Ten en cuenta que [a1] no equivale a range("a1") sino a evaluate("a1"). Así, puedes comparar estos dos bucles:

bucle 1 (evaluate):

Código: Seleccionar todo
Sub prueba_evaluate()
    For X = 1 To 50000
        Evaluate("a" & X) = Evaluate("a" & X).Row
    Next X
End Sub


bucle 2 (range):

Código: Seleccionar todo
Sub prueba_range()
    For X = 1 To 50000
        Range("a" & X) = Range("a" & X).Row
    Next X
End Sub


verás que usando evaluate la macro se demora casi el doble, al menos en mis pruebas en mi equipo (y acá podrás encontrar una discusión sobre el tiempo de ejecución de distintos tipos de bucles, al igual que una forma para medirlos: http://www.ayudaexcel.com/foro/showthre ... 048&page=2

Bueno, eso en cuanto a convertir un nombre en un objeto (y no aplica sólo para celdas como bien puedes leer en la ayuda de VBA).

La otra parte, que hace muy poderoso al método evaluate, es lo que tu citas como convertir un nombre en un valor.

Piensa en evalute como una celda. Es decir, cuando ingresas algo en evalute("...") o [...] has de cuenta que lo estás ingresando en un celda y que el resultado será el que te dé la celda. Si en una celda ingresas =SUMA(A1:A10) el resultado es la suma de los valores en A1:A10. Si usas evaluate("sum(a1:a10)") tendrás el mismo resultado. =HOY() en una celda te dará el mismo resultado que evaluate("today()") o simplemente [today()].

Otro ejemplo, si usas [1+1] o lo que es lo mismo, evaluate("1+1") el resultado será 2. Así, puedes crear cualquier cadena de texto como una fórmula de una hoja de excel y obtener su resultado por medio de evaluate. Así, con evaluate puedes hacer practicamente cualquier cosa que harías en una celda :shock: , sí sí, eso fue lo que dije, jeje, has de cuenta que tienes una celda pero en VBA con evaluate, lo que te permite el uso de fórmulas matriciales, nombres definidos (si tienes una celda llamada "pacop", puedes usar [pacop] o evaluate("pacop") para traer el valor de esa celda), inlcuso puedes convertir una cadena de texto en una matriz:

Sub Matriz_evaluate()

Range("a1:e1") = Evaluate("{1,2,3,4,5}")

End Sub

Bueno, seguro dentro de poco alguien nos dará una mejor explicación y más convincente, y creo que yo la agradeceré tanto como tú :D.
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
mjrofra
Miembro Frecuente
Miembro Frecuente
 
Registrado: 21 Dic 2009 21:08
Ubicación: Colombia

Re: Evaluate

Notapor Héctor Miguel » 09 Ene 2010 04:52

hola, ! (solo por "meter mi cuchara") :)

una direccion de celda/rango o nombre de hoja o rango entre corchetes, se llama "notacion abreviada"

una instruccion entre corchetes es (efectivamente) una llamada a la funcion vba Evaluate("cadena de texto")

ciertamente, la notacion abreviada tiene una (ligera) desventaja... cuando se usa en bucles (pero..)
si se usa eficientemente, sirve (precisamente) para evitar los bucles

consideren las alternativas via macros (solo agregue un cuadro de mensaje con el tiempo)
op1 y op2 son las mismas sugeridas por "mjrofra" (???), y la op3 es la adicional

saludos,
hector.

Sub prueba_evaluate()
Dim Inicio As Single
Inicio = Timer
For X = 1 To 50000
Evaluate("a" & X) = Evaluate("a" & X).Row
Next
MsgBox "Tiempo: " & Timer - Inicio
End Sub

Sub prueba_range()
Dim Inicio As Single
Inicio = Timer
For X = 1 To 50000
Range("b" & X) = Range("b" & X).Row
Next
MsgBox "Tiempo: " & Timer - Inicio
End Sub

Sub prueba_directa()
Dim Inicio As Single
Inicio = Timer
[c1:c50000] = [row(c1:c50000)]
MsgBox "Tiempo: " & Timer - Inicio
End Sub
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
Héctor Miguel
Miembro Frecuente
Miembro Frecuente
 
Registrado: 26 Mar 2005 18:31

Re: Evaluate

Notapor Antoni » 09 Ene 2010 05:06

Héctor Miguel escribió:hola, ! (solo por "meter mi cuchara") :)

una direccion de celda/rango o nombre de hoja o rango entre corchetes, se llama "notacion abreviada"




No tenía ni las mas remota idea de la existencia de la notación abreviada. ¡ La de bucles que me habría ahorrado !

Gracias Héctor
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
Antoni
Miembro Frecuente
Miembro Frecuente
 
Registrado: 22 Dic 2009 04:58
Ubicación: GALICIA (ESPAÑA)

Re: Evaluate

Notapor mjrofra » 09 Ene 2010 06:18

Héctor Miguel escribió:...ciertamente, la notacion abreviada tiene una (ligera) desventaja... cuando se usa en bucles (pero..)
si se usa eficientemente, sirve (precisamente) para evitar los bucles

consideren las alternativas via macros (solo agregue un cuadro de mensaje con el tiempo)
op1 y op2 son las mismas sugeridas por "mjrofra" (???), y la op3 es la adicional


Gracias Héctor por meter la cucharada, un honor para nosotros tenerte por acá metiendo la cucharada, ojalá sea frecuentemente.

Qué bueno tu aporte. Como bien dices, si se puede evitar un bucle se ganará tiempo, sea con evaluate o con range. Los bucles que yo proponía justamente eran para resaltar como afecta el uso de evaluate en el rendimiento... pero igual se podría usar range para evitar el bucle:

Código: Seleccionar todo
Sub prueba_directa()
    range("c1:c50000") = [row(c1:c50000)]
End Sub


creo que lo justo, si me permites, sería comparar el desempeño no de un bucle contra el método directo (está claro que siempre ganará por mucho el método directo, sea con range o con evaluate), sino comparar los dos métodos directos. He probado estos dos bucles y contrastado los tiempos y no he encontrado diferencias siginificativas:

Código: Seleccionar todo
Sub prueba_directa_evaluate()

    With Evaluate("a1:iv65536")
        .Clear
        .Value = "Prueba"
    End With

End Sub


Código: Seleccionar todo
Sub prueba_directa_range()

    With Range("a1:iv65536")
        .Clear
        .Value = "Prueba"
    End With

End Sub


esto confirmaría lo que dices, que evaluate repercutirá significativamente si se usa en un bucle, si no, parece (al menos en las pruebas acá en mi equipo) que no hay mayor diferencia entre usar range o evaluate (los tiempos los he medido con el mismo método que tu has indicado, tanto para los bucles de mi primera entrada en este tema como para los métodos directos). No sé qué resultados encuentres tu o qué ideas tengas al respecto.

y esta claro: siempre que se pueda evitar un bucle (ya sea con evaluate o range o no sé), habrá una ganancia significativa en rendimiento.

Una vez más, gracias por meter la cucharada.

____
Mauricio
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
mjrofra
Miembro Frecuente
Miembro Frecuente
 
Registrado: 21 Dic 2009 21:08
Ubicación: Colombia

Re: Evaluate

Notapor mjrofra » 09 Ene 2010 06:37

y bueno, ya sé que al evitar el bucle usando range como propuse igual estoy usando evaluate:

Código: Seleccionar todo
Sub prueba_directa()
    range("c1:c50000") = [row(c1:c50000)]
End Sub


y antes de que alguien me diga que igual estoy usando evaluate acá. El punto es comparar evaluate para devolver un objeto tipo range contra range. En este caso, lo que hace evaluate ([row(c1:c50000)]) es devolver un valor, no un objeto tipo range y lo que permite evitar el bucle claramente es el uso de evaluate, pero todo esto surgió por si existía alguna diferencia en cuanto al tiempo de ejecución entre usar algo como [a1] versus range("a1"), por lo que digo que lo justo sería comparar:

Código: Seleccionar todo
Sub prueba_directa()
    range("c1:c50000") = [row(c1:c50000)]
End Sub


versus

Código: Seleccionar todo
Sub prueba_directa()
    evaluate("c1:c50000") = [row(c1:c50000)]
End Sub


aún cuando en ambos casos se esté usando evaluate.

En todo caso, tú eres acá el maestro Héctor :D, qué agradable poder compartir unas palabras sobre lo que nos apasiona, aunque yo en realidad soy un principiante, espero sepas tolerar cualquier barbaridad que yo diga.
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
mjrofra
Miembro Frecuente
Miembro Frecuente
 
Registrado: 21 Dic 2009 21:08
Ubicación: Colombia

Re: Evaluate

Notapor Gerson Pineda-El Catracho » 09 Ene 2010 13:49

Hola como están!

Vaya que pequeña gran discusion de las que me llaman siempre la atencion, nunca dejaremos de aprender hasta que nos vayamos al otro lado, quiero mencionarle que con las macros comienzo a gatear (no caminar, aunque quisiera decirlo, trato de usar mas las funciones nativas las cuales las manejo bien, estoy claro que el lenguaje VBA es para poder realizar proyectos que con las funciones nativas no se puede)

Me considero principiante mas que tu mjrofra (Mauricio) por lo cual ya nos hemos cruzado por otro foro... en el cual nos regalas tus aportes muy buenos por cierto, lo que mas me agrada al programar o armar formulas es tratar de ser lo mas resumidas posibles, y el método que usas tu me llama mucho la atención y es el que tratare de adaptar siempre en mis macros, es decir unificar las macros lo mayor posible... y por lo visto lo aplicaste con Evaluate

Por lo que yo considero es que los foros mas allá de dar aportes o ayudar a los demás es también sinonimo de discusión, de este modo no solo aprende el que pregunta/responde sino todos

Foro = Discusión

Saludos desde Honduras
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
Gerson Pineda-El Catracho
Miembro Frecuente
Miembro Frecuente
 
Registrado: 08 Abr 2005 13:52

Re: Evaluate

Notapor p@li » 11 Ene 2010 11:02

Hola que tal gente,
Muy interesante la discusión, muchas gracias a todos los que saben por compartir sus conocimientos, les cuento algo, cuando leí la consulta original me acordé de un problema que se me presentó hace bastante tiempo. Lo interesante es que al leer la respuesta de mjrofra, se me ocurrió la solución, muy tardía, por cierto, al problema de aquella oportunidad.

En javascript existe la función eval(), con la que se pueden hacer infinidad de cosas, pensé que Evaluate era similar a eval(), pero al hacer algunas pruebas me di cuenta de las limitaciones que tenía la función de VBA.

Lo que a mi me interesaba era poder llamar a una función a partir de una cadena, con una cantidad de argumentos indefinida, por ejemplo: "sumarnumeros(2,4,5,7,5)", o "concatenar(""hola"","" "",""mundo"")", con eval() es totalmente posible, pero con Evaluate no pude lograrlo.

Ahora veo que si podía hacerlo, unicamente tenía que hacer dos cosas, la función tiene que ser pública, como una UDF, porque es obligatorio que pueda llamarse desde la hoja de excel ("Piensa en evalute como una celda"), la función tiene que tener un parámetro de tipo Array, para que pueda tomar indefinida cantidad de parámetros, y por último cuando llamo a la función por medio de Evaluate, le tengo que agregar un signo igual delante.

El resultado de todo eso es el siguiente:

Código: Seleccionar todo
Public Function sumarnumeros(ParamArray Args()) As Double
    Dim i As Long
    For i = 0 To UBound(Args)
        sumarnumeros = sumarnumeros + CDbl(Args(i))
    Next
End Function
Sub prueba()
    Debug.Print Evaluate("=sumarnumeros(1,2,3,2)")
End Sub


Este es un ejemplo y no tiene ninguna utilidad, únicamente les planteo una idea que se me ocurrió, puede servir para hacer un código más dinámico, en aquella oportunidad terminé pasando un array como parámetro, algo así:

Código: Seleccionar todo
Public Function sumarnumeros2(Args) As Double
    Dim i As Long
    For i = 0 To UBound(Args)
        sumarnumeros2 = sumarnumeros2 + CDbl(Args(i))
    Next
End Function
Sub prueba2()
    Debug.Print Run("sumarnumeros2", Split("1,3,5,45,8", ","))
End Sub


Esto tampoco tiene ninguna utilidad, solo es un ejemplo.

Saludos.
Pablo.
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
Avatar de Usuario
p@li
Miembro Frecuente
Miembro Frecuente
 
Registrado: 04 Oct 2005 16:55
Ubicación: Argentina

Re: Evaluate

Notapor mjrofra » 04 Jun 2010 15:56

Esto quizás resulte interesante acerca del uso de la notación abreviada para referirse a un rango por medio de Evaluate:

http://excelpatas.blogspot.com/2010/06/ ... se-un.html

Dejo el vínculo por si resulta interesante para alguien :D.
* Te recomendamos estos productos Excel: Manual de Macros | Manual de Funciones | Nuevas Funciones | ddTraDa
mjrofra
Miembro Frecuente
Miembro Frecuente
 
Registrado: 21 Dic 2009 21:08
Ubicación: Colombia


Compartir en:
     

  • Anuncio
Manual Excel avanzado

Volver a Macros

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 6 invitados