Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 2 de 3
Ir a la página Anterior  1, 2, 3  Siguiente
 
Copiar Variables De Un Form A Otro
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
Después de leer este hilo, tengo que confesarles que quedé un poco mareado, así que lo volví la leer y saqué algunas conclusiones que quiero compartir:

  1. Se estuvo hablando de pasar variables de aquí para allá; ese vocabulario no es muy acertado e influye negativamente en los razonamientos.
  2. Se están mezclando conceptos de los paradigmas de programación imperativa (de procedimientos) con el de programación orientada a objetos.


Hay que tener claro que:

  • Un formulario es una clase.
  • Una variable pública declarada en un formulario rompe el encapsulamiento que debe tener esa clase.
  • Los controles en los formularios pueden ser privados o públicos y cuando se generan en tiempo de diseño su ámbito se controla desde el cuadro de diálogo Propiedades del proyecto. Si se crean en tiempo de ejecución sin especificar el ámbito (PRIVATE|PUBLIC) su ámbito será controlado por la opción de configuración antes mencionada. Si son públicos se rompe el encapsulamiento de esa clase.
  • Si no se declara el ámbito de las variables en un módulo, serán públicas o privadas de acuerdo a la configuración Símbolos en módulos son públicos por defecto [Sí|No] del mismo cuadro de diálogo.


Entonces, si se opta por el paradigma imperativo se debe evitar el uso de variables globales (hay que hacerse la idea de que están prohibidas) y toda rutina (procedimiento o función) debe recibir los datos con los que opera por medio de sus argumentos. A veces esto genera largas listas de argumentos en una gran cantidad de funciones, pero es la única manera de mantener bajo control los terribles efectos colaterales que puede traer el uso de variables globales (y esto es especialmente cierto en proyectos medianos/grandes).

Es frecuente que varias rutinas tengan que operar con los mismos datos, si se usan variables globales (cuantas más sean mayor es el riesgo) cualquier modificación a una de esas variables afectará a todas las funciones que la usen.

Si en cambio las funciones operan únicamente con sus propios argumentos, sus valores se definen en cada llamada de forma explícita permitiendo un mayor control (pero de nada serviría si lo que se pasa como argumentos son variables globales).

Las funciones (FUNCTION) pueden modificar un valor y devolverlo (RETURN). Las funciones deberían usarse cuando resulta necesario devolver un único valor.

Los procedimientos (SUB) deberían usarse para procesos que no devuelven resultados o devuelven varios valores modificados.

Se debe recordar utilizar la palabra clave byref al pasar argumentos a un procedimiento que éste debe modificar.

Puede parecer trivial pero uno de los problemas más habituales de este paradigma desde siempre ha sido la modificación inadvertida de una variable (global) que usa una determinada rutina.

Si por el contrario se opta por el paradigma de programación orientada a objetos, cada formulario (clase) debe encapsular sus datos (propiedades). Por lo tanto, no debería accederse directamente a ninguna variable ni propiedad de un control desde otra clase, sino sólo a través de las interfaces públicas que hayas declarado en ese formulario (clase).

Esas interfaces públicas se pueden declarar a través de la palabra clave (PROPERTY) o métodos (FUNCTION | SUB), pero nunca debería utilizarse una variable pública (global) como interfaz.

Mezclar los paradigmas es una muy, pero muy mala idea.

En conclusión, si se utiliza el POO no hay ninguna necesidad de "pasar" absolutamente nada. Cada clase (sea visual -formulario- o no) debe tener su interfaz pública (propiedades y métodos) que es lo que se debe usar desde otras clases. Si esto no se respeta de forma estricta: no se está usando POO, es muy fácil liarse y los problemas aparecerán como por arte de magia.

Saludos cordiales.
 




===================
Cómo programar con Gambas

Speed Books: informática libre.
 
fabianfv - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
Pero es que esa es la cuestión.
Por ejemplo algo tan utilizado en todas partes como una conexión.

¿Qué opciones tienes?
1. Declarar una variable global de tipo connection. En alguna parte estableces la conexión y la dejas en esa variable que será conocida en toda al a aplicación
2. Declarar y establecer una conexión en cada formulario que la necesite (o en el colmo del disparate declarando una conexión como variable local en cada función o sub que lo necesita, estableciendo la conexión y haciendo lo que se tenga que hacer.

La solución.
Pues la solución es crear una variable privada por ejemplo en el formulario inicial o en main o donde sea y cuando el usuario pincha en alguna parte al escoger una opción que abrirá un formulario nuevo enviarla como parámetro.
private sub boton_click()
Dim F as new FormularioNuevaOpcion(Cn) 'creo una nueva instancia del formulario correspondiente a esa opción y le envío la conexión
End Sub


Y por tanto el formulario que recibirá esa conexión tendrá lo siguiente
private Cn as connection 'crear una variable de tipo conexion privada para este formulario

public sub _new(ConexionEntrante as connection)
Cn=ConexionEntrante
end sub


Y con ello lo que has hecho es pasar la conexión a ese otro formulario que podrá hacer lo que necesite y que si crea otros forrmularios podrá pasar de nuevo ese valor de la misma manera.

Cubel preguntaba por como pasar una variable a otro formulario. Pues esa es la forma y puede pasar variables u objetos. Por ejempo puede pasar un form si se quiere (cosa que veo poco útil) pero puede pasar una clase o una variable o un objeto concreto o un recordset ya calculado, etc.

Y ya mencioné antes las posibilidades de crear propiedades pero es que Cubel está empezando y bastante tiene con ir viendo la potencia que tienen las clases. Ya irá viendo como heredar y crear nuevos objetos con propiedades adicionales que le solucionen estos problemas de una forma mejor.

 
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
Citar:

Off topic
Pero es que esa es la cuestión.
Por ejemplo algo tan utilizado en todas partes como una conexión.

¿Qué opciones tienes?


Como bien mencionas, a priori no habría problema de usar una variable global de tipo connection ya que ella no guarda ningún dato que el programa manipule. Esto sería aceptable al usar programación procedimental (imperativa).

Sin embargo, hay varias cosas que observar. Las opciones son:

  1. Aplicar el paradigma imperativo
  2. Aplicar el paradigma POO


1. Paradigma imperativo:

Resulta muy útil para mantener un orden en la aplicación no poblar los formularios con rutinas de procesamiento de datos. Los formularios sólo deberían contener rutinas que se ocupan del interfaz gráfico y llamadas a rutinas ubicadas en módulos, por tanto ningún formulario debería operar con una variable de tipo connection. Esto tiene que ver con buenas prácticas y estilo de programación en el paradigma imperativo.

En un módulo:

a- Declaras una variable privada de tipo connection
b- Escribes una función pública que abre una conexión específica (tomando como argumentos los datos necesarios), tal como lo has hecho en tu ejemplo.
c- Creas las rutinas (funciones o procedimientos) públicas que operan con la conexión y la base de datos (no necesariamente deberán estar en un único módulo).
d- Desde el formulario que lo requiera, llamas a esas rutinas para operar sobre la base de datos.


2. Paradigma POO:

1. En una clase:

1.a- Declaras un miembro privado de tipo connection.
1.b- Escribes un método privado que abre una conexión específica (tomando como argumentos los datos necesarios).
1.c- Declaras una propiedad pública (PUBLIC PROPERTY READ) que devuelve una referencia al objeto connection (también puede ser un método).

2. En cualquier otra clase que necesites operar con la base de datos:

2.a- Declaras un miembro privado de tipo connection.
2.b- Le asignas una referencia al objeto connection mediante una llamada al método o propiedad del punto 1.c.
2.c- A través de la referencia al objeto connection realizas las operaciones que necesites (al usar POO se busca que cada objeto encapsule sus propias operaciones).

Como ves no es necesario usar el constructor de una clase. En tu ejemplo, el diseño que eliges te conduce a usar el constructor para asignar la referencia del objeto connection a una propiedad de la clase del formulario. Esto no es recomendable en el contexto que se planteó en este hilo.

Citar:

Cubel preguntaba por como pasar una variable a otro formulario. Pues esa es la forma y puede pasar variables u objetos. Por ejempo puede pasar un form si se quiere (cosa que veo poco útil) pero puede pasar una clase o una variable o un objeto concreto o un recordset ya calculado, etc.


Eso es lo que pregunta Cubel, así es. Pero lo que indicas no es "la" forma de pasar, sino una forma y no es la más recomendable. No estás evitando que se enfrente a cuestiones relativas a la POO, le estás indicando que instancie un formulario por código y use su constructor. Sería mejor indicarle que estudie cómo usar clases y objetos.

Citar:

Y ya mencioné antes las posibilidades de crear propiedades pero es que Cubel está empezando y bastante tiene con ir viendo la potencia que tienen las clases. Ya irá viendo como heredar y crear nuevos objetos con propiedades adicionales que le solucionen estos problemas de una forma mejor.


Sin embargo, para este caso Cubel no necesita usar herencia, ni siquiera POO. El problema es que al mostrarle tu ejemplo que usa el constructor de un formulario (clase) para pasar una referencia de un objeto, estás mezclando ambos paradigmas: el constructor es un mecanismo del paradigma de programación orientada a objetos y su finalidad es inicializar estructuras de datos internas del objeto que se instancia (no pasarle datos).

Pero lo que tú propones funciona y eso complica un poco más las cosas: cuando hacemos algo que funciona tendemos a no querer tocarlo y seguir haciéndolo así, pero lo que hay que hacer es... recodificar (refactoring), ya que conceptualmente está un poco errado y eso en muchas situaciones puede llevar a mayores problemas.

Pero te comprendo soplo, porque a todos nos ha pasado liarnos un poco al buscar una solución a un problema que se plantea en los foros (a mi me ha pasado antes respecto de este mismo tema, precisamente). A veces uno mira el problema tomando el planteo que hace quien pregunta y en ocasiones, como en este caso, ese planteo es erróneo: lo que Cubel necesitaba no era "pasar variables entre formularios" (de hecho las variables no se pueden pasar, sino sus valores).

Además hay otro aspecto que complica las cosas: gambas es un lenguaje híbrido, soporta el paradigma imperativo y no completamente el paradigma POO y eso también constribuye un poco a la confusión. Pero que no se malinterprete lo que dije muchos lenguajes son o fueron híbridos: Object Pascal, Visual Basic, C++...

Saludos cordiales.

PD: soplo, me has hecho pensar mucho el día de hoy... y eso está genial !!!

Editado: el texto que figura en cursiva para evitar confusión a lectores futuros de este hilo.
 




===================
Cómo programar con Gambas

Speed Books: informática libre.
 
última edición por fabianfv el Sabado, 16 Enero 2010, 20:47; editado 3 veces 
fabianfv - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
Yo tengo un módulo con funciones comunes al uso de una base de datos. En ese módulo hay una serie de funciones y procedimientos privados y unas poquitas funciones públicas además de algunas variable privadas. Entre ellas un objeto de clase connection.

Al iniciar mi aplicación yp suelo hacer algunas comprobaciones iniciales. por ejemplo cargo el settings y si no está hago uno por defecto y aviso al usuario que faltan datos de configuración. Tambien conecto a la base de datos con un usuario con permisos insert, update, delete y select. Si no se puede establecer esa conexión pregunto la clave de root, conecto a mysql con él y construyo al usuario y a la base. Luego compruebo espacio de logs ocupado. Si hay demasiados los comprimo y creo el nuevo log para esta sesión

Osea que yo tengo en un módulo un connection privado y una función pública que me conecta a mi base de datos con el usuario adecuado y un parámetro opcional por si en algún caso quiero entrar con un usuario con mas permisos a la base datos e incluso si quiero entrar como root

En mi formulario principal tengo declarado un connection privado. Una de las primeras cosas es hacer CN=BD:Conectar y si todo fue bien en CN tengo una conexión abierta con el usuario adecuado a mi base de datos.

A partir de ahí el usuario escoge opciones del menú o de la barra. Cada una de esas opciones abre un nuevo formulario al que se le pasa la conexión abierta. Eso podría hacerlo de dos forma

1. Llamando a una propiedad establecida al efecto
private sub Opcion_click()
Dim F as new FormularioOpcion
F. conexion=Cn
F.show


2. Pasando la conexión al constructor
Dim F as new FormularioOpcion(Cn)
F.show


Si utilicé el caso 1 entonces en FormularioOpcion tengo escrito lo siguiente:
private Cn as conection 'declarar una conexión privada para este form
property Conexion as connection 'crear la propiedad conexion
private sub Conexion_Read() 'el caso de leer el valor de la propiedad
return Cn
End
public function Conexion_Write(Value as connection 'el caso de dar valor a la propiedad
Cn=Value
End


Si utilicé el caso 2 entonces en el formularioOpcion tengo esto
private Cn as connection
public sub _new(ConexionEntrante as connection) 'la rutina del constructor
Cn=ConexionEntrante
End


En ambos casos yo tenía abierta una conexión en FormPrincipal y se la he pasado a FormularioOpcion que no neesitará volver a establecer la conexión. En ambos casos la conexión es un objeto privado conocido en todo su formulario

Lo normal ahora es que este form construya una nueva clase donde están las rutinas y funciones que deben llevar a cabo esta opción y que el form se preocupe de lo que es suyo que son los evento así que el propio constructor crea una clase donde están esos procedimientos y a la que se pasa la conexión de forma análoga

Ambos procedimientos son perfectamente válidos
 
 



 
última edición por soplo el Sabado, 16 Enero 2010, 14:22; editado 1 vez 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
En el código que muestras, el diseño por el que optas te obliga a usar el constructor al instanciar para asignar a una propiedad una referencia de otro objeto. Funciona: sí (aplicado a otras situaciones tal vez no). Es correcto conceptualmente: no (estás mezclando los paradigmas imperativo y POO).

Saludos cordiales.

Editado: el texto que figura en cursiva para evitar confusión a lectores futuros de este hilo.
 




===================
Cómo programar con Gambas

Speed Books: informática libre.
 
última edición por fabianfv el Sabado, 16 Enero 2010, 20:47; editado 3 veces 
fabianfv - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
Mis objeciones son que según tú en cada formulario o clase que necesite recurrir a la base de datos hay que llamar a la función que establece una nueva conexión, cosa que me parece un trabajo completamente innecesario ¿Si tienes abierta una conexión para que vas a abrir otra en un formulario/clase hijo que la pueda necesitar? ¿No es mas lógico pasársela como parámetro bien como propiedad bien llamando al constructor?

 
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
La segunda manera que acaba de plantear Soplo me parece la mas elegante, pasar la conexión en el constructor. Quisiera preguntarte Soplo que pasaría si en el formularioOpcion ejecutas cn.close? Eso hace que el objeto CN que esta en el formulario también se cierre, puede ser? Es posible que no afecte al otro CN?

Muchas veces me pasa que quiero pasar una copia de un objeto hacia otro, pero los dos terminan haciendo referencia a la misma cosa. Es que solo los parámetros se pasan por referencia y no por valor?

Pongo un ejemplo, porque tal vez no me haya explicado bien:

PUBLIC SUB Form_Open()
  PictureBox1.Picture = Picture["perro.png"]
  PictureBox2.Picture = Picture["gato.png"]
  AhiVaUnPictureBox(PictureBox1)
END

PUBLIC SUB AhiVaUnPictureBox(picbox AS PictureBox)
  PictureBox2 = picbox
  PictureBox2.Move(0, 0)
  PictureBox2.picture = Picture["arbol.jpg"]
END


En este caso PictureBox1 y PictureBox2 es la misma cosa, intento cambiar el gato por un arbol y el perro se pasa a arbol. Es un ejemplo tonto que acabo de inventar.

Es posible que luego de llamar a AhiVaUnPictureBox, PictureBox1 sea una cosa y PictureBox2 sea otra, pero ambos con idénticos valores? Es decir PictureBox1 siga siendo un perro y a PictureBox2 le pueda cargar un arbol.

Atte Mil.
 



 
mil_arg - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
El caso que tu propones no es igual porque son únicamente prámetros enviados a una función. En gambas Los parámetros son pasados POR VALOR mientras que en VB los parámetros se pasaban por REFERENCIA a menos que pusieras por medio la palabra clave byval.
Parece ser que gambas 3 resolverá esto con los nuevos operadores byval y byref, pero de momento está como está.

En el caso de la conexión a otro formulario/clase que si interviene el constructor, si haces un cn.close cierras la conexión también en el principal.

Fíjate en el código que va en FormularioOpcion
private Cn as connection
public sub _new(ConexionEntrante as connection) 'la rutina del constructor
Cn=ConexionEntrante
End

Cn es declarado como connection, pero no lleva el parámetro NEW. No se está llamando al constructor al crearla. Es únicamente una declaración para que gambas sepa como tratarla.

Posteriormente se le asigna un valor Cn=ConexionEntrante osea que lo que se ha transferido es la dirección de memoria (puedes comprobarlo haciendo un debug). Osea que no has pasado una instancia de la conexión, sino que has pasado la conexión propiamente.

Ahora bien, si hubieras hecho en vez de lo anterior
private Cn as NEW connection
public sub _new(ConexionEntrante as connection) 'la rutina del constructor
Cn=ConexionEntrante
End

Ahí si que habrías creado una instancia nueva a la que habrías asignado posteriormente la conexion entrante y por tanto al cerrarla no habría afectado a la conexión en principal.que seguiría intacta.

 
 



 
última edición por soplo el Sabado, 16 Enero 2010, 16:31; editado 1 vez 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
Seguro Soplo? Para mi el New solo inicializa los componente internos de la clase Connection, pero al hacer

 Cn=ConexionEntrante

Cn (del formOpciones) y CN (del formprincipal) son la misma cosa. Ahora lo pruebo bien con el ejemplo de los PictureBox y te confirmo.

Atte Mil.
 



 
mil_arg - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Copiar Varibales De Un Form A Otro 
 
Citar:

Mis objeciones son que según tú en cada formulario o clase que necesite recurrir a la base de datos hay que llamar a la función que establece una nueva conexión, cosa que me parece un trabajo completamente innecesario


Si vuelves a leer con detenimiento lo que expliqué, verás que no es eso lo que propongo. Abrir una conexión y luego cerrarla inmediatamente cuando ya no es necesaria sólo tiene sentido si sabes que el servidor de bases de datos estará sometido a una carga importante y si evalúas (no si lo imaginas, si lo evalúas) que abrir y cerrar conexiones ayudará a disminuir esa carga.

Citar:

¿Si tienes abierta una conexión para que vas a abrir otra en un formulario/clase hijo que la pueda necesitar? ¿No es mas lógico pasársela como parámetro bien como propiedad bien llamando al constructor?


Si para asignar una referencia al objeto connection utilizas el constructor te obligas a instanciar la clase (el formulario). ¿Pero es realmente necesario hacerlo así?. Estás usando módulos (por tanto el paradigma imperativo y en los formularios usas mecanismos del paradigma POO (el constructor) para pasar una referencia de un objeto, ¿es eso lógico?

Si quieres usar el paradigma imperativo, lleva las rutinas que manipulan los datos a módulos y llámalas desde los formularios.

Si quieres usar el paradigma POO (aún conviene usar los formularios sólo como clases que se ocupan del GUI), puedes asignar la referencia al objeto connection tal como cuando asignas un valor a cualquier propiedad de un objeto (tal como lo mencionas) o llamando a un método que tome como argumento dicha referencia.

De todos modos no habría ningún problema de usar el constructor para asignarle a una propiedad de un objeto una referencia a un objeto connection, si estuvieras usando en todo tu sistema el paradigma POO y realmente existe la necesidad de instanciar la clase (crear el objeto).

En cualquier caso que exista previamente el objeto que requiere una referencia a otro objeto, no debes usar el constructor de la clase porque ello no tendría sentido (para que instanciar una clase si ya existe una instancia de ella).

mil_arg
Citar:

La segunda manera que acaba de plantear Soplo me parece la mas elegante, pasar la conexión en el constructor.


Aprender a usar correctamente los paradigmas de programación no es una cuestión meramente estética y por lo tanto subjetiva. Tu criterio estético madurará en la medida que aprendas a usar POO correctamente.



gambas 2.18 ya soporta el pasaje de parámetro por referencia (byref).

Saludos cordiales.

Editado: el texto que figura en cursiva para evitar confusión a lectores futuros de este hilo.
 




===================
Cómo programar con Gambas

Speed Books: informática libre.
 
última edición por fabianfv el Sabado, 16 Enero 2010, 20:53; editado 2 veces 
fabianfv - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 
OcultarTemas parecidos
Tema Autor Foro Respuestas último mensaje
No hay nuevos mensajes Copiar Desde El Bash Una Archivo A Otro Or... jsbsan Shell Scripting 3 Domingo, 22 Agosto 2010, 11:59 Ver último mensaje
jsbsan
No hay nuevos mensajes ¿Como Usar Variables De Un Form Desde Otro? ariel Controles/Librerías/Componentes 9 Lunes, 08 Noviembre 2010, 20:04 Ver último mensaje
jsbsan
No hay nuevos mensajes Se Puede Llamar Desde Un Form A Un Menupop... v3ctor General 6 Martes, 03 Diciembre 2013, 09:06 Ver último mensaje
jsbsan
No hay nuevos mensajes Copiar Formulario De Un Proyecto A Otro. frajanic General 3 Miercoles, 13 May 2015, 20:16 Ver último mensaje
frajanic
 

Publicar nuevo tema  Responder al tema  Página 2 de 3
Ir a la página Anterior  1, 2, 3  Siguiente

Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado
Usuarios registrados conectados: Ninguno


 
Lista de permisos
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario



  

 

cron