ejecutar procedimiento teniendo su nombre(como string)

29/12/2006 - 02:03 por Ivan | Informe spam
hola a todos

estoy intentando una cosa que no se si es posible (de momento no lo
consigo)

se trata de ejecutar un procedimiento tomando su nombre de una celda, o
de una variable que lo tome de esta

Algo asi como 'Call .[a1].value', o mimacro=.[a1]: call mimacro, pero
me da error.

Sin embargo, y si no me equivoco, esto si es valido para la propiedad
OnAction de los comandos de barras de herramientas -> mimacro=.[a1]:
.OnAction=mimacro

he estado indagando a partir de ->
Application.VBE.ActiveCodePane.CodeModule. -> pero no he llegado a
ningun lado

¿existe algun modo de referirse a los procedimientos que no sea su
nombre directamente?¿son/pueden considerarse un objeto, con su
respectiva coleccion contenedora?, y de ser asi, ¿cual es su nombre y
como se podria recorrer esta?

bueno, no se si me he explicado, pero si me podeis echar un nueva mano,
os lo agradezco

un saludo y hasta pronto
Ivan

Preguntas similare

Leer las respuestas

#11 Ivan
16/01/2007 - 20:11 | Informe spam
hola de nuevo, Vinchenzo,

permiteme que te vuelva a robar un poco de tiempo con otra duda sobre
CallByName (con el resto de contenidos de tu ayuda todavia ando en
fases 'preliminares')

aunque en un principio esta consulta iba a ser por que no conseguia
aplicarlo en un procedimiento (al final lo expongo), tras una buena
dosis de peleas con sus 'caprichos' <de CallByName>, justo al ir a
enviar el mensaje se me ha ocurrido (he recordado) la parte de la
conversion de tipos del argumento pasado, y he conseguido que funcione.

sobre esto va ahora la consulta. ¿me podrias explicar cual es el
motivo de tal conversion (casi me vuelve majara)?.

En este caso concreto se trata de asignar/reservar un valor Boolean a
determinadas propiedades del objeto Application tomandolo (o
depositandolo) de una celda. Si se aplica directamente (ej:
DysplayStatusBar=.[a1]) lo recone sin problemas, sin embargo con
CallByName parece necesaria la conversion, y no acabo de ver porque,
dado que ademas, en la ayuda, si parece poder pasarsele argumentos
directos

bueno, como veras es una duda mas sobre 'teoria' que necesaria, pues al
fin y al cabo, con acordarse de aplicar la conversion valdria.

ya que estoy expongo el codigo, sobre todo por que veas hata que punto
me va a venir bien tu ayuda, y aunque se que debe haber formas mucho
mejores de hacerlo, por si a alguien puede serle util

un saludo y hasta pronto
Ivan

aqui va el codigo:

se trata de guardar determinadas propiedades de la configuracion del
entorno del usuario (barra de formulas, de estado, scrollsbars, etc )
al entrar al archivo y sustituirla por nuestra propia configuracion,
pero restaurar la del usuario al cerrar y/o desactivar nuestro archivo

'''--
Public Usr as Boolean
'''--
'''Función para cambiar/alternar determinadas propiedades
'''del objeto Application al entrar/salir del archivo.
'''Las prop. a manipular irian en la columna P de Hoja9.
'''El argumento Usuario se toma de una variable publica
'''puesta a False en Open, se llama a la funcion desde
'''Activate y Deactivate del libro.
'''-16/01/2007 19:26:30
Function Alternar_Prop_Appl(ByRef Usuario As Boolean)
Dim celda As Range
If Usuario Then
For Each celda In Hoja9.Range("p2:p6")
CallByName Application, Trim(celda.Value), VbLet, _
CBool(Trim(celda.Offset(0, 1).Value)): Usuario = False
Next
Else
For Each celda In Hoja9.Range("p2:p6")
celda.Offset(0, 1) = CallByName(Application, _
Trim(celda.Value), VbGet)
CallByName Application, Trim(celda.Value), VbLet, _
CBool(Trim(celda.Offset(0, 2).Value)): Usuario = True
Next
End If
End Function
'''
'''aunque en este procedimiento de prueba se inicializa Usr
'''no es necesario, y en cualquier caso para continuar las pruebas
'''de alternar automaticamente hay que eliminarlo o ponerlo como
'''comentario, pue la propia funcion alterna el valor con solo llamarla
Sub testAplicarProp()
' Usr = False
Call Alternar_Prop_Appl(Usr)
End Sub
Respuesta Responder a este mensaje
#12 Vinchenzo vinç
17/01/2007 - 22:40 | Informe spam
"Ivan" escribió en el mensaje news:

...tras una buena dosis de peleas con sus 'caprichos'
<de CallByName>, ...he recordado la parte de la
conversion de tipos ...
[]
¿...cual es el motivo de tal conversion...?.

...asignar/reservar un valor Boolean
a determinadas propiedades del objeto Application
tomandolo (o depositandolo) de una celda.
Si se aplica directamente (ej: DysplayStatusBar=.[a1])
lo recone sin problemas, sin embargo con
CallByName parece necesaria la conversion, y no acabo de ver porque,...



Hola Iván,
en verdad no sabría darte una explicación puramente técnica de este comportamiento, porque ignoro la forma en que opera internamente esa función. Las pruebas que yo llegué a hacer, ví que el problema parecía estar en la capacidad de conversión interna.

Hagamos unas observaciones: Digamos que puedes asignar un valor boleano enviando una cadena, como por ejemplo "True", e incluso una variable 'String' que posea ese valor:

'**************
CallByName Application, Trim$(Celda.Value), VbLet, "True"
Dim strCad As String
strCad = "True"
CallByName Application, Trim$(Celda.Value), VbLet, strCad
'**************

En cambio, no sucede lo mismo con el texto "Verdadero" (luego verás por qué lo comento)
'== CallByName Application, Trim$(Celda.Value), VbLet, "Verdadero"
Dim strCad As String
strCad = "Verdadero"
CallByName Application, Trim$(Celda.Value), VbLet, strCad
CallByName Application, Trim$(Celda.Value), VbLet, CBool(strCad)
CallByName Application, Trim$(Celda.Value), VbLet, CBool("Verdadero")
'==
De éstas, sólo aceptará las que 'CBool' convirtió.

Si el Excel con el que trabajas es la versión española, entonces te preguntarás: «¿y porqué cuando la celda tiene almacenado "VERDADERO" funciona la asignación directa?»
Buena pregunta :-)
Si has almacenado un valor boleano mediante código en esa celda -que tenía el formato 'General'- te escribe el texto "VERDADERO", pero el tipo de dato subyacente de la celda es 'Boolean', es decir, la asignación directa del contenido de la celda ya es un valor boleano para 'CallByName'. Esto lo puedes comprobar mediante 'TypeName'.

Pero, «¿y por qué no funciona entonces "Trim(laCelda.Value)"?»
Otra buena pregunta. Porque la función 'Trim' está convirtiendo el valor de la celda en una cadena de texto sin espacios al principio ni al final, es decir, te está devolviendo un 'Variant/String', y al parecer 'CallByName' no sabe qué es "Verdadero".

Pero si a esa celda que contiene "VERDADERO" en formato 'General', le cambias el formato de celda a 'Texto', dejará de funcionarte la asignación directa, porque el tipo de dato subyacente será 'String'. Pero (cuantos pero's) si escribes "true" en lugar de "verdadero", sí sabe realizar la conversión a dato boleano, y no generará error.
Al menos no deja de ser curioso...

Ya que lo que se genera es un error no definido, da que pensar que el error se está produciendo en el objeto de Excel, y la función no lo propaga, mostrando por ejemplo el error de 'No coinciden los tipos'.
Entonces, pienso que la función no sabe determinar que "verdadero" tiene una correspondencia con un valor boleano, al igual que pasaría al intentar ejecutar «CBool("pepito")», y acaba mandando un valor no aceptado por el objeto 'Application' en este caso. Vamos, que "se lo tenemos que dar masticado" ;-)

Como te decía, tómatelo como mi opinión/punto de vista, y no como una explicación como tal.


CBool(Trim(celda.Offset(0, 1).Value)): Usuario = False
Next
Else
For Each celda In Hoja9.Range("p2:p6")
celda.Offset(0, 1) = CallByName(Application, _
Trim(celda.Value), VbGet)
CallByName Application, Trim(celda.Value), VbLet, _
CBool(Trim(celda.Offset(0, 2).Value)): Usuario = True
Next
End If
End Function



Una sugerencia|observación, nota que puedes "sacar" la instrucción «Usuario = True/False» de los bloques 'For'. Se está realizando la asignación en cada iteración.
Pero, como en realidad lo que se pretende es 'invertir' el estado del argumento recibido, puedes poner la inversión justo antes de salir de la función:

'**********
...
End If
Usuario = Not Usuario
End Function
'**********


Saludos
( ! ) Respuestas precedentes en Google:
http://groups.google.com/group/micr...c.es.excel
( i ) Temperancia en el foro:
http://support.microsoft.com/defaul...newsreglas
Respuesta Responder a este mensaje
#13 Ivan
17/01/2007 - 23:41 | Informe spam
hola Vinchenzo,

pues se trata de una opinión/punto de vista muy convincente y
esclarecedora. Muchas gracias de nuevo.

es ironico: usé Trim precisamente para evitar posibles errores, pero
no se me ocurrio (mas bien no cai) que lo convertiria en un
'irreconocible' string.

de todas formas toda la explicacion tiene su logica (aunque este
tachonada de supuestos toques de irracionalidad/incomodidad). Es
cierto, no deja de resultar cuanto menos curiosillo.

en cuanto a esto: -> Usuario = Not Usuario

muchas gracias por ello en si mismo, una sencilla forma de alternar un
valor boolean que añado directamente a la saca, ( aunque supongo que
lo habre visto en mas de una ocasion, es como si fuera nuevo)

y en cuanto a sacarlo de los bucles, la verdad es que inicialmente la
funcion era totalmente diferente, con un solo bucle y asignando el
valor de offset con unas variables y sin cambiar el valor de Usuario,
pero tras esos 'caprichos' de callbyname y estando medio desquiciado,
lo puse tal cual sobre la marcha y ahi se quedo. Gracias por verlo. (
aunque al final creo que no voy a usar el codigo tal cual por otros
motivos, ...pero eso seria otra historia)

lo dicho, gracias por todo y voy a seguir con el resto de 'tareas', a
ver si cojo algo

un saludo y hasta pronto
Ivan
Respuesta Responder a este mensaje
#14 Ivan
10/02/2007 - 11:59 | Informe spam
hola Vinchenzo,

aunque un poco tarde, solo queria comentarte que al fin he probado tu
funcion para instanciar/referenciar la DLL y que ha funcionado de
maravilla, pero me gustaria hacerte una ¿pequeña? consulta:

he puesto como comentario la instruccion -> 'WriteErrLog
Err.Number,.' pues me pedia la declaracion de la variable
'WriteErrLog '. Tras mirar un poco he llegado a la conclusion (quizas
erronea) de que se trata de un resto de tus mencionados inicios con
las APIs en la construccion de la funcion. De ser asi, lo que no tengo
claro es si la instruccion ya no es necesaria, o de si convendria
incluir la funcion API a la que (si estoy en lo cierto) hace
referencia.

muchas gracias otra vez: no solo me va a ser muy util, ademas me ha
servido para empezar a conocer el funcionamiento de la encriptacion y
su utilizacion (agrego aqui un fuerte agradecimiento para Ruben
Vignon, a quien por cierto todavia no le he 'pagado' la dll)

tambien comentarte que estoy estudiando los mas a fondo de lo que soy
capaz tu ejemplo sobre manipulacion de controles en tiempo de
ejecucion, y que de nuevo esta resultando un fantastico 'cursillo'
acelerado sobre uso de las APIs y las clases (por cierto, aunque, por
mi falta de base, no me he enterado de mucho, tu enlace sobre
IsNumeric me resulto muy interesante). Cuando lo tenga un poco mas
mascado, lo mismo tambien te vuelvo a molestar por alli.

lo dicho, muchas gracias por todo

un saludo y hasta pronto
Ivan
Respuesta Responder a este mensaje
#15 Vinchenzo vinç
12/02/2007 - 17:42 | Informe spam
"Ivan" escribió en el mensaje news:

hola Vinchenzo,

aunque un poco tarde,



Hola, como se suele decir, «nunca es tarde, si la dicha es buena» :-)


he puesto como comentario la instruccion -> 'WriteErrLog
Err.Number,.' pues me pedia la declaracion de la variable
'WriteErrLog '. Tras mirar un poco he llegado a la conclusion (quizas
erronea) de que se trata de un resto de tus mencionados inicios con
las APIs en la construccion de la funcion. De ser asi, lo que no tengo
claro es si la instruccion ya no es necesaria, o de si convendria
incluir la funcion API a la que (si estoy en lo cierto) hace
referencia.



En verdad 'WriteErrLog' no pertenece a la API de Windows, se trata de una función propia que usaba para guardar en un fichero de registro de errores (con el nombre del libro pero con extensión '.log', que no son más que ficheros de texto plano) los posibles errores no-controlados que pudieran producirse, desde la que se guardaba el error y su descripción, la línea de error, la fecha-hora (en realidad, era su valor Double que usaba como nombre de sección), el nombre de la función y del módulo. Algunos parámetros son opcionales.
El fichero lo creaba con la estructura de un fichero '.Ini':
'[NombreSección]
Campo1=Valor1
Campo2=Valor2
...
CampoN=ValorN
'
para luego poder cargar la información de los errores mediante las funciones de la API de Windows relativas a los ficheros Ini, que tenía encapsuladas en una librería dinámica.

Por si te interesa, la función es la siguiente, y verás que es muy simple y que no tiene ningún secreto (cuanto más simple mejor, pues lógicamente sería un problema que se produjeran errores en la función encargada de guardar el registro de errores)
'********************************
Public Function WriteErrLog( _
ByVal lngErrNumber As Long, _
ByVal strErrDesc As String, _
ByVal strFuncName As String, _
Optional ByVal strModName As String, _
Optional ByVal lngErrLine As Long)

Dim intFree As Integer, strPath As String

On Error Goto ErrHandler
With ThisWorkbook
strPath = Barrar(.Path) & Left$(.Name, InStrRev(.Name, ".")) & "log"

intFree = FreeFile()
Open strPath For Append As #intFree
Print #intFree, "[" & CDbl(Now) & "]"
Print #intFree, "Linea=" & lngErrLine
Print #intFree, "Número=" & lngErrNumber
Print #intFree, "Descripción=" & strErrDesc
Print #intFree, "Procedimiento=" & strFuncName
Print #intFree, "Módulo=" & strModName
Close #intFree
End With
Exit Function
ErrHandler:
MsgBox "Error, no se pudo guardar en el registro de errores", vbCritical
End Function
'********************************

Por cierto, la función 'Erl()' te devuelve el número de linea en el que se produjo el error, únicamente si las lineas estan numeradas. Por ejemplo:

'***********
Sub ErlTest()
Dim intEntero As Integer

On Error Goto ErrHandler
10 intEntero = 123
20 intEntero = intEntero * 1E+20

Exit Sub
ErrHandler:
MsgBox "Error en la linea " & Erl() & vbCrLf & Err.Number & vbCrLf & Err.Description
End Sub
'***********




Saludos
( ! ) Respuestas precedentes en Google:
http://groups.google.com/group/micr...c.es.excel
( i ) Temperancia en el foro:
http://support.microsoft.com/defaul...newsreglas
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida