De esta forma no lo veo muy complicado:
Código SQL
[-]
select * from maestra
where dni in (
select dni from detalle
where modalidad in (:incluir) and
modalidad not in (:noincluir)
)
He buscado la mejor forma para programarlo (no de ejecución). Yo suelo crear un StringList que tenga "Hogar" y "Auto" y con una simple rutina QuotedList, ya tengo lo que va entre paréntesis armado como si fuera un parámetro.
Código Delphi
[-]
function QuotedList( Items: TStrings):string;
var i:integer;
begin
result := '';
for i:= 0 to Items.Count-2 do
Result := Result +QuotedStr(Items[i])+',';
if Items.count > 0 then
Result := Result + quotedstr(Items[Items.count-1]);
end;
Para armar la consulta:
Código Delphi
[-]
var st:StringList;
begin
st := stringlist.Create;
st.add('Hogar');
st.Add('Auto');
query1.parambyname('incluir').AsString := QuotedList(st);
query1.parambyname('noincluir').AsString := QuotedList(st); query1.Open;
Como la rutina QuotedList recibe un TStrings, incluso puedes usar un memo, o combobox, o Listbox para que el usuario añada las modalidades.
Vuelvo a Editar el mensaje
Esto quizás sea más cómodo:
Código Delphi
[-]
function QuotedListchklb( ctrl:TCheckListBox;const SoloChecked:Boolean = True):string;
var i:integer;
begin
result := '';
with ctrl do
for i:= 0 to Items.Count-1 do
if SoloChecked then
begin
if Checked[i] then
Result := Result +QuotedStr(Items[i])+',';
end
else
Result := Result +QuotedStr(Items[i])+',';
if Length(Result)>0 then
Delete(Result,Length(Result),1);
end;
Saludos