FastReport Tipps und Tricks: Formatierung: Unterschied zwischen den Versionen
(→Formatieren in einem Textfeld) |
|||
Zeile 277: | Zeile 277: | ||
* Siehe auch [[FastReport_Tipps_und_Tricks#Zahlenwert_in_Text_umwandeln]] | * Siehe auch [[FastReport_Tipps_und_Tricks#Zahlenwert_in_Text_umwandeln]] | ||
+ | |||
+ | Wenn es in einem Textfeld (Memo) mehrere eingebettete Felder gibt, kann man mit der rechten Maustaste - Anzeigeformat das gewünschte Feld auswählen... | ||
+ | |||
+ | [[Datei:FastReport_Formatieren_Uhrzeit.png]] | ||
+ | |||
+ | ...und formatieren. In diesem Beispiel wird die Uhrzeit formatiert. | ||
=== Monats-Namen aus Monats-Zahl === | === Monats-Namen aus Monats-Zahl === |
Version vom 4. Februar 2019, 23:04 Uhr
Inhaltsverzeichnis
- 1 Formatierung
- 1.1 Schrift-Farbe von Felder abhängig von der Fremdmenge
- 1.2 Farbe eines Bandes abwechselnd grau/weiß
- 1.3 Gruppenkopf auf letzter Seite unterdrücken, wenn keine Daten mehr kommen
- 1.4 Report mit Sub-Detail-Band wird abgebrochen, wenn es keine Sub-Daten gibt
- 1.5 Unterschiedliche Schriftarten in Auftrags-/Rechnungspositions-Texten
- 1.6 Rahmen per Code setzen
- 1.7 Positionsangaben im Code
- 1.8 Top-Position im Code ändern
- 1.9 Feld reagiert nicht auf Änderung der Schriftgröße
- 1.10 Zahlen und Datum formatieren
- 1.11 Monats-Namen aus Monats-Zahl
- 1.12 Text in Großbuchstaben
- 1.13 Schriftattribute (Fett, unterstreichen ) in Feldern
- 2 Konstanten im Code
- 3 Links
1 Formatierung
1.1 Schrift-Farbe von Felder abhängig von der Fremdmenge
Wenn man die Schrift-Farbe von Felder abhängig von der Fremdmenge setzen will, kann man das im Ereignis
procedure DetailPositionenOnBeforePrint(Sender: TfrxComponent);
z.B. so machen:
Am Anfang die Farbe auf den Standard setzen:
memoPosMengeAuftrag.Font.Color := clBlack; MemoPositionenBezeichnung.Font.Color := clBlack;
Dann unten die gewünschte Farbe setzen, z.B. so:
// Fremdmengen rot: if <Positionen."MengeFremd"> > 0 then begin memoPosMengeAuftrag.Font.Color := clRed; MemoPositionenBezeichnung.Font.Color := clRed; end;
1.2 Farbe eines Bandes abwechselnd grau/weiß
Wenn man die Farbe eines Bandes (z.B. den Detail-Bereich, also die Positionen eines Auftrags) abwechselnd grau/weiß hinterlegen will, muss man ein bisschen in die Trickkiste greifen. Im OnBeforePrint-Ereignis des Bandes schreibt man diesen Code:
- Variante 1
procedure DetailPositionenOnBeforePrint(Sender: TfrxComponent); begin // Dieser Code wird ausgeführt, BEVOR das Positionen-Detail-Band ausgegeben wird. // Farbe abwechselnd weiß/grau: if <Line> mod 2 = 1 then // Bei jeder GERAD-STELLIGEN Zeile! begin TfrxBrushFill(DetailPositionen.Fill).BackColor := cl3dLight; TfrxBrushFill(ChildDetailPositionen.Fill).BackColor := cl3dLight; end else begin TfrxBrushFill(DetailPositionen.Fill).BackColor := clNone; TfrxBrushFill(ChildDetailPositionen.Fill).BackColor := clNone; end; end;
Der erste Trick ist die Zeile
if <Line> mod 2 = 1 then // Bei jeder GERAD-STELLIGEN Zeile!
<Line> ist eine System-Variable, die eine fortlaufende Zeilennummer (Datensatz-Nummer) zurückgibt, die FastReport einfach hochzählt. Der erste Datensatz hat einfach die Zeilennummer 1, der nächste 2 usw.
mod 2 ist eine Division und bringt den Rest der Divison zurück.
- Variante 2
Wenn im Code allerdings eine Unterdrückung des Bandes unter bestimmten Umständen drin ist, funktioniert diese Methode oben nicht!
Wenn oben das Band wg. Kennzeichen unterdrückt wird, geht das nicht mehr, weil die Zeilen-Nummer ja eine Art von Datensatz-Nummer ist und irgendein Datensatz davon unterdrückt sein kann!
Das geht also nicht...
if <Line> mod 2 = 1 then // Bei jeder GERAD-STELLIGEN Zeile!
...weil man ja nicht weiss, welche Zeile (=Datensatz) unterdrückt wurde.
Deshalb dieser Code:
procedure ddEinleitTermineDetailsOnBeforePrint(Sender: TfrxComponent); begin // Drucken-Kennzeichen in den Terminen berücksichtigen: ddEinleitTermineDetails.Visible := True; // Erst mal einschalten if ( <AuftragsKopf."StatusNr"> = 3 ) or ( <AuftragsKopf."StatusNr"> = 7 ) then begin // Angebot (3) und Anfrage (7): if <AuftragsTermine."DRUCKEN_ANG"> = 0 then ddEinleitTermineDetails.Visible := False; end else begin // Sonst: if <AuftragsTermine."DRUCKEN_AUFTR"> = 0 then ddEinleitTermineDetails.Visible := False; end; // Farbe abwechselnd weiß (=clNone) oder grau (cl3dLight): if ddEinleitTermineDetails.Visible then begin // Termin ist sichtbar: if TfrxBrushFill(memoBackgroundAuftrTermine.Fill).BackColor = clNone then begin TfrxBrushFill(memoBackgroundAuftrTermine.Fill).BackColor := cl3dLight; end else begin TfrxBrushFill(memoBackgroundAuftrTermine.Fill).BackColor := clNone; end; end; end;
1.3 Gruppenkopf auf letzter Seite unterdrücken, wenn keine Daten mehr kommen
Man kann den Gruppenkopf einer Gruppe ganz gut dazu benutzen, eine Überschrift über die Positionen zu drucken, die auch auf jeder Seite wiederholt wird. Es kann nun aber vorkommen, dass die Positionen gerade an Ende einer Seite aufhören und auf der nächsten Seite trotzdem noch die Überschrift dazu gedruckt wird. Das sieht unschön aus. Dieser Artikel beschreibt, wie man das verhindert.
1.4 Report mit Sub-Detail-Band wird abgebrochen, wenn es keine Sub-Daten gibt
Ein Report hat folgende Bänder:
- Master (Kopfdaten)
- Details (Positionen)
- SubDetails (Unterpositionen zu jeder Position)
- Details (Positionen)
Der Report wird wird jedoch abgebrochen, denn es keine Sub-Daten gibt!
Grund:
Man muss die Option "Drucken wenn Detail leer" auf dem Detail-Band einschalten!
1.5 Unterschiedliche Schriftarten in Auftrags-/Rechnungspositions-Texten
In den Textbausteinen eines Angebots, Auftrags oder einer Rechnung kommen die Texte in unterschiedlichen Schriftarten oder -Größen. Die Schriftart-Änderung im Report ist ohne Wirkung.
- Grund
- Die Schriftarten kommen aus den Texten selbst, also aus der Datenbank, nicht aus dem Report!
- Es handelt sich hier ja um RTF-formatierte Texte. Die Schriftart/-Größe wird in den Stammdaten festgelegt. Das ermöglicht es, innerhalb des Textes Formatierungen vorzunehmen, z.B. Fettschrift.
- Beim Einfügen eines solchen Textes wird die Formatierung aus den Stammdaten in die Positionen 1:1 übernommen.
- Lösung
- Man muss also die Schriftart in den Artikelstammdaten⇒Texte ändern!
- Will man die Änderung testen, hat das zuerst keine Auswirkung! Grund: Änderungen in den Stammdaten werden nicht in die bestehenden Positionen übernommen, sonst würden dort eventuelle individuelle Änderungen unkontrolliert überschrieben. Man muss daher in den Positonen im Textbereich rechts unten auf den Sternchen-Button klicken, damit der Text neu aus den Stammdaten in die Position geholt wird.
1.6 Rahmen per Code setzen
Manchmal möchte man den Rahmen eines Objektes nur unter bestimmten Bedingungen setzen. Beispiel: Im Fuss eines Auftrags wird ja die Mehrwertsteuer ausgewiesen. Hat man nun einen Auftrag ohne Mehrwertsteuer, so sollen die Brutto-Felder (mit doppeltem Rahem unten) ausgeblendet werden und das Netto-Feld als Summenfeld den doppelten Rahmen bekommen. Beispiel:
Dazu kann man folgenden Code verwenden:
procedure FussPositionenOnBeforePrint(Sender: TfrxComponent); begin // Ohne Mwst.: Mwst-Felder unterdrücken: if <AuftragsFuss."MwstBetrag"> = 0 then begin memoFussGesamtBrutto.Visible:= False; AuftragsFussMwstBetrag.Visible:= False; AuftragsFussMwstSatzProzent.Visible:= False; AuftragsFussGesamtBetragBrutto.Visible:= False; memoFussGesamtNetto.Text := 'Endbetrag in €'; // Ohne Mwst gibt's kein brutto/netto! memoFussGesamtNetto.Frame.Typ := ftBottom; // Rahmen unten memoFussGesamtNetto.Frame.BottomLine.Style := fsDouble; // Rahmen-Style "Doppelt" end; end;
- Hinweis
- Das Textfeld memoFussGesamtNetto reicht bis zum rechten Rand des Formulars! Es liegt also teilweise unter dem Feld "NettoBetrag". Durch diesen Trick wird die Linie unten bis zum Betragsfeld rechts gezogen.
1.7 Positionsangaben im Code
Manchmal möchte man im Code ein Objekt verschieben.
- Beispiele
- Der Pauschal-Betrag in einem Angebot soll nach links eingerückt werden.
- Ein Feld soll nach oben verschoben werden, wenn andere darüber ausgeblendet werden.
Dann kann man im Code die Position des Objektes festlegen:
- Left
- Legt die horizontale Position des Objektes fest, bezogen auf den linken Rand des Bands.
- Top
- Legt die vertikale Position des Objektes fest, bezogen auf das Band.
Beispiel:
if <BestellFuss."Nettobetrag1"> = 0 then //JC//160209// begin RichFussStandardText.Top := 0.5 * fr1cm; end;
Dieser Code verschiebt ein Feld nach oben, und zwar auf 0,5 cm, bezogen auf das Band, auf dem es liegt.
"fr1cm" ist dabei eine Umrechnungs-Variable, die FastReport zur Verfügung stellt.
Der Grund: Alle Angaben von Positionen im Code wie Top, Left usw. werden in Pixeln gemacht. Dadurch ist eine sehr genaue und Hardware-unabhängige Positionierung möglich. Damit man nun die Angaben von Pixeln z.B. in cm einfach angeben kann, muss man nur die gewünschte cm-Anzahl mit fr1cm multiplizieren.
Im Beispiel oben wird das Textfeld auf die Top-Position (=von oben auf dem Band) auf 0,5 cm gesetzt.
- Beachten Sie, dass das Kommata im Code der Punkt ist! Wenn man im Code also "0,5" schreibt, erhält man eine Fehlermeldung! Man muss "0.5" schreiben!
- ACHTUNG! Wenn Sie die Top-Position im Code verschieben, kann das den Gesamt-Seitenzähler durcheinander bringen! Angenommen, es gibt ein Feldobjekt im Detail-Band, das im Editor auf der Feldposition 3 cm liegt und Sie verschieben es im Code auf "Top=0", dann kann es passieren, dass der Gesamt-Seitenzähler eine Seite mehr angibt als es in Wirklichkeit sind!!!
1.8 Top-Position im Code ändern
Manchmal möchte man die Top-Position von Objekten (also die "Zeile") im Code unter bestimmten Umständen ändern, z.B. Felder nach oben schieben, wenn die "Zeile" darüber ausgeblendet wurde.
In diesem Artikel wird ein Beispiel dazu beschrieben.
1.9 Feld reagiert nicht auf Änderung der Schriftgröße
Wenn man im Designer die Schriftgröße eines Feldes ändern und es wird trotzdem noch zu groß/zu klein/zu fett dargestellt, ist vermutlich ein sog. "Highlight" auf dem Feld gesetzt. Um das zu prüfen und zu entfernen, doppelklicken Sie auf das Feld und entfernen das Highlight.
1.10 Zahlen und Datum formatieren
1.10.1 Formatieren über die Objekt-Eigenschaften
Um Zahlen zu formatieren, klickt man mit der rechten Maustaste auf das Feld und wählt "Anzeigeformat". Neben den Standard-Formatierungen kann man dort auch individuelle Formate angeben:
Format-String | Beschreibung, Beispiel |
---|---|
00 | Formatiert die Zahl mit zwei Stellen. Wenn die Zahl einstellig ist, wird die leere Stelle mit "0" aufgefüllt. Anwendung z.B. für Tages- oder Monatszahlen. Beispiele "01", "02", "10", "12". |
%0.0n | Formatiert die Zahl ohne Nachkommastellen. Beispiele "1", "2", "10", "12". |
%1.1f | Formatiert die Zahl ohne Nachkommastellen. Beispiele "1,4", "2,5", "10,0", "12,0". |
ddd dd.mm.yyyy | Formatiert ein Datumsfeld mit Wochentag und Datum. Beispiel: "Mo 29.02.2016". |
Diese Format-Strings können...
- ...im Objekt-Inspektor links unter "DisplayFormat" in das Eingabefeld "FormatString" eingegeben werden
- oder
- ...mit der rechten Maustaste auf das Objekt klicken und "Anzeigeformat" wählen.
1.10.2 Formatieren in einem Textfeld
Wenn man ein Datum in einem Textfeld (Memo) formatieren will, kann man dazu die eingebaute Funktion FormatDateTime(Format-String,[Feld]) verwenden.
Im Format-String kann man die Formatierung festlegen.
Beispiel:
<b>[AuftragsKopf."AuftrNr"]</b> [FormatDateTime( 'd-mmm-yyyy' , <AuftragsKopf."DruckDat">) ]
ergibt das Datum
6-Apr-2016
Das Ausschreiben des Monats verhindert Missverständnisse mit englisch- bzw. amerikanischen Ländern. Die Monats-Namen werden jedoch aus der Einstellung des Rechners geholt, d.h. ist der Rechner auf Deutsch eingestellt, werden auch die deutschen Monats-Namen verwendet!
Wenn es in einem Textfeld (Memo) mehrere eingebettete Felder gibt, kann man mit der rechten Maustaste - Anzeigeformat das gewünschte Feld auswählen...
...und formatieren. In diesem Beispiel wird die Uhrzeit formatiert.
1.11 Monats-Namen aus Monats-Zahl
Da es keine eingebaute Funktion gibt, mit der man eine Monats-Nummer in einen Namen umwandelt, kann man sich eine eigene Funktion bauen:
procedure PageHeader1OnBeforePrint(Sender: TfrxComponent); var Monatsnamen : Array[0..12] of String = ['FEHLT!','Januar','Februar','März','April','Mai','Juni','Juli', 'August','September','Oktober','November','Dezember' ]; begin MemoTitel.Text := 'Statistik ' + Monatsnamen[<Monat>] + ' [Jahr]' end;
Die Funktion geht davon aus, dass es eine Variable <Monat> gibt, in der die Zahl 1 bis 12 steht.
- Anderes Beispiel
- Hier wurde unter "Report⇒Variablen" eine Variable "Monatsname" deklariert.
- Diese Variable wird für die Ausgabe des Monatsnamens verwendet.
- Im BeforePrint-Ereignis des PageHeaders (Seitenkopf) steht:
procedure PageHeader1OnBeforePrint(Sender: TfrxComponent); var Monatsnamen : Array[0..12] of String = ['FEHLT!','Januar','Februar','März','April','Mai','Juni','Juli', 'August','September','Oktober','November','Dezember' ]; begin Set( 'Monatsname', '''' + Monatsnamen[ <Reisen."Monat"> ] + '''' ); // Setzt den Namen in die Variable. Zu beachten sind die einfachen Anführungszeichen '''' end;
- Zu beachten sind die einfachen Anführungszeichen ' am Anfang und am Ende der Zuweisung.
- Diese muss man angeben, damit FastReport weiß, dass es um einen Text geht.
- Da FastReport die einfachen Anführungszeichen ' aber als Steuerzeichen benutzt, kann man die nicht einfach so in den Code schreiben!
- Man muss deshalb '''' verwenden.
- Das erste ' sagt aus, dass nun ein Text kommt.
- Die beiden nächsten ' sagen, dass in dem Text ein ' benutzt werden soll.
- Am Ende schließt das ' den Text ab.
- Monatsnummer aus einem Datumsfeld
- Um die Monatsnummer aus einem Datumsfeld zu bekommen, kann man die eingebaute Funktion MonthOf(Date) verwenden.
- Wenn z.B. das Datum aus einem Datenbank-Feld kommt, sähe der Code so aus:
procedure PageHeader1OnBeforePrint(Sender: TfrxComponent); var Monatsnamen : Array[0..12] of String = ['FEHLT!','Januar','Februar','März','April','Mai','Juni','Juli', 'August','September','Oktober','November','Dezember' ]; Monat : Integer; begin Monat := MonthOf( <Statistik."Datum"> ); MemoTitel.Text := 'Statistik ' + Monatsnamen[<Monat>] + ' [Jahr]' end;
1.12 Text in Großbuchstaben
Manchmal möchte man, dass der Text eines Datenbank-Felder immer in GROSSBUCHSTABEN ausgegeben wird, auch wenn er in der Datenbank in Kleinbuchstaben gespeichert ist.
Beispiel:
Nach DIN 5008 muss der Ländername im Anschriften-Feld bei ausländischen Adressen in Großbuchstaben ausgegeben werden.
Um ein Feld in Großbuchstaben auszugeben, kann man Befehl
UpperCase( <Tabelle."Feldname"> ) )
verwenden.
Beispiel:
In einem Auftragsformular befindet sich ein Memo-Feld memoAnschrift
, in das die Anschrift im Code eingefügt wird:
// Anschriftenfeld zusammenstellen: memoAnschrift.Lines.Clear; memoAnschrift.Lines.Add( <AuftragsKopf."NameFirma"> ); if <Ansprechpartner."Briefanrede"> > then memoAnschrift.Lines.Add( <Ansprechpartner."Briefanrede"> ); memoAnschrift.Lines.Add( <AuftragsKopf."Str"> ); memoAnschrift.Lines.Add( <AuftragsKopf."PLZ"> + ' ' + <AuftragsKopf."Ort"> ); memoAnschrift.Lines.Add( UpperCase( <Adresse."Landname"> ) );
In der letzten Zeile des Codes wird der Land-Name in Großbuchstaben ausgegeben.
1.13 Schriftattribute (Fett, unterstreichen ) in Feldern
Manchmal will man innerhalb eines Textfeldes (Memo) bestimmte Teile in Fett oder unterstrichen oder beides einsetzen.
Beipsiel:
Im Anschriftenfeld eines Auftrags soll die PLZ und der Ort fett-unterstrichen sein.
Am Einfachsten macht man das über sog. "HTML-Steuerzeichen". Dieses kann man einfach in den Text einfügen.
Steuerzeichen | Auswirkung |
---|---|
<b> | Fettschrift ein |
</b> | Fettschrift aus |
<u> | Unterstreichen ein |
</u> | Unterstreichen aus |
<i> | Kursiv (Italic) ein |
</i> | Kursiv (Italic) aus |
<sub>Text tiefstellen ein | </sub>Text tiefstellen aus |
<sup> hochstellen ein | </sup> hochstellen aus |
<font color> | Schriftfarbe wählen. Beispiel: "Normaler Text <font color=red>Text in rot</font>, <font color="#FF8030">Text in orange</font> |
- Im konstanten Text-Feld
- Wenn es dabei um einen konstanten Text geht kann man diese Steuerzeichen einfach in den Text schreiben.
- Beispiel:
- "Es gelten unsere <b>Allgemeinen Geschäftbedingungen</b> und bla bla..."
- Im Code ein Textfeld (Memo ) füllen
Wenn man im Code ein Textfeld füllt (z.B. das Anschriften-Feld im Auftragskopf) muss man im OnBefore-Print-Ereignis des entsprechenden Bandes folgendes schreiben:
// Anschriftenfeld zusammenstellen: memoAnschrift.Lines.Clear; memoAnschrift.Lines.Add( <AuftragsKopf."NameFirma"> ); if <Ansprechpartner."Briefanrede"> > then memoAnschrift.Lines.Add( <Ansprechpartner."Briefanrede"> ); memoAnschrift.Lines.Add( <AuftragsKopf."Str"> ); memoAnschrift.Lines.Add( '<b><u>' + <AuftragsKopf."PLZ"> + ' ' + <AuftragsKopf."Ort"> + '</b></u>' ); memoAnschrift.Lines.Add( UpperCase( <Adresse."Landname"> ) );
Wichtig ist, dass man die Steuerzeichen in einfache Anführungszeichen setzt:
'<b><u>'
- Hinweis
- Im Memo-Feld muss dazu die Eigenschaft "AllowHTMLTags" auf "True" gesetzt werden!
- Verwenden Sie diese Methode mit Bedacht und nicht bei großen Textfelder (z.B. AGB'S über mehrere Seiten)!
- So formatierte Textfelder werden (wie RTF-Felder) beim Export in eine PDF-Datei von FastReport1) in Grafiken umgewandelt!
- Das vergrößert die PDF-Datei u.U. immens!
1) Gilt für FastReport 5.0. Ab 2018 wird FastReport 6.0 benutzt, wo formatierte Texte als Vector-Textgrafiken exportiert werden.
2 Konstanten im Code
Deklararion von Konstanten: Das vereinfacht/Vereinheitlicht z.B. die Datumsformatierung.
Statt überall..
FormatDateTime( 'd.mmm yyyy',<AuftragsKopf."VA-VonDatum"> )
...macht man besser:
FormatDateTime( sDateFormat ,<AuftragsKopf."VA-VonDatum"> )
...damit man bei einer gewünschten Änderung nur eine Stelle ändern muss.
Im Code oben schreibt man dazu:
const sDateFormat = 'd.mmm yyyy';