Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 1 de 1
 
 
Consulta Acerca De Una Matriz De Objetos: Todos Los Objetos Tienen Los Mism...
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje Consulta Acerca De Una Matriz De Objetos: Todos Los Objetos Tienen Los Mismos Datos¿? 
 
Buenos días,

Leyendo hace algún tiempo atrás el siguiente link:

http://foro.gambas-es.org/viewtopic.php?f=1&t=1467

se me abrió la cabeza acerca de cómo realizar la aplicación que tengo en mente....

Tal como sugieren en ese link tengo una clase (denominada lote) que tiene los siguientes elementos:

PUBLIC nombre AS String
PUBLIC pcompra AS Float
PUBLIC pventa AS Float
PUBLIC pultimo AS Float

PUBLIC SUB leevalores(xmlnombre AS String, xmlpcompra AS Float, xmlpventa AS Float, xmlpultimo AS Float)
  
  nombre = xmlnombre
  pcompra = CFloat(xmlpcompra)
  pventa = CFloat(xmlpventa)
  pultimo = CFloat(xmlpultimo)

END


Asimismo tengo un módulo donde creo una NEW collection o bien un NEW object[] (he probado con los dos, pudiendo acceder mediante los index teniendo el mismo problema)...


Pues resulta que leyendo un xml tomo unos atributos que se los paso a un objeto del tipo lote mediante el procedure leevalores.... Todo va bien.

Luego hago un modulo.nombredelobject[].add(objetodetipolote) y obviamente me lo agrega....

El tema es que cuando quiero acceder a los objetos almacenados en el array de objetos (o bien en la collection cuando probé de esa forma) resulta que todos los objetos almacenados tienen el mismo valor: el del último que asigné y guardé....

Es como si todos los objetos que fui guardando... en lugar de dejar guardados el valor que tenían cuando los agregué al object[] fueron actualizando los valores de sus elementos a los nuevos datos que se fueron leyendo del xml....

No se si esto se debe a que estoy declarando mal el ámbito de alguna variable o errando en alguna metodología....

Cualquier idea de acerca de dónde puedo seguir investigando para corregir esto será sumamente agradecida!


Si necesitan algún fragmento de código adicional lo subo sin problemas.

He aprendido mucho leyendo inquietudes de otros, este es el primer post que hago así que todavía no le tengo tomada la mano al sistema para foros, jeje.
Muchas gracias!
Saludos.
Santiago.
 



 
santijav - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Consulta Acerca De Una Matriz De Objetos: Todos Los Objetos Tienen Los Mismos Datos¿? 
 
Hola

La parte de código que no pones es la que en mi opinión deberías poner.

Mas o menos debería ser algo como esto

private sub LeerXml()
dim L as Lote 'definir la variable de clase Lote
Dim O as new object[] 'definir el espacio para el conjunto de lotes
Dim Nombre as string,  PrecioCompra as string,  PrecioVenta as string, PrecioUltimo as string

do while condicion 'mientras este bucle siga, leerás y meterás los datos en el object
   'aquí haces la extracción de datos de donde los saques
   ...
   'y obtienes Nombre,  preciocompra, precioventa, precioultimo
   ...

   'ahora viene la parte importante
  
   L=NEW Lote 'crear una nueva instancia
   L.InsertarValores(Nombre, Preciocompra, Precioventa, PrecioUltimo) 'asignar datos
   O.add(L) 'insertar el lote en el conjunto de lotes
   L.delete 'eliminar lote (No es necesario)
loop
end

Lo que hace ese bucle es ir leyendo del xml o lo que sea y va obteniendo un nombre, preciocompra, etc
Luego crea un lote, le asigna los valores y lo inserta en el conjunto de lotes
Ya puedes prescindir del lote porque está en el conjunto de lotes. Lo pongo para remarcar que no necesitas ese lote porque ya lo tienes guardado en el conjunto de lotes. Cuando quieras en otra parte rcuperar el lote N puedes hacer
Dim L as new Lote
L=Obj[N)
 


Por otra parte esa forma que has utilizado para enviar parámetros a la clase lote la veo incorrecta (aunque funciona)  y te explico la razón.

Si defines las variables como Public puedes acceder a ellas directamente, no necesitas un método para darles valor.  Podrías haber definido esas variables como private y funcionaría igual (mas limpio) o bien podrías haberlas definido públicas y darles valor directamente en cuyo caso no necesitas el método leevalores.

Prueba porque manejar estas cosas ayuda mucho.

Por último hay otro método para pasar variables a una clase lote que es crearle propiedades a esa clase. En este caso lo veo por completo innecesario pero en otros casos es extremadamente útil y te aconsejo que lo mires.

Puse un ejemplo en este lugar, echa un vistazo
Enlace

Manejar estas técnicas para pasar datos de una clase a otra, de un formulario a otro (un formulario es una clase), etc es muy muy interesante y muy sencillo.

Un saludo
 
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Consulta Acerca De Una Matriz De Objetos: Todos Los Objetos Tienen Los Mismos Datos¿? 
 
Estimado Soplo,

Muchísimas gracias por tu prontísima respuesta.

La principal diferencia entre tu código y el mío  que veo es que instanciamos el objeto de tipo lote en distintos lugares. Vos lo hacés dentro del bucle y después de tener cada valor y yo lo hago al principio de todo... incluso antes de meterme en el bucle... Será eso el problema?

El tema de las variables públicas en el objeto lote... los creé así ya que esos valores son importantes para mi programa y necesito accederlos desde distintos lugares del programa. Sería mejor declararlas private y crear una función que me devuelva el valor que necesito? (suena más "correcto"... parece más oop, jeje)

Copio aquí mi código actual antes de tus sugerencias para que los interesados puedan aprender a través de un antiejemplo, jeje:

PUBLIC SUB Form_Open()
DIM aanombre AS String
DIM aacompra AS String
DIM aaventa AS String
DIM aaultimo AS String
DIM loteactual AS NEW lote


DIM xml AS NEW XmlReader

TRY xml.Open(User.Home & "/prueba2/opciones.xml")

IF ERROR THEN
Message.Error("No se encuentra el archivo o no se puede abrir")
RETURN
END IF
DO WHILE TRUE
  TRY xml.Read()
  IF xml.Eof THEN BREAK
  
  IF xml.Node.Type = XmlReaderNodeType.Element
    IF xml.Node.name = "information" 'si es este elemento que no haga nada

    ELSE

    aanombre = xml.Node.Name 'tomo el nombre del elemento
      

      FOR EACH xml.Node.Attributes
        
        SELECT CASE xml.Node.Name 'esto es muy ineficiente. Tendría que cortar cuando llega a last y pasar a otro elemento
          CASE "bid"
            aacompra = xml.Node.Value 'tomo el valor del elemento
          CASE "ask"
            aaventa = xml.Node.Value
          CASE "last"
            aaultimo = xml.Node.Value
        END SELECT


      NEXT

loteactual.nombre = aanombre
loteactual.pcompra = aacompra
loteactual.pventa = aaventa
loteactual.pultimo = aaultimo

variables.almacen.Add(loteactual)
variables.arraybusca.Add(loteactual.nombre)

      ENDIF
  ENDIF
  

  IF ERROR THEN Message.Error("no pude leer")
          
LOOP
TRY xml.Close()
IF ERROR THEN Message.Error("no pude cerrar")
rellenaxml.rellenalbox(ListBox1, "/prueba2/opciones.xml")

END


Hasta allí las partes del formulario principal.

Ahora el código de la clase lote:

PUBLIC nombre AS String
PUBLIC pcompra AS Float
PUBLIC pventa AS Float
PUBLIC pultimo AS Float

PUBLIC SUB leevalores(xmlnombre AS String, xmlpcompra AS Float, xmlpventa AS Float, xmlpultimo AS Float)
  
  nombre = xmlnombre 'aca me mete el nombre del lote
  pcompra = CFloat(xmlpcompra)
  pventa = CFloat(xmlpventa)
  pultimo = CFloat(xmlpultimo)


END

Y estas dos líneas de un módulo donde almaceno las cosas.

PUBLIC almacen AS NEW Object[]
PUBLIC arraybusca AS NEW String[]



En breve voy a poner a rodar tus ideas y postearé los resultados de la prueba.

Muchas gracias!

Saludos.
Santiago.
 



 
santijav - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Consulta Acerca De Una Matriz De Objetos: Todos Los Objetos Tienen Los Mismos Datos¿? 
 
Hola

Citar:
La principal diferencia entre tu código y el mío que veo es que instanciamos el objeto de tipo lote en distintos lugares. Vos lo hacés dentro del bucle y después de tener cada valor y yo lo hago al principio de todo... incluso antes de meterme en el bucle... Será eso el problema?

Efectivamente. Por eso te lo puse así, para que veas como lo instancio y que luego puedo incluso eliminarlo porque ya no me srive

En cuanto a las variables public yo no estoy en contra de lo que hss hecho. Seguro que te funciona, ahora bien es importante tener claros los conceptos. Por ejemplo si necesitas esas variables públicas lo que te sobra es el método porque no es necesario porque puedes asignarles valores directamente sin necesidad de ese método.

Otra alternativa es que hubieras hecho propiedades. Te explico como hacer la propiedad nombre

Lo que hacemos es crear una variable $Nombre conocida a nivel de clase y no conocida en el exterior.
Luego definimos la propiedad nombre y al darle al enter a esa línea se escribe automáticamente al final de tu clase lo siguiente
private function Nombre_Read() as string

end

private sub Nombre_Write(Value as string)

end

La procedure _Read está para cuando quieras leer el valor de la propiedad nombre allá donde sea
La función _Write está para cuando quieras asignarle un valor a la propiedad nombre.

Todo lo que tu haces es editar esto un poquito para que te quede así
private function Nombre_Read() as string
   return $nombre
end

private sub Nombre_Write(Value as string)
   $Nombre=value
end

Y ya está.
A partir de ese momento tu puedes instanciar una clase y darle valores a la propiedad
Dim L as NEW lotes
'al hacer esto se ejecuta el _write y la variable privada $nombre coge su valor
L.nombre="pepito"

'al hacer esto se ejecuta el _read y se devuelve lo que la variable privada $nombre valga.
print L.nombre


Naturalmente es el caso mas simple pero puedes complicarlo cuanto quieras. Por ejemplo tu puedes hacer una propiedad que pida un dni y que cuando se lo das compruebe si es un DNI válido. Para eso en procudure _read añadirías una función ComprobarDni

Si en vez de declarar property pones property read es una propiedad de solo lectura que te devuelve algún valor que tu clase calcula internamente. Por ejemplo yo tengo una clase que hace certificados y le paso una serie de parámetros. La clase calcula el certificado y hay una property read que devuelve ese valor calculado.

Por último decir que los valores que pasas no tienen por que ser integers o strings, etc. Puede ser cualquier cosa. Yo tengo un formulario donde el usuario va escribiendo y rellenando cosas y todo lo que hace se va metiendo en un columnview. Cuando le da a terminar yo instancio una clase y en una propiedad le doy como valor el columnview entero. La clase esa tiene una variable privada de tipo columnview y lo que hago es analizar todo ese columview y en cada caso ir haciendo lo conveniente. Solo es un ejemplo de que puedes hacer una propiedad que como parámetro tenga un columnview, un formulario, otra clase o cualquier cosa que se te pueda ocurrir.
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Consulta Acerca De Una Matriz De Objetos: Todos Los Objetos Tienen Los Mismos Datos¿? 
 
Sublime...

Hombre... me imagino que sabes programar muy bien... pero en lo que no tengo absolutamente ninguna duda es en tu pedagogía y en tu capacidad para explicar las cosas.

Simplemente... muchas gracias!
 



 
santijav - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Consulta Acerca De Una Matriz De Objetos: Todos Los Objetos Tienen Los Mismos Datos¿? 
 
Soplo,

En el código que comentaste originariamente ponías un

L.delete (volviendo al tema: tienes un objeto de clase lote, que lo has almacenado en un object[] y ahora lo eliminas)

Pues bien... yo en el objeto que creé no puse el método delete, y por defecto no lo tengo.

Qué método (función/procedure) tengo que agregar y con qué código para poder destriuir los objetos cuando ya no los uso más?

Muchas gracias!
 



 
santijav - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: Consulta Acerca De Una Matriz De Objetos: Todos Los Objetos Tienen Los Mismos Datos¿? 
 
Efectivamente delete no está para clases, solo está para objetos.
Osea que si tu haces
Dim T as NEW textbox
Luego puedes hacer T.Delete

Pero si lo que haces es
Dim T as NEW Lotes
luego no puedes hacer T.Delete porque T es una clase no un control. Eso te lo puse mal.

Esa clase se destruirá al terminar la función o procedure en la que tiene ámbito.

En cualquier caso creo que queda clara la solución a tu problema
 
 



 
última edición por soplo el Jueves, 21 Abril 2011, 05:16; editado 1 vez 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 
OcultarTemas parecidos
Tema Autor Foro Respuestas último mensaje
No hay nuevos mensajes Necesito Una Matriz En Uno De Mis Objetos cyberx0x General 2 Sabado, 07 Noviembre 2009, 17:30 Ver último mensaje
shordi
No hay nuevos mensajes Observador De Objetos aristicol Controles/Librerías/Componentes 4 Domingo, 21 Noviembre 2010, 03:25 Ver último mensaje
aristicol
No hay nuevos mensajes Objetos Drawningarea agrgal Controles/Librerías/Componentes 5 Jueves, 27 Octobre 2011, 20:51 Ver último mensaje
jguardon
No hay nuevos mensajes Se Puede Eliminar Todos Los Objetos, Textb... luisrel General 7 Miercoles, 13 Junio 2012, 20:34 Ver último mensaje
jguardon
 

Publicar nuevo tema  Responder al tema  Página 1 de 1
 

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