Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   funcion genérica para cargar combos (https://www.clubdelphi.com/foros/showthread.php?t=42205)

Byfed 07-04-2007 13:20:19

funcion genérica para cargar combos
 
Hola a todos de nuevo,

Como ya comenté en otro post, suelo diseñar las aplicaciones haciendo que cada opción del programa active el frame que corresponda. Al seleccionar la opción del menú, se llama al procedimiento init, que siempre pongo en todos los frames. Este procedimiento se encarga de limpiar los formularios si es preciso, cargar los combos que pueda haber y por último, de mostrar el formulario.

Para cargar los combos (con datos de una tabla mysql) suelo hacer lo siguiente:

he declarado una variable en private como

valores: array of integer;

y para cargar el combo hago:

Código:

procedure TFrame.Cargar_valores();
var
  sSql: String;
  SoloQuery : TQuery;
  i: integer;
begin
  Ssql := 'Select * from tabla';
  SoloQuery := TQuery.Create(nil);
  SoloQuery.DatabaseName := 'basededatos';
  SoloQuery.SessionName := 'session';
  SoloQuery.SQL.Clear;
  SoloQuery.SQL.Add(sSql);
  SoloQuery.ExecSQL;
  SoloQuery.Active := True;
  SoloQuery.Open;

  Combobox.ClearSelection;
  Combobox.Items.Clear;
  Combobox.Text := 'Selecciona valor';
  Combobox.ItemIndex := Combobox.Items.Count - 1;
  SetLength(valores, 0);
  while (not SoloQuery.EOF) do
  begin
      Combobox.Items.Add(SoloQuery.FieldByName('texto').AsString);
      i := Length(valores);
      SetLength(valores, i + 1);
      Valores[i] := SoloQuery.FieldByName('valor').AsInteger;
      SoloQuery.Next;
  end;
  SoloQuery.Close;
  SoloQuery.Destroy;
end;

Esto lo hago por cada combo que tenga que cargar y en ocasiones son unos cuantos. Para cada combo hago un procedimiento. Lo que estoy buscando es la forma de crear UN SOLO PROCEDIMIENTO GENERAL para cargar los distintos combos, pasándole como parámetros los datos del combo que se trate cada vez. Las llamadas serían del estilo:

cargarCombo(NombreCombo, ArrayValores, Tabla, CampoTexto, CampoValor)

He intentado hacerlo, pero cometo algún error al pasar el array. Imagino que el problema estará en que paso el array por valor y se debe pasar por referencia. No estoy seguro. También he intentado hacerlo con una función y que la llamada fuera así:

ArrayValores := CargarCombo(NombreCombo,Tabla, CampoTexto, CampoValor)

Pero no puedo definir la función para que devuelva un array de enteros.

¿A Alguien se le ocurre cómo podría realizar esta tarea? Me ahorraría muchas horas de tecleo.

Gracias y un saludo.

droguerman 07-04-2007 15:02:40

una forma para hacerlo con valores de tipo integer y un combo;
Código Delphi [-]
var
  Dataset : TDataset;
begin
   //aqui inicializamos el dataset
       ....
       ....
       ....
  //empezamos el llenado del combo
   combo.items.clear;
   with Dataset do
     while not eof do
     begin
         combo.items.add(fieldByName('nombre').asString);
         //uso la propiedad objects para almacenar el número
         combo.items.objects[combo.items.count-1] := 
                     Pointer(fieldByName('id').asInteger);
         next;
     end;
end;
cuando quieras recuperar el entero de la posicion 2 haces lo siguiente
Código Delphi [-]
x:= Integer(combo.items.objects[2]);

Por cierto no necesariamente tiene que ser un TComboBox, cualquier derivado de TStrings (por ejemplo TStringList) tiene la propiedad objects.


para valores de otro tipo creas un TList (no confundir con ListBox) y haces que los objects apunten a los items del TList

Lepe 07-04-2007 16:46:52

La idea de droguerman se puede simplificar un poquito:
Código Delphi [-]
     combo.items.addObject(fieldByName('nombre').asString,
                             Pointer(fieldByName('id').asInteger);
         //uso la propiedad objects para almacenar el número
         next;

Saludos

CrazySoft 07-04-2007 20:17:22

Hola, una duda, como podria recuperar una cadena, en lugar de un entero

Código Delphi [-]
    combo.items.addObject(fieldByName('nombre').asString,
                             Pointer(fieldByName('id').asString);

recuperar el valor de id

Código Delphi [-]
var x:String;

x:= combo.items.objects[combo.itemindex]);
Gracias

droguerman 07-04-2007 21:20:43

Cita:

Empezado por CrazySoft
Hola, una duda, como podria recuperar una cadena, en lugar de un entero

en ese caso se usa otro stringList o tambien un TList, puesto que la propiedad objects es un arreglo de punteros, pero tambien puede funcionar un array de variants donde objects mantendría los indices, me faltaba comentar que el problema en el ejemplo de Byfed es que el pasa el array por valor es por ello que la función que él hace no guarda los valores de la tabla.

Byfed 07-04-2007 23:08:39

Gracias, Doguerman,

Me ha venido de perlas tu explicación. También agradezco el resto de aportaciones desde luego. Desconocía la propiedad objects y que se lo podía dar este uso. Ahora ya tengo hecha una función "genérica", que pasandole el nombre de la tabla, el campo que quiero almacenar y el campo que quiero mostrar en el combo, me permite cargar un combo. Esto me va a ahorrar mucho trabajo. Gracias de nuevo.

En todo caso, y ya solo por curiosidad, pregunto:

Si tu tienes una variable global en un unit, pongamos un array de enteros y quieres hacer una función que haga alguna cosa con ellos ¿cómo se ha de pasar el parámetro?. Para ser más específicos. Imaginemos que tengo una variable que es un array de enteros [1,2 y 3] y quiero hacer una función que multiplique ese array por dos (evidentemente, y que los datos permanezcan almacenados en dicho array).

Código:

miarray: array[0..2] of integer = (1,2,3);

duplicar_array(miarray)

Lo que me pregunto es si después de ejecutar en el código anterior duplicar_array, imprimo los valores del array, van a seguir siendo 1 2 y 3, porque al llamar a la función, se hace una copia local y luego se destruye. ¿Cómo se evita esto?..

Gracias de nuevo y un saludo.

CrazySoft 08-04-2007 00:31:29

Cuando se tiene que optener un resultado de tipo string y se tiene el combobox ordenado, se debe relacionar el combobox con el StringList para recuperar los datos de lista


Código Delphi [-]
//Cargado de datos al combo y a list
var
   Lista := TStrings;
   Aux:String;
   i:Integer;
begin
    Lista := TStringList.Create;
    i:=0;
    with table1 do
    while not eof do
    begin
    Lista.Add(fieldByName('city').asString);
    combo.items.addObject(fieldByName('company').asString,
                                 Pointer(i));
             inc(i);
             next;
    end;
end;
// recuperacion de los datos
 
aux := Lista[Integer(combo.items.objects[combo.ItemIndex]];

Gracias

Lepe 08-04-2007 01:14:36

para el tema de arrays, mira aqui

Usa High(nombreArray) y Low(nombreArray) para saber los índices superior e inferior respectivamente.

Saludos


La franja horaria es GMT +2. Ahora son las 06:30:14.

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