guizans   31-03-2023, 12:01
#1
Hola a todos.

Estoy haciendo un pequeño proyecto personal. Tengo el formulario principal, cuando pulso un botón (llamado toolAnadirNuevoTrabajo) se abre un nuevo formulario (anndirTrabajo). En este formulario hay una serie de campos a mostrar y rellenar. Contiene un botón llamado Nuevo Cliente. Al pulsar se abre un nuevo formulario llamado NuevoCliente. Aquí hay que rellenar unos campos y se guarda en la base datos de tipo Sqlite3. Hasta aquí todo normal y funciona. El caso es que de este último formulario le paso al anterior antes de que se cierre un identificador que es un entero. La solución que siempre he usado es crear una propiedad en el segundo formulario y antes de que se cierre el tercer formulario pasar el parámetro necesario.
 Hasta aquí parece todo correcto, no se si es la forma correcta de programar pero hasta ahora me ha funcionado sin problemas, pero es en ese preciso momento cuando se cae el programa y me da error en la línea de la llamada a la propiedad diciendo que no hay argumentos suficientes. ¿Cómo que no hay argumentos suficientes? Es una propiedad, le estoy pasando un sólo parámetro que es un entero (línea 41 del formulario NuevoCliente)
 Busco otra solución salomónica. Crear en el segundo formulario un método público que reciba el parámetro necesario. Pues lo mismo, el mismo error en la misma línea. No lo entiendo. He estado haciendo pruebas en un proyecto aparte y no logro replicar el error. No se que estoy haciendo mal o es cosa de Gambas.
 Tengo otra solución, y es desde el segundo formulario llamar a la base de datos para recibir ese dato necesario. Es una solución, pero coño, me estoy rompiendo los cuernos y no logro descifrar el problema, si es que lo hay.

 Estoy usando Gambas 3.18 en Debian Estable.

 Si alguna alma caritativa puede echarle un vistazo a este punto se lo agradezco. Como he comentado, tengo solución, pero me gustaría aprender lo que estoy haciendo mal.

Muchas gracias.
Archivos adjuntos
.gz
Asignatra-0.0.1.tar.gz (Tamaño: 27.51 KB Descargas: 4)
Última modificación: 07-04-2023, 18:22 por guizans.
Shordi   31-03-2023, 12:43
#2
Ejecuto el proyecto que has subido y veo que no es funcional. En concreto el botón de Nuevo Cliente no tiene asociado ningún evento por lo que no es posible reproducir el error. Sube un proyecto que funcione y te podremos ayudar.

Saludos.

No podemos regresar
guizans   31-03-2023, 13:15
#3
Hola Shordi.

Si, está en fase de construcción el proyecto, lo empezé ayer sin planificar y al final me va a quedar como un churro.

 Pero al caso. Los pasos a seguir son en el formulario principal pulsar el botón que está arriba a la izquierda. Esto abrirá otra ventana y dentro de está ventana hay un botón que se llama Nuevo Cliente. Después se abrirá una tercera ventana donde hay que rellenar el campo Nombre y el campo Telefono 1. Pulsas en Guardar y ahí se va a producir el error.

Muchas gracias.
guizans   31-03-2023, 16:55
#4
Mas o menos he solucionado el problema. No se si es ideal o es una característica de Gambas o algo que me pierdo. Resulta que si en el formulario del inicio creo una propiedad, la puedo usar en la siguiente ventana sin problemas. El problema es al abrir una tercera ventana. Así que he hecho esto:

Código:
Private a as anndirTrabajo

Public Sub _new($a as anndirTrabajo)
a = $a
End

Public Sub Guardar_Click()
a.identifcador = 1
End
Es decir, que enviando como parámetro al constructor de la tercera ventana la segunda ya puedo manejar sin problemas las propiedades de la segunda ventana. No se por que de este comportamiento pero asumo que es normal.

Un saludo.
Shordi   01-04-2023, 11:03
#5
Le he echado un vistazo y te puedo decir el error:

Un formulario es una clase estática, es decir no es necesario instanciarla para utilizarla... aunque, a mi entender es muy conveniente. El problema con tu código es que en el fMain  haces esto:

Código:
Public Sub toolAnadirNuevoTrabajo_Click()

  Dim ventana As AnndirTrabajo

  ventana = New AnndirTrabajo(base)
  ventana.Show

End
Es decir creas una nueva instancia de AnndirTrabajo con New
Luego desde AnndirTrabajo, a la hora de mostrar el formulario nuevoCliente haces esto:
Código:
  Dim ventana As NuevoCliente
  Dim a As Integer
  Dim n As String

  ventana = New NuevoCliente(base, True)
  ventana.Showmodal()
...
...
Es decir creas una nueva instancia de NuevoCliente, igual que antes con New.
Pero a la hora de cerrar NuevoCliente, haces esto:
 
Código:
Message.Info("Cliente creado correctamente.")
  If anadirTrabajo Then
    anndirTrabajo.$idCliente = i
  Endif
  Me.Close(1)
Es decir invocas un símbolo de anndirTrabajo como clase estática pero sin instanciar...  y eso no es posible.
Solución:
Cuando en un formulario quieras mencionar algún símbolo del formulario que lo llamó, pásale una referencia de éste. Es decir, en este caso, en el formulario instanciado anndirTrabajo haz esto:

Código:
  Dim ventana As NuevoCliente
  Dim a As Integer
  Dim n As String

  ventana = New NuevoCliente(base, True, Me) 'Como tercer parámetro una referencia al formulario llamador
  ventana.Showmodal()

Luego en el formulario NuevoCliente:
Código:
Private base As BaseDatos
Private anadirTrabajo As Boolean  'Si es True es que viene de la ventana anadirTrabajo, eso significa que llama a la propiedad de esta ventana
Private $anndirTrabajo As Object

Public Sub _new($base As BaseDatos, $anadirTrabajo As Boolean, oLlamador As Object) 'Recibimos la referencia al form llamador como tercer parámetro

  base = $base
  anadirTrabajo = $anadirTrabajo
  $anndirTrabajo = oLlamador    'asignamos la referencia del llamador a una variable privada

End

Public Sub btnGuardar_Click()

  ....
  ....

  i = base.annadirNuevoCliente(textos)
  Message.Info("Cliente creado correctamente.")
  If anadirTrabajo Then
    $anndirTrabajo.$idCliente = i   'asignamos valor al símbolo $idCliente de la instancia del formulario llamador
  Endif
  Me.Close(1)

End

Public Sub btnCancelar_Click()

  Me.Close(0)

End

y con esto te funcionará siempre. Usa esta técnica siempre que quierar pasar datos de un formulario a otro abierto por él mismo, no importa si es la primera o la segunda.

Por último me permito un consejo:
Yo no soy muy partidario de una notación Húngara estricta, hay momentos en los que más bien me estorba que me ayuda. Pero hay algunas convenciones que deberían "ser sagradas" y una de ellas es: Reserva el $ inicial para las variables privadas y en lo posible asigna un nombre indicativo a las propiedades (eso ya lo haces) y el mismo nombre precedido por el $ para las variables controladas por ellas. No uses $ ni para nombres de métodos ni controles ni variables públicas.

Es algo, quizá, relativo a las preferencias de cada uno, pero realmente hace el código más legible.

Perdón por el ladrillo.

Saludos

No podemos regresar
guizans   01-04-2023, 22:31
#6
Pues tienes toda la razón del mundo, muchas gracias. Ya sabía que el tenía que ser algo que he hecho mal. Si es que no se puede empezar a escribir código a lo loco sin planificar. Big Grin

Un saludo.
tincho   01-04-2023, 23:08
#7
(01-04-2023, 11:03)Shordi escribió: Pero hay algunas convenciones que deberían "ser sagradas" y una de ellas es: Reserva el $ inicial para las variables privadas y en lo posible asigna un nombre indicativo a las propiedades (eso ya lo haces) y el mismo nombre precedido por el $ para las variables controladas por ellas. No uses $ ni para nombres de métodos ni controles ni variables públicas.

En los fragmentos de código así sucede, si escribes svs[tab] aparece esto:
[code]

Pero a veces cuando el código es extenso también le pongo $ a las variable Publicas así las identifico como globales en cualquier parte del código en la que este trabajando, aunque no me gusta hacerlo, no encuentro otra manera de "marcar" las globales. ¿Sugerencias?

(31-03-2023, 12:01)guizans escribió: Hola a todos.

No es lo que preguntas pero como lo he visto te lo digo.
El método:
Private Function eliminarAcentos(palabra As String) As String
Podría omitirse usando el la función
[code]
Para activarla usa el componente gb.util
Última modificación: 01-04-2023, 23:34 por tincho.

1 Saludo.
Shordi   02-04-2023, 09:47
#8
Cita:Pero a veces cuando el código es extenso también le pongo $ a las variable Publicas así las identifico como globales en cualquier parte del código en la que este trabajando, aunque no me gusta hacerlo, no encuentro otra manera de "marcar" las globales. ¿Sugerencias?
Hablando de clases de hecho una variable pública es equivalente a una propiedad. Yo les asigno nombre significativo y ya está. El $ implica un entorno concreto (privado). Un símbolo público ya te lo ofrece el ide per se.

Saludos

No podemos regresar
  
Usuarios navegando en este tema: 1 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.