Steuerung der Kreuztabelle aus dem Script

Navigation:  Bericht im FR-Designer > Kreuztabellen (Cross-tab Objekt) >

Steuerung der Kreuztabelle aus dem Script

Previous pageReturn to chapter overviewNext page

Falls die visuellen Möglichkeiten der Tabelleneinstellungen nicht ausreichen, kann man das Script nutzen, um Feineinstellungen des Tabellenäußeren vorzunehmen. Das "Cross-tab Objekt" besitzt folgende Ereignisse:

 

Ereignis        Beschreibung

OnAfterPrint        Ereignis wird nach dem Druck der Tabelle aufgerufen.

OnBeforePrint        Ereignis wird vor dem Druck der Tabelle aufgerufen.

OnCalcHeight        Ereignis wird vor dem Berechnen der Zeilenhöhe der Tabelle aufgerufen. Der Bearbeiter des Ereignisses gibt die eingegebene Höhe wieder oder 0 um  die Zeile zu verbergen.

OnCalcWidth        Ereignis wird vor dem Berechnen der Spaltenbreite der Tabelle aufgerufen. Der Bearbeiter des Ereignisses gibt die eingegebene Breite wieder oder 0 um  die Spalte zu verbergen.

OnPrintCell        Ereignis wird vor dem Anzeigen der Zellen der Tabelle aufgerufen. Der Bearbeiter kann das Format und den Inhalt ändern.

OnPrintColumnHeader        Ereignis wird vor dem Anzeigen der Spaltenköpfe der Tabelle aufgerufen. Der Bearbeiter kann das Format und den Inhalt der Spaltenköpfe ändern.

OnPrintRowHeader        Ereignis wird vor dem Anzeigen der Zeilenköpfe der Tabelle aufgerufen. Der Bearbeiter kann das Format und den Inhalt der Zeilenköpfe ändern.

 

In den Ereignissen kann man folgende Methoden des "Cross-tab Objektes verwenden":

 

Methode        Beschreibung

function ColCount: Integer        Zählt die Anzahl der Spalten in der Tabelle.

function RowCount: Integer        Zählt die Anzahl der Zeilen in der Tabelle.

function IsGrandTotalColumn(Index: Integer): Boolean        Zeigt True an, falls die angegebene Spalte eine Summenspalte ist.

function IsGrandTotalRow(Index: Integer): Boolean        Zeigt True an, falls die angegebene Zeile eine Summenzeile ist.

function IsTotalColumn(Index: Integer): Boolean        Zeigt True an, falls die angegebene Spalte eine Spalte mit Zwischensummen ist.

function IsTotalRow(Index: Integer): Boolean        Zeigt True an, falls die angegebene Zeile eine Zeile mit Zwischensummen ist.

procedure AddValue(const Rows, Columns, Cells:arrayof Variant)        Fügt einen Wert in die Tabelle ein.

 

Betrachten wir am Beispiel, wie man den Hintergrund der dritten Spalte hervorheben kann (in unserem Beispiel sind es die Daten des November 1999). Wir markieren die Kreuztabelle und erstellen den Bearbeiter des Ereignisses OnPrintCell:

 

Pascal script:

 

procedure Cross1OnPrintCell(Memo: TfrxMemoView;

 RowIndex, ColumnIndex, CellIndex: Integer;

 RowValues, ColumnValues, Value: Variant);

begin

if ColumnIndex = 2then

   Memo.Color := clRed;

end;

 

C++ Script:

 

void Cross1OnPrintCell(

TfrxMemoView Memo,

int RowIndex,

int ColumnIndex,

int CellIndex,

Variant RowValues,

Variant ColumnValues,

Variant Value)

{

if (ColumnIndex == 2) { Memo.Color = clRed; }

}

 

Wir erhalten folgendes Ergebnis:

 

_img201

 

Um den Spaltenkopf hervorzuheben, erstellen wir einen Bearbeiter des Ereignisses OnPrintColumnHeader:

 

Pascal script:

 

procedure Cross1OnPrintColumnHeader(Memo: TfrxMemoView;

 HeaderIndexes, HeaderValues, Value: Variant);

begin

if (VarToStr(HeaderValues[0]) = '1999') and

   (VarToStr(HeaderValues[1]) = '11') then

   Memo.Color := clRed;

end;

 

C++ Script:

 

void Cross1OnPrintColumnHeader(

TfrxMemoView Memo,

Variant HeaderIndexes,

Variant HeaderValues,

Variant Value)

{

  if ((VarToStr(HeaderValues[0]) == "1999") &&

     (VarToStr(HeaderValues[1]) == "11"))

 {

   Memo.Color = clRed;

 }

}

 

Das Resultat:

 

_img202

 

Klären wir die Arbeitsweise der Scripte. Der Bearbeiter des Ereignisses OnPrintCell wird vor dem Druck der Zelle, welche in der Tabelle ist,  aufgerufen. Beim Druck der Zellen der  Spaltenköpfe der Tabelle werden die Bearbeiter OnPrintColumnHeader oder OnPrintRowHeader aufgerufen. Dazu wird in den Bearbeiter OnPrintCell ein Link zum Objekt "Text" erstellt. Dieser stellt die Zellen der Tabelle (Parameter Memo) und die Adresse der Zellen in zwei Varianten dar: Zeilen-, Spalten-, Zellennummer (die letzte aktuell, falls Sie in der Tabelle Zellen mit mehreren Ebenen haben) in Parametern RowIndex, ColumnIndex, CellIndex entsprechend. Die zweite Variante der "Adresse", sind die Parameter RowValues und ColumnValues. Das Parameter Values stellt den Inhalt der Zelle dar.

 

Um eine "Adresse" zu spezifizieren, können Sie sowohl die erste Variante (RowIndex, ColumnIndex), als auch die zweite Variante (RowValues, ColumnValues) verwenden. Diese ist in unserem Beispiel besser. Wir wollten in unserem Fall die dritte Spalte hervorheben, deswegen analysieren wir am besten die erste Variante. Da die Nummerierung der Spalten und Zeilen bei 0 beginnt, hilft die Überprüfung ColumnIndex = 2 uns, die dritte Spalte zu ermitteln. Man kann auch anders vorgehen und die Spalte anhand der Daten ermitteln (wir benötigen den 11 Monat 1999):

 

Pascal script:

 

procedure Cross1OnPrintCell(Memo: TfrxMemoView;

 RowIndex, ColumnIndex, CellIndex: Integer;

 RowValues, ColumnValues, Value: Variant);

begin

if (VarToStr(ColumnValues[0]) = '1999') and

   (VarToStr(ColumnValues[1]) = '11') then

   Memo.Color := clRed;

end;

 

C++ Script:

 

void Cross1OnPrintCell(

TfrxMemoView Memo,

int RowIndex,

int ColumnIndex,

int CellIndex,

Variant RowValues,

Variant ColumnValues,

Variant Value)

{

 if ((VarToStr(ColumnValues[0]) == "1999") &&

    (VarToStr(ColumnValues[1]) == "11"))

 {

   Memo.Color = clRed;

 }

}

 

Die Werte, die in den Parametern RowValues und ColumnValues sind Reihen des Types "Variant" mit einer Nullbasis. Das Nullelement ist der Wert der obersten Ebene im Tabellenkopf, das erste Element der Wert der nächsten Ebene usw. In unserem Fall ist ColumnValues[0] die Jahre und ColumnValues[1] die Monate.

 

Wozu benötigt man VarToStr? Dies garantiert die Fehlerfreiheit bei der Konvertierung der Typen. Bei Operationen des Typs Variant versucht FastReport die Zeilen automatisch im Format "Zahl" darzustellen. In unserem Fall würde das zu einem Fehler führen, wenn die Werte der Spalten 'Total' und 'Grand Total' angezeigt werden sollen.

 

Der Bearbeiter des Ereignisses OnPrintColumnHeader wird beim Druck der Zellen des Spaltenkopfes aufgerufen. Die Auswahl der Parameter ist ähnlich der Bearbeiter OnPrintCell, hier jedoch wird die "Adresse" der Zelle (Parameter HeaderIndexes, HeaderValues) anders transferiert. Der Parameter HeaderValues zeigt dieselben Werte wie die Parameter ColumnValues und RowValues im Bearbeiter OnPrintCell. Der Parameter HeaderIndexes ist ebenfalls eine Reihe des Types Variant und enthält die "Adresse" der Zelle des Kopfes in einer anderen Form. Das Nullelement ist die Reihennummer der obersten Ebene, das erste Element die Nummer der nächsten Ebene usw. Das Prinzip der Nummerierung der Zellen wird verständlich, wenn man die Grafik betrachtet:

 

_img203.zoom93

 

In unserem Beispiel ist es einfacher die Werte HeaderValues zu analysieren, aber man kann auch den folgenden Bearbeiter schreiben:

 

Pascal script:

 

procedure Cross1OnPrintColumnHeader(Memo: TfrxMemoView;

 HeaderIndexes, HeaderValues, Value: Variant);

begin

if (HeaderIndexes[0] = 0) and (HeaderIndexes[1] = 2) then

   Memo.Color := clRed;

end;

 

C++ Script:

 

void Cross1OnPrintColumnHeader(

TfrxMemoView Memo,

Variant HeaderIndexes,

Variant HeaderValues,

Variant  Value)

{

if ((HeaderIndexes[0] == 0) && (HeaderIndexes[1] == 2)) { Memo.Color = clRed; }

}

 

 

Mit Hilfe der Bearbeiter der Ereignisse OnCalcWidth und OnCalcHeight kann man die Breite und Höhe der Zeilen/Spalten steuern. Zeigen wir das an einem Beispiel: wir vergrößern die Breite der Spalte, welche 11 Monat 1999 entspricht. Hierfür erstellen wir Bearbeiter des Ereignisses OnCalcWidth:

 

Pascal script:

 

procedure Cross1OnCalcWidth(ColumnIndex: Integer;

 ColumnValues: Variant; var Width: Extended);

begin

if (VarToStr(ColumnValues[0]) = '1999') and

   (VarToStr(ColumnValues[1]) = '11') then

   Width := 100;

end;

 

C++ Script:

 

void Cross1OnCalcWidth(

int ColumnIndex,

variant ColumnValues,

Extended &Width)

{

if ((VarToStr(ColumnValues[0]) == "1999") &&

   (VarToStr(ColumnValues[1]) = "11"))

   {

     Width = 100;

   }  

}

 

Das Resultat:

 

127

 

Um die Spalte zu verbergen, reicht es aus Width := 0 einzustellen. Beachten Sie, dass die Summen nicht neu berechnet werden, da die Matrix schon mit Werten gefüllt worden ist.