Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-07-2006
patorecalde patorecalde is offline
Miembro
 
Registrado: jul 2006
Posts: 35
Poder: 0
patorecalde Va por buen camino
Cual es la mejor manera de cargar Objetos?

Hola a todos los integrantes de este foro, les cuento que este es mi primer mensaje y es que tengo una duda para mi importante, y la respuesta a la misma es para sentar una base en cuanto a la programcion de mis proyectos de ahora en adelante.
Desde ya hace dos meses trabajo con Clases, antes no lo hacia y la verdad es mas proligo, antes era todo muy confuso en fin no tengo mucha experiencia.
Vamos al problema: Tengo una clase Tprovincia en donde tengo

Id :Codigo de Provincia
Descripcion:Nombre de la Provincia
Habitantes:Cantidad de Habitantes
Superficie:Superficie en km2
Localidades :Cantidad de localodades

en fin no muchas mas propiedades que esas , lo que hago es lo siguiente en un Form dispongo un Combobox y en el quiero cargar las provincias (Descripcion) y cada vez que selecciono una provincia en cuadros de texto TEdit situados debajo del Combo mostrar los datos correspondientes a cada provincia.

Las provincias las cargo a mano es decir Item por Item(en tiempo de diseño) y luego hago una consulta al sql por el nombre de la provincia y traigo los datos.(Trabajo con Delphi 5 y sqlserver 7)para luego cargarlos en los Edit.

Esto funciona bien pero...
1) Para que tengo entonces la clase si no la uso.
2)Cade vez que cambio de provincia consulto al motor e insume mucho tiempo y muchas idas y vueltas al motor.

Lo que quiero hacer es crear todos los objetos de una sola vez y almacenarlos en alguna estructura ya sea del combobox u otra, y luego poder recuperar la informacion sin acceder al motor, es por eso que acudo a uds a que me orienten un poco y me digan cual es la mejor forma o tecnica de hacer esto , como lo hacen ustedes o lo harian Uds.
Como crear objetos lo tengo claro pero he creado de a uno y los quiero crear todos juntos.
He oido de listas, colecciones y otras cosas mas pero desconosco como se usan y cuales son sus beneficios o defectos.

Espero haberme explicado bien y si no lo hago de vuelta ya que esto me va a ser de mucha ayuda de aqui en adelante, por que es la base para aprender a utilizr objetos.

Muchas Gracias.
Responder Con Cita
  #2  
Antiguo 08-07-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
Lo que hablas de obviar consultar al motor, es casi imposible. No comentas si estas en modo monousuario o multiusuaio, pero de todas formas, si das de alta una provincia, tendrás que actualizar tu clase TProvincia y despues cargar de nuevo los elementos del combo.

Si el motor tarda mucho, primero tendremos que hablar de Segundos o milisegundos, es decir, en hacer una tarea en cuestión ¿cuanto tarda?.

También habría que ver el diseño de la BBDD, los índices creados y lo que más se consulta en esa BBDD para crear índices Ascendentes o Descendentes.

Al actualizar controles visuales ¿haces un DisableControls / EnableControls? o bién un BeginUpdate / EndUpdate, ahí suele estar los cuellos de botella de los controles.

No conozco sqlServer, así que no puedo darte mucha información, pero si debe tener como mínimo Triggers (disparadores), Store Procedures (procedimientos almacenados) y si tiene Events (Eventos del propio motor de BBDD) pues tienes todo lo necesario para que se ocupe el motor de todas las tareas.

¿Por qué se debe encargar el motor? Porque tus clases no tienen índices, las búsquedas en tu "lista de objetos" serán secuenciales, o como mucho basado en caracteres de texto; El motor de BBDD tiene los índices precisamente para acelerar las búsquedas. Explotando las capacidades nombradas en el párrafo anterior, todo se ejecuta en el servidor y por la red solo viaja los datos mínimos y necesarios.

Yo al menos lo de las provincias lo haría así:
- Sin complicarme la vida: Una tabla de provincias con un autoincremento de clave principal, un índice sobre el campo NombreProvincia de forma ascendente. Tenemos 2 alternativas:
  1. Un TDBLookUpCombo para seleccionar una Provincia, con la consabida circunstancia de que el usuario no puede escribir en ese combo (realmente puede escribir, pero no es intuitivo, para ello estoy usando el TDBLookUp de las JVCL).
  2. Un TComboBox donde al crear el form, lanzo una consulta la tabla (SELECT DISTINCT nombreProvincias from provincias order by NombreProvincias Asc) y despues paso todos los registros al combo. Esto es pesado y con 5000 provincias ya se nota al abrir el Form.

    En ambos casos creo un Evento en el motor de la BBDD 'Provincia_Modificadas', y en los Triggers de la tabla Provincias: After Update, After Delete, After Insert, lanzo el evento. El form que tiene el combo registra ese evento para que pueda ser recibido, de tal forma que al realizar una modificación sobre la tabla Provincias, el propio motor informa al programa que ha habido un cambio y en ese caso:
    - Si he usado un TDBLookUpCombo, cierro el origen de datos y la vuelvo a abrir (para que se refresque con las nuevas provincias).
    - Si he usado un TComboBox, vuelvo a lanzar la consulta al servidor.

Si creas un TObjectList (busca en el foro) para tener una lista de Objetos Provincias, en caso de insertar una nueva provincia tienes que:
- Solicitar las provincias al motor
- Actualizar tu Lista de Provincias
- Actualizar el TComboBox

Yo prefiero:
- Realizar una consulta al servidor
- Actualizar mi Combo.

Seguro que este tema da mucho que hablar, estaré encantado de oir otras alternativas / técnicas .

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #3  
Antiguo 08-07-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
Se me olvidaba un detalle:

En el caso de no usar controles data-aware, si he implementado la opción de Listas de Objetos solicitando los datos a la BBDD, en este caso me he sentido "muy libre" ya que podía hacer lo que se me antojase, sin estar atado a mostrar la información en un DBGrid, sino por ejemplo, en un TVirtualStringTree mostrando la información de una forma muy actual, elegante, simple para el usuario y eficiente con los datos.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #4  
Antiguo 10-07-2006
patorecalde patorecalde is offline
Miembro
 
Registrado: jul 2006
Posts: 35
Poder: 0
patorecalde Va por buen camino
Wink Entender para aprender y no ser reiterativo.

Lepe:
Muchas gracias por tu tiempo y tu respuesta me ha sido de mucha ayuda y he aprendido muchas cosas, tambien te cuento que despues de probar tus alternativas me he quedado con el TComboBox, tambien he investigado y buscado por el foro y me he topado con que en los Items del combo puedo cargar las decripcion de las provincias y un puntero a los objetos con la funcion AddOject pero no entendi como trabaja? y si no entiendo voy tener que recurrir al foro en cuanto deje las provincias de lado y empiece con otro tema como pueden ser las Localidades, es por eso me gustaria si puede aclararme si no es un tema muy complejo como es que trabaja esta funcion y como hago luego para obtener los datos de determinado objeto(Provincia).
Gracias de nuevo, Saludos.
Responder Con Cita
  #5  
Antiguo 11-07-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
Con un poco de código lo verás más claro.

Normalmente querás crear los objetos y añadir los items a mostrar en el combo:
Código Delphi [-]
type TProvincia = class (TObject)
  public
     property Provincia:String read GetProvincia write SetProvincia;
end;


procedure TForm1.AddItems;
var p :TProvincia;
begin
 query1.sql.text := ' select distinct nombreProvincia from Provincias;';
 query1.Open;
 while not query1.eof do // para cada registro
 begin
   p := Tprovincia.Create; // creo en memoria mi objeto
   p.Provincia := query1.Fields[0].AsString;
   Combo1.AddObject(p.Provincia, p); // Añado el Nombre de la Provincia
//                                                 al combo y lo asocio con su objeto
   query1.next;
 end;
end; // AddItems

Si te fijas, no libero los objetos, ya que, como bien has dicho, solo se guarda un puntero, por tanto, el objeto debe existir en memoria mientras queramos acceder a él.

Tambien verás que siempre uso la misma variable "p" para crear los objetos; esto no es problema, ya que al decir "p := Tprovincia.Create" siempre se reserva memoria nueva para la variable "p" en cada iteración del bucle, así que no machacamos objetos en memoria. Cada Objeto creado estará en RAM, y la única forma de acceder a él, es mediante el ComboBox.
Código Delphi [-]
Function TForm1.ConseguirObjetoAsociado:TProvincia;
begin
  Result := nil; // en caso de error devolvemos un puntero nulo.
  if Combobox.ItemIndex = -1 then Exit; 
// No hay seleccionado ningún elemento en el combo,
// se devuelve el puntero nulo y salimos de la función

  Result := TProvincia(Combobox1.Objects[Combobox1.Itemindex]);
end;

Como norma general, si una funcion devuelve un objeto (que en realidad devuelve un puntero a ese objeto), se debe asignar un puntero nulo en caso de fallos. Obviamente cuando se use esta función, siempre se deberá tener en cuenta:
Código Delphi [-]
var x:Tprovincia;
x := ConseguirObjetoAsociado;
if  x <> nil then
  ShowMessage(x.Provincia)
else
  ShowMessage('no se ha encontrado el objeto. No puedo usar la variable X  porque daría un Access Violation');

Despues de este paréntesis, sigo explicando la funcioncita.
Cada Item del Combobox tiene asociado su propio objeto, por tanto, podemos usar el ItemIndex del Combo para acceder a ese objeto.

Se debe hacer un moldeo de Tipos "TProvincia (.....)" porque el combo acepta un TObject o una clase que derive de TObject. Nosotros, que lo hemos programado, sabemos que hemos introducido con AddObject un tipo de datos TProvincia, pues debemos decir al compilador que lo trate como tal, para que podamos acceder a todas las propiedades que tiene dicha Clase.

Por último nos queda un detalle: Liberar los objetos.
Código Delphi [-]
procedure Tform1.VaciarComboYObjetos;
var i:integer;
begin
  for i:=0 to Combobox.Items.count-1 do
     TProvincia(combobox.Objects[i]).Free; // libero cada Objeto de la RAM

  Combobox.Items.Clear;
end;
Despues de vaciar el combo, cualquier intento de acceder a los objetos nos dará un Access Violation. Normalmente se llama antes de liberar el Form de memoria.

Podría parecer que con solo hacer un "comboBox.Items.Clear" se debería destruir los objetos, pero lamentablemente delphi no sabe como tratar el objeto concreto que nosotros hemos añadido.

Saludos y espero se entienda.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #6  
Antiguo 11-07-2006
patorecalde patorecalde is offline
Miembro
 
Registrado: jul 2006
Posts: 35
Poder: 0
patorecalde Va por buen camino
Wink Probado y testeado .... Todo muy bien

Pero como no voy a entender, es una explicacion maravillosa y acompañada de codigo me fue de mucha utilidad y esta vez entiendo el por que de cada cosa, que es mi idea.
Ahora yo digo de usar esto cuando se trate de poca cantidad de objetos no es asi? es decir 100 o 150 objetos y depende de el tamaño de los objetos? por que si de repente quiero hacer esto con clientes y mi base tiene 50000 clientes voy a necesitar 1gb de memoria y no es ese el caso verdad?, ahora si tendre que consultar la base cuando quiera los datos de determinado objeto(supongamos un cliente) o existe alguna otra tecnica o forma de encarar los proyectos cuando existe una cantidad de datos muy grande?

Gracias y un fuerte abrazo a toda la gente de este club, que la verdad esto es grandioso.
Responder Con Cita
  #7  
Antiguo 11-07-2006
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.043
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por patorecalde
Pero como no voy a entender, es una explicacion maravillosa y acompañada de codigo me fue de mucha utilidad y esta vez entiendo el por que de cada cosa, que es mi idea.
Ahora yo digo de usar esto cuando se trate de poca cantidad de objetos no es asi? es decir 100 o 150 objetos y depende de el tamaño de los objetos? por que si de repente quiero hacer esto con clientes y mi base tiene 50000 clientes voy a necesitar 1gb de memoria y no es ese el caso verdad?, ahora si tendre que consultar la base cuando quiera los datos de determinado objeto(supongamos un cliente) o existe alguna otra tecnica o forma de encarar los proyectos cuando existe una cantidad de datos muy grande?

Gracias y un fuerte abrazo a toda la gente de este club, que la verdad esto es grandioso.
Las personas que hay aquí son las que lo hace grandioso.

Responder Con Cita
  #8  
Antiguo 19-07-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
No es que me haya olvidado de este hilo, es que mis programas son para pymes y jamás he tenido 50.000 clientes con movimientos.

Lamento no poder ofrecer más ayuda, sólamente la que hay en los foros:
Datawares o no datawares
ECO o Bold for delphi
Ayuda de ECO

Realmente no sé si es lo que necesitas, pero algunas pistas no vienen mal.

Saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Cual es el mejor acceso a FireBird/InterBase?; cuanto mejor?? Combat-F2D Firebird e Interbase 9 22-06-2006 18:32:36
La mejor manera de hacer reportes con Qreport Coco_jac Impresión 6 29-04-2006 11:49:09
Cual es la manera mas rapida para copiar registros ilichhernandez Conexión con bases de datos 2 02-11-2005 02:00:57
La mejor manera de Trabajar con Form manuelpr Varios 8 07-03-2005 17:08:14
Cual es la mejor manera para darle formato a un numero ctronx Varios 4 21-07-2004 19:27:33


La franja horaria es GMT +2. Ahora son las 09:26:07.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi