Najłatwiej byłoby oczywiście dodać podzapytanie w głównym query, ale komplikowanie mocno rozbudowanego sql'a to zły pomysł - wydajnościowo i (nie)higienicznie. Raport podrzędny też odpada - armata na komara. Pozostaje użycie dedykowanego Dataset przez wstawienie tabelki krzyżowej.
Crosstabs to niewdzięczne struktury. Moj iReport (3.5.3) kompletnie sobie z nimi nie radzi - próby wstawienia tabeli krzyżowej z palety kończą się szybkim pożegnaniem z GUI NetBeans bez zapisania zmian i komunikatu o błędzie. Pozostaje edycja źródeł raportu w XML'u, ale po kolei.
Poniżej załączam przepis na wstawienie do dowolnej sekcji raportu pola odczytanego dedykowanym zapytaniem sql. Ważne jest takie zgrupowanie kolumn i wierszy w Crosstab, żeby została widoczna tylko jedna komórka sekcji Detail, bez nagłówków i sum. Oczywiście podany kod trzeba dopasowac do swoich potrzeb (zapytanie, wielkość elementów, itd).
Krok 1. Do raportu dodać nowy Dataset - "Add Dataset" z menu kontekstowego po kliknięciu na nazwę raportu. Dodać parametr. Typ parametru musi być zgodny z id rekordu i parametrem zewnętrznym raportu.
Krok 2. Wpisać sparametryzowane zapytanie do Dataset.
Krok 3. Wstawić Crosstab do raportu, np. do sekcji nagłówka (z palety). Jeśli iReport nie chce współpracować - przejść do następnego punktu (wkleić XML).
Krok 4. Wyciąć nagłówki i stopki kolumn i wierszy tabeli. W edytorze tabeli powinna zostać widoczna tylko jedna komórka sekcji Detail typu String (w sekcji Measures pole ma Value Expression=$F{number}). Jako bucket expression (wyrażenie grupujące) w Row Groups i Column Groups wpisać stały tekst, np. "a".
Jeśli przy edycji tabeli iReport odmawia współpracy, wkleić gotowy szablon kodu do żródła XML raportu.
<crosstab isRepeatColumnHeaders="false" isRepeatRowHeaders="false" columnBreakOffset="0">
<reportElement x="60" y="14" width="200" height="14"/>
<crosstabParameter name="orderId" class="java.lang.Long"/>
<rowGroup name="row" width="0">
<bucket>
<bucketExpression class="java.lang.String"><![CDATA["a"]]></bucketExpression>
</bucket>
<crosstabRowHeader>
<cellContents/>
</crosstabRowHeader>
<crosstabTotalRowHeader>
<cellContents/>
</crosstabTotalRowHeader>
</rowGroup>
<columnGroup name="col" height="0">
<bucket>
<bucketExpression class="java.lang.String"><![CDATA["a"]]></bucketExpression>
</bucket>
<crosstabColumnHeader>
<cellContents/>
</crosstabColumnHeader>
<crosstabTotalColumnHeader>
<cellContents/>
</crosstabTotalColumnHeader>
</columnGroup>
<measure name="orderNumber" class="java.lang.Object">
<measureExpression><![CDATA[$F{number}]]></measureExpression>
</measure>
<crosstabCell width="237" height="25">
<cellContents>
<textField>
<reportElement style="Crosstab Data Text" x="0" y="0" width="237" height="14"/>
<textElement textAlignment="Left">
<font isBold="true"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[""+$V{orderNumber}]]></textFieldExpression>
</textField>
</cellContents>
</crosstabCell>
</crosstab>
Krok 5. Przypisać nazwę Dataset do tabeli. Zrobić mapowanie wartości parametru raportu na Dataset.
Krok 6. Jeśli nie istnieje, wstawić pole tekstowe do sekcji Detail tabeli i przypisać zmienną typu String (Text Field Expression=$V{orderNumber}).
I to byłoby na tyle. Wszelkie uwagi są mile widziane. :)
1 komentarze:
dokładnie tego szukałem:)
Prześlij komentarz