Me parece que te estás liando demasiado debido a que piensas que hay que tratar muchos casos pero en realidad no es así.
Al construir la consulta SQL tienes que fijarte cómo contribuye cada combo a la condición
where. Cada combo puede contribuir de
dos maneras, no 4, ni 5 ni 7, sólo dos:
- nada - si comboN.text = 'todos'
- campoN = comboN.text - si comboN.text <> 'todos'
Es decir, si un combo tiene 'todos' por texto,
no contribuye a la consulta pues quiere decir que no impones ninguna condición sobre él.
Esto implica cuatro condicionales- uno tras otro.
La construcción del condicional
where (es decir, las sentencias
después de
where) es un poco enredada debido a que las condiciones de los distintos combos deben estar unidas por un conector
and y por cada combo debes fijarte si realmente hay necesidad de poner
and:
Código Delphi
[-]
if whereStr = '' then begin
if comboN.text <> 'todos' then
whereStr := 'campoN = ' + QuotedStr(comboN.text);
end
else
if comboN.text <> 'todos' then
whereStr := whereStr + ' and ' + QuotedStr(comboN.text);
y necesitarás uno de estos bloques por cada combo. Con esto sería más que suficiente pero como a mi me da flojera leer este tipo de código te lo voy a complicar un poco:
Código Delphi
[-]
if whereStr = '' then begin
if comboN.text <> 'todos' then
whereStr := 'campoN = ' + QuotedStr(comboN.text)
else
whereStr := '1 = 1';
end
else if comboN.text <> 'todos' then
whereStr := whereStr + ' and ' + QuotedStr(comboN.text)
else
whereStr := whereStr + ' and ' + '1 = 1';
La extraña condición '1 = 1' es una condición que
siempre se cumple por lo que el efecto es el mismo: no imponer condición alguna sobre el campo.
En principio parece una complicación innecesaria (y quizá lo sea) pero el hecho de que cada combo
siempre contribuya con algo me permite simplificar la lógica de cuándo agregar el
and pues sé de fijo que lo agrego después del primer, segundo y tercer combo quedando así ya con todos los combos:
Código Delphi
[-]
if combo1.text <> 'todos' then
whereStr := 'campo1 = ' + QuotedStr(combo1.text)
else
whereStr := '1 = 1';
if combo2.text <> 'todos' then
whereStr := whereStr + 'and ' + 'campo2 = ' + QuotedStr(combo2.text)
else
whereStr := whereStr + 'and ' + '1 = 1';
if combo3.text <> 'todos' then
whereStr := whereStr + 'and ' + 'campo3 = ' + QuotedStr(combo3.text)
else
whereStr := whereStr + 'and ' + '1 = 1';
if combo4.text <> 'todos' then
whereStr := 'campo4 = ' + QuotedStr(combo4.text)
else
whereStr := whereStr + 'and ' + '1 = 1';
Pero más aún, como los cuatro condicionales son
esencialmente iguales podemos definir una función:
Código Delphi
[-]
function CondicionCampo(Campo, Valor: String): String;
begin
if Valor = 'todos'
then Result := '1 = 1'
else Result := Campo + ' = ' + QuotedStr(Valor);
end;
que los construya genéricamente con lo cual reducimos el código a:
Código Delphi
[-]
whereStr := CondicionCampo('campo1', combo1.text);
whereStr := whereStr + ' and ' + CondicionCampo('campo2', combo2.text);
whereStr := whereStr + ' and ' + CondicionCampo('campo3', combo3.text);
whereStr := whereStr + ' and ' + CondicionCampo('campo4', combo4.text);
Y listo. Ya sólo tienes que agregar esto al resto de la cadena SQL, por ejemplo:
Código Delphi
[-]
Query.Sql.Text := 'select * from tabla where ' + whereStr;
Yo colocaría esto en un evento OnChange común a los cuatro combos.
// Saludos