Dynamisches Prompten eines CL-Befehls auf IBM i mit Blazor und NTi

In diesem Artikel erfahren Sie, wie Sie mit Toolbox Extension, NTi und Blazor dynamisch Eingabeschnittstellen für beliebige IBM i / AS400 CL-Befehle generieren können. Ein moderner, generischer und nativer .NET-Ansatz als Ergänzung zu den 5250-Bildschirmen.

Illustrationsbild zu Artikel

Wenn es darum geht, CL(CMD)-Befehle auf IBM i auszuführen, gehen die meisten Benutzer immer noch über die traditionellen grünen Bildschirme (5250). Diese Schnittstellen sind zwar für Insider effektiv, aber für Nutzer mit wenig oder keinen IBM i-Kenntnissen oft komplex und wenig intuitiv. Heute gibt es Lösungen, um die Benutzererfahrung zu modernisieren, zu vereinfachen und zu bereichern.

Mit NTi und seiner Toolbox-Erweiterung, die als NuGet-Paket erhältlich ist, können Sie die System-API direkt abfragen QCDRCMDD, die von IBM bereitgestellt wird, um automatisch die vollständige Beschreibung eines CL-Befehls abzurufen.

Die Methode RetrieveCommandDefinition() kapselt diese Operation vollständig ab, indem sie sie automatisch durchführt:

  • 1️⃣ Der Anruf der API.
  • 2️⃣ Das Abrufen des XML-Feeds (CDML) der Bestellung.
  • 3️⃣ Die Deserialisierung dieses Streams in ein stark typisiertes C#-Objekt, das direkt in Ihren .NET-Anwendungen verwendet werden kann.

Je nach Ihren Bedürfnissen können Sie :

  • Direktes Abrufen des rohen XML mit der Methode RetrieveCommandDefinitionXml() zur benutzerdefinierten Auswertung, insbesondere über APIs oder externe Analysetools.

XML-Fluss des CL-Befehls CRTLIB aus QCDRCMDD

  • Verwenden Sie das strukturierte C#-Objekt, das von RetrieveCommandDefinition() zurückgegeben wird, um automatisch und dynamisch moderne Benutzeroberflächen zu erzeugen, insbesondere mit Blazor, wie in diesem Tutorial veranschaulicht.

CmdDefinition-Objekt in C# deserialisiert

So wird aus einer einzigen Anweisung

CommandDefinition commandDef = Conn.RetrieveCommandDefinition("CRTLIB", "QSYS", false);

Sie erhalten eine vollständige und sofort verwertbare Beschreibung in Ihrem Code, die unter anderem Folgendes umfasst:

  • Die umfassende Liste der Parameter (obligatorisch und optional)
  • ihre genauen Typen (Text, numerisch, qualifiziert, Liste usw.)
  • Standard-, Sonder- und einmalige Werte
  • Talle bedingten Abhängigkeiten (Control Prompt) zwischen den Parametern
  • Die detaillierten Subelemente jedes komplexen Parameters

Diese Fähigkeit, die Struktur von CL-Befehlen dynamisch zu generieren, eröffnet neue Nutzungsmöglichkeiten wie die Erstellung interaktiver Formulare mit automatischer Vorbefüllung, die fortgeschrittene Automatisierung von Parametervalidierungen und die automatische Generierung fertiger CL-Befehle, um deren Ausführung und Wiederverwendung zu vereinfachen.

💡 Der in diesem Artikel vorgestellte Code dient lediglich der Veranschaulichung. Er stellt keine endgültige oder optimierte Lösung für alle Nutzungskontexte dar. Er veranschaulicht lediglich, was mit den Methoden der Toolbox Extensions NTi und Blazor möglich ist.

Das Szenario: eine dynamische Schnittstelle für einen beliebigen CL-Befehl erstellen

Um diese Möglichkeiten konkret zu veranschaulichen, werden wir in diesem Tutorial eine Blazor Web App (.NET 8) erstellen, die sich auf NTi und die Toolbox-Erweiterung stützt. Das Ziel wird sein, eine dynamische, generische Schnittstelle zu bauen, die es ermöglicht:

  • Die detaillierte Struktur eines beliebigen CL-Befehls (Standard oder benutzerdefiniert) zu laden.
  • Automatisch passende Eingabefelder zu generieren (Text, Dropdown-Listen, Kontrollkästchen usw.).
  • Die komplette, gebrauchsfertige CL-Syntax dynamisch aufzubauen.
  • Diesen bestätigten Befehl direkt auf IBM i auszuführen.

Das Ganze wird in einer modernen Benutzeroberfläche mit dem IBM Carbon-Design präsentiert, die sich radikal vom traditionellen IBM i-Ansatz unterscheidet.

Blazor-Formular für CL CRTLIB generiert

Schritt 1: Die Struktur einer Bestellung dynamisch laden

Im ersten Schritt wird die komplette Struktur eines vom Benutzer eingegebenen CL-Befehls dynamisch geladen. Diese Struktur wird dann ausgewertet, um die Felder des Eingabeformulars automatisch zu generieren.

Zuallererst muss eine klassische Verbindung zum IBM i über NTi hergestellt werden:

  • Installieren Sie das NuGet-Paket Aumerial.Data.Nti (NTi Data Provider).
  • Fügen Sie dann das NuGet-Paket Aumerial.Toolbox hinzu, um auf die CL-Methoden zuzugreifen.
  • Instantiieren Sie eine NTiConnection, die auf Ihren IBM i zeigt, und verweisen Sie auf die beiden Pakete in Ihrem Projekt.

Sobald diese Konfiguration vorgenommen wurde, kann die Anwendung das System abfragen, um die vollständige Beschreibung einer Bestellung abzurufen.

Konkret: Sobald der Benutzer den Namen eines Befehls eingibt (z. B. CRTLIB), fragt die Blazor-Anwendung die IBM i API über NTi ab und ruft alle Informationen ab, die für den dynamischen Aufbau des Formulars erforderlich sind.

1️⃣ Meldung interner Datenstrukturen

Im Code der Blazor-Komponente deklarieren wir mehrere Variablen, die den Status des Formulars verwalten und die vom Benutzer eingegebenen Werte speichern werden:

// Hauptgegenstand, der die vollständige Definition des Auftrags enthält
private CommandDefinition? Command;
// Der aktuell ausgewählte Befehl
private Command? SelectedCommand;
// Speichern der einfachen Werte, die jedem Schlüsselwort (Kwd) der Befehlsparameter zugeordnet sind
private Dictionary CommandValues = new();
// Verwaltung von qualifizierten Parametern (z.B. Datei(NAME/LIB))
private Dictionary> QualifierValues = new();
// Erlaubt dem Nutzer, einen benutzerdefinierten Wert einzugeben (Override)
private Dictionary> QualifierCustom = new();
// Verwaltung von Unterelementen eines komplexen Parameters vom Typ ELEM
private Dictionary> ElementValues = new();
// Verwaltung von Mehrfachauswahlen über Kontrollkästchen
private Dictionary> CheckedValues = new();

Mithilfe dieser Wörterbücher kann jeder Datentyp, der mit den verschiedenen Parametern verknüpft ist, unabhängig und isoliert verwaltet werden, wodurch eine übersichtliche Verwaltung gewährleistet wird.

2️⃣ *Dynamisches Abrufen und Initialisieren von Daten

Wenn ein Benutzer einen Befehl eingibt und bestätigt, wird die Methode RetrieveCommandDefinition() aufgerufen:

try
{
    // Aufruf der Methode RetrieveCommandDefinition() von NTiConnection über Toolbox
    Command = await Task.Run(() => DBService.Conn.RetrieveCommandDefinition(CommandName.ToUpper(), "QSYS", true));
    // Überprüfen, ob eine gültige Bestellung zurückgegeben wurde
    if (Command != null && Command.CmdDefinition.Any())
    {
        // Auswahl des ersten zurückgegebenen Befehls
        SelectedCommand = Command.CmdDefinition.FirstOrDefault();
        if (SelectedCommand != null)
        {
            // Wörterbücher vor der Verwendung zurücksetzen
            CommandValues.Clear();
            QualifierValues.Clear();
            QualifierCustom.Clear();
            CheckedValues.Clear();
            ElementValues.Clear();
            // Parameterdurchlauf für individuelle Initialisierung
            foreach (var param in SelectedCommand.Parameters)
            {
                // Speicherung des Standardwerts oder leer, wenn nicht definiert
                CommandValues[param.Kwd] = param.Dft ?? string.Empty;
                // Initialisierung der Checkboxen für Einstellungen mit mehreren Auswahlmöglichkeiten
                if (param.SpecialValues.Any() && int.TryParse(param.Max, out int max) && max > 1)
                {
                    CheckedValues[param.Kwd] = new Dictionary();
                    foreach (var spcVal in param.SpecialValues.SelectMany(s => s.SpecialValues))
                    {
                        CheckedValues[param.Kwd][spcVal.Value] = false;  // aucune sélection cochée par défaut
                    }
                }
                // Initialisierung von qualifizierten Parametern (Typ QUAL, z. B. FILE(NAME/LIB))
                QualifierValues[param.Kwd] = new Dictionary();
                QualifierCustom[param.Kwd] = new Dictionary();

                int qualIndex = 0;
                foreach (var qual in param.Qualifiers)
                {
                    var key = !string.IsNullOrEmpty(qual.Prompt) ? qual.Prompt : $"{qual.Type}_{qualIndex++}";
                    
                    // Wenn der Parameter vom Typ QUAL ist, initialisieren Sie die Werte standardmäßig auf leer
                    QualifierValues[param.Kwd][key] = param.Type == "QUAL" ? "" : (qual.Dft ?? "");
                    QualifierCustom[param.Kwd][key] = ""; // anfänglich immer leer für eine mögliche Benutzereingabe
                }

                // Initialisierung von Unterelementen für komplexe Parameter (Typ ELEM)
                ElementValues[param.Kwd] = new Dictionary();
                foreach (var elem in param.Elements)
                {
                    ElementValues[param.Kwd][elem.Prompt] = elem.Dft ?? string.Empty;
                }
            }
        }
    }
}
catch (Exception ex)
{
    errorMessage = ex.Message;
}

Sobald die vollständige Struktur des Befehls abgerufen wurde, bestätigen wir, dass er korrekt definiert ist, und initialisieren die internen Wörterbücher, um jeden Wert, der mit diesem Befehl verbunden ist, separat zu speichern. Konkret durchlaufen wir jeden von der API zurückgegebenen Parameter, um festzustellen:

  • Die Standardwerte, die in einfachen Feldern angezeigt werden sollen,
  • Mehrfachoptionen (Kontrollkästchen) und ihr Anfangszustand (standardmäßig nicht markiert),
  • Die möglichen qualifizierten Werte (Name/Bibliothek), die dem Nutzer präsentiert werden sollen,
  • Unterelemente komplexer Einstellungen, die getrennt angezeigt werden sollen.

Dynamische Blazor-Oberfläche mit abhängigen Feldern

Diese Vorgehensweise garantiert, dass alle notwendigen Informationen, die in unseren Wörterbüchern klar strukturiert und isoliert sind, sofort zur Verfügung stehen, um dynamisch eine Schnittstelle zu erstellen, die für jeden CL-Auftrag geeignet ist, unabhängig von seiner Komplexität oder seinen Besonderheiten, mit der Gewissheit, dass alle Felder korrekt vorausgefüllt sind, dass die Dropdown-Listen, Checkboxen und bedingten Felder perfekt funktionieren und dass der Auftrag dynamisch ohne Informationsverlust rekonstruiert wird.

👉 Weitere Details über die zurückgegebene Struktur finden Sie in der Dokumentation der Methode RetrieveCommandDefinition.

Schritt 2: Eingabefelder dynamisch generieren

Sobald die vollständige Struktur des CL-Befehls geladen und unsere Zustandswörterbücher initialisiert sind (siehe Schritt 1), können wir in unserer Blazor-Schnittstelle dynamisch die für jeden Parameter geeigneten Eingabefelder erzeugen, die die von der IBM i über NTi zurückgegebenen Parameter getreu wiedergeben.

Konkret wird jeder Parameter aus SelectedCommand.Parameters durchlaufen und eine bedingte Logik angewendet, die es ermöglicht, dynamisch die richtige Komponente anzuzeigen, je nach Typ und den auf der Seite von IBM i definierten Einschränkungen: einfacher Typ, spezielle Werte, qualifizierter Parameter, verschachtelte Elemente, Mehrfachauswahl usw.

Eine von Metadaten gesteuerte Logik

Jeder Parameter wird in einer @foreach-Schleife verarbeitet, und je nach seinen Eigenschaften (Type, SpecialValues, Elements, etc.) wird ein spezifisches Rendering erstellt. Diese Logik beruht auf if/else-Blöcken, die die von der API bereitgestellten Metadaten für jedes Feld dynamisch interpretieren.

@foreach (var param in SelectedCommand.Parameters)
{
    if (param.Type == "QUAL")
    {
        foreach (var key in QualifierValues[param.Kwd].Keys)
        {
            <input class="bx--text-input" @bind="QualifierValues[param.Kwd][key]" placeholder="@key" />
        }
    }
    else if (param.SpecialValues.Any())
    {
        <select class="bx--select-input" @bind="CommandValues[param.Kwd]">
            <option value="">Choisir</option>
            @foreach (var val in param.SpecialValues.SelectMany(s => s.SpecialValues))
            {
                <option value="@val.Value">@val.Value</option>
            }
        </select>
    }
    else if (param.Elements.Any())
    {
        <fieldset>
            @foreach (var elem in param.Elements)
            {
                <input class="bx--text-input" @bind="ElementValues[param.Kwd][elem.Prompt]" placeholder="@elem.Prompt" />
            }
        </fieldset>
    }
    else if (param.Type == "CHAR")
    {
        <input class="bx--text-input" @bind="CommandValues[param.Kwd]" placeholder="@param.Prompt" maxlength="@param.Len" />
    }
}

Dynamische Generierung von CL-Eingabefeldern

Las Rendering ist nicht nur dynamisch in seiner Struktur, sondern passt sich auch dem erwarteten Verhalten auf der IBM i-Seite an, dank der Metadaten, die von der API über NTi zurückgegeben werden.

  • Die maximal zulässige Länge (param.Len)
  • Der Vorschlagstext (param.Prompt)
  • Die Standardwerte (param.Dft)
  • Die zulässigen Werte (SpecialValues)
  • Eingabegruppen (qualifiziert, verschachtelte Elemente)

Wenn ein Parameter vom Typ CHAR mit einem Standardwert eine Länge von 10 Zeichen hat, wird dieser automatisch vorausgefüllt und die Länge durch das Attribut maxlength auf 10 begrenzt. Wenn der Parameter einen qualifizierten Wert erwartet (z. B. Datei + Bibliothek), werden mehrere Felder angezeigt und mit ihren Unterteilen verknüpft. Jedes Feld wird direkt an früher initialisierte Zustandswörterbücher (CommandValues, QualifierValues, ElementValues usw.) gebindent, sodass die eingegebenen oder ausgewählten Werte ohne weitere Verarbeitung sofort erfasst werden können.

Verwaltung von Abhängigkeiten

Einige Befehle integrieren auch bedingte Abhängigkeiten zwischen Parametern, die als Control Prompt bekannt sind und über SelectedCommand.Dependencies offengelegt werden. Diese Regeln können in der Komponente ausgewertet werden, um bestimmte Felder zu deaktivieren, vorauszufüllen oder obligatorisch zu machen, je nachdem, welche Werte in andere Felder eingegeben werden. Beispiel: Wenn der Parameter TYPE den Wert *USR hat, dann wird OWNER zum Pflichtfeld.

In diesem Tutorial wird nicht im Detail auf ihre Verwaltung in der Schnittstelle eingegangen, aber alle notwendigen Elemente sind über die Methode RetrieveCommandDefinition() zugänglich, sodass sie leicht in die Bazor-Komponente integriert werden können.

Schritt 3: Dynamisches Konstruieren des auszuführenden CL-Befehls

Zu diesem Zeitpunkt sind alle Felder der Schnittstelle gefüllt und ihre Werte in den internen Wörterbüchern (CommandValues, QualifierValues, ElementValues, usw.) gespeichert. Das Ziel ist es nun, die vollständige Syntax des CL-Befehls aus den gesammelten Daten dynamisch als ausführungsfertigen String auf der IBM i-Seite zu rekonstruieren.

Diese Implementierungslogik wird in einer eigenen Methode zentralisiert: BuildCommandCL():

string BuildCommandCL()
{
    var commandCl = SelectedCommand.CommandName.ToUpperInvariant().Trim() + " ";
    foreach (var param in SelectedCommand.Parameters)
    {
        if (!string.IsNullOrWhiteSpace(CommandValues[param.Kwd]))
        {
            string value = CommandValues[param.Kwd].ToUpperInvariant().Trim();
            if (param.Kwd.Equals("TEXT", StringComparison.OrdinalIgnoreCase))
            {
                value = $"'{value}'"; // Le champ TEXT est entre quotes
            }
            commandCl += $"{param.Kwd.ToUpperInvariant()}({value}) ";
        }
        else
        {
            var segment = new List();

            // Verschachtelte Elemente (ELEM)
            if (ElementValues.TryGetValue(param.Kwd, out var elements))
            {
                var values = elements.Values.Where(v => !string.IsNullOrWhiteSpace(v))
                                            .Select(v => v.ToUpperInvariant().Trim()).ToList();
                if (values.Any())
                {
                    segment.Add($"{param.Kwd.ToUpperInvariant()}({string.Join(" ", values)})");
                }
            }

            // Qualifizierte Parameter (QUAL)
            if (QualifierValues.TryGetValue(param.Kwd, out var qualifiers) &&
                QualifierCustom.TryGetValue(param.Kwd, out var customQualifiers))
            {
                var values = qualifiers.Keys.Select(key => !string.IsNullOrWhiteSpace(customQualifiers[key])
                                                           ? customQualifiers[key]
                                                           : qualifiers[key])
                                             .Where(v => !string.IsNullOrWhiteSpace(v)).ToList();

                if ((param.Kwd == "FILE" || param.Kwd == "SRCFILE") && values.Count < 2)
                {
                    // Nichts generieren, wenn eines der Elemente fehlt
                }
                else if (values.Any())
                {
                    var combined = string.Join("/", values.AsEnumerable().Reverse());
                    segment.Add($"{param.Kwd.ToUpperInvariant()}({combined.ToUpperInvariant().Trim()})");
                }
            }

            // Mehrfachauswahlen (Checkbox)
            if (CheckedValues.TryGetValue(param.Kwd, out var checkDict))
            {
                var checkedValues = checkDict.Where(x => x.Value).Select(x => x.Key.ToUpperInvariant().Trim());
                if (checkedValues.Any())
                {
                    segment.Add($"{param.Kwd.ToUpperInvariant()}({string.Join(",", checkedValues)})");
                }
            }

            if (segment.Any())
            {
                commandCl += string.Join(" ", segment) + " ";
            }
        }
    }
    return commandCl.Trim();
}

Man initialisiert den endgültigen Befehl ausgehend vom Hauptnamen (DLTLIB, CRTLIB, usw.), gefolgt von einer Reihe von Parametern, die je nach ihrem Typ dynamisch formatiert werden. Für jeden Parameter werden mehrere Fälle behandelt.

  • Wenn ein einfacher Wert eingegeben wird CommandValues, wird er direkt hinzugefügt, wobei der Parameter TEXT (umgeben von einfachen Anführungszeichen) besonders behandelt wird.
  • Wenn kein einfaches Feld ausgefüllt ist, werden die Sekundärstrukturen analysiert
  • Bei verschachtelten Parametern vom Typ ELEM setzt man die Unterwerte zusammen, indem man sie durch ein Leerzeichen trennt.
  • Bei qualifizierten QUAL-Parametern werden die Unterwerte (z. B. Datei/Bibliothek) kombiniert, wobei eventuelle manuelle Eingaben berücksichtigt werden (Override). Man vermeidet es, den Parameter hinzuzufügen, wenn ein Teil fehlt (insbesondere bei kritischen Paaren wie FILE).
  • Bei Mehrfachwerten checkbox werden alle gewählten Optionen mit einem Komma verkettet, wie in OPTION(*SRC, *MBR).

Jedes Segment wird in Großbuchstaben umgewandelt, bereinigt und dann mit dem Hauptbefehl verkettet. Das Endergebnis ist ein vollständiger, sauberer, konformer und ausführbarer CL-Befehl auf der IBM i-Seite - genau so, als wäre er in ein 5250-Terminal eingegeben worden, hier jedoch dynamisch von einer modernen Schnittstelle aus generiert.

Dynamisch in Blazor erstellter CL-Befehl

Schritt 4: Den Befehl auf der IBM i-Seite ausführen

Nachdem der Befehl erstellt wurde (siehe Schritt 3), muss er nur noch auf dem IBM i ausgeführt werden. Dies geschieht in zwei Schritten: zunächst wird die Syntax überprüft, dann wird der Befehl tatsächlich ausgeführt. Dies geschieht in einer Methode SubmitCommand(), die beim Absenden des Blazor-Formulars aufgerufen wird:

private async Task SubmitCommand()
{
    messageSubmit = "";
    string commandCL = BuildCommandCL();
    try
    {
        DBService.Conn.CheckCLCommand(commandCL); // Prüft die Syntax, ohne auszuführen
        DBService.Conn.ExecuteClCommand(commandCL); // Führt den Befehl aus
        messageSubmit = "Commande envoyée avec succès.";

        await Task.Delay(4000); // Pause vor dem Zurücksetzen
        ResetForm();            // Leere das Formular
        ResetGenerateCommand(); // Leert den angezeigten Befehl
    }
    catch (Exception ex)
    {
        messageSubmit = $"{ex.Message}"; 
    }
}

1️⃣ Vorabprüfung mit CheckCLCommand().

Vor dem Absenden muss man den erzeugten Befehl bestätigen. Dies wird mit der Methode CheckCLCommand() überprüft, die auch über [NTi Toolbox Extension] (https://www.documentation.aumerial.com/toolbox/commande-CL/check-cl-command) verfügbar ist. Sie fragt die IBM i ab, um die vollständige syntaktische Gültigkeit des Befehls zu analysieren, ohne ihn auszuführen: unbekannte Schlüsselwörter, falsch formatierter Wert, fehlender obligatorischer Parameter. Diese Vorabprüfung vermeidet Fehler im laufenden Betrieb, indem sie exakt das gleiche Verhalten wie das System in der 5250-Umgebung nachbildet.

Syntaxprüfung mit CheckCLCommand

2️⃣ Ausführung mit ExecuteClCommand().

Nach der Bestätigung wird der Befehl über ExecuteClCommand() weitergeleitet, eine Methode, die von der Klasse NTiConnection des NTi DataProvider ausgestellt wird. Sie wird in der bereits geöffneten Sitzung ausgeführt - mit ihrer kompletten Umgebung: Benutzer, aktiver Job, aktuelle Bibliothek, Berechtigungen. Alle Rückmeldungen oder Systemfehler werden so wiedergegeben, als ob der Befehl direkt von einem IBM i-Terminal aus gestartet worden wäre.

Ausführung des CL mit ExecuteClCommand

Was auf der Blazor/.NET-Seite kontrolliert wird

Der gesamte Prozess wird in der .NET-Anwendung beherrscht. Sie orchestriert:

  • Die dynamische Generierung des CL-Befehls mit BuildCommandCL() aus den in der Schnittstelle eingegebenen Werten.
  • Syntaxvalidierung durch CheckCLCommand(), die das Verhalten des Systems simuliert, ohne den Befehl tatsächlich auszuführen.
  • Die tatsächliche Ausführung mit ExecuteClCommand(), im Kontext der IBM i-Sitzung (Job, Benutzer, aktuelle Bibliothek).
  • Die Behandlung von Fehlern und Meldungen über einen Try/Catch-Block, um dem Benutzer das Feedback des IBM i-Systems zurückzugeben.

Der Befehl wurde erfolgreich ausgeführt und zeigt uns die Erfolgsmeldung an

Erfolgsmeldung nach CL-Ausführung

Und die Bibliothek ist auf unserem IBM i gut angelegt:

MYLIB-Bibliothek auf IBM i erstellt

Schlussfolgerung

Mit RetrieveCommandDefinition() und RetrieveCommandDefinitionXml(), die von ToolboxExtension angeboten werden, können Sie dynamisch Eingabeschnittstellen für jeden CL-Befehl erzeugen, indem Sie einfach auf die von der QCDRCMDD API zurückgegebenen Metadaten zurückgreifen.

RetrieveCommandDefinition()` kapselt diesen Prozess auf der .NET-Seite vollständig: Es fragt die IBM i-API ab, ruft den XML-Stream im CDML-Format ab, dekodiert ihn und deserialisiert ihn zu einem stark C#-geprägten Objekt. Es ist kein manuelles Parsen oder Manipulieren von XML erforderlich. Die gesamte Befehlsstruktur (Parameter, Typen, Werte, Abhängigkeiten...) ist sofort verfügbar und kann in Ihrem Code verwendet werden.

Diese Abstraktion reduziert den Arbeitsaufwand auf der Entwicklungsseite erheblich, sodass man sich ausschließlich auf UX und Geschäftslogik konzentrieren kann, ohne jemals die Struktur jedes Befehls manuell zu codieren.

Vor allem aber verlassen Sie endlich den starren Rahmen eines 5250-Terminals. Ihre Oberfläche wird portabel und ist über einen Browser, eine Geschäftsanwendung, einen Client oder eine containerisierte Plattform zugänglich. Mit anderen Worten, diese Änderung des Ansatzes eröffnet neue Nutzungsmöglichkeiten:

  • Vereinfachte Formulare für nicht spezialisierte IBM i-Teams
  • Zentralisierung von Bestellungen in einem Verwaltungsportal
  • Integration in DevOps-Workflows oder Support-Tools
  • Automatisierung von System- oder technischen Aufgaben, ohne Green Session

Sie verlassen das IBM i nicht - Sie erweitern es. In Richtung Web, in Richtung .NET, in Richtung morgen.

Die Toolbox-Methoden sollen Ihre IBM i-Kenntnisse nicht ersetzen, sie befreien Sie von der technischen Komplexität und verlängern sie in ein neues, agileres und zugänglicheres Ökosystem. Eine Zeitersparnis auf der Entwicklungsseite und eine klare Wertsteigerung Ihrer Anwendungen.


Quentin Destrade