Formelsammlung

Eine Sammlung von nützlichen Formeln für den Reportgenerator

Die Beschreibung der Helper wurde aus allgemein\muster_qr_code.jrxml entnommen.

iReport = Java 7

Kalenderwoche aus Timestamp errechnen

und das immer für die vorige Woche, als vom Stichtag = Timestamp den Wochentag abzuziehen um auf den Sonntag davor zu kommen

com.lp.util.HelperReport.berechneKWJahr( new java.sql.Date( $P{P_STICHTAG}.getTime() - $P{P_STICHTAG}.getDay()*1000*3600*24 ) )

SQL Abfragen für einen Return-Wert

  • $P{P_SQLEXEC}.execute( SQL Query String)

SQL Abfragen für mehrere Werte

  • $P{P_SQLEXEC}.executes( SQL Query String) siehe

Werte aus der Datenbank

  • Bigint aus DB = Long im Jasper Report
  • sum() aus der DB liefert immer BigDecimal

Strings in Zahlen wandeln

  • com.lp.util.HelperReport.toBigDecimal (String bigDecimal, Locale stringLocale) mit und ohne Local
  • com.lp.util.HelperReport.toInteger(String integer)

Datum aus Date/Timestamp

$V{LosEnde}.toLocaleString().substring(6,10)+"-"+
$V{LosEnde}.toLocaleString().substring(3,5)+"-"+
$V{LosEnde}.toLocaleString().substring(0,2)
/* $V{LosEnde}.toLocaleString() liefert DD.MM.JJJJ */

ACHTUNG: Liefert das Datum in Abhängigkeit des Report-Locales. Also bei italienisch die italienische Schreibweise (8-nov-2023), welche für SQL Abfragen dann nicht verwendbar ist. Für SQL Abfragen daher z.B. (new SimpleDateFormat(“yyyy-MM-dd”, Locale.GERMAN)).format($V{Datum}) verwenden. Siehe auch.

Datum in String konvertieren

  • (new SimpleDateFormat(“dd.MM.yyyy”, Locale.GERMAN)).format($P{P_ANGEBOTSGUELTIGKEIT}) Locale.ENGLISH
  • bei den Schreibweisen auf 24Std 12Std achten, für Kalenderwoche auch auf die Java Definitionen (siehe Erfolgsrechnung bzw. Link oben)

Mögliche Beispiele:

  • (new SimpleDateFormat(“yyyy-MM-dd”, Locale.GERMAN)).format($V{DiesesMonat})+" 00:00:00"
  • (new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”, Locale.GERMAN)).format($F{Von})
  • (new SimpleDateFormat(“dd.MM.yyyy”, Locale.GERMAN)).format($V{V_HEUTE}) – im in deutsch lesbaren Format

String in Datum konvertieren

  • Wichtig Datum muss im Stringformat dd.MM.yyyy übergeben werden
    com.lp.util.Helper.parseString2Date($F{F_REALISIERUNGSTERMIN})

Zahlen in String konvertieren

  • String.format("%05d", $F{F_ARBEITSGANG})
    nur für integer

BigDecimal to String

String.format("%05.4f" , $V{Rabatt}.doubleValue()*100).replace(",",".")

Je nachdem was man damit machen muss, es kommt der String im default Locale, also ev. noch die Dezimaltrenner usw. bearbeiten.

Time in Double konvertieren

Manchmal muss man aus der Datenbank eine Time, z.B. die Sollzeit eines Zeitmodelles, in ein Double konvertieren um damit weiterrechnen zu können.

$V{U_Sollzeit} == null ? 0.00 : ((new Double($V{U_Sollzeit}.getTime())).doubleValue() / 1000 / 3600 ) +1.0

Gerade oder ungerade

für ein int

$V{KW_int}.intValue()%2 == 0 ? ist eine gerade Zahl

für ein double

xxx.doubleValue()%2 == 0 ? ist eine gerade Zahl

Fremdsprachige Installationen

Bei fremdsprachigen Installationen, z.B. Konzernsprache in Englisch, müssen bereits die default Reports in der Mandantensprache, z.B. Englisch sein.
D.h. unter z.B. report/auftrag/anwender/ müssen bereits die englischsprachigen Reports für den Auftrag sein. Sollte dann ein Kunde eine deutsche AB benötigen, ist diese unter 001/de zu hinterlegen.

Zugriff auf die Bezeichnung der intelligenten Zwischensumme

Da die intelligente Zwischensumme hierarchiefähig ist, ist der eigentliche Feldinhalt ein String[Array]. Das bedeutet, will man nun auf den Inhalt zugreifen, so muss das Array-Element angegeben werden. So erhält man z.B. mit $F{F_ZWSTEXTE}[0] eben die Bezeichnung der ersten Zeile des Textes der intelligenten Zwischensumme.

Timestamp / Datum formatieren

von ist ein Timestamp (new SimpleDateFormat(“HH:mm”, Locale.GERMAN)).format($F{Von}.getTime())

jetzt als String

new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”).format(new java.util.Date())

zwei Timestamps nur das Datum vergleichen

https://tableplus.com/blog/2018/07/postgresql-how-to-extract-date-from-timestamp.html

To extract a date (yyyy-mm-dd) from a timestamp value For example, you want to extract from ‘2018-07-25 10:30:30’ to ‘2018-07-25’

  1. Extract from a timestamp column: Use date() function: SELECT DATE(column_name) FROM table_name;
  2. Extract date from a specific timestamp value: Cast the timestamp to a date by adding ::date suffix: SELECT ‘2018-07-25 10:30:30’::TIMESTAMP::DATE; Or combine date() and substring() function: SELECT DATE(SUBSTRING(‘2018-07-25 10:30:30’ FROM 1 FOR 10));

im Query mit Monaten rechnen

(t_letztewartung+(i_wartungsintervall * ‘1 month’::INTERVAL))

eine weitere interessante Variante ist

(start_date + (duration || ’ month’)::INTERVAL) < ‘2010-05-12’
siehe https://stackoverflow.com/questions/5909363/calculating-a-date-in-postgres-by-adding-months

einen Subreport mit Tagen

com.lp.util.HelperReport.getSubreportKalendertage(
$P{P_VON},
$P{P_BIS},
$P{P_MANDANT_OBJ}.getTheClientDto())

Liefert einen Subreport mit Datum, Feiertag und Sollzeit (in Stunden) des Firmenzeitmodells
Beispiel siehe: proj_projekt_journal_offene_gantt_zeitachse.jrxml

Query um eine Summe der jüngsten 10 Mengen zu erhalten

Der Trick liegt hier darin, dass man sich mit einem Select (dem inneren) die Werte holt, den man dann mit einem zweiten Select (dem äußeren) aufsummiert. Man könnte auch sagen, dass man damit einen zweistufigen Select macht. Also z.B. für die Aufträge:

select sum(n_menge) from (
select n_menge from auft_auftragposition
inner join auft_auftrag on auft_auftrag.i_id=auft_auftragposition.auftrag_i_id
where artikel_i_id in (select i_id from ww_artikel where c_nr like ‘ABC%’)
order by auft_auftrag.t_belegdatum desc
limit 10) as foo;

Für diverse SQL Querys

Siehe https://www.postgresql.org/docs/current/functions-formatting.html alleine schon das SQL kann jede Menge

X_TEXT direkt aus der Datenbank holen

Nachdem im Jasper üblicherweise mit Strings (und nicht mit String-Objekten) gearbeitet wird, aber in der Datenbank auch lange / große X_Texte abgelegt sind, müssen diese mittels CAST aus der Datenbank geholt werden. Z.B. für die Bemerkung aus einer Kostenstelle.

$P{P_SQLEXEC}.execute( “select CAST(X_BEMERKUNG as VARCHAR(3000)) from LP_KOSTENSTELLE where C_NR = ‘10’;” )

Abfrage mit locale

Um das locale in den Querys verwenden zu können:
{REPORT_LOCALE}.toString().replace("_","")

z.B. Übersetzung der Bezeichnung der Mengeneinheiten

$P{P_SQLEXEC}.execute( “select c_bez from lp_einheitspr where einheit_c_nr=’"+$P{P_EINHEIT}+”’ and locale_c_nr=’"+$P{REPORT_LOCALE}.toString().replace("_","")+"’;" )

Datenreihen mit Datum generieren

Für PostgresQL (MS-SQL ist anderes und wird, da nicht OpenSource, von Kieselstein ERP nicht verwendet).

Tage zwischen Datumsbereich:

SELECT day::date
FROM generate_series(timestamp ‘2023-03-01’, timestamp ‘2023-03-31’, interval ‘1 day’) day;
Ergebnis:

“2023-03-01”
“2023-03-02”
“2023-03-03”

“2023-03-28”
“2023-03-29”
“2023-03-30”
“2023-03-31”

Stunden für Zeitbereich:

SELECT day::timestamp
FROM generate_series(timestamp ‘2023-03-01 12:00’, timestamp ‘2023-03-02 18:00’, interval ‘1 hour’) day;
“2023-03-01 18:00:00”
“2023-03-01 19:00:00”

“2023-03-02 09:00:00”
“2023-03-02 10:00:00”

1. Tag im Monat:

SELECT date ‘2023-03-01’ + interval ‘1’ month * s.a AS date
FROM generate_series(0,3,1) AS s(a);
Ergebnis:
“2023-03-01 00:00:00”
“2023-04-01 00:00:00”
“2023-05-01 00:00:00”

Raufzählen

SELECT * FROM generate_series(1,3);

Ergebnis:
1
2
3 als integer

Konvertieren auf BigDecimal

Das einfachste ist BigDecimal.valueOf(value) wobei value z.B. ein Double sein kann.

gerundet auf Nachkommastellen

BigDecimal.valueOf(value).setScale(2, BigDecimal.ROUND_HALF_UP)

weitere Helper

Du findest eine Aufstellung aller verfügbaren Report-Helper im Report
…/allgemein/muster_qr_code.jrxml
Hier gibt es den Parameter HelperReport . Fügst du diesen ein ein Textfield ein, so siehst du alle verfügbaren Helper.

Usecase ID wird nicht angedruckt

Macht man einen Druck der Auswahlliste (FLR Liste) muss rechts oben die UseCaseID angedruckt werden.
Diese wird nicht angedruckt, wenn im ../report/allgemein auch der flrdruck.jasper vorhanden ist. Zusätzlich darf es den flrdruck.jrxml ausschließlich ein Mal im allgemein geben und in keinem anderen Verzeichnis.

Das führende Herr / Frau ersetzen

Manchmal will / muss man die förmlichen Anreden entfernen. Also aus Herr Mustermann nur Mustermann haben. Das macht man üblicherweise mit replace. Da es aber auch vorkommen kann, dass der Name des Ansprechpartners Herr enthält muss man das über .replaceAll("^Herr","") machen. D.h. es wird NUR das erste Herr durch den nachfolgenden (Leer-)String ersetzt. Ganz genau muss man dann auch noch auf den beginnenden String prüfen. Für die Ansprechpartner gehen wir hier davon aus, dass es immer eine entsprechende Anrede gibt.
Da man damit auch oft noch das Frau entsprechend herausfiltern will, heißt das dann:

.replaceAll("^Herr “,”").trim().replaceAll("^Frau “,”").trim()

Subreport overflowed on a band that does not support overflow

Wenn das nicht der Title, die Page Header / Footer betrifft, dann ist der Report, der den Subreport aufruft auf Horizontal gestellt. Er muss auf Vertikal gestellt sein. Passiert gerne wenn man Reports umkopiert, z.B. mit mehreren Columns und dann gehts am Anfang und auf einmal nicht mehr (weil dann der Overflow kommt). D.h. wenn die Columns auf 1 gesetzt werden, dann auf die Richtung achten.

Zu Datum Tage dazuzuzählen

com.lp.util.Helper.addiereTageZuDatum(date Datum, int Tage)

Beispiel

com.lp.util.Helper.addiereTageZuDatum(com.lp.util.Helper.parseString2Date($P{Liefertermin}) , -2)

Wochentage / Wochentagsnamen andrucken

  • com.lp.util.HelperReport.getWochentag($P{REPORT_LOCALE}, $F{Datum})
  • com.lp.util.HelperReport.getWochentag($P{REPORT_LOCALE}, new java.sql.Timestamp($F{BeginnDatum}.getTime()) … wenn das ein Date ist

Daten anders sortieren

Üblicherweise werden die Daten des Reports anhand der gewählten Sortierung übergeben. Manchmal will man aber diese, z.B. in einer Reportvariante, anders sortieren. Um dies zu bewerkstelligen kann direkt im jrxml das Sortierkriterium angegeben werden.
Es muss dies zwischen field name und variable eingefügt werden.
D.h. hier muss:

eingetragen werden. Damit werden die Daten vom Jasper nach diesem Feld sortiert. Beispiel siehe z.B.: ..\report\bestellung\bes_sammelmahnung.jrxml

Sortierung des Materials des Fertigungsbegleitscheines

So wie oben beschrieben, einfach nur zwischen den Zeilen field_name und variable die Sortfields einfügen.

<sortField name=“F_ARBEITSGANG”/>
<sortField name=“F_UNTERARBEITSGANG”/>
<sortField name=“F_MATERIAL_LAGERORT”/>

Dies ist leider nur im XML ersichtlich.

EMail Nachricht aus dem Report erzeugen

Mit folgendem Helper kann aus dem Report heraus eine Nachricht versandt werden. Z.B. wenn ein Wareneingang gebucht wurde und das Wareneingangsetikett gedruckt wird.

com.lp.util.HelperReport.emailSenden(
    "wareneingang@kieselstein-erp.org",
    "WE zu BS: "+$F{F_BESTELLNUMMER},
    "Es wurde ein Wareneingang von "+$F{F_IDENT}+" "+$F{F_BEZ}+" gebucht",
    $P{P_MANDANT_OBJ}.getTheClientDto())
  • Empfänger
  • Betrifft
  • Nachricht
  • Clientobjekt um es versenden zu können.