C# Scripting
Es wird vorrausgesetzt das Sie C# Programmierkenntnisse haben.
Im Berichts Generator können C# Skripte auf Basis .NET verwendet werden. Der Skripting Editor verfügt über ein einfaches Auto Complete und Fehleranalyse.
Wenn Sie im Script Editor auf "Beispiel Quelltext" klicken sehen Sie Beispiel wie sie mit der API arbeiten können.
- Der Skriptcode wird immer auf dem MapEdit Web Server ausgeführt, nicht auf dem Client!. Mahen Sie also keine Zugriffe auf lokale Dateien.
- Verwechseln die Report API nicht mit der Map Edit Client API (Beschrieben im Kapitel API) Funktionen der MapEdit Client API wie Mum.Geo.DataAccess etc können hier nicht verwendet werden!!
- Zur Abfrage von Daten wird empfohlen immer die mit der Report API mitgelieferten Funktionen die Sie in den Beispielen sehen zu verwenden und nicht direkt mittels anderen Methoden auf die Daten zu zugreifen auch wenn dies möglich ist.
Achten Sie darauf das Sie im Code keine MessageBoxen oder UI Element aufrufen oder verwenden. Das Plugin läuft immer auf dem WebServer und nicht auf dem Client. D.h. beim Endkunden kann der Kunde kein MessageBoxen bestätigen oder UI Element eingeben und ihr WebServer wird ggf den ganzen MapEdit Server blockieren!! Verwenden Sie this.Report.WriteError/WriteLog um Fehler oder Log Meldungen auszugeben.
Starten Sie wenn Sie sehr viele Tests und Änderungen an Berichten mit Scripten durchführen den IIS einmal pro Woche neu. Dies gibt Speicher frei.
Anlegen einer eigenen Funktion
Drücken Sie im Berichsdesigner auf "C# Script"
Es wird ihnen ein Grundgerüst erzeugt.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XSystem;
using Mum.Geo.ReportDesigner;
namespace Report
{
public class MyReportPlugIn : ReportPlugIn
{
public MyReportPlugIn(IReportApiHost host) : base(host)
{
//
}
}
}
Fügen Sie nun Ihre eigenen Funktionen, Im Bespiel unten MyFunction1 und MyFunction2 hinzu.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XSystem;
using Mum.Geo.ReportDesigner;
namespace Report
{
public class MyReportPlugIn : ReportPlugIn
{
public MyReportPlugIn(IReportApiHost host) : base(host)
{
//
}
public string MyFunction1(string value)
{
return "Name=" + value.ToUpper();
}
public string MyFunction2(string value)
{
return "Name=" + value.ToLower();
}
}
}
Beispiel Funktionen sehen Sie wenn den Knopf Bespiel Quelltext aktivieren.
Um eine im Script vorhandene Funktion im Bericht zu verwenden klicken Sie im Bericht auf den Script Funktion Knopf.
Sie Syntax ist folgende:
{Fun. + Name der Funktion + ()}
Beispiel:
{Fun.MyFunction1()}
Funktionen können auch Parameter enthalten die an die Funktion übergeben werden können. Parameter statische Texte oder auch Feldnamen in geschweiften Klammern sein. Werden Feldnamen angegeben dann wird der Inhalt des Feldes an di Funktion übergeben.
Beispiele:
{Fun.MyFunction1("Rot")}
{Fun.MyFunction1("{A.NAME}")}
Komplexe Berichte
Ab Version 24.1.97
Wenn Sie Berichte haben die Sie nicht direkt mittels SQL erzeugen können sondern die mittels Programmierung vorverarbeitet müssen, dann können Sie folgendermaßen vorgehen:
Erzeugen Sie eine Hilfestabelle. Fügen Sie eine Spalte mit dem Namen "PRINT_TASK_ID" vom Typ Text mit der Länge 40 hinzu.
In dieser Tabelle erzeugen Sie dann mittels der Funktion "BeforePrinting" vor dem Drucken die Daten die im Berichts ausgegeben werden sollen. Und löschen Sie dann diese Datensätze in der Funktion "AfterPrinting" wieder.
Da mehrere Anwender gleichzeitig Drucken könnten wird die PRINT_TASK_ID benötigt. Geben Sie allen Datensätzen diese ID mit in dem Sie diese im Feld PRINT_TASK_ID speichern. Mit dieser ID hat jeder Druck Auftrag seine eigenen Werte.
Legen Sie im Bericht einen Parameter mit dem Namen "PrintTaskId" und dem Wert 0 ein.
Legen Sie einen Datenbereich an der der die Hilfstabelle ausgibt.
select WERT1,WERT2 from PRINT_TEMP where PRINT_TASK_ID='{Parameter.PrintTaskId}'
Der Parameter "PrintTaskId" wird dann zur Laufzeit im Code gesetzt. Siehe unten.
Eine andere Variante ohne die Benutzung von echten Tabellen sehen unten bei "Benutzung von Virtuelle/In Memory Tabellen"
Beispiel Code:
private string _taskId = "";
public override void BeforePrinting()
{
string filter = this.Report.GetParameter("Filter");
//Erzeuge eindeutige ID und merke sie dir
_taskId = System.Guid.NewGuid().ToString();
//PrintTaskId an den Bericht geben damit der SQL diesen benuzten kann.
this.Report.SetParameter("PrintTaskId", _taskId);
//Werte per Code erzeugen und in Hilfstabelle schreiben
for(int i=1;i<20;i++)
{
string wert1="Wert a"+i;
string wert2="Wert b"+i;
string sql = "insert into PRINT_TEMP (PRINT_TASK_ID,WERT1,WERT2) values ('" + _taskId + "','" + wert1 + "','" + wert2 + "')";
this.Report.SqlExecute(sql);
}
}
public override void AfterPrinting()
{
//Werte der Hilfstabelle wieder entfernen
string sql = "delete from PRINT_TEMP where PRINT_TASK_ID='" + _taskId + "'";
this.Report.SqlExecute(sql);
}
Benutzung von Virtuelle/In Memory Tabellen
Ab Version 24.1.140
Wenn Sie Berichte haben die Sie nicht direkt mittels SQL erzeugen können sondern die mittels Programmierung vorverarbeitet müssen, dann können Sie eine temporärer, virtuelle Tabelle im Speicher des Rechners anlegen.
Tragen Sie in das Band statt einem SQL Befehl folgendes ein
{Report.TableSource}
Dies sagt dem Programm das Sie eine In Memory Tabelle verwenden wollen.
Das Programm ruft dann am Anfang die Funktion OnInitTableSource in der Sie definieren können welche Spalten die Tabelle haben soll.
Wenn Sie diese für mehr als ein Band tun, benutzen sollten Sie "tableSource.BandAliasName" um herauszufinden um welches Band es sich handelt.
public override void OnInitTableSource(ReportTableSource tableSource)
{
if (tableSource.BandAliasName == "B")
{
//Tell the Report Designer what Columns the virtual Table has.
tableSource.AddColumn("FID");
tableSource.AddColumn("NAME");
}
}
Beim drucken des Berichtes wird dann vom Programm die Funktion OnQueryTableSource aufgerufen. In dieser können Sie nun die Daten hinzufügen.
Im Berichts Designer verwenden Sie dann als Feld Namen z.B.
{B.NAME}
Also den Bandaliasnamen plus dem Feldnamen (in Grossbuchstaben)
public override void OnQueryTableSource(ReportTableSource tableSource)
{
if (tableSource.BandAliasName == "B")
{
string fid = this.Report.Record.GetString("A.FID");
//Fill the virtual Table
//Try not to use this for huge amounts of data as all the data is loaded into Memory
for(int i=1; i<10; i++)
{
tableSource.AddRow();
tableSource.Write("FID", fid);
tableSource.Write("NAME","Name_" + i.ToString());
}
}
}
Bitte Spaltennamen bei tableSource.AddColumn und tableSource.Write immer in Großbuchstaben angeben. Ebenso im Report Designer {B.NAME}
Wenn Sie ein Plugin verwenden binden Sie bitte die DLL Mum.Geo.Shared.dll ein. Dort ist die Klasse ReportTableSource definiert.
Verweden Sie in OnInitTableSource und OnQueyTableSourcekein kein this.Report.Record das auf sich selbst, also das gleiche Band zugreift. Ansonsten wird kommt es zu einer Endlosschleife.
Verwendung einer .NET DLL (plugin) statt Skript Code.
Verfügbar ab Version 24.1.100
Im Skripting können Sie wahlweise auch eigene .NET Framework DLLs einbinden die z.B. mit Visual Studio erzeugt wurden.
Die bietet unter anderem den Vorteil das Sie den Code debuggen können. Bedenken Sie immer das die DLL auf dem MapEdit Web server ausgeführt werden und nicht auf dem Client.
Achten Sie darauf das Sie im Code keine MessageBoxen oder UI Element aufrufen oder verwenden. Das Plugin läuft immer auf dem WebServer und nicht auf dem Client. D.h. beim Endkunden kann der Kunde kein MessageBoxen bestätigen oder UI Element eingeben. Verwenden Sie this.Report.WriteError/WriteLog um Fehler oder Log Meldungen auszugeben.
Erzeugen Sie mit Visual Studio eine DLL vom Typ "Class Library .NET Framework". Sie müssen .NET Framework 4.8 verwenden und die Target Platform muss auf "x64" gesetzt sein.
Erzeugen Sie eine Referenz auf die DLLs XSystem.dll und Mum.Geo.Shared.dll und stetzen beim einbinden "CopyLocal=False" so das diese nicht ins Ausgabe Verzeichnis kopiert werden.
Erzeugen Sie dann eine Klasse mit dem Namen MyReportPlugIn die von ReportPlugIn ableitet.
Hier das Grundgerüst der Klasse. Diese Grundgerüst ist 1:1 wie im Skripting.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XSystem;
using Mum.Geo.ReportDesigner;
namespace MeinBericht
{
public class MyReportPlugIn : ReportPlugIn
{
public MyReportPlugIn(IReportApiHost host) : base(host)
{
//
}
}
}
Ihre fertige DLL muss auf dem MapEdit Server unter:
C:\inetpub\wwwroot\MumGeoData\Repositories\Default\Plugins\ReportDesigner\
abgelegt werden (bzw. ihrem Repository Ordner)
Das Unterverzeichnis "ReportDesigner\" muss händisch erzeugt werden.
Zum testen sollten Sie den MapEdit Server lokal auf dem gleichen Rechner installiert haben wo Sie mit Visual Studio entwickeln.
Tragen Sie bei Ouput Path
C:\inetpub\wwwroot\MumGeoData\Repositories\Default\Plugins\ReportDesigner\
ein.
Um ihre DLL Klasse zu laden muss im Skripting Edit der Report Designers (nicht in Visual Studio) im Konstruktor folgendes angegeben werden:
public MyReportPlugIn(IReportApiHost host) : base(host)
{
//MAPEDIT_REGISTER_FUNCTION "MyFunction1(value)"
//MAPEDIT_REGISTER_FUNCTION "MyFunction2(value1,value2)"
_plugin = this.Report.LoadReportPlugIn("MeineFirma.MeinBeispiel1", host);
}
public string MyFunction1(string value)
{
return "Name=" + value.ToUpper();
}
public string MyFunction2(string value1, string value2)
{
return value1 + value2
}
Der Befehl LoadReportPlugIn läd ihre DLL, erzeugt eine instanz ihrer Klasse und verbindet diese mit dem Bericht. Wobei bei "MeineFirma.MeinBeispiel1" der Name ihrer DLL ohne die Endung ".dll" und ohne Pfadangabe stehen muss.
Die "Kommentare"
//MAPEDIT_REGISTER_FUNCTION "Ihr Funktinonsname()"
Teilen der Berichts Designer UI mit welche Funktionen im Berichtsdesigner in der Auswahlliste angezeigt werden sollen. Damit kann der Anwender diese aus der Liste wählen. Die muss im Skripting gemacht werden, nicht in der DLL!
Zum debuggen der DLL ist zu beachten das Visual Studio mit Windows Admin Rechten ausgeführt werden muss!! Dies ist wichtig!!
Desweiteren muss in der gleichen Visual Studio Solution ein Projekt vom Typ
"ASP.NET Web Application(.NET Framework) / (ASP.NET Web Anwendung)" angelegt werden vom Typ "Empty/Leer".
Diese Projekt dient nur zum starten des Debuggens via Start "Local IIS (Google Chrome)"
Gehen Sie sicher das "Local IIS" eingestellt ist.
Bei den Visual Studio Optionen diesen Projektes geben Sie bei "START URL" die URL des Berichtes an.
Die URL bekommen Sie im Berichtsdesigner mit dem Knopf "Get Report URL".
Beispiel URL:
http://localhost/mum.geo.services_Preview/../Mum.Geo.Server.Report/CreatePdf.ashx?ReportName=LASVEGAS_STRASSEN&Format=Pdf
Fügen Sie für das Debuggen der DLL am Ende dieser URL folgendes hinzu:
&Debug=True
Dies ist wichtig, ansonsten wird beim ändern der DLL diese nicht neu geladen und die bereits geladene DLL im Speicher befindliche DLL verwendet.
Verwenden Sie "&Debug=True" immer nur für das Testen mit dem Debugger und nie im Echt Berieb. Ansonsten geht Performance des Berichtes verloren und der Speicher wird schnell verbraucht! Für das Testen/Debuggen wird immer eine neue Instanz der DLL geladen und alte Instanzen werden erst beim Neustart des IIS entladen!
Vor dem ausführen des debuggens sollten sie immer neu kompilieren!
Der Bericht muss vor dem Debuggen im Berichtsdesigner gespeichert werden um den aktuellen Stand des Berichtes zu sehen.
Wenn der Debugger nicht funktioniert prüfen Sie alle oben aufgeführten Schritte und gehen Sie sicher das der MapEdit WebServer auf ihrer Lokalen Maschine ausgeführt wird und nicht auf einem anderen Rechner.
Mit
this.Report.DebugMode
können Sie im Code prüfen ob der Bericht im Debug Modus ausgeführt wird bzw ob der Bericht mit "&Debug=True" aufgerufen wurde.
Wenn Sie den Bericht mit den "LOG" Informationen starten wollen ändern Sie in der URL den Wert
&Format=Pdf&
um in
&Format=PdfWithLog&
Hochladen der Report Plugin DLL auf den Produktive Server
Klicken Sie im Reporsitor auf "Berichts Designer" (nich auf einen Bericht!). Klicken Sie dann "Upload Report Plugin" und wählen Sie ihre Report Plugin DLL.
Der Upload läd diese dann auf dem MapEdit Web Server unter
C:\inetpub\wwwroot\MumGeoData\Repositories\Default\Plugins\ReportDesigner\
hoch.
Wie öffne ich einen Berichte via API
Wenn Sie den Bericht aus eigenen MapEdit Fachschalen Plugins öffnen wollen können Sie die vorhandene API Funktion nutzen.
siehe API Hilfe:
https://help.mapedit.de/api/DesktopApi/Weitere_Beispiele#mapedit-berichte-%C3%B6ffnen
Wenn Sie Berichte in eine eigene, Nicht MapEdit Applikationen einbinden wollen und keinen Zugriff auf di MapEdit API haben dann können Sie diese direkt via URL Aufrufen.
Wenn Sie Parameter übergeben wollen müssen diese in der URL encoded mit übergeben werden.
Nuzten Sie z.B. Micrsoft C# Funktion "WebUtility.UrlEncode" für das encoding.
Beispiel:
Wir wollen die folgenden Parameter und Werte übergeben
Filter: (1=1) limit 5
LOGIN_USERNAME: ADMINISTRATOR
LOGIN_USERCOMMENT: Hallo
Ergeben diese URL
http://localhost/mum.geo.services_Preview/../Mum.Geo.Server.Report/CreatePdf.ashx?ReportName=LASVEGAS_STRASSEN&Format=Pdf&Parameter=Filter%3D(1%253D1)%2Blimit%2B5%26ReportId%3D0%26%2524LOGIN_USERNAME%2524%3DADMINISTRATOR%26%2524LOGIN_USERCOMMENT%2524%3DHallo
Achten Sie darauf das in der URL für den Endanwender "&Debug=True" nicht enthalten ist!!
Ansonsten wird ihr Server extrem langsam werden!!
Benutzen Sie "&Debug=True" immer nur für eigene testst mit der API!