[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Nov 2015
    Beiträge
    80

    Eigene Funktionen erstellen

    Hallo,

    Ist es im AS400 Umfeld möglich sich eigene Funktionen zu bauen.

    Beispiel: Ich hätte ein Feld was ich immer +5 und anschließend -4 rechnen muss, in sehr vielen verschiedenen Programmen...
    Nun würde ich eine Funktion (z.b. %rechnen) erstellen in der ich das Feld nur noch angebe.
    Etwas wie %rechnen(Feld1).
    Prinzipiell genau das gleiche wie mit %trim %date etc etc..

    Danke im Voraus, ich hoffe ich habe das einigermaßen verständlich erklärt.

    Grüße

  2. #2
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... diese Dinger heißen Subprocedure und können mit RPG oder einer andere ILE language erstellt werden, müssen allerdings einen erlaubten Namen haben (kein "%" am Anfang) und gebunden werden.

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  3. #3
    Registriert seit
    Aug 2001
    Beiträge
    2.873
    Das folgende Redbook (überarbeitet im Dezember 2016) liefert in Kapitel 3 und 4 eine ganz gute Beschreibung mit Beispielen, wie Funktionen, Prozeduren, Module, Service-Programme erstellt werden können.
    Who Knew You Could Do That with RPG IV? Modern RPG for the Modern Programmer

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  4. #4
    Registriert seit
    Nov 2015
    Beiträge
    80
    super, danke für die Rückmeldungen.
    Besonders das Redbook sieht sehr interessant aus, werde ich mir die Tage mal genauer ansehen.

    Grüße
    Max

  5. #5
    Registriert seit
    Nov 2015
    Beiträge
    80
    Leider bräuchte ich bezüglich dem Thema nochmal Hilfe..
    Ich habe mich an dem einfachen Beispielcode aus dem Redbook orientiert.
    Beim Umwandeln sagt er mir jedoch das nicht bestimmt werden kann wie das pgm enden soll.
    Umgewandelt wird als rpgle
    Code:
    ctl-opt dftactgrp(*no) ;
    dcl-pr Afunction packed(10:0);
    packed1 packed (5:0);
    packed2 packed (5:0);
    end-pr;
    dcl-Proc Afunction;
    dcl-pi Afunction packed(10 : 0);
    AnInputParm1 packed (5 : 0);
    AnInputParm2 packed(5 : 0);
    end-pi;

    Dcl-s AReturnValue packed(10 : 0);
    AReturnValue = AnInputParm1 + AnInputParm2;
    Dsply AReturnValue;
    Return AReturnValue;
    end-proc ;

    Danke schonmal

    Max

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    So kannst du kein Programm erstellen.
    Der Unterschied zwischen Programm und Funktion ist die Erstellung.
    Funktionen erstellt man mit CRTxxxMOD-Befehlen.
    Funktionen werden in Serviceprogrammen angeboten (die dann die Module enthalten) oder können auch direkt in einem Programm eingebunden werden.
    Das Ganze ist in den ILE-Konzepten auch beschrieben.

    Wenn du ein Programm erstellst, dann hat dies automatisch eine "Main"-Funktion die vom System aufgerufen werden kann und auch beendet werden muss (Return oder *INLR = *ON), eigentlich so wie immer.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  7. #7
    Registriert seit
    Nov 2015
    Beiträge
    80
    Ok den Aufbau habe ich denke ich ungefähr verstanden...
    Ein Programm besteht aus mehreren Modulen. Diese Können ein oder mehrere Prozeduren enthalten.
    Dabei ist es egal ob es sich um eine Main- oder eine Subprozedur handelt. Wobei der Unterschied zwischen einer Main- und Subprozedur in der "Zyklusverarbeitung" liegt.
    Kann man das so sagen?

    So.., versuche ich nun mit CRTRPGMOD(da das Modul später in einem RPGLE verwendet werden soll) umzuwandeln kommt trzd. die Meldung Programm kann nicht beendet werden..
    Füge ich einen LR ein meldet er „*RNF0256 301 Bestimmung zwischen Prozeduren gefunden. Bestimmung ignoriert.

    Wirklich nochmal vielen Dank für die Hilfe, ist echt nicht so einfach wenn man sich das alles selbst mit Skripten und Beispielen im Selbststudium beibringen muss..

    Max

  8. #8
    Registriert seit
    Aug 2001
    Beiträge
    2.873
    Das Problem liegt darin, dass Du bei einer Quelle OHNE Main Procedure (alles vor dem 1. P-Statment bzw. mit C-Bestimmungen vor dem 1. P-Statement) in den H-Bestimmungen das Schlüssel-Wort NOMAIN angeben musst.

    Wenn Prozeduren mehrfach verwendet werden sollen, sollte man sie in einem Service-Programm binden, anstatt die Module direkt in die Programme zu binden.
    Ändert sich ein Modul bzw. eine Prozedur innerhalb eines Moduls, muss lediglich die Prozedur im Service-Programm ausgetauscht werden.
    Wurden die Module direkt in Programme gebunden muss das Modul in allen Programmen ausgetauscht werden.

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  9. #9
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    Hallo Max,

    bevor du ganz verzweifelst, zur Klarstellung hier auch noch ein paar Anmerkungen von mir:


    1. Das was du suchst, sind "Serviceprogramme". Das sind quasi ausgelagerte Funktionen. Das heißt, du kannst den Funktionen lange Namen geben und kannst sie in Ausdrücken verwenden:
      z.B.: betrag = berechneNettowert(bruttobetrag)
    2. Serviceprogramme sind super. Die Programmierung unterscheidet sich kaum von "normalen" RPGLE-Programmen. Aber das Kompilieren hat IBM uns ziemlich schwer gemacht. Das Kompilieren ist die eigentliche "Kunst" bei Serviceprogrammen. Das kannst du auf Dauer nicht manuell machen. Da musst du dir ein passendes Compilierscript (z.B. in CL) basteln.
    3. In der free format Syntax fangen Serviceprogramme mit der Control Option "Nomain" an. Meistens gibt man noch ein paar weitere Parameter mit, wie z.B. das Datumsformat usw.Dann kommt der eigentliche Programmcode. Hier ein Beispiel:
    4. Code:
      ctl-opt nomain;
      dcl-proc isZiffer export;
         dcl-pi *n ind;
            zeichen char(1) const;
         end-pi;
      if %scan(zeichen:'0123456789') > 0;
         return *on;
      else;
         return *off;
      endif;
      end-proc;
    5. Wichtig ist in dem Beispiel das Schlüsselwort "export". Es besagt, dass die Funktion "isZiffer" von dem Serviceprogramm nach außen gegeben wird. Andere Programme, die Zugriff auf das Serviceprogramm haben, können die Funktion "isZiffer" also benutzen. Wenn das Schlüsselwort export fehlt, kann die Funktion nur innerhalb des Serviceprogramms benutzt werden.
    6. Das Kompilieren von Serviceprogrammen erfolgt bei uns in 2 Schritten:
      Zuerst wird mit CRTRPGMOD aus dem Source ein Modul erstellt. Danach wird aus dem Modul mit dem Befehl CRTSRVPGM ein Programmobjekt vom Typ *SRVPGM erstellt.
    7. Damit ist dein Serviceprogramm fertig. Aber was jetzt noch fehlt, ist das Verfügbarmachen des Serviceprogramms für andere Programme. Dazu müssen die anderen Programme dein Serviceprogramm bei ihrem Kompiliervorgang einbinden. Wir machen das so, dass wir Serviceprogramme bei der Kompilierung in ein sogenannntes Binderverzeichnis eintragen. Geht mit CRTBNDDIR bzw. dann mit ADDBNDDIRE. Das Bindervezeichnis geben wir unseren normalen Programmen bei jedem Kompiliervorgang mit.
    8. Jetzt hast du aber noch das Problem, dass deine normalen Programme wissen müssen, wie die Parameterschnittstelle deiner Funktion aussieht. Dazu musst du in deinem normalen Programm einen sogenannten Prototype eintragen. Für die Funktion oben sieht das dann ungefährt so aus:
      Code:
        
      dcl-pr isZiffer ind;
         zeichen char(1) const;
      end-pr;
      Solche Prototypes packt man sich üblicherweise in COPY-Strecken und bindet sie dann in seinen Code ein.

    Es ist leider sehr aufwändig, alles im Detail zu beschreiben. Aber vielleicht hilft dir dieses Grundgerüst schon mal weiter. (Wahrscheinlich habe ich auch noch die Hälfte vergessen :-) )

    Dieter

  10. #10
    Registriert seit
    Nov 2015
    Beiträge
    80
    Hallo Dieter,

    danke für die ausführliche Antwort. Das waren in der Tat genau die Infos die mir gefehlt hatten. Mein Programm läuft, danke!

    Was noch offen ist wären nur eins zwei Detailfragen zum Verständnis.
    1. Kann es sein das sobald ich eine Änderung im Modul vornehme ich sowohl das Serviceprogramm als auch den Eintrag unter bnddir neu erstellen muss? Habe das mal getestet und es scheint sich so zu verhalten.
    2. Wenn ich dieses Binderverzeichnis beim kompilieren mit einbeziehen erwartet er das Standardaktivierungsgruppe auf *no gesetzt wird --> Hat das irgendwelche Auswirkungen die man beachten muss?

    Grüße und ein schönes langes Wochenende!
    Max

  11. #11
    Registriert seit
    Jan 2012
    Beiträge
    1.120
    1. Kann es sein das sobald ich eine Änderung im Modul vornehme ich sowohl das Serviceprogramm als auch den Eintrag unter bnddir neu erstellen muss? Habe das mal getestet und es scheint sich so zu verhalten.
    Wenn du dein Serviceprogramm neu erstellst, musst du meiner Meinung nach den Binderverzeichniseintrag nicht neu machen. Bei uns macht das aber immer unser Compileprogramm automatisch. Da wird das jedesmal neu eingetragen, glaube ich.

    2. Wenn ich dieses Binderverzeichnis beim kompilieren mit einbeziehen erwartet er das Standardaktivierungsgruppe auf *no gesetzt wird --> Hat das irgendwelche Auswirkungen die man beachten muss?
    Ja ist hier die richtige Antwort. Aber das hilft dir wahrscheinlich auch nicht sonderlich weiter.

    Bei uns werden die Programme standardmäßig in der ACTGRP(*CALLER) gewandelt. Das heißt, jedes Programm befindet sich immer in der gleichen Gruppe wie das Programm, das es aufgerufen hat.

  12. #12
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    ... ich staune immer wieder, wieviel Halbwissen rund um ILE existiert.
    Ein Binderverzeichnis ist eine Suchliste nach Exporten, der ist es egal, wann ein Eintrag da gemacht wurde. Gesucht wird immer nach dem aktuellen Stand zur Bindezeit. Was auch heißt, dass von zentralen Binderverzeichnissen ohne Change Management System abzuraten ist.

    Änderungen im Binderverzeichnis können beim nächsten rebind zu unerwarteten Effekten führen (falsche Funktion gebunden bei Namensgleichheit, bzw. per Copy statt per referenece oder umgekehrt). In jedem Fall sollte man eindeutige Exportnamen sicherstellen (einfach ist: Modulnamen als prefix durch Umbenennung im Prototyp).

    Einfacher und besser als BNDDIR (weil sicherer) ist, beim binden (CRTPGM, bzw. CRTSRVPGM) die benötigten Komponenten dezidiert anzugeben. Unter MODULE alles was per COPY gebunden werden soll, unter BNDSRVPGM alles was via SRVPGM per REFERENCE gebunden werden soll. Dann braucht man entweder jeweils ein Umwandlungs CL, oder man verwendet einen der Open Source Pre-Processor, die das aus der Quelle aus speziellen Kommentaren auslesen.

    ACTGRP *CALLER ist für Programme auch nicht das Gelbe vom Ei, das kann zu unangenehmen Seiteneffekten führen.

    Auch hier hat selbst das oben erwähnte Redbook durchaus Schwächen - gehört aber trotzdestonichts zu den Besseren (die über SQL Procedures und Functions sind grauselig und enthalten sogar falsche Beispielprogramme).

    D*B
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

Similar Threads

  1. SQL Datensatzzähler erstellen
    By Franz.Rung in forum IBM i Hauptforum
    Antworten: 6
    Letzter Beitrag: 20-02-15, 13:02
  2. PDF/A-3 erstellen
    By Dschainers in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 05-12-14, 08:24
  3. Eigene Character-Funktionen
    By Kurmas Zeschlon in forum NEWSboard Programmierung
    Antworten: 27
    Letzter Beitrag: 18-08-14, 08:36
  4. Foxtrot erledigt Datawarehouse/MIS Funktionen
    By Dick Dekker in forum NEWSboard Server Software
    Antworten: 0
    Letzter Beitrag: 14-01-03, 14:14
  5. Antworten: 0
    Letzter Beitrag: 04-07-02, 06:31

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •