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

#1 Héctor Miguel
29/12/2006 - 02:29 | Informe spam
hola, Ivan !

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...



asumiendo que 'A1' contiene el nombre 'valido' de algun procedimiento 'existente' [etc. etc. etc.]

op1: Application.Run [a1].Text

op2: Application.Run (Range("a1"))

si no se trata de la hoja 'activa'... [habra que 'emparentar' la celda con su hoja correspondiente]
si la celda no coincide con el nombre de alguna macro existente... [habra que usar un On Error Resume Next] ... ;)

si cualquier duda [o informacion adicional]... comentas ?
saludos,
hector.
Respuesta Responder a este mensaje
#2 Ivan
29/12/2006 - 02:32 | Informe spam
hola de nuevo,

ya lo he solucionado volviendo a rebuscar en el foro, Esto es un ej:->

Sub ActivarMacrosDesdeHoja()
Dim Celda As Range
With Hoja1
For Each Celda In .[a1:a7]
If Celda = True Then
Application.Run Celda.Offset(0, 1).Value
End If
Next
End With
End Sub

un saludo a todos y feliz año
Ivan
Respuesta Responder a este mensaje
#3 Ivan
29/12/2006 - 02:40 | Informe spam
hola Hector Miguel, gracias por duplicado.

primero por esta respuesta, y segundo por la que ya me habia adelantado
la solucion en otra respuesta tuya anterior a otro consultante

lo dicho, dos veces (mas) gracias

un saludo y que tengas buena salida y entrada y mejor año
Ivan
Respuesta Responder a este mensaje
#4 Vinchenzo vinç
30/12/2006 - 16:02 | Informe spam
"Ivan" <@> escribió en el mensaje news:

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




Hola Iván,
aunque como ya has comprobado para tu caso basta el método 'Run', sabe que además dispones de la función 'CallByName', una función bastante flexible (y si no ando errado viene incorporada desde Office 2000).
Mediante una cadena de caracteres puedes obtener y establecer propiedades a un objeto dado, llamar a sus procedimientos, con transferencia de argumentos, recibir el valor de retorno de una función, etcétera.

El primer parámetro de la función siempre deberá ser un objeto (ya sea un libro, hoja, celda, módulo estándar, formulario, control,...) éste no puede estar representado por un String.
Su segundo parámetro sí será un String que represente el nombre de una propiedad, método o función, de «alcance público», perteneciente a dicho objeto.
El tercer parámetro será el valor de una constante que indicará el tipo de llamada que se le hace. El último es un array opcional, que no se usa cuando es una obtención, indica el valor si es una asignación, o son zero o varios cuando ejecutas un método o función que requiere argumentos.

En tu caso, para ejecutar una macro cuyo nombre tienes almacenado en una celda, la cual estuviere albergada en un módulo estándar de nombre 'Módulo1', podrías hacer lo siguiente:
' CallByName Módulo1, [a1].Value, vbMethod

Y cuando tratárase de una función que reciba algún parámetro y regresara un valor de retorno:
Resultado = CallByName(Módulo1, "NombreFunción", vbMethod, Argumento1, "Argumento2")
'
Por poner un (en este caso absurdo) ejemplo, cambiar el nombre de una hoja, obtener el valor de una celda, eliminar una hoja de cálculo, ...
'*****************
CallByName Hoja1, "Name", vbLet, "Nuevo nombre"
MsgBox CallByName(Hoja1.Cells(1,1), "Value", vbGet)
CallByName ThisWorkbook.Sheets(2), "Delete", VbMethod
...
'*****************

Precisamente quiero aprovechar para comentarte que en verdad la principal utilidad que le encontrarás a esta función es al momento de cargar la información de inicialización del usuario, que desde el punto de vista de -y de cara a- un usuario, es una característica importante en las aplicaciones que desarrollemos.

Típico caso en el que en ocasiones tenemos formularios que deseamos que se carguen en la misma posición en la que el usuario lo cerró, con la última información establecida de mano del usuario, como opciones seleccionadas, casillas de verificación, elemento seleccionado de una lista, etc...
Para este menester ya no se usan (al menos es la recomendación de Microsoft) los antiguos ficheros '.INI' mediante sus funciones relacionadas de la API de Windows, sino que se guarda en el Registro de Windows a través de las funciones de la biblioteca "VBA":
· 'SaveSetting' para guardar una sección con una clave y su valor asociado en el Registro
· 'GetSetting' para recuperarla
· 'DeleteSetting' para eliminar una clave o sección
· 'GetAllSettings' para obtener todas las subclaves de una entrada determinada.

Como podrás comprobar en la ayuda, la función 'GetSetting' incorpora un argumento opcional "[Default]", que te permitirá establecer una configuración de carga predeterminada en caso de no haber sido indicada por el usuario.

Las entradas creadas por tu proyecto con las funciones anteriores, las podrás ver (y gestionar manualmente si se diera el caso) desde el Registro de Windows (Inicio>Ejecutar>RegEdit) bajo la clave 'HKCU\Software\VB and VBA Program Settings".

Un ejemplo práctico sería en el cierre del formulario, guardar las informaciones necesarias de los objetos que requieras, como mencionaba antes, y supongamos que queremos que el formulario se vuelva a cargar en la misma posición en la que el usuario lo cerró, y además volver a tener el texto que dejó escrito en una de las cajas de texto, presentar seleccionada la página actual de un control de página múltiple, y el estado de activación de una opción:
'Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Call GuardarConfig(Me, "Top")
Call GuardarConfig(Me, "Left")
Call GuardarConfig(TextBox1, "Text")
Call GuardarConfig(MultiPage1, "Value")
Call GuardarConfig(CheckBox1, "Value")
End Sub
'
Como verás más abajo en la función "LeerConfig(Objeto)", de esta forma sólo en el cierre del formulario deberás determinar de qué objetos quieres almacenar información de inicialización, pues en la lectura de la configuración durante la carga, no necesitarás volver a indicar manualmente dichos objetos, un bucle recorrerá los controles obteniendo posible información, y sólo encontrará las claves pertenecientes a su 'Parent.Controls(Control)'.

Lógicamente, para poder posicionar el formulario en la carga del formulario, su propiedad 'StartUpPosition' deberá estar establecida a 'Manual', o de lo contrario usar un miembro privado que use como "bandera boleana" en el evento '_Activate'.
Así pues, en la carga de cada formulario llamas a leer la posible información almacenada para ese formulario:
'*****************************
Private Sub UserForm_Initialize()
Call CargarConfiguración(Me)
End Sub
'*****************************

En un módulo estándar albergas las funciones de inicialización y almacenamiento, con lo que podrás usar lo arriba citado para cualquier formulario de tu libro, y con todo esto "dotar de memoria" a tu aplicación, por ejemplo:
'==Option Explicit

Public Sub CargarConfiguración(ByRef Formulario As Object)
Dim oCtl As Control

'Leeremos la configuración del formulario recibido
Call LeerConfig(Formulario)
' y se buscará posible información almacenada para sus controles
For Each oCtl In Formulario.Controls
Call LeerConfig(oCtl)
Next
End Sub

Public Sub GuardarConfig(ByRef Objeto As Object, ByVal strProcName As String)
Dim strObjeto As String

If IsForm(Objeto.Name) = True Then
strObjeto = Objeto.Name
Else
strObjeto = Objeto.Parent.Name & ".Controls(" & Objeto.Name & ")"
End If
'Obtenemos y guardamos el valor solicitado del objeto recibido
SaveSetting "IniConfig: " & ThisWorkbook.Name, strObjeto, strProcName, CallByName(Objeto, strProcName, VbGet)
End Sub

Private Sub LeerConfig(ByVal Objeto As Object)
Dim vntArSettings As Variant

'Obtenemos todos los nombres de subclaves y sus respectivos valores
If IsForm(Objeto.Name) Then
'Cuando se trate de un formulario, leeremos una clave similar a:
'..\VB and VBA Program Settings\IniConfig: Libro1.xls\UserForm1
vntArSettings = GetAllSettings("IniConfig: " & ThisWorkbook.Name, Objeto.Name)
Else
'Cuando se trate del control de un formulario, será una entrada del tipo
'..\VB and VBA Program Settings\IniConfig: Libro1.xls\UserForm1.Controls(TextBox1)
vntArSettings = GetAllSettings("IniConfig: " & ThisWorkbook.Name, Objeto.Parent.Name & ".Controls(" & Objeto.Name & ")")
End If

'Comprobamos que exista información de inicialización para el objeto actual
If IsEmpty(vntArSettings) = True Then
' "No existe información de inicialización para este objeto."
Else
Dim intPropCont As Integer
'Recorremos todas las entradas obtenidas de la clave especificada
For intPropCont = 0 To UBound(vntArSettings)
' En la matriz obtenida,
' vntArSettings(intPropCont, 0) Contiene el nombre de la propiedad
' vntArSettings(intPropCont, 1) Contendrá el valor de la propiedad

'Realizaremos la conversión del valor para la asignación
' según el tipo de dato de la propiedad de destino:
Select Case TypeName(CallByName(Objeto, vntArSettings(intPropCont, 0), VbGet))
Case "Boolean": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CBool(vntArSettings(intPropCont, 1))
Case "Byte": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CByte(vntArSettings(intPropCont, 1))
Case "Currency": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CCur(vntArSettings(intPropCont, 1))
Case "Date": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CDate(vntArSettings(intPropCont, 1))
Case "Double": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CDbl(vntArSettings(intPropCont, 1))
Case "Integer": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CInt(vntArSettings(intPropCont, 1))
Case "Long": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CLng(vntArSettings(intPropCont, 1))
Case "Single": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CSng(vntArSettings(intPropCont, 1))
Case "String": CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CStr(vntArSettings(intPropCont, 1))
Case Else: CallByName Objeto, vntArSettings(intPropCont, 0), VbLet, CVar(vntArSettings(intPropCont, 1))
End Select
Next
End If
End Sub

Private Function IsForm(ByVal strName As String) As Boolean
Dim i As Long

For i = 0 To UserForms.Count - 1
If UserForms(i).Name = strName Then
IsForm = True
Exit For
End If
Next
End Function
'==
Por si quieres probar el ejemplo, recuerda que el formulario deberá tener -al menos- un control TextBox1, un MultiPage1 y un CheckBox1.


Próspero año.

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
#5 Ivan
30/12/2006 - 19:52 | Informe spam
hola Vinchenzo,

lo primero, muchas gracias por esta impagable 'lección', que, me da la
impresión, me va a ayudar mucho a empezar a conocer/comprender un
(para mi) nuevo y desconocido 'peldaño' en mi (intento de) escalada
hacia las 'faldas' del Himalaya que para mi es VBA ( creo que estos
dias estoy todavia mas cursi de lo habitual )

aparte de introducirme en algo que intuia tenia que existir (la
'memoria') pero que no sabia muy bien como/donde buscar, creo que me va
a venir de perlas, pues actualmente, casi todo el proceso que mencionas
lo hago utilizando una hoja de excel a modo de
'archivo/memoria/matrices', en la que voy depositando, tanto las
diversas configuraciones del usuario que he pensado podrian verse
afectadas por la apertura de la aplicacion (pej: para Excel, las barras
de herramientas, de estado, formulas, etc.., o aunque no he empezado
todavia, las opciones de impresion, ...), como las que afectan ( o se
ven afectadas por opciones/decisiones del usuario) a los formularios,
controles, hojas, etc,.. dentro del propio archivo.

esta hoja la uso, aparte de para restaurar las opciones previas del
usuario, para recuperar determinadas variaciones, reponiendo unas
predeterminadas al cerrar el archivo, o/y para conservar entre sesiones
las opciones permitidas (mediante un formulario 'Opciones de Usuario')
asignandolas al abrirlo.

como imaginaras, esto hoja, y sus respectivos codigos 'asociados', cada
vez se va embarullando mas, a medida que se embarulla el proyecto. De
ahí que tu propuesta pueda serme muy util.

de momento no he podido hacer mas que una lectura rapida, pero no
queria esperar al año que viene para agradecertelo, y si no te
importa, me gustaria estudiarlo con un poco de calma y volver a
consultarte (ahora si, ya casi seguro el proximo año ) con las dudas
que, a buen seguro, me surgiran.

y por ultimo, desearte yo tambien que tengas un prospero y feliz 2007
(y 2008, y ...). Y que pases a gusto, como y con quien quieras, lo que
queda del 6

un saludo y hasta pronto
Ivan
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida