FastReport a dialog

vložil Radek Červinka 3. května 2017 00:09

Mám rád FastReport. Už jsem se mu zde několikrát věnoval, např. jak využít FastScript. Ale až nedávno jsem začal používat ve skriptech dialog.

K čemu je to dobré? Umožňuje mi to flexibilněji reagovat na specifické požadavky uživatelů bez úprav hlavního programu. Lehkou úpravou FastReportu mám zabezpečeno streamování reportů z a do databáze (pořád se držím teze, že na data jsou databáze a kromě ini tam patří v rámci možností vše). To mi umožňuje lehce přidat libovolný report a okamžitě ho uživatel může začít používat. Navíc dialog uložený v reportu rozšíří základní funkcionalitu.

Dialog a FastReport

Například na obrázku dialog reprezentující filtr. Jednotlivé komponenty jsou převážně TfrxDBLookupComboBox, která jednoduše přiřadím datasetům definovaným ve FastReportu na záložce Data a pak jen stačí nastavit property KeyField a ListField.

Červený flek na tlačítku OK značí navěšenou událost. Dialog se zobrazí po spuštění skriptu a po stisku OK modifikuje SQL příkaz hlavního datasetu.

Obsluha pak vypadá nějak takto:

procedure btnOkOnClick(Sender: TfrxComponent);
var
  sSql, sFilter: string;                              
begin
  sSql := qData.SQL.Text;
  sFilter := '';                              
  if VarToStr(cmbRezivo.KeyValue) <> '' then
    sFilter := sFilter + ' P.flMaterial = '+IntToStr(cmbRezivo.KeyValue) + ' AND ';

  if edtheight.Text <> '' then
    sFilter := sFilter + 'P.dlHeight ='+edtheight.Text + ' AND  ';                                                                                      

  if VarToStr(cmbPaketStore.KeyValue) <> '' then
    sFilter := sFilter + ' P.flPaketStore = '+IntToStr(cmbPaketStore.KeyValue) + ' AND ';

  if VarToStr(cmbProducer.KeyValue) <> '' then
    sFilter := sFilter + ' PO.flProducer = '+IntToStr(cmbProducer.KeyValue) + ' AND ';

…                                                                                 
      
  if sFilter <> '' then
  begin
    sSql := StringReplace(sSql, 'WHERE', ' WHERE ' + sFilter);
    qData.SQL.Text := sSql;                                                          
  end;              

end;

Jen upozorňuji, že v SQL je část WHERE, kterou jen rozšířím za jinou WHERE. Problém je, že starší verze FastReportu neměla StringReplace, takže google mi našel něco takového (upraveno):

function StringReplace(const S, OldPattern, NewPattern: string;
  iReplaceAll: boolean=true; iIgnoreCase :boolean=true): string;
var
  SearchStr, Patt, NewStr: string;
  Offset: Integer;
begin
  if iIgnoreCase then begin
    SearchStr := UpperCase(S);
    Patt := UpperCase(OldPattern);
  end else begin
    SearchStr := S;
    Patt := OldPattern;
  end;
  NewStr := S;
  Result := '';
  while SearchStr <> '' do begin
    Offset := Pos(Patt, SearchStr);
    if Offset = 0 then begin
      Result := Result + NewStr;
      Break;
    end;
    Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern;
    NewStr := Copy(NewStr, Offset + Length(OldPattern), 1000000);
    if not iReplaceAll then begin
      Result := Result + NewStr;
      Break;
    end;
    SearchStr := Copy(SearchStr, Offset + Length(Patt), 1000000);
  end;
end;  

Celý kód je psán v integrovaném FastScriptu a je součástí reportu.

Založení dialogu

Dialog a FastReport

Podle obrázku, jednoduše přes kontextové menu přidáte nový dialog. Nezapomeňte u tlačítka nastavit ModalResult, nebo si jinak zajistěte zavření vašeho dialogu.

Následně máte k dispozici základní komponenty podobně jako ve VCL a můžete normálně programovat.

Tagy: ,

Praxe

Komentáře

11.5.2017 13:25:48 #

Karel Rys

Díky za hezký článek. Upozornil bych jen na jeden potenciální problém - pokud je v SQL použit subselect, tak StringReplace nahradí WHERE i v něm, což je většinou špatně.

Karel Rys

14.5.2017 18:24:44 #

Peca

Ano, jde to, ale dle mne je lepší se takovýmto praktikám vyhnout.
- Dodatečná konstrukce selectu může být časem nevalidní (změní se tabulka, sloupec bude odstraněn..) a v případě např. 100 reportů může být problém dohledat postižené.
- Různé DB stroje mohou mít různou syntaxi SQL příkazu
- Konstrukce sql podmínky nepoužívá parametry a tedy může být méně efektivní, ale hlavně skoro vybízí k nějakému SQL injection. A to jak neoprávněné získání dat rozšířením podmínky, tak i použití destruktivních DML či DDL příkazů.

Peca

15.5.2017 11:01:42 #

radekc

Ad Peca - slo mi primarně o dialog, který se dá použít pro libovolné věci - SQL byl jen případ, ale i tak si myslím, že hledáš problém v detailech.

Ad neefektivnost bez parametrů - to podle mne je nepodstatné, jelikož se SQL provede jednou. Ad SQL injection: pokud je použit combobox,  tak to nehrozi, v ostatních případech se to musí řešit fakt opatrně. Uživatel nemá sám možnost editovat SQL.

radekc

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců