Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Añadir elementos sin repetir (https://www.clubdelphi.com/foros/showthread.php?t=43988)

MaMu 25-05-2007 17:57:38

Añadir elementos sin repetir
 
Hola, yo relleno un ComboBox, con elementos de una tabla, de la siguiente manera:

Código Delphi [-]
procedure TPedidos.ADOQuery2AfterOpen(DataSet: TDataSet);
var i:integer;
begin
 ComboBox2.Clear;
 for i:=0 to ADOQuery2.RecordCount-1 do
  begin
    ComboBox2.Items.Add(ADOQuery2.FieldByName('servicio').AsString);
    ADOQuery2.Next;
  end;
end;

Pero por ejemplo, tengo servicios con el mismo nombre, pero con otros valores de campo diferentes, como ser:

(CAMPOS) SERVICIO VARIABLE
(VALORES) "Limpieza" "Alfombra"
"Limpieza" "Cortina"
"Limpieza" ...etc....

Yo lo que hago es a su vez, rellenar otro ComboBox, con los valores de VARIABLE segun el SERVICIO seleccionado, y me funciona perfectamente.
Mi pregunta es la siguiente:

- Como puedo agregar elementos a un ComboBox sin que estos se repitan si son iguales??? Por ejemplo si hay un servicio "Limpieza" con 10 variables, quiero que se agregue solamente uno solo "Limpieza" puesto a que en el otro ComboBox ya estoy cargando sus variables.
El segundo ComboBox lo relleno de la siguiente manera, sin ningun problema:

Código Delphi [-]
procedure TPedidos.ComboBox2Change(Sender: TObject);
begin
 ADOQuery2.Locate('servicio',ComboBox2.Text,[loPartialKey]);
 ADOQuery8.Close;
 ADOQuery8.SQL.Clear;
 ADOQuery8.SQL.Add('select * from servicios where servicio like '''+ComboBox2.Text+'%''');
 ADOQuery8.ExecSQL;
 ADOQuery8.Open;
end;

Realmente no se como hacer para agregar un elemento sin que se repita si hay 2 o mas con el mismo nombre, estuve intentado cosas, pero por ahi me muestra la mitad, algunos los repite, otros ni los muestra.... en fin

Si alguien me puede dar una mano se lo agradecere.

Saludos y Gracias

Delphius 25-05-2007 18:07:13

Puede que diga una tontera pero:

¿En la consulta que lanzas para llenar el combo de los servicios tienes la clausura DISTINCT?

Ahora, no dices en que base de datos estás trabajando...

EDITO:
Me confunde tu código. Por lo que veo, en tu primer código lo que haces es llenar los servicios en el combobox2. Pero en el código siguiente estás consultando los servicios que concidan con el texto seleccionado de dicho combo.

A mi modo de entender, tu código dice una cosa pero tu escrito dice otra:
Cita:

Empezado por mamu
Por ejemplo si hay un servicio "Limpieza" con 10 variables, quiero que se agregue solamente uno solo "Limpieza" puesto a que en el otro ComboBox ya estoy cargando sus variables.
El segundo ComboBox lo relleno de la siguiente manera, sin ningun problema:

¿Podrías aclararme mejor? Estoy confundido...


Saludos,

Kenobi 25-05-2007 18:07:15

algo asi use en su momento...
 
hola, al menos en teoria lo que debes hacer es antes de introducir el elemento chequeando que no este y si es asi introducirlo....

yo haria una function llamada buscar en combo

Código SQL [-]
function TFrmCancelRetiroLotes.Buscar_en_combo(Elemento: string): boolean;
var
i:integer;
encontrado:boolean;
begin
encontrado:=false;
 for i:=0 to combo.Items.Count-1 do
 begin
   if Elemento = combo.Items.Item[i].Caption then
   begin
       encontrado:=true;
       break;
   end;
 end;

 Result:=encontrado;

end;

luego antes de introducir el elemento

haria algo asi

Código SQL [-]
Encontrado:=buscar_en_Combo(TEdit.text);
if not Encontrado then 
begin
//aca el codigo para introducir el elemento eso ya lo tienes ......
end;


Espero que te sirva....

Saludos....

Robert01 25-05-2007 18:11:02

Hola

Si no me equivoco este anda perfectamente es para dos listbox, no debería haber problemas en aplicarlo a un combobox.

Código Delphi [-]
procedure TAnalisisCls.Lista1Click(Sender: TObject);

var
   index, i : integer;
begin
     index := Lista1.Items.Count;
     i := 0;
     while i < index do
     begin
         if (ListaPob1.Selected[i]) then
         begin
            Lista2.Items.Add(Lista1.Items.Strings[i]);
            Lista1.Items.Delete(i);
            index := index - 1;
            i := 0;
         end
         else i := i + 1;
     end;
  end;

procedure TAnalisisCls.Lista2Click(Sender: TObject);
   var
     index: integer;
   begin
     index := Lista2.ItemIndex;
     Lista1.Items.Add(Lista2.Items.Strings[index]);
     Lista2.Items.Delete(index);
     //InBtn.Enabled := true;
     //if Lista2.Items.Count = 0 then OutBtn.Enabled := false;
   end;
Saludos

MaMu 25-05-2007 18:24:01

Cita:

Empezado por Delphius
¿Podrías aclararme mejor? Estoy confundido...
Saludos,

Si, por ahi me explaye demaciado, lo que quiero saber simplemente, es como agregar elementos a un ComboBox sin que se repitan, osea que si dos elementos tienen el mismo nombre, solo agregue uno de ellos.

Saludos

Delphius 25-05-2007 18:34:52

Pues como te dije, en la consulta deberías poner la clausura DISTINCT. Con esto no devolvería los repetidos.

Tan solo deberías hacer:

Código Delphi [-]
ComboBox2.Items.Add(ADOQuery2.FieldByName('servicio').AsString);

un SQL como esto:

Código SQL [-]
SELECT DISTINCT nombre_servicio
FROM servicios

Saludos,


jhonny 25-05-2007 18:36:04

Yo lo haría asi, asumiendo que Edit1 es el componente que usaras para introducir datos a ese ComboBox1:
Código Delphi [-]
 
if ComboBox1.Items.IndexOf(Edit1.text) <> -1 then //IndexOf devuelve la posición en la que se encuentra el parámetro que se paso, y si no existe pues devuelve -1
begin
  //Introduces el codigo correspondiente...
end;

jhonny 25-05-2007 18:40:34

Esto me pasa por no leer bien la cuestión y andar de nuevo con mis prisas, si sigue el consejo de Delphius sera mas eficiente pues el sql traerá los datos sin repetirlos...

Mi ejemplo te sirve por ejemplo, en caso de que estuvieras alimentando los datos desde un Edit o algo por el estilo.

MaMu 25-05-2007 18:41:05

Cita:

Empezado por Delphius
Pues como te dije, en la consulta deberías poner la clausura DISTINCT. Con esto no devolvería los repetidos.

Tan solo deberías hacer:


Código Delphi [-]ComboBox2.Items.Add(ADOQuery2.FieldByName('servicio').AsString);



un SQL como esto:


Código SQL [-]SELECT DISTINCT nombre_servicio
FROM servicios




Saludos,


Asi fue como hice:

Código Delphi [-]
select distinct servicios.servicio from servicios

pero me salta: List Index out of bounds(3)

Saludos

MaMu 25-05-2007 19:00:45

SOLUCIONADO


Lo solucioné, el error estaba en la sintaxis SQL, ya que justamemte en la tabla servicios, tenia dos campos, uno servicio y el otro servicios, y los consulte invertidos, eso era todo. Por las demas respuestas estan muy buenas y me son de mucha utilidad, ya que no siempre relleno con datos de una base de datos. Archivado.

Saludos y Gracias

Robert01 25-05-2007 19:20:32

Hola

No me di cuenta que estabas trabajando con bases de datos, disculpame por enviar código que no es lo que necesitabas.
Me alegra que hayas solucionado el problema.

Saludos

ciskokkid 21-10-2015 17:58:18

otra forma de llenar el combobox a partir de un clientdataset
 
no quiero decir que las formas anteriores de solucionarlo no son validas, solo quiero aportar una forma diferente de hacerlo,
llegue hasta aqui buscando como llenar un combobox desde un clientdataset, no me apetece hacer otra consulta sql con distinct porque estoy partiendo del hecho que ya tengo la informacion en un clientdataset, solo quiero que el combobox coincida con la informacion del clientdataset que estoy mostrando en un grid

este es mi codigo
Código Delphi [-]


begin
   // hago la consulta ,  el clientdataset obtiene la informacion del query a traves de un datasetprovider
   adoquery1.Close;
   adoquery1.SQL.Text:='select c.sucursal, c.id, c.mov, c.movid, c.fechaemision ' +
                       ' , c.proveedor,prov.nombre , c.usuario,  c.referencia, ' +
                       ' c.importe, c.moneda, c.tipocambio, c.condicion,  c.autorizacion' +
                       ' from compra c ' +
                       ' join prov on prov.proveedor=c.proveedor ' +
                       ' where c.mov='      + quotedstr('ECN') +
                       ' and c.estatus='    + quotedstr('SINAFECTAR') +
                       ' order by c.sucursal,c.proveedor';
   adoquery1.Prepared:=true;
   adoquery1.Open;

   // ahora limpio el combobox, recorro el clientdataset y simplemente voy comprobando si el valor "usuario"
   // no esta en el combo lo agrego

   cbUsuario.clear;
   cbUsuario.Items.Add('TODOS');              // este sera el primer valor
   clientdataset1.First;
   while not clientdataset1.Eof do
   begin
       if cbUsuario.items.indexOf(clientdataset1.FieldByName('usuario').AsString)<=0 then
          cbUsuario.Items.Add(clientdataset1.fieldByName('usuario').asstring);
       clientdataset1.Next;
   end;
   cbUsuario.ItemIndex:=0;                          // para que  por default ponga  por defecto el primer valor
   cbUsuario.style:=csDropDownList;             //  para que el usuario no agregue mas valores al combo

end

la informacon consultada son pocos registros, no mas de 50, de esta manera evito enviar otra consulta por separada al servidor sql

AgustinOrtu 21-10-2015 21:17:40

Para que pones a Prepared := True el query?
Otra cosa, TStrings ya implementa esta funcionalidad, y es configurable mediante las propiedades Duplicates y CaseSensitive

Por otro lado la solucion es apta para cualquier TStrings, el ComboBox tiene poco que ver aca


La franja horaria es GMT +2. Ahora son las 08:02:18.

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