Hacer referencia a controles de multipage, page o frame

11/11/2006 - 04:32 por Ivan | Informe spam
Hola a todos

¿sabeis si existe alguna forma de hacer referencia a los controles
concretos contenidos en un multipagina, pagina y/o frame?

hasta ahora consgo listar todos los controles del formulario (incluso
los 'page', aunque los catalogue -con TypeName - como multipage), pero
no consigo que me de los contenidos en una pagina concreta ( aunque con
el frame y el mutipage no lo he probado, supongo que ocurrira lo
mismo).

he usado la prop. tag para crear una especie de indice y asi me apaño,
pero no se si habra algo mas sencillo

si podeis echarme una mano, oss lo agradezco

un saludo y hasta pronto
Ivan

Preguntas similare

Leer las respuestas

#6 Vinchenzo vinç
16/11/2006 - 22:24 | Informe spam
Hola Iván,
en estos días estoy teniendo más trabajo del que había previsto, por lo que cuando dije que te prepararía un ejemplo entre mañana y pasado (Martes o Miércoles), aún no sabía lo que se me avecinaba.
Mañana (seguro) te prepararé un ejemplo sencillo como te comenté, y te responderé estos dos últimos mensajes. De hecho, he mirado el otro mensaje un poco por encima, y veo que "habrá tela" :-)

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
#7 Ivan
17/11/2006 - 00:14 | Informe spam
hola Vinchenzo,

no tengas ningun problema, yo ando mas o menos igual, y ademas, con las
'tareas' de tu ultimo mensaje tengo una buena dosis de trabajo para la
espera. Y poco a poco parece que algunas van dando sus frutos.

pej, en lo que se refiere a ByRef y ByVal ( y despues de tu aclaracion
sobre el espacio/lugar en memoria que tampoco acababa de tener claro
con la ayuda), siguiendo un poco tu ej., he hecho esta sencilla prueba
que mas o menos ha resuelto mis dudas sobre sus efectos 'reales', que
aunque (creo que) son 'exactamente' los que dice la ayuda, no acababa
de verlos

***********************************
Function ProbarVal(ByVal nPi As Integer) As Integer
ProbarVal = nPi * 100
nPi = ProbarVal
End Function
**********************************
Function ProbarRef(ByRef nPi As Integer) As Integer
ProbarRef = nPi * 100
nPi = ProbarRef
End Function
***********************************
Sub Pruebas_Inmediato()
Dim x As Integer
x = 1
Debug.Print ProbarVal(x)
Debug.Print x
x = 1
Debug.Print ProbarRef(x)
Debug.Print x
End Sub
**********************************

en cuanto a los controles sigo en la pelea, pero cuando creo que lo he
logrado, de repente alguno se ha 'escapado', o se ha ido a la casa
de un vecino.

y en cuanto a la ventana inmediato, he conseguido 'medio' domarla, y
digo medio porque aunque he conseguido que se comporte mas o menos
normal, ahora es como si hubiera dos instancias de la misma.->ahora
mismo (creo). una minimizada (que me estorba pej. al intentar volver al
editor desde este mensaje, pues se maximizaba y me impedia acceder al
editor hasta que dando un rodeo he conseguido minimizarla) y otra
activa en su posicion normal. Pero bueno no quiero volver a alargarme,
voy a ver por donde anda cuando vuelva.

muchas gracias de nuevo por tu atencion, y estare encantado de recibir
tu ayuda cuando puedas. Mientras voy a ver que es eso de .
'recursivas'

un saludo y hasta pronto
Ivan
Respuesta Responder a este mensaje
#8 Vinchenzo vinç
18/11/2006 - 04:47 | Informe spam
Hola,

¿Sabes si hay en la ayuda (o en ...) explicaciones un poco mas
'explicitas' sobre los UserForms, y a ser posible el acceso a
VBComponents, que a las que se accede (al menos en mi caso) con F1
(Coleccion UserForms, Ventana UserForms, y poco mas)?



No conozco nada en concreto, yo siempre voy "picoteando de aquí y de allá". Entre Google y los grupos de discusión se suele encontrar mucha más información que en la propia ayuda, pero habitualmente dispersa.
Tal vez otro miembro del grupo conozca y pueda sugerir algún lugar específico.


En cuanto a ... Referencias ...
¿donde podria encontrar
ayuda sobre el tema, sino detallada, si al menos un poco mas clara y
extensa que la del propio excel ?



El problema es que las referencias disponibles, que básicamente son el acceso a librerías externas de componentes instalados en el computador, pueden pertenecer a gran variedad de aplicaciones. Por decir algo, si instalas el 'Adobe Reader' (versión 6, creo), podrás agregar un componente suyo (Adobe Acrobat Control for ActiveX) el 'Pdf.ocx'. Lo mismo sucede con muchas otras aplicaciones, y en ese caso no te queda más remedio que intentar encontrar (si está publicada) la documentación del componente.

Por otro lado, unas referencias las añades manualmente, y otras pueden añadirse automáticamente, cuando seleccionas un control adicional. Por ejemplo (aprovechando nuestro caso), supongamos que quieres usar un control TreeView: abres los "Controles adicionales", lo buscas en la lista y lo seleccionas. En este momento te aparece el icono en el cuadro de herramientas. Cuando añadas el control al formulario, verás en las referencias del proyecto que se ha añadido la referencia de la librería a la que pertenece.
En cambio, si quisieras usar (por poner un ejemplo) el modelo de objetos del sistema de ficheros (FileSystemObject), añadirás manualmente la referencia 'ScrRun.dll' (Microsoft Scripting Runtime), pues no expone ninguna interfaz gráfica, sino una colección de propiedades y métodos a la que accederás desde código cuando declares e instancies una variable de su tipo «Dim oFs As New FileSystemObject» (esto se conoce como Early Binding, enlace temprano).

Y de hecho puedes crear referencias en tiempo de ejecución (conocido como Late Binding, enlace tardío), siguiendo el ejemplo, al 'FileSystemObject', declararías una variable genérica 'Object', y la instanciarías tal que: «Set oFs = CreateObject("Scripting.FileSystemObject")».
Sucede lo mismo con los controles adicionales, tanto puedes añadir el control en el formulario en tiempo de diseño, como no añadir su referencia ni control adicional sino crearlo en tiempo de ejecución. La colección 'Controls' dispone del método '.Add', desde el que puedes hacer algo como:
'******
With Controls.Add("Forms.CommandButton.1", "MiBotón", True)
.Top = 10
.Left = 20
.Caption = "Nuevo botón"
End With
'y como está en la colección, puedes acceder a él por su nombre...
Controls("MiBotón").Caption = "Nuevo Caption"

'ó en el caso del TreeView
With Controls.Add("MSComctllib.TreeCtrl", "MiTree", True)
...
'******
Pero habitualmente esto no tiene mucho sentido cuando se trata de controles que requieren interacción por parte del usuario, porque te obligas a declarar una variable con eventos, y codificar dichos eventos de antemano. Que sería: Private WithEvents MiControl As TipoDeControl.
Se consigue reducir el tamaño del fichero, pero nada del otro mundo (dependiendo de la cantidad que fueran, pero igualmente deberían ser muchos para un cambio sustancial), y es un poco liante, pues no puedes crear matrices de controles...
...bueno, creo que me he desviado del tema...


o en su defecto ¿cuales serian las
(practicamente) imprescindibles para un uso 'normal' de excel?.



Lo que se podría considerar "referencias mínimas", te lo indica el propio Excel al abrir un libro nuevo.
Abre el cuadro de 'Referencias', e intenta desmarcar las que lo estén, las que no te lo permita serán las imprescindibles.
Todo lo demás son 'extras' que puedes ir agregando a conveniencia, y no se requieren para nada en general, sino para algo en concreto. Siempre teniendo en cuenta que varias de las referencias y controles adicionales que a tí te aparezcan, pueden no estar presentes en el ordenador de otro usuario, y por consiguiente, puede que abras un libro en otra máquina y obtengas errores de carga dependiendo de las librerías referenciadas en tu libro.
Normalmente los problemas se suelen presentar por controles de terceros, que basta instalar/registrar en la máquina destino, aunque supongo que también dependerá del tipo de instalación del Office que realizó el usuario.


Seria sobre todo para dejar las minimas y cargar solo las especificas para
determinados casos, como el que propones.



Regresando al comentario del control de 'Adobe' que he mencionado, si después de haberlo añadido lo decidieses eliminar del formulario, la referencia puede permanecer activada. Ese es el problema en el que debes encontrarte ahora, y -como ya te puedes imaginar- sería difícil indicarte cuales te sobran, porque depende de los controles usados en el formulario, del tipo de variables que usa tu código, etc...


> y aunque de hecho puedes indentar los textos, pregunto,
> ¿has pensado en usar un control 'TreeView' para mostrarlos?.

...despues de echarle un ojo, creo que efectivamente me podria valer,
...pero tambien me interesria que luego se pudieran traspasar a una hoja



En el ejemplo que te he preparado, verás (una posible forma de) cómo puedes "exportar" el resultado a una hoja.


En cuanto a TreeView, lo he
cargado en el cuadro de herramientas, pero no me permite ver la ayuda
sobre sus propiedades, etc. Me da el error :

"No se puede hallar el archivo comctl1.htp ¿Deseas ?"



En principio, creo que (si lo tienes) deberías agregar el de la 'MSComCtl.ocx' (que si no estoy equivocado, el componente se instala con el Office), aunque (otra vez no sé si estaré equivocado) creo que el fichero de ayuda se instala con Visual Basic 6, ...al menos siempre puedes consultar la MSDN Online


> De hecho, no sé muy bien qué aconsejarte, porque no sé cuál es el objetivo real (la información que buscas depurar), es decir, que no entiendo muy bien lo de «para poder sanearlos/homojeneizarlos».

...se trata de un proyecto
...que comence hace +o- 7 meses, cuando apenas tenia ni idea de VBA, y en la
cual he ido acumulando practicamente toda mi evolucion en estas lides
aparte de haberlo ido enrevesando cada vez mas
...al final me he encontrado con un monton de formularios,
modulos, hojas, y por supuesto codigos y variables., que en muchos
casos seguramente podria simplificar bastante y/o unificar mediante
(pej) argumentos en el caso de los codigos, y (pej) multipaginas en el
caso de los formularios,
...



Bueno, este tipo de situación la he vivido varias veces, y creo que es lo normal (al menos, yo lo veo como una evolución natural). En mi caso, cada vez que voy acumulando nuevos conocimientos, y veo que puedo aplicar algunas mejoras en trabajos existentes (aunque en muchos casos sea sólo por practicar), voy realizando modificaciones. Pero hay ocasiones que en proyectos grandes, el cambio es excesivo, y una de dos, o se pierde demasiado tiempo "atando cabos" (por muy modulado que esté), y/o consigues obtener un proyecto potencialmente inestable.
Como ya me he dado "de morros" más de una vez, cada vez que preveo cambios notablemente grandes, dejo el fichero "para la posteridad", y creo una versión nueva del libro apoyándome en los requisitos, aprovechando sólo partes concretas que no necesitan cambio, o que requieran modificaciones ligeras, y vuelvo a comenzar.
Ya sé que parece una barbaridad.
Ojo, no es una recomendación para tu caso, simplemente te comento mi caso particular...


Por eso (y tambien como te digo por practicar) estoy intentando hacer
unos listados con los controles, asi como lo estoy intentando con
variables y procedimientos, para intentar 'minimizar' el codigo, los
objetos, etc., pero sin empezar de nuevo, sobre todo por que me temo
que comenzaria a complicarme la vida otra vez con mas añadidos y
podria no acabar nunca.



Desde luego que siempre es mejor si se pueden aplicar los cambios en lo ya desarrollado.
Intenté un vez modificar un libro que ya tenía unas 15000 líneas de código, con nuevas técnicas que me hubieran permitido reducir el tamaño, una ejecución más rápida, más eficiente, etc..., y lo único que conseguí fue un berenjenal que pagué perdiendo mis vacaciones.
Pero como te decía, unas veces (posiblemente la mayoría) no son cambios muy traumáticos, y en cambio hay ocasiones que es inevitable... Por supuesto, si en tu caso puedes evitar comenzar de nuevo, será lo mejor.


llevo tiempo intrigado con el funcionamiento de las funciones
recursivas, aunque todavia no he intentado probar ninguna. Quizas vaya
siendo hora



En el ejemplo que te he preparado verás dos o tres. Y verás que no son nada complicado, son simplemente funciones que se llaman a sí mismas mientras no se alcanza una condición de salida. El caso más típico es el del cálculo del factorial de un número (aplicable a efectos docentes, y, poqué no, por elegancia estructural).
Verás en el ejemplo una forma recursiva de recorrer toda la descendencia de un nodo específico de un TreeView.



esta es otra de mis espinas. Aunque creo entender las
defiiciones/explicaciones sobre ByRef/ByVal que voy encontrando, no
consigo acabar de 'comprender' su, llamemosle, uso practico, o sea, las
consecuencias al usar uno u otro y la diferencia en el resultado,
llamemosle, 'real' .



El uso práctico lo ves cuando necesitas un procedimiento que modifique el valor de un argumento que se le transfiere. Si el argumento lo pasas por valor pasarás una copia. Aclaro: Cuando declaras una variable se reserva un espacio en memoria, de tamaño acorde a su tipo. A través de esa variable obtendrás/modificarás el contenido de ese espacio de la memoria. Al pasar la variable por valor, se reserva otro espacio en memoria, y se le asigna el valor contenido en el espacio al que apuntaba la variable. Entonces, en la función llamada, la variable apuntará a ese nuevo espacio de memoria reservado, y no leerás/modificarás el contenido original.
Por consiguiente, al pasar el argumento como ByVal, cualquier cambio que realices sobre esa variable sólo tendrá efecto localmente en la función llamada, la variable que se pasó desde el procedimiento llamante siguirá conservando su valor original al regresar de la llamada.
Por el contrario, si el argumento se pasa por referencia, estarás pasando el apuntador a la posición en memoria del contenido, y lógicamente la variable del procedimiento llamante reflejará las modificaciones que se hayan hecho dentro de la función llamada.
El siguiente código es un caso típico con el que es posible ver claramente el asunto. Examina los resultados en la ventana 'Inmediato' (más abajo ya te comento lo que consultabas acerca de esta ventana)
'********************
Sub Test()
Dim intByRef As Integer 'la pasaremos por referencia
Dim intByVal As Integer 'la pasaremos por valor

intByRef = 2: intByVal = 2
Debug.Print "***** Test ByRef vs ByVal *****"
Debug.Print "Posición en memoria de intByRef: " & VarPtr(intByRef)
Debug.Print "Posición en memoria de intByVal: " & VarPtr(intByVal)
Call Duplicar(intByRef, intByVal)
Debug.Print "Por referencia se ha duplicado el valor :: " & intByRef
Debug.Print "Por valor ha conservado el valor pasado :: " & intByVal
Call Duplicar(intByRef, intByVal)
Debug.Print "ByRef ha cuatriplicado el valor original :: " & intByRef
Debug.Print "ByVal no produjo cambio alguno en la variable original :: " & intByVal
End Sub

Sub Duplicar(ByRef intRef As Integer, ByVal intVal As Integer)
'la dirección de memoria apuntada por "intRef" es la misma
' que la apuntada por "intByRef" en el procedimiento "Test"
Debug.Print "Posición en memoria de intRef: " & VarPtr(intRef)
intRef = intRef * 2
'se ha reservado un nuevo espacio en memoria para almacenar el valor pasado,
' la dirección de memoria apuntada por "intVal" es la de la nueva variable
' que se ha creado, y no la del procedimiento llamante
Debug.Print "Posición en memoria de intVal: " & VarPtr(intVal)
intVal = intVal * 2
End Sub
'********************

Igualmente, te comento que un caso práctico es el ejemplo de la descomposición de un entero largo, que representa un color, a sus valores RGB (cantidad de rojo, verde y azul). La función recibe el color y tres variables a las que "cederá" el resultado la función llamada:
'=Sub Test()
Dim R As Integer, G As Integer, B As Integer

'RGB es una función incorporada en VBA, que hace justamente lo contrario,
' recibe las tres cantidades de cada color, y devuelve su correspondiente entero largo
' Mostramos un valor de comparación
Debug.Print "RGB(50, 100, 200) = " & RGB(50, 100, 200)
'Obtenemos la descomposición de este valor
Call DescomponerRGB(RGB(50, 100, 200), R, G, B)
'Resultado de la descomposición
Debug.Print RGB(R, G, B) & " = RGB(" & R & ", " & G & ", " & B & ")"
End Sub

'Recuerda que si no se indica el tipo en la declaración, predeterminadamente se pasa por referencia.
Sub DescomponerRGB(ByVal lngColor As Long, Rojo As Integer, Verde As Integer, Azul As Integer)
Rojo = lngColor And &HFF&
Verde = (lngColor And &HFF00&) \ 256
Azul = (lngColor And &HFF0000&) \ 65536
End Sub
'=


no se que me pasa en la ventana Inmediato que no consigo que
funcione como las otras del editor, o me ocupa toda la pantalla, o se
minimiza, o funciona como una ventana de modulo mas. No consigo que se
quede acoplada abajo o donde sea, como las demas (inspeccion, etc), y
como, si no me equivoco, ella misma hasta hace poco. Cuando ocupa toda
la pantalla,solo tiene el boton de cerrar(x), ni maximizar ni
minimizar. He revisado opciones pero no he visto nada.



Ventanas como la «Inmediato, Inspecciones, Locales», tienen esa característica. Si abres el menú contextual con el botón derecho sobre esas ventanas, verás una opción que dice "Acoplable". Cuando la opción está desmarcada se comporta como una ventana más del editor (lo que comentas que te sucede ahora), y cuando la opción está marcada es cuando puedes "anclarla" a un lateral o arriba o abajo.


Bueno, ya referente al ejemplo que te comenté, lo puedes descargar de la siguiente dirección:
http://www.telefonica.net/web2/vbut...rForms.zip

Contiene dos ficheros, el del formulario y un '.frx' que contiene las imágenes usadas por el formulario.
Abres el fichero de Excel que contenga los formularios que quieres revisar, e importas sólo el fichero '.frm' al proyecto. En la sección "Declaraciones" del código del formulario están de recordatorio las opciones y referencias necesarias para que el formulario se pueda ejecutar correctamente.

He añadido comentarios, pero ya sabes que puedes preguntar si algo no lo ves claro. Es recomendable en algunas ocasiones ejecutarlo en modo 'Paso a paso por instrucciones {F8}', para seguir la ruta de ejecución y ver cómo se realizan las acciones.

El control de errores, lo dejo a deber ;-)


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
#9 Ivan
18/11/2006 - 18:57 | Informe spam
hola Vinchenzo,

muchas gracias por tu tiempo y por tu extensa (y completa) ayuda.

Con tus respuestas ( y, para hacer justicia, con la de otros cuantos
colaboradores de los foros) estoy consiguiendo encarrilar hacia algo
parecido a la comprension una gran parte de mis actuales dudas, y no
sabes como te lo agradezco, porque ademas, una gran parte de ellas,
nacen (se obcecan) a causa de mi inseguridad. Y eso es dificil de
resolver solamente con la ayuda en linea.

tambien ayuda bastante saber que los atolladeros en los que uno se mete
aprendiendo por su cuenta algo como VBA, no son patrimonio propio, sino
algo relativamente normal ( quizas sea eso de " ¿mal? de muchos,
consuelo de ")

en cuanto a tu respuesta no he podido mas que hacer una lectura rapida
( ya me he bajado el archivo), pero, como tu decias, parece que tiene
'tela', y de la buena.

Por eso he querido darte las gracias ahora, pues creo que analizarlo me
llevara su tiempo. Cuando vaya avanzando, es un honor saber que puedo
seguir contando con tu inestimable ayuda para las dudas.

Muchas gracias de nuevo, y, un saludo y hasta pronto
Ivan

PD:-> no se si entre tus actividades estará la docencia, pero si no es
asi, no sabe el mundo academico la 'joya' que se ha perdido.

PPD:-> de momento habia conseguido +o- la clasificacion de controles,
dando dos 'pasadas', una primera cargando los 'contenedores' y sus
prop. en la hoja, y una segunda con el resto de los controles usando
los rangos ya cargados y condicionales tipo:->

If Celda = TypeName(Ctl)
-> o/y -> If Celda.Ofsset(x,y) > Ctl.TopIndex

pero estoy dandole vueltas a las f. recursivas y demas. Voy a ponerme
duro con tu ayuda. Un saludo de nuevo.
Respuesta Responder a este mensaje
#10 Ivan
18/11/2006 - 19:04 | Informe spam
perdon, queria decir

y una segunda con el resto de los controles usando
los rangos ya cargados y condicionales tipo:->



-> If Celda = Ctl.Parent
<-- o similar

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