Ersatz einer textbasierten RPG-Greenscreen
Transcrição
Ersatz einer textbasierten RPG-Greenscreen
AKAD Hochschule Stuttgart Wirtschaftsinformatik Projektbericht Ersatz einer textbasierten RPG-GreenscreenBenutzeroberfläche durch einen Java-GUI-Frontend von Manfred Schiefers Pflasteräckerstr. 44 70186 Stuttgart Immatrikulationsnummer 360 828 Betreuender Hochschullehrer: Prof. Dr. Franz-Karl Schmatzer Stuttgart, 31.05.2011 INHALTSVERZEICHNIS 1 Einleitung 1 1.1 Hintergrund 1 1.2 Ziel dieser Arbeit 2 1.3 Vorgehensweise 2 1.4 Hilfsmittel 2 2 Theoretische Grundlagen 3 2.1 Allgemeines zur 3-Tier-Architektur 3 2.2 Eigenheiten der iSeries bezüglich der Benutzeroberfläche 4 2.2.1 OS/400-Objekte 5 2.2.2 RPG 6 2.2.3 DSP-Files 7 2.2.4 MSG-Files 7 2.2.5 Tastatur 8 2.3 Erwartungen an grafische Benutzeroberflächen 9 2.4 verschiedene Arten grafischer Frontends 10 2.4.1 HTML und Browserdarstellung 10 2.4.2 Microsoft .NET Framework 11 2.4.3 Java 12 3 Ausgangssituation 13 3.1 Darstellung der bisherigen Greenscreen-Eingabemaske 13 3.2 Betrachtung aus Anwendersicht 13 3.3 grundsätzliche Maskenelemente 14 3.3.1 Funktionstasten 14 3.3.2 Variablen 14 3.3.3 Textkonstanten 15 3.3.4 Layoutelemente, Farben 15 3.4. Quellcodeanalyse 16 I 4 Festlegung des Soll-Zustands 17 4.1 Idealvorstellung 17 4.2 notwendige Kompromisse 18 5 Umsetzung: Erstellung eines neuen grafischen Prototyps in Java 19 5.1 19 Elemente der neuen Eingabemaske 5.1.1 Schriftarten, Schriftgrad, Farbgebung, Layout 19 5.1.2 Überschrift, Logo 20 5.2.3 Eingabefelder, Comboboxen 20 5.2.4 Buttons 21 5.2 Implementierung in Java (Quellcode) 21 5.3 Darstellung der neuen grafischen Eingabemaske 23 6 Schlussbetrachtungen 24 Abkürzungen III Abbildungsverzeichnis V Anhang VII Literaturverzeichnis LI weitere Quellen LIII eidesstattliche Erklärung LV II ABKÜRZUNGEN Anw. = Anweisung, Programmzeile im RPG-Sourcecode API = Application Programming Interface ASCII = American Standard Code for Information Interchange AWT = Abstract Window Toolkit CL = Control Language CLR = Common Language Runtime COBOL = Common Business-Oriented Language CRTUSRPRF = create user profil DB = data base DBMS = data base management system DIN = Deutsches Institut für Normung DLL = Dynamic Link Library DSPF = display file EGL = Enterprise Generation Language EN = Europäische Norm ERP = Enterprise Resource Planning EXSR = Execute (Invoke) Subroutine FORTRAN = FORmula TRANslation GUI = Grafical User Interface HTML = Hypertext Markup Language HTTP = HyperText Transfer-Protokoll IBM = International Business Machines Corporation IKS = Informations- und Kommunikationssystem(e) ILE = Integrated Language Environment ISO = International Organization for Standardization LF = logical file LOC = Lines of Code MSGF = message file OOP = Objektorientierte Programmierung III PDM = Programm Developement Manager PF = physical file PRTF = printer file RPG = Report Program Generator SaaS = Software as a Service SEU = Source Entry Utitity SOA = Serviceorientierte Architektur TCP/IP = Transmission Control Protocol / Internet Protocol USRPRF = user profil WDSC = WebSphere Development Studio Client WRKOBJ = work with objects WRKMSGF = work with message files WRKSPLF = work with spoolfiles IV ABBILDUNGSVERZEICHNIS 1 Prinzip: Ersatz RPG-Greenscreen-Benutzeroberfläche durch GUI VII 2 Greenscreen-Maske als Ausgangsbasis, Komplettdarstellung VIII 3 Greenscreen-Maske, Eingabe: Teilestamm-Matchcode VIII 4 Greenscreen-Maske, Teilestamm Matchcode-Auswahl IX 5 Greenscreen-Maske, Einblendung Teilestammdaten IX 6 Greenscreen-Maske, Lieferantenauswahlliste X 7 Greenscreen-Maske, Einblendung Lieferantenstammdaten X 8 Greenscreen-Maske, Aufruf Nachrichtendatei M1MSGF XI 9 Greenscreen-Maske, Beispiel Textkonstante KON0009 XI 10 Greenscreen-Maske, Übersicht alle Textkonstanten XII 11 Greenscreen-Maske, Übersicht Displayfiles XIII 12 Greenscreen-Maske, Displayfile für Hauptbildschirm XIV 13 Greenscreen-Maske, Displayfile für Lieferantenauswahl XVI 14 Greenscreen-Maske, Displayfile für Teilestammauswahl XVII 15 Greenscreen-Maske, RPG-Hauptprogramm XVIII 16 Greenscreen-Maske, RPG-Startprogramm XIX 17 Greenscreen-Maske, Copysource Abteilung / Sachbearbeiter XX 18 Greenscreen-Maske, Copysource Bestellnummernvergabe XX 19 Greenscreen-Maske, Copysource Lieferantenstammdaten XX 20 Greenscreen-Maske, Copysource Lieferantenauswahl XX 21 Greenscreen-Maske, Copysource Bestellung versenden XXI 22 Greenscreen-Maske, Copysource Teilestammdaten XXI 23 Greenscreen-Maske, Copysource Teilestammdaten-Matchcode XXI 24 Greenscreen-Maske, Copysource Zahlungs-/Lieferbedingungen XXII 25 GUI-Maske, Java-Packages XXII 26 GUI-Maske, Komplettdarstellung XXIII 27 Logo alt XXIV 28 Logo neu XXIV 29 GUI-Maske, Klasse XML_Kommunikation XXV 30 GUI-Maske, Klasse HinweisFenster XXX V 31 GUI-Maske, Klasse Fehlermeldung 32 GUI-Maske, Klasse BestellStart XXXII 33 GUI-Maske, Klasse BestellEingabeParameter XXXIII 34 GUI-Maske, Klasse TeileMatchcodeMaske XXXVI 35 GUI-Maske, Klasse BestellEingabeMaske XXXIX 36 GUI-Maske, leer XLVII 37 GUI-Maske, Fehlermeldung XLVII 38 GUI-Maske, Teilestamm Matchcode-Auswahl XLVIII 39 GUI-Maske, Einblendung Teilestammdaten XLVIII 40 GUI-Maske, Lieferantenauswahlliste XLIX 41 GUI-Maske, Einblendung Lieferantenstammdaten XLIX 42 GUI-Maske, Konsolenausgabe XXXI L VI 1 Einleitung 1.1 Hintergrund AS/400, iSeries, System i oder auch i5 sind Bezeichnungen für eine Computer-Baureihe von IBM. Die Zuverlässigkeit des IBM-Systems wird geschätzt und steht dabei in Konkurrenz zu Windows-Servern [vgl. infor, 2009]. Zahlreiche Unternehmen weltweit setzen bei betriebswirtschaftlicher Standardsoftware nach wie vor ihr Vertrauen in System-i-Anwendungen, die ehemals in der Programmiersprache RPG erstellt wurden. Über die Jahre hinweg wurden vorhandene Anwendungen immer umfangreicher und komplexer, die ihren Ursprung vor 15 oder 20 Jahren hatten [vgl. pks, 2008]. Mit hunderten von Mannjahren erstellter Quellcode ist nicht von heute auf morgen austauschbar. Daher werden auch heute noch Jahrzehnte alte COBOL-, RPG- und FORTRAN-Programme gewartet [vgl. Krüger 2009, Seite 53]. Andererseits ist klar, dass auf prozeduralen Programmiersprachen basierende Geschäftsanwendungen auf lange Sicht keine Zukunft mehr haben. Gründe sind u.a. die fehlende Objektorientiertheit, fehlende Plattformunabhängigkeit sowie das „Aussterben“ geeigneter Programmierer zur Wartung. Das Betriebssystem OS/400 ist geeignet für Java [vgl. com, 07/2006]. So realisierten Systemhäuser der ERP-Branche bereits eine Umstellung auf eine drei-schichtige Java-Architektur auf der iSeries. Beispiele: die Command AG mit Oxaion [vgl. com, 10/2002], Intentia mit Movex [vgl. com, 03/2006], QSC (Quality Software & Consulting) [vgl. qsc, 2010] usw. Da aber dieser Umstellungsprozess lange Entwicklungszeit in Anspruch nimmt, ist für eine Übergangszeit auch ein Kompromiss möglich. Um dem Ruf der Anwender nach einer grafischen Benutzeroberfläche gerecht zu werden, kommen sog. Thin-Clients zum Einsatz. Hierbei wird die Applikation auf dem Server ausgeführt, die Clients hingegen dienen zur reinen Darstellung [vgl. man, 2002]. Die Kommunikation erfolgt über eine Middleware, die auf der AS/400 läuft und einen XML-Datenstrom zwischen Applikation und Client koordiniert. Der vorhandene RPG-Quellcode des Geschäftsanwendungskerns bleibt und muss „geringfügig“ angepasst werden. Sehr aufwendiger gestaltet sich der Ersatz der bisherigen textbasierten Greenscreen-Benutzeroberfläche durch einen grafischen Frontend (Prinzip siehe Abbildung 1, Seite VII). Dieses Vorgehen ist Gegenstand der Untersuchung im Folgenden. 1 1.2 Ziel dieser Arbeit Ziel ist es, die Implementierung eines Prototyps mittels Java exemplarisch an einer grafischen Eingabemaske zu beschreiben, wobei eine textbasierte und RPG-programmierte Eingabemaske als Ausgangsbasis und Richtschnur dienen soll. Unterschiede zwischen beiden Varianten sollen herausgestellt werden, sowohl bei der Bedienung durch den Benutzer, als auch in der Programmierung. Die programmtechnische Anbindung des grafischen Clients an den Server ist nicht Bestandteil der Ausarbeitung. 1.3 Vorgehensweise Im Vorfeld werden zunächst themenspezifische Inhalte theoretischer Natur dargestellt. Dies sind zu Beginn prinzipielle Betrachtungen zur 3-Tier-Architektur. Danach werden relevante Spezifika der AS/400-Plattform herausgestellt. Zwei weitere Grundlagenkapitel widmen sich zum einen den Gestaltungskriterien grafischer Benutzeroberflächen im Allgemeinen, zum anderen einer kurzen Darstellung dreier konkreter grafischer Frontend-Alternativen. Der darauf folgende Praxisteil besteht aus drei Komponenten: Erfassung der Ausgangssituation mit der Analyse wichtiger Parameter der bisherigen Greenscreen-Eingabemaske. Darauf aufbauend erfolgt dann die Erarbeitung des Sollzustands und letztendlich die Entwicklung der neuen grafischen Eingabemaske. 1.4 Hilfsmittel Alle zum Praxisteil genutzten Plattformen und Ressourcen stammen aus dem Privatbereich des Autors. RPG- und Java-Quellen wurden selbst erstellt. Als AS/400-Umfeld steht mit Betriebssystem-Release V5R3M0 ein kostenloser Account beim ‚Rechenzentrum Kreuznach’ (http://www.rzkh.de/) zur privaten Nutzung zur Verfügung (Genehmigung zur Verwendung für die vorliegenden Arbeit sowie zur Publikation von Screenshots wurde durch den Geschäftsführer Holger Scherer ausdrücklich erteilt.). Für den Remote-Zugang wird ‚Mocha TN5250 for Vista’ benutzt. RPGSourcen basieren auf RPG IV, ILE-RPG (ILE = Integrated Language Environment). Der Java-Teil wird bearbeitet über jre1.6.0_05. Als Editor wird hierzu eclipse 3.1 verwendet. Betriebssystem auf dem heimischen Laptop ist Windows VistaTM Home Basic, Service Pack 2. 2 2 Theoretische Grundlagen 2.1 Allgemeines zur 3-Tier-Architektur Zu Beginn der kommerziellen Nutzung von Datenverarbeitung waren Computer groß und teuer, so dass nicht für jeden Anwender ein eigener Rechner zur Verfügung stehen konnte. Stattdessen waren diese über „dumme“ Terminals mit einem Hauptrechner verbunden [vgl. Vogel 2008, Seite 222]. Mit der Durchsetzung kostengünstiger PCs konnte diese sog. Mainframe-Architektur abgelöst und Anwendungen dezentralisiert werden. Mittels File Sharing wurden nun ganze Dateien vom Server auf die Arbeitsplatzrechner übertragen. Da dieses Verfahren sehr netzbelastend war, zeitgleiche Anwenderzugriffe zu Engpässen führten, bot das Client-/Server-Modell Abhilfe. Hierbei laufen Anwendungsprogramme auf dezentralen Rechnern und greifen auf zentral abgelegte Ressourcen über ein Frage-Antwort-Schema zu [vgl. Vogel 2008, Seite 223]. Ein Nachteil hierbei ist, dass die dezentral installierten Anwendungsprogramme aufwendig zu warten sind, ein einheitlicher Stand schwer zu gewährleisten ist. 3-Tier-Architekturen lösen dieses Problem, indem hier Anwendungslogik und Datenhaltung zentral gelagert sind und die Benutzeroberflächen auf den verteilten Clients liegen. Zwischen den drei Komponenten liegen Zwischenschichten, die die Datenübertragung organisieren [vgl. Vogel 2008, Seite 225]. Man spricht auch von einer Dreischichtigen Architektur. Eine Präsentationsschicht sorgt für die Interaktion mit dem Benutzer, indem sie GUI-Elemente bereitstellt und die Dialogkontrolle übernimmt. Die darunter liegende Anwendungsschicht dient der eigentlichen Verarbeitung der Funktionalitäten aus fachlicher Hinsicht. Durch Benutzereingaben werden dort Prozesse ausgelöst und Berechnungen durchgeführt. Gleichzeitig besteht von ihr aus eine Beziehung zur wiederum darunter angeordneten Persistenzschicht [vgl. Dunkel 2008, Seite 43]. Hier werden Daten als eine ausschnittsweise Abbildung der realen Welt dauerhaft (persistent) gespeichert. Eine Sammlung solcher Daten wird als Datenbank (DB) bezeichnet. Über ein DBMS werden diese Daten strukturiert, Datenmodelle festgelegt und die Beziehungen untereinander geregelt [vgl. Kudraß 2007, Seite 21]. Die drei angesprochenen Schichten können räumlich auf hardwaremäßig verschiedene Rechnersysteme verteilt werden. 3 2.2 Eigenheiten der iSeries bezüglich der Benutzeroberfläche Die IBM eServer iSeries-Produktfamilie gehört zu den midsize business ComputerSystemen. Die Rede ist auch von Midrange Systemen (Mittlere Datentechnik), die sich zwischen Mainframe- und Microcomputern ansiedeln lassen. Die iSeries baut auf ihren Vorgänger-Generationen System/36, System/38 und AS/400 auf [vgl. Hoskins 2003, Seite 7]. Die im vorherigen Kapitel beschriebenen drei Schichten stehen auf einer iSeries gänzlich zur Verfügung: Standardmäßig besitzt die AS/400 eine bereits integrierte relationale DB2-Datenbank [vgl. heise, 01/2008]. Gleichfalls dient sie als Applikationsserver [vgl. Gulbins 2002, Seite 616]. Ursprünglich war die das multiuserfähige System über eine zweiadrige TWINAX-Verkabelung mit zahlreichen nichtintelligenten Benutzer-Terminals (z.B. InfoWindow II workstations) verbunden, und stellten damit letztendlich die Präsentationsschicht dar [vgl. Hoskins 2003, Seite 77]. Seit Einführung des IBM Client Access Express besteht die Möglichkeit die AS/400-Frontenddarstellung über eine 5250-Emulation auf einem „normalen“ PC innerhalb eines grafischen Fensters laufen zu lassen (Terminal Emulation) [vgl. Hoskins 2003, Seite 78]. Der Zugriff erfolgt dabei über die IP-Adresse der AS/400, die innerhalb eines lokalen Windows-Netzwerkes betrieben werden kann. Die Authentifizierung ist dabei über das Kennwort des AS/400-Userprofil (usrprf) notwendig. Somit ist auch Remotezugang ortsungebunden über das Internet möglich. Weiterer Vorteil ist, dass auf dem Rechner des Benutzers parallel auch andere Anwendungen (Office, Email etc.) verfügbar sind. Dennoch mutet die Darstellung nach wie vor spartanisch an. Immerhin bietet die 5250-Emulation erweiterte Funktionen wie z.B. Copy-and-Paste von Texten sowie mehrere Sitzungsanmeldungen (Sessions). Das textbasierte Layout besteht aus einem 80 x 25 Zeichen-Raster. Quasi als „Lesezeichen“ kann der Cursor über eine Tastenkombination in eine Art Fadenkreuz eingebettet werden. Die Bezeichnung ‚Greensscreen’ ist im Übrigen irreführend, da sehr wohl verschiedene Schriftfarben zur Auswahl stehen. AS/400-seitig ist der Hintergrund stets schwarz, über die 5250-Emulation sind allerdings individuelle Hintergrundfarbeinstellungen möglich. Auch für den durchschnittlichen Benutzer obligatorisch, ist eine Kommandozeile am unteren Bildschirmrand, um z.B. generierte Ausdrucke über den Befehl WRKSPLF (work with spoolfiles) steuern zu können. 4 2.2.1 OS/400-Objekte Ein wichtiges Architekturkonzept der iSeries stellen Objekte dar. Dieser Objektbegriff darf hier jedoch nicht mit dem der ’Objektorientierten Programmierung’ verwechselt werden. Bei OS/400-Objekten handelt es sich um Strukturen des Betriebssystems. Jedes Element, das auf der AS/400 namentlich über die Befehlszeile über den command WRKOBJ angesprochen werden kann, ist ein Objekt. Konkret können dies z.B. Benutzerprofile, ausführbare Programme, Dateien, Gerätebeschreibungen, commands, Jobbeschreibungen, Output Queues usw. sein [vgl. Fottral 2002, Seite 65]. Es können neue OS/400-Objekte erstellt werden. Alle derartigen Objekte sind kategorisiert in über 40 Objekttypen, die auf ihren Verwendungszweck hinweisen. An den Objekttyp sind seine spezifischen Eigenschaften (Attribute) gebunden. So sind beispielsweise bei der Erstellung eine Benutzerprofils über CRTUSRPRF automatisch Attribute wie ‚Benutzername’, ’Benutzerkennwort’ und ’Startmenü’ an das Objekt geknüpft [vgl. Fottral 2002, Seite 67]. Weit hergeholt könnte man quasi einen Vergleich zu Windows ziehen, wenn beispielsweise eine .doc-Datei angeklickt wird und sich dabei automatisch MS-WORD öffnet. Werden OS/400-Objekte über CLcommands angesprochen, wissen sie somit, „von sich selbst“, wie sie strukturiert sind. Dateien sind ebenfalls Objekte. Sie gehören dem Objekttyp *file an. Hier ist wiederum eine weitere Untergliederung üblich. So können insgesamt 12 Varianten des Typs *file unterschieden werden [vgl. Fottral 2002, Seite 123]. Nachfolgend nur die vier wichtigsten: Physische Files mit dem Attribut (subtype) ’PF’ beinhalten und organisieren Daten. Als PF-DTA stehen sie für Tabellen einer relational organisierten Datenbank, als PF-SRC hingegen beherbergen sie den Sourcecode z.B. von Programmen in Form von Teildateien. Im Gegensatz zu den Physischen Files stehen Logische Dateien (LF) [vgl. Fottral 2002, Seite 124]. Sie enthalten keine Daten, sondern stellen verschieden Zugriffspfade für PF-DTAs zur Verfügung (Stichwort ’Schlüsselattribute’ für Datenbanktabellen). Bei den Printerfiles (PRTF) handelt es sich um files, die die Struktur und das Layout von Ausdrucken definieren. Ähnlich fungieren Displayfiles (DSPF). In ihnen ist das Design von Bildschirmdarstellungen festgelegt. Außerdem werden Ein- und Ausgabefelder als Variablen mit ihrem Datentyp deklariert und ihre Lage auf dem Bildschirm bestimmt. Displayfiles haben einen maßgeblichen Anteil für die Frontendgestaltung (mehr hierzu in Kapitel 2.2.3). 5 2.2.2 RPG RPG (Report Program Generator) ist eine Programmiersprache mit hohem Bekanntheitsgrad speziell in der Midrange-Computerfamilie [vgl. Malaga 2000, Kapitel 20, Seite 1]. Ehemals wurde RPG von IBM zur Erstellung kaufmännischer Listen (sog. Reports) entwickelt. Von daher rührt noch der Name. In der 60er/70er-Jahren des vergangenen Jahrhunderts waren Lochkarten als Datenträger (auch für ProgrammQuellcodes) üblich. In Anlehnung an dieses Prinzip ist RPG auch in späteren Compiler-Versionen stark spaltenorientiert. D.h. es bestehen strenge Konventionen darüber, welche Sourcecode-Komponenten wo, in horizontaler Ausrichtung zu stehen haben [vgl. Malaga 2000, Kapitel 20, Seite 4]. Seit 1994 gibt es die vierte RPG-Generation RPG IV, auch bekannt als ILE RPG. RPG-Programme können die, im vorhergehenden Kapitel genannten, Objekttypen *file nutzen, indem diese im Kopfbereich des Quellcodes unter dem Designator ’F’ deklariert werden. Alle z.B. in Displayfiles vordefinierten Variablen sind damit innerhalb des RPGs bekannt und können dort im Quellcodebereich ’C’ (Calculation Specification) in Rechenbestimmungen verwendet werden. Gleiches gilt für PFs und PRTFs [vgl. Malaga 2000, Kapitel 20, Seite 5]. Häufig wieder verwendete RPG-Routinen, wie z.B. Währungsumrechnungen können über sog. Copysourcen („Kopiestrecken“) einmalig kodiert, separat abgelegt und ins Programm integriert werden. Beim Compiliervorgang werden diese dann fester Bestandteil RPG-Programm-Objekts. Vom Prinzip her also ähnlich wie die Wiederverwendbarkeit vordefinierter Klassen, die mit Imports in Java-Programme eingebunden werden. Um Sourcecode zu editieren steht auf der iSeries der Haupt-Quelleditor SEU (Source Entry Utitity) zur Verfügung. Ebenso wie SEU stellt auch der Programm Developement Manager (PDM) ein IBM-Utility für Programmierer dar [vgl. Malaga 2000, Kapitel 22, Seite 1]. Über das PDM wird eine Ordnungsstruktur hinsichtlich der Archivierung von Quellcodes organisiert. So bilden Sammlungen von RPG-Sourcen Teildateien der Datei PF-SRC QRPGSRC bzw. QRPGLESRC. Quellen von Displayfiles werden in der QDDSSRC abgelegt. Übergeordnete „Container“ für alle Objekte bilden Bibliotheken (libraries). Die, einem Benutzer zugeordnete Bibliotheksliste entscheidet während der Laufzeit, welche Programmobjekte „greifen“. Bei einer Bildschirmdarstellung steuert das RPG-Objekt die Funktion und den Ablauf, das Displayfile-Objekt hingegen bestimmt über den statischen Aufbau des Layouts. 6 2.2.3 DSP-Files Um innerhalb eines RPG-Programms eine Bildschirmausgabe zu verwenden, muss der gesamte Bildschirm vorab definiert werden. Die Definition einer Bildschirmdatei (Displayfile) geschieht in ähnlicher Weise wie bei Datendateien (PFs), obgleich die erstere eine größere Spaltenanzahl im Sourcecode aufweist. Der Zeilentyp ’A’ der beginnenden Spalte ist bei beiden identisch. Korrespondieren die Bildschirmvariablen mit denen einer Datenbankdatei, kann darauf referenziert werden. Separate Deklaration entfällt somit. Vorteil dieser Referenzierung ist, dass Änderungen in Felddefinitionen zentral an einer Stelle erfolgen können. Im Kopf des DSPF wird ebenfalls die Bezeichnung eines Satzformates (Namensart ’R’) festgelegt. Mit dem Ansprechen dieses Satzformats über EXFMT innerhalb des RPG wird dann der Aufruf des Bildschirms ausgelöst. Es sind mehrere Satzformate in einem RPG, und damit Aufruf mehrerer verschiedener Bildschirme im Programm möglich. Unterhalb des Satzformats erfolgt die Angabe einzelner Bildschirmvariablen zusammen mit ihren X-/Y-Koordinaten sowie einer Kennzeichnung, ob es sich um Ein- oder Ausgabefelder handelt. Über einen Code wird die jeweilige Schriftfarbe festgelegt. Außerdem finden auch Funktionstasten ihre Definition innerhalb des Displayfiles. 2.2.4 MSG-Files Meldungen des Betriebssystems OS/400 (i5/OS) werden im Volltext ausgegeben. Dahinter stehen sog. Nachrichtendateien, die den Text eine (Fehler-)Meldung in der jeweiligen Systemsprache anhand eines Message-Codes ermittelbar machen. Ein Beispiel hierfür: CPF4101 = „Datei &2 in Bibliothek &3 nicht gefunden.“ Dieses Prinzip kann in Anwendungsprogrammen weiter verfolgt werden. Alle Textkonstanten werden an zentraler Stelle einmalig verwaltet und sind im Bedarfsfall über einen Code aufrufbar. Hieraus ergeben sich Vorteile: immer wiederkehrend verwendeter Text in Bildschirmmasken oder Drucklayouts wie z.B. „Speichern“, „Beenden“, „Artikel-Nr.:“ oder „Bestell-Nr.:“ braucht nur einmal angelegt, geändert oder korrigiert werden. Wird zudem in den Textcode noch ein Sprachkennzeichen integriert, kann anhand diesem die Konstante entsprechend der eingestellten Benutzersprache ausgegeben werden. Nachrichtendateien können über den Befehl WRKMSGF zur Verwaltung aufgerufen werden. 7 2.2.5 Tastatur Wichtige Schnittstellen von Informationssystemen zum Benutzer stellen Bildschirmgeräte und Tastaturen dar. Die Normenreihe DIN EN ISO 9241 befasst sich mit der Anpassung von Bildschirmarbeitsplätzen an die Arbeit des Menschen. Speziell dem Thema ’Tastatur’ widmen sich die Normen der Reihe DIN 2137 [vgl. Klein 2001, Seite 42]. Eine tatsächlich einheitliche PC-Tastatur setzte sich allerdings erst Ende der 80er-Jahre des letzten Jahrhunderts durch. Bis dahin verwendeten viele Systemhersteller ihre eigenen Standards (IBM, Siemens, Nixdorf usw.). Die Ursprungstastatur der AS/400 glich der Größe nach einem „Waschbrett“. Längst fand sie aber Dank der 5250-Emulation Ersatz in der heute gängigen PC- bzw. Laptop-Tastatur. Jedoch sind aufgrund verschiedener Funktionen gewisse Relikte bei der Bedienung nach wie vor vorhanden. Ein Beispiel hierfür stellt eine separate ’Datenfreigabetaste’ dar. Um einzelne Eingabefelder einer Bildschirmmaske frei zugegeben wir die übliche ENTER-Taste verwendet. Diese wird auch als ’Feld-Eingabe’ bezeichnet. Um jedoch die komplette Bildschirmmaske freizugeben (abzuschließen), wird die Datenfreigabetaste verwendet. Um die Taste auf einer normalen PC-Tastatur simulieren zu können, wird über die 5250-Emulation die rechte STRG-Taste hierzu herangezogen. Funktionstasten gibt es 24 statt 12. Die Zweitbelegung kann über die SHIFT-Taste erreicht werden (SHIFT F12 entspricht F24). Funktionstasten haben sowohl betriebssystemseitig und auch in Anwendungsprogrammen oft einheitliche Bedeutungen: F3 = beenden, F12 = zurück, F4 = löschen, F7 = Speichern, F24 = weitere Tasten. Geläufig ist auch der Ausdruck „Bedienertaste“ (BT3 = F3) anstelle von „Funktionstaste“. Eine [ESC]-Taste mit der hierfür vorgesehenen Funktion gibt es nicht. Diese Aufgabe ist meist der F3-Taste zugewiesen (s.o.). Ein ähnlicher Effekt, den man unter Windows mit [Strg] + [Alt] + [Entf] bewirkt, wird bei der AS/400 mit [Shift] + [ESC] erreicht. Man nennt diese Funktion auch „Systemabbruch“. Gefolgt von „2“ wird damit die Programmlaufzeit unterbrochen (z.B. bei Endlosschleifen). Gefolgt von „3“ können Informationen zum gegenwärtigen Interaktiven Job über eine Menü aufgerufen werden: Programmaufrufstapel, im Zugriff befindliche Dateien, die aktuelle Bibliotheksliste oder auch das Jobprotokoll. 8 2.3 Erwartungen an grafische Benutzeroberflächen Informations- und Kommunikationssysteme allgemein benötigen Schnittstellen zum Benutzer, damit dieser mit dem System interagieren kann. Derartige Mensch-Computer-Interfaces bedürfen nutzergerechter Gestaltung [vgl. Hellige 2008, Seite 7]. Unter anderem spielt die Ergonomie eine entscheidende Rolle bei der Akzeptanz beim Endanwender, was letztendlich Auswirkung auf die Produktivität hat. Schulungsaufwand und an Anwenderbetreuung sind kostenintensiv. Die Bedienung sollte intuitiv möglich sein, was jedoch oft subjektiv empfunden wird, da individuelle Vorerfahrungen mit einfließen. Die weite Verbreitung von Microsoft-Office-Applikationen (auch im Privatbereich) führt allerdings dazu, dass sich Anwender am schnellsten an sich dort angelehnte Benutzeroberflächen einarbeiten [vgl. Schmidl 2008, Seite 16]. Kaum noch nachvollziehbar, dass Grafikoberflächen bei ihrer ersten Vorstellung als Spielerei abgetan wurden [vgl. Missomelius 2006, Seite 77]. Intuition bei GUI-Oberflächen entsteht u.a. durch ihre selbstsprechende Symbolik (Icons, Piktogramme, Metaphern) und durch die Maussteuerbarkeit mittels Direktmanipulation (z.B. Bildobjekte verschieben) bzw. Zeigebefehle (virtuelle Buttons statt Tastaturtasten) [vgl. Saier 2007, Seite 17]. Generell sollten sich Informations-Ein/Ausgaben direkt an der Arbeitsaufgabe orientieren. D.h. bei Eingaben müssen Daten in einer Maske zusammengefasst werden, die aus einer gemeinsamen externen Quelle stammen, auch wenn deren spätere Verarbeitung getrennt erfolgt. Ebenso lehnt sich die Genauigkeit der Datenformatierung von Eingabefeldern an den Anwendungszweck an (z.B. Geldbeträge mit zwei Nachkommastellen) [vgl. Herczeg 2005, Seite 125]. Was man unter dem Aspekt „Benutzbarkeit“ einer Anwendung betrachtet, kann unter dem Begriff „usability“ zusammengefasst werden. Dabei gelten Kriterien, die auch speziell auf grafische Benutzeroberflächen bezogen werden können: Zum einen wird Verständlichkeit (understandability) verlangt. D.h. Symbole, Beschriftungen, Menüführung usw. sollten möglichst selbstsprechend mit wenig Erklärungsbedarf ausgeführt werden. Tooltip-Texte und Onlinehilfen unterstützen die Verständlichkeit. Über die Bedienbarkeit (operability) soll der Benutzer in der Lage versetzt werden, das Softwareprodukt zu steuern. Der „Bediener“ muss geführt werden, z.B. mit Hinweismeldungen, wie „dieses Feld darf nicht leer sein“. „Verbotene“ Eingabefelder und Buttons sind von vorne herein auf ‚disabled’ gesetzt und erscheinen ausgegraut. 9 Nicht zuletzt entscheidet auch die Attraktivität (usability compliance) über die Akzeptanz des Softwareprodukts sowie über die Arbeitszufriedenheit und schlägt sich u.a. nieder in Farbgestaltung, Hervorhebungen, Anordnung/Gruppierung von Labels und Eingabefeldern, Schriftart und Schriftgrad [vgl. Balzert 2009, Seite 469]. Weitere Kriterien bilden Erlernbarkeit und Einprägsamkeit, die sich darin auszeichnen, wie schnell sich ein Benutzer erstmals und auch in Wiederholungsfällen zurechtfindet [vgl. Thum 2008, Seite 17]. In der Norm ISO/IEC 9126 sind ausführliche Beschreibungen zahlreicher Kriterien bezüglich der Softwarequalität niedergelegt [vgl. Balzert 2009, Seite 469]. 2.4 2.4.1 verschiedene Arten grafischer Frontends HTML und Browserdarstellung Browser greifen über HTTP (HyperText Transfer-Protokoll) auf einen Server zu, der ein HTML-Dokument zurücksendet, welches wiederum vom Browser interpretiert und zur Darstellung gebracht wird. Die Kommunikation läuft über TCP/IP-Port 80. Der eigentliche Inhalt von HTML-Dokumenten setzt sich aus Text sowie aus Anweisungen zur Formatierung dieses Textes zusammen. Die Anweisungen (Tags) stehen innerhalb spitzer Klammern. HTML-Dateien sind im ASCII-Code geschrieben. Somit sind sie über jeden Text-Editor bearbeitbar [vgl. Däßler 2003, Seite 259]. Hauptaufgabe von HTML liegt in der formatierten Darstellung von Texten einer Website. Über Hyperlinks sind Verknüpfungen zu anderen Seiten möglich [vgl. Däßler 2003, Seite 266]. Mit zum Sprachumfang gehören Formulare, die übliche Elemente wie z.B. Eingabefelder, Radiobuttons, Comboboxen usw. beinhalten (mit der Syntax: <FORM action=...></FORM>) [vgl. Däßler 2003, Seite 272]. Dynamische Seiten, ge- eignet für die Anwenderinteraktion, werden durch Skriptsprachen unterstützt und ermöglichen den Dialog mit einer Applikationsschicht. Was im Internet funktioniert, ist auch für ein Intranet für den betriebswirtschaftlichen Anwendungszweck geeignet. Der Browsereinsatz bietet Vorteile: der administrative Aufwand ist gering und die Distribution erfolgt quasi automatisch durch das jeweils neue Laden einer aktualisierten Seite. Außerdem findet die Browserdarstellung (zumindest theoretisch) unabhängig vom verwendeten Betriebssystem statt [vgl. Ebel 2005, Seite 17]. 10 Vorteile aus Sicht von Softwareanbietern ergeben sich daraus, dass Verantwortlichkeiten bei fehlerhaften Darstellungen auf die Browserhersteller verlagert werden können. Da hinsichtlich der HTML Standards existieren, stehen Browseranbieter hierin in Konkurrenz zueinander (beispielsweise Mozilla Firefox, Google Chrome und brandaktuell: Internet Explorer 9 von Microsoft) [vgl. heute, 03/2011]. Dennoch bieten Browseranwendungen (noch) nicht den Komfort wie herkömmliche PC-Anwendungen. Durch die „Beliebigkeit“ unterschiedlicher Browser bei der HTML-Interpretation können sich auch Inkonsistenzen ergeben [vgl. Ebel 2005, Seite 17]. 2.4.2 Microsoft .NET Framework Die .NET-Strategie wurde im Jahr 2000 von Microsoft ins Leben gerufen, um serverseitig Marktanteile zu gewinnen [vgl. Masak 2005, Seite 208]. Das .NET-Framework ist Bestandteil dieser Strategie, und stellt eine umfangreiche Programmierumgebung bzw. Software-Plattform dar. Diese dient sowohl zur Entwicklung, als auch zur Ausführung von Programmen. Wesentliche Komponenten sind hierbei eine Laufzeitumgebung namens Common Language Runtime (CLR) zur Programmausführung, Programmierschnittstellen und verschiedene Services sowie eine umfangreiche Sammlung von Klassenbibliotheken. Das .NET-Framework ermöglicht die Entwicklung komplexer Web- und Windowsapplikationen unter verschiedenen Programmiersprachen wie Visual Basic oder Visual C++. Vorgefertigte Bestandteile der Klassenbibliothek erleichtern die Programmierung, indem sie Lösungen für Standard-Aufgaben bereitstellen [vgl. Kotz 2008, Seite 17]. Bei den Klassenbibliotheken handelt es sich um kleinste weitergebbare Codeeinheiten sog. Dynamic Link Librarys mit der Dateiendung .dll. DLLs enthalten außer einem Code, der unter der CLR ausführbar ist, Daten zu ihrer internen Beschreibung. Mit DLLs wird das Paradigma der Wiederverwendbarkeit in der objektorientierten Programmierung (OOP) realisiert. [vgl. Wirtz 2008, Seite 176]. Microsoft bietet Visual Studio als integrierte Entwicklungsumgebung für verschiedene Programmiersprachen, wie z.B. Visual Basic oder C++ an. Erstellung von Anwendungen für das .NET Framework wird hierbei unterstützt. Vorgefertigte Grafikelemente für Eingabemasken können über eine Toolbox per Copy and Paste hinzugefügt und mit der Maus gestalterisch bearbeitet werden. Über Visual Studio können im Anschluss hieraus lauffähige DLLs generiert werden. 11 2.4.3 Java Die Komfortabilität bei der Erstellung von Grafikoberflächen unter Zuhilfenahme des Microsoft .NET Framework hat den Nachteil, dass der Schwerpunkt auf Windows-Anwendungen fixiert ist. Plattformunabhängigkeit hingegen bietet Java. Das Unternehmen Sun Microsystems umschrieb diesen Umstand mit „write once, run anywhere“ [vgl. Flanagan 2003, Seite 6]. Als weitere Vorteile von Java können genannt werden: Einfachheit (im Vergleich z.B. zu C++), Netzwerkfähigkeit (für verteilte Anwendungen geeignet), Robustheit (geringe Fehleranfälligkeit, Abfangen von Exceptions über try/catch), Sicherheit (Kapselung von Objekten), Interpretierbarkeit (als semi-kompilierte Sprache) und Parallelisierbarkeit (unterstützt Multithreading) [vgl. Deck 2010, Seite 24]. Speziell für die GUI-Programmierung stellt die Java-API die Packages AWT und Swing zur Verfügung. AWT (Abstract Window Toolkit) bildet hierbei die Grundlage, kümmert sich insbesondere um die Ereignisverwaltung und ist auch erforderlich, wenn Swing zum Einsatz kommt. Zwar bietet AWT eine ganze Reihe eigener Fenster und Steuerelemente, die jedoch vom Erscheinungsbild eher einfach gehalten sind. Um Konformität hinsichtlich des Designs auf unterschiedlichen Betriebssystemen sicherzustellen wurde ursprünglich mit AWT auf die jeweiligen betriebsysteminternen Steuerelemente zurückgegriffen. Dieses Verfahren stellte jedoch nur einen Kompromiss dar und war zudem fehleranfällig. Swing beschreitet einen anderen Weg, indem hier sämtliche Steuerelement komplett in Java ausimplementiert werden. Die Anzahl verfügbarer Swing-Komponenten beträgt ein Vielfaches gegenüber der von AWT [vgl. Louis 2007, Seite 287]. Auch unter dem Gesichtspunkt der Ästhetik stellt sich Swing als die „schönere“ Variante dar. Die eigentliche Codierung kann bei Java prinzipiell mit jedem Texteditor durchgeführt werden. Nützliche Tools stellen Eclipse oder NetBeans dar, die als integrierte Entwicklungsumgebungen das Editieren komfortabler machen. Z.B. werden hier syntaktische Fehler bereits vorab erkannt und hervorgehoben. Sogenannte GUI-Builder unterstützen speziell das Erstellen von grafischen Oberflächen vergleichbar mit Microsoft Visual Studio (s.o.). GUI-Builder sind bei vielen Entwicklungsumgebungen bereits enthalten. Im Fall von Eclipse gibt es aufgrund seiner Erweiterbarkeit zu diesem Zweck Plugins. Als Beispiele hierzu können Jigloo, Window Builder Pro oder Visual Editor genannt werden [vgl. com, 11/2004]. 12 3 Ausgangssituation Für das vorliegende Projekt wurde als Ausgangsbasis eine (fiktive) Eingabemaske gewählt, wie sie in einem ERP-System vorkommen könnte. Es handelt sich um eine Maske zur Erfassung von ’Direktbestellungen’. Gemeint sind hiermit Bestellungen, die nicht auf Rahmenverträgen oder Lieferabrufen basieren. Also für Gemeinkostenartikel oder auch sog. C-Teile wie Schreibwaren, Büroartikel, Reinigungsmittel usw. 3.1 Darstellung der bisherigen Greenscreen-Eingabemaske In Abbildung 2, auf Seite VIII ist die Maske mit bereits erfolgten Benutzereingaben dargestellt. Zur eindeutigen Identifizierung erhält jede Bestellung ihre eigene Bestellnummer. Teilestammdaten und Lieferantenstammdaten müssen vorab in der Datenbank angelegt sein. Gleiches gilt für eine Auswahl von Zahlungs-/Lieferbedingungen sowie ’anfordernde Abteilung’ und ’Sachbearbeiter’. Die restlichen Eingaben können ohne Bezug zu Stammdaten vom Benutzer direkt erfasst werden. 3.2 Betrachtung aus Anwendersicht Der Aufruf zur Bestellerfassung erfolgt über einen Punkt vom Einkaufsmenü aus. Dabei wird zuerst die Bestellnummer innerhalb eines eigenen Nummernkreises automatisch hoch gezählt und mitgegeben. Sie wird in der Maske links oben eingeblendet. Der Anwender wird bei den Eingaben weitgehend geführt: Für eine eindeutige Zuordnung des Bestellartikels muss eine Teilenummer eingegeben werden. Kennt man diese nicht auswendig, so ist Suche über Matchcode möglich. Dies wird hier so gelöst, dass die ersten Buchstaben der bekannten Teilebezeichnung mit einem Fragezeichen voran gestellt eingegeben wird. Beispielsweise „?KO“ für „Kopierpapier“ (Abbildung 3, Seite VIII). Nach <Datenfreigabe> gelangt man in eine Folgemaske, die eine Liste in Frage kommender Artikel zeigt (Abbildung 4, Seite IX). Die Auswahl geschieht mit „ankreuzen“ gefolgt von <Datenfreigabe>. Man gelangt zurück zur Ausgangsmaske, die nun außer der Teilenummer noch weitere Teilestammdaten wie Teilebezeichnung und Maßeinheit zur Anzeige bringt (Abbildung 5, Seite IX). In ähnlicher Weise wird mit Zahlungs-/Lieferbedingungen sowie ’anfordernde Abteilung’ und ’Sachbearbeiter’ verfahren. In diesen Fällen gelangt man zu den jeweils dafür vorgesehenen Auswahlbildschirmen über die Funktionstasten F5, F8 bzw. F9. 13 Abbildung 6, Seite X zeigt die Lieferantenauswahl-Liste. In Abbildung 7, Seite X sind die nach Lieferantenauswahl automatisch ergänzten Daten Lieferantennummer, Lieferantenname und -währung ersichtlich. Weitere Daten werden „von Hand“ eingegeben. Um die Bestellerfassung zu verwerfen, kann die Erfassungsmaske über die Funktionstaste F3 verlassen werden. Hierbei muss die bereits vergeben Bestellnummer wieder automatisch zurückgesetzt werden. Zur Übernahme aller Eingabedaten wird F7 betätigt. Im Anschluss werden verschiedene Plausiprüfungen vorgenommen. Das kann z.B. eine Datumsprüfung sein. Im Falle des 30.02.2011 wird dann eine entsprechende Fehlermeldung ausgegeben. Ansonsten erfolgt die Abspeicherung mit anschließender Meldung „-Bestellung wurde versendet-“ (siehe Abbildung 2, auf Seite VIII links unten). 3.3 3.3.1 grundsätzliche Maskenelemente Funktionstasten Im Sinne der Durchgängigkeit wird die Belegung der Funktionstasten (wo möglich) auf allen Bildschirmen gleich gewählt. Dabei wird sich außerdem an Konventionen der Betriebssystem-Oberfläche angelehnt. Dies betrifft speziell die Funktionstasten F3 zum Verlassen des gegenwärtigen Bildschirmes und die Funktionstaste F7 zur Datenübernahme. 3.3.2 Variablen Der Sprachgebrauch im RPG-Umfeld bezeichnet Variablen auch als „Felder“. Die Felder des Bildschirmes orientieren sich an denen der Datenbank, was zum einen den Datentyp und zum anderen deren Länge anbetrifft. Vorzugweise numerisch sind Bestellmengen und Preise festzulegen. Die Dimensionierung orientiert sich dabei an der betrieblichen Praxis. D.h. Bestellmengen können durchaus auch Nachkommastellen erfordern, wenn z.B. 25,75 Liter eines bestimme Reinigungsmittels benötigt werden. Hier gilt, ebenso wie bei Geldbeträgen, dass der Anwender tatsächlich ein Komma bei der Eingabe erwartet und keinen Dezimalpunkt. Während Bestell- und Lieferantennummer einem geschlossenen Nummernkreis entstammen, ist die Teilenummer alphanumerisch und wird bei der Teilestammanlage vom Anwender selbst festgelegt. 14 Beim Bestelldatum wird aufgesplittet in Tag, Monat und Jahr. Ablage in der Datei erfolgt jedoch zusammengefasst in einem Feld als sog. gedrehtes Datum im Format 20110327, was spätere Selektionen (Datum von/bis) und Sortierung erleichtert. Die aus Codetabellen entstammenden Kürzel, wie z.B. die Zahlungsbedingung Z31 werden nur als solche (hier 3-stellig) in der Bestelldatei abgelegt. Der zugehörige Text („10 Tage 3%...“) wird immer erst bei Bedarf ermittelt und ausgegeben. Für Bemerkungen ist noch ein 4-zeiliger Zusatztext vorgehen. Da Memofelder in RPG nicht bekannt sind, sind hierfür vier getrennte eigenständige Textfelder vorgesehen. 3.3.3 Textkonstanten Das im Kapitel 2.2.4 beschriebene Konzept der Message-Files kommt bei der Definition von Textkonstanten zum Einsatz. Dies betrifft angefangen von der Überschrift „Direktbestellung erfassen“, ebenso Labels wie „Teile-Nr.:“, sowie die Bezeichnungen der Funktionstasten. Die Abbildungen 8, 9 und 10, Seite XI ff. zeigen die zu diesem Zweck eingerichtete Nachrichtendatei M1MSGF, welche die Nachrichten-IDs KON0001 bis KON0030 für Layouttexte sowie FUN0003 bis FUN0014 für Funktionstasten enthält. Beispielhaft ist Textkonstante KON0009 = „Teile-Bezeichnung:“ dargestellt. 3.3.4 Layoutelemente, Farben Das Erscheinungsbild verschiedener Bildschirmmasken sollte durchgängig und einheitlich sein. Zur räumlichen Aufteilung tragen in unserem Falle weiße Trennlinien bei, die im Kopfteil die ebenfalls weiße Überschrift und im Fußteil den Funktionstastenbereich vom Arbeitsbereich im Mittelteil separieren. Um der Bestellnummer als zentralem Element gerecht zu werden, ist ihr mit der Farbe Magenta eine Sonderrolle zugedacht. Bei den übrigen Texten gilt folgendes Prinzip: Vorgaben, die von Anwenderseite nicht änderbar sind, erhalten die Textfarbe grün. Gelbe Schriftfarbe hingegen signalisiert, dass es sich um Eingabefelder handelt bzw. Auswahlen über Listen in Folgebildschirmen ermöglicht wird. Funktionstasten in blau lehnen sich an OS/400-Konventionen an. Fehler- oder Hinweismeldungen werden in rot eingeblendet. Das in der linken oberen Ecke platzierte Produktlogo zeigt dem Benutzer, in welcher Anwendung er sich gerade befindet. 15 3.4. Quellcodeanalyse Die Voraussetzung zur Implementierung von Bildschirmprogrammen unter RPG ist die Existenz zugehöriger Displayfiles. Für unser Beispielprogramm sind drei DSPFs vorgesehen (siehe Abbildung 11, auf Seite XIII). Das DSPF M1BESTFM (siehe Abbildung 12, auf Seite XIV) ist für die Hauptbestellmaske zuständig. In der Anweisung 0002.00 des Quellcodes wird zunächst die Anzahl Zeilen und Spalten (24 x 80) des Bildschirms festgelegt. Es wird nicht in Pixel, sondern mit Anzahl ASCII-Zeichen gerechnet. Mit dem Format ‚BEST101’ (Anweisung 0007.00) erfolgt später der Aufruf aus dem Hauptprogramm. Mit Overlay CA03 bis CA09 (Anw. 0010.00 ff.) werden die entsprechenden Funktionstasten aktiviert. Anhand der Bildschirmüberschrift (Anw. 0035.00) kann die Anwendung von MSGFs verdeutlicht werden: Die Textkonstante KON0001 ist platziert auf Zeile 1 und Spalte 25. Ab dieser Spalte 25 wird Platz für 50 Zeichen reserviert. Die Darstellung soll in WHT = weiß ausgeführt werden. Als „Platzhalter“ für dieses Feld ist der Name MSGF001 festgelegt, und der Großbuchstabe A bestimmt hierbei, dass es sich um ein alphanumerisches Feld handelt. Im Gegensatz dazu steht DSMENG in Anw. 0057.00. Es handelt sich um ein bearbeitbares Eingabefeld für die Bestellmenge. Die Bearbeitbarkeit wird über den Buchstaben B (im Gegensatz zu O) bestimmt. Die Variable wird mit 8S2 definiert. S steht in diesem Fall für numerisch, 8 Stellen lang, hiervon 2 Nachkommastellen. Mit +1 wird in horizontaler Richtung eine Leerstelle zum davor stehenden Feld freigelassen. Die genannten Vorgehensweisen gelten entsprechend für die übrigen Bildschirmkomponenten auch in den DSPFs M1LIWAFM (Lieferantenauswahl) sowie M1TEWAFM (Teilestammauswahl). Im RPG-Hauptprogramm (Abbildung 15, auf Seite XVII) werden diese drei DSPFs in den Anw. 0011.00 bis 0013.00 deklariert und damit beim Kompilierungsvorgang mit eingebunden. Gleiches gilt für eine ganze Reihe von Copy-Sourcen in Anw. 0113.00 ff. Mit zu den Deklarationen gehören auch sog. Workfelder in Anw. 0016.00 ff., die lediglich innerhalb des Programms die Funktion von Hilfsvariablen einnehmen. Der eigentliche Algorithmus findet seinen Anfang ab Anw. 0035.00 ff. unter „Rechenbestimmungen“. Der Startpunkt wird über das Wort ‚ENTRY’ (Anw. 0038.00) signalisiert. An der Stelle findet das aufrufende Programm den Eintritt, wobei gleichzeitig eine gegebenenfalls vorhandene AufrufParameterliste über ‚PARM’ übernommen wird. 16 Mit dem Statement ’EXSR’ = ‘Execute (Invoke) Subroutine’ können Unterroutinen aufgerufen werden. Abbildung 15, auf Seite XVIII zeigt in Anw. 0042.00 den Aufruf der Routine ’BESTVR’ zur Vergabe der neuen Bestellnummer. Alle Ereignisse, die innerhalb der Bestellmaske von Belang sind, werden nun in einer endlos laufenden Schleife abgefangen, die in Anw. 0046.00 beginnt und in Anw. 0101.00 endet. Ist die Teilenummer nicht leer und steht an erster Stelle kein Fragezeichen, dann wird die Routine ’TELESE’ zum Lesen des Teilestamms aufgerufen (Anw. 0050.00). Ansonsten, bei vorhandenem Fragenzeichen, wird in Anw. 0055.00 mit ’TEWAHL’ in die Teilestamm-Auswahlmaske verzweigt. In Anw. 0064.00 wird geprüft, ob die Funktionstaste F3 gedrückt ist. Trifft dies zu, erfolgt das Verlassen des Programms über ’SRRETU’. In gleicher Weise werden in Folge die Funktionstasten F5, F7, F8 und F9 abgefragt und die jeweils zugeordneten Subroutinen ausgeführt. Insoweit sind die bisherigen aufgeführten Programmteile lauffähig und stellen die Funktionalität eines Prototypen in RPG vollumfänglich dar. Da wir uns hier vorwiegend auf die Gesichtspunkte der Bildschirmdarstellung konzentrieren, sind weiterführende Komponenten der Applikation nur rudimentär realisiert. Dies betrifft zu einen das aufrufende Startprogramm (Abbildung 16, auf Seite XIX). Zum anderen sind in zahlreichen Copysourcen Funktionalitäten aus dem Hauptprogramm ausgelagert (Abbildung 15, Seite XVIII, Anw. 0113.00 ff.). Der Vollständigkeit halber sind diese dargestellt in den Abbildungen 17 bis 24 ab Seite XX. 4 Festlegung des Soll-Zustands 4.1 Idealvorstellung Erinnern wir uns an das ursprüngliche Anliegen. Ziel ist es, eine grafische Benutzerschnittstelle bereitzustellen, die den Anforderungen der Zeit genügt, und für die Akzeptanz bei modernen Anwendern förderlich ist. Dies als Marketingkonzept, um im Wettbewerb mit anderen Anbietern bestehen bzw. gleichziehen zu können. Durch die weite Verbreitung von Microsoft Windows-Oberflächen sollten diese auch folgerichtig als Vorbild bzw. Leitlinie herangezogen werden. Der Benutzer sollte dabei möglichst keinen Unterschied zwischen einer MS Office-Applikation wie ‚Outlook’ und unserer eigenen Geschäftsanwendung wahrnehmen können. „Look and feel“ als Ziel. 17 Als Gestaltungselemente steht eine mannigfaltige Palette grafischer Elemente zur Verfügung. Als eine der vordringlichsten Aspekte drängt sich die Möglichkeit auf, mehrere Fenster gleichzeitig geöffnet zu haben. Hierdurch hat man Ein-/Ausgabedaten etwaiger Vor- und Nachfolgemasken gleichzeitig im Überblick. Unterstützt wird dies durch die Tatsache, dass durch die bessere Grafikauflösung kleinere Schriftgrößen darstellbar sind. So kann gleiche Information auf engerem Raum ausgegeben werden. Die Verschiebbarkeit sowie die Umschaltbarkeit zwischen Fenstern tragen ihr Übriges dazu bei. Konkreten Einsatz basierend auf dieser Grundlage bietet sich in unseren Anwendungsfall für die Matchcode-Auswahlliste für die Teilenummer an. Auswahl-Listen mit Inhalten aus einer geringeren Grundgesamtheit lassen sich am Besten über Comboboxen realisieren. Das kann beispielsweise bei der Zuordnung der Zahlungs- und Lieferbedingungen geschehen. Überall wo möglich, setzen wir mausbetätigbare Buttons ein. Somit kann auf die bisherigen Funktionstasten gänzlich verzichtet werden. Für den mehrzeiligen Zusatztext bietet sich ein Memofeld an. 4.2 notwendige Kompromisse Natürlich sind wir zuvorderst an die darunter liegende Applikation gebunden. Diese Geschäftsanwendung bleibt weitgehend unverändert. So müssen Übergabeformate der Variablen für die Schnittstelle von „oben nach unten“ und auch umgekehrt eingehalten werden. Dies ohnehin, weil bei einem Update auf das neue Release Altdaten weiterhin verwendbar sein müssen. Eine Einschränkung stellt das gewünschte Memofeld dar. Da datenbankseitig der Zusatztext der Maske nach wie vor durch vier Einzelzeilen abgebildet wird, muss dem Umstand auch im Maskendesign Rechnung getragen werden. Codetabellenbasierte Auswahlen wie die Zahlungsbedingung beinhalten nach wie vor den reinen Code z.B. „Z31“ anstelle des ganzen Volltextes. Auch beinhaltet die Strategie, dass für eine erhebliche Anzahl von Stammusern ein bestimmter Wiedererkennungswert zum bisherigen Standard vorhanden sein sollte. In dem Zusammenhang wäre zu überlegen, bei verschiedenen Buttons parallel die ehemalige Funktionstastenlogik zu belegen. Strittig ist dabei, ob das Verlassen der Maske nun über [ESC] oder weiterhin über [F3] möglich sein soll. Hierbei ergeben sich wiederum Ansätze, derartige individuelle Anwendervorlieben mittels Customizing über „Schalter“ in Form von Steuerungswerten zu regeln. 18 5 Umsetzung: Erstellung eines neuen grafischen Prototyps in Java Es wurde eine Entscheidung zu Gunsten von Java getroffen, da wir so einerseits plattformunabhängig sind. Andererseits stehen uns gegenüber einer HTML-Variante weit mehr Möglichkeiten zur Verfügung. Von der Gesamtanwendung eines fiktiven ERP-Systems wird lediglich ein kleiner Ausschnitt zur Darstellung gebracht. Mit der Ausführung eines Prototyps soll dem Anwender eine „fassbare“ Beispielvariante der neuen Grafikoberfläche präsentiert werden, die alle vorhandenen Dialogabläufe im Zusammenhang mit der bisherigen Bestellmaske zu Testzwecken verfügbar macht. Zur thematischen Einordnung wurden verschiedene Java-Packages gebildet (Abbildung 25, auf Seite XXII). Wir trennen zwischen einem ‚Einkaufspaket’ und einem Paket speziell für die ‚Teilestammverwaltung’. Zusätzlich soll ein neutrales Paket namens ‚Framework’ bereitgestellt werden. Diese Vorgehensweise auch um dem Paradigma der Wiederverwendbarkeit bei der Objektorientierung gerecht zu werden. Auf die Vorstellung der einzelnen Klassen sowie der Funktionalitäten kommen wir später zurück. 5.1 Elemente der neuen Eingabemaske Im Folgenden soll zunächst der Fokus auf den gestalterischen Aspekten liegen. 5.1.1 Schriftarten, Schriftgrad, Farbgebung, Layout Die Schrift in der Greenscreendarstellung ist (zwangläufig) einheitlich gehalten. Die Schriftart möchte man von der Erscheinung her als COURIER identifizieren. Die Buchstabenhöhe ist überall gleich hoch. Somit bieten sich nicht viel stilistische Mittel, um Akzente zu setzen. Allein eine gewisse Farbpalette und die Inversdarstellung taugen für Hervorhebungen. In Java haben wir nun eine weit größere Auswahl. Dennoch ist ein sparsamer Einsatz empfehlenswert, um das Design nicht zu überfrachten. Sinnvoll sind auf alle Fälle Durchgängigkeit bei gleichen Darstellungselementen. Abbildung 26, auf Seite XXIII zeigt die neue GUI-Maske. Hier wurden alle Labels (z.B. „Teilenummer:“) in ARIAL, schwarz und Größe 14 ausgeführt. Variableninhalte innerhalb von Textfeldern erhalten die Schriftart COURIER. Durch diesen „Schreibmaschinencharakter“ wird klargelegt, hier ist etwas einzugeben. Da die maximale Variablenlänge fix ist, wird mit der Spaltengerechtigkeit von COURIER 19 gewährleistet, dass der Gesamtschriftzug der maximalen Länge der Textfeld-Rechtecke entspricht. In ARIAL hingegen fallen zehn Buchstaben „llllllllll“ oder zehnmal „OOOOOOOOOO“ eben unterschiedlich lang aus. Weiterhin differenzieren wir bei den Variablen zwischen manuell direkt eingebbaren in schwarz und Variablen, die sich mittelbar aus den Stammdaten ergeben in blau. Das Window als solches präsentiert sich im grau-blauen Windows Vista Style. Zur Raumaufteilung wurde das Fenster horizontal in drei Panels eingeteilt. Die beiden oben und unten in grau, der Mittelteil mit weißem Hintergrund. Im Kopfbereich die beiden maßgeblichen zentralen Elemente: Bestellnummer in rot mit Schriftgrad 16 sowie der Lieferant. Der Mittelteil wiederum ist nochmals mit zwei horizontalen Trennlinien unterteilt. Dadurch entstehen drei Bereiche mit logisch zusammenpassenden Elementen: 1) Teilen-Nr. mit den wichtigsten Eckdaten Menge, Termin und Preis 2) Ergänzungen wie z.B. die Zahlungsbedingungen 3) Zusatztext. Im Fuss-Panel der Buttonbereich. 5.1.2 Überschrift, Logo Auch das Produkt-Logo wird einem „Facelifting“ unterzogen. Dieses kann nun originalgetreu wie in den Printmedien wiedergegeben werden. Zusatzfunktion kommt bei der GUI-Version nicht nur dem Logo, sondern auch der Überschrift zu. Beide stehen links oben im jeweiligen Fenster. Gleichfalls dient es bei minimierten Windows zur Orientierung bei der Auswahl in der Taskleiste. Dementsprechend müssen die Bezeichnungen aufgrund des hier begrenzten Platzes möglichst kurz und prägnant formuliert werden. Nicht zuletzt findet das Logo auch als Icon auf dem Desktop Verwendung. Abbildungen 27 und 28, Seite XXIV zeigen eine Gegenüberstellung. 5.2.3 Eingabefelder, Comboboxen Beim Handling der Textfelder in GUI werden bestimmte Verhalten erwartet. Ausschneiden, Kopieren und Einfügen gehören dazu. Javax.swing stellt JTextField zur Verfügung. Hiermit wird das Editieren von einzeiligen Texten ermöglicht. Durch Klicken in ein Textfeld wird erreicht, dass dort der Fokus liegt. Ebenso soll aber auch das Springen von Feld zu Feld mittels [Enter] möglich sein. JComboBox verbindet Textfeldeigenschaften mit denen einer Aufklappliste. Die Hauptbestellmaske enthält 15 Textfelder und fünf Comboboxen. 20 5.2.4 Buttons Während bei unserer RPG-Variante stets eine Schleife durchlaufen wird, bei der auf Funktionstastendruck gewartet wird, sind bei der Java-Ausführung Listener im Einsatz, welche auch in verschiedenen, gleichzeitig geöffneten Fenstern auf Ereignisse reagieren. Auslöser dieser Ereignisse stellen u.a. Buttons dar. So ist beim prozeduralen Aufbau des RPGs der Ablauf weitgehend vorgezeichnet. Im Java-Programm hingegen kann nicht vorhergesehen werden, was der Anwender als nächstes macht. Dem Umstand ist bei der Erstellung des Algorithmus Rechnung getragen werden. Drei Buttons in unserer Hauptbestellmaske zuzüglich des [X] zum Schließen der einzelnen Windows müssen somit „unter einen Hut“ gebracht, Plausibilitätsüberlegungen für jeden möglichen Event angestellt werden. 5.2 Implementierung in Java (Quellcode) Klasse XML_Kommunikation (Abbildung 29, Seite XXV) Um eine Schnittstelle zum Kern der Geschäftsanwendung bereitzustellen, simuliert diese Klasse alle Funktionen, die zur Kommunikation mit der Bestellmaske erforderlich sind. Methoden wie zur Festlegung der nächsten Bestellnummer, Zugriff auf verschiedene Stammdaten sowie zur Speicherung der Bestellung werden bereitgestellt. Klasse HinweisFenster (Abbildung 30, Seite XXX) Zur Mitteilung allgemeiner Hinweise z.B. „Bestellung wurde versendet“ an den Benutzer werden über diese Klasse ausgegeben. Aufrufparameter bilden Überschrift, Hinweistext, Fensterabmessungen und Fensterposition. Klasse Fehlermeldung (Abbildung 31, Seite XXXI) Ist vom Prinzip her gleich wie das Hinweisfenster. Hinzu kommt ein OK-Button. Zweck sind Meldungsausgaben in der Form „Geben Sie eine gültige Teilenummer ein“. Aufruf kann z.B. in der catch-Schleife beim Werfen einer Exception erfolgen. Klasse BestellStart (Abbildung 32, Seite XXXII) Die eigentliche Bestellmaske würde in der Realität über einen Punkt im Einkaufsmenü aufgerufen. Die Klasse ‚BestellStart’ simuliert diesen Vorgang. In der mainMethode wird der Konstruktor für alle Bestellparameter aufgerufen. Zwei weitere Methoden dienen dem Eröffnen und Schließen der Hauptbestellmaske. Der Maskentitel wird als Textkonstante über ‚XML_Kommunikation’ abgefragt und mitgegeben. 21 Klasse BestellEingabeParameter (Abbildung 33, Seite XXXIII) Diese Klasse enthält alle notwendigen Attribute für eine Bestellung. Instanzen hiervon stellen somit eine ganz konkrete Bestellung dar. Das komplette Objekt wird als Übergabeparameter an Folgeklassen weitergereicht, damit diese Kenntnis über die innere Datenstruktur haben. Der Zugriff erfolgt dabei ausschließlich über Setter- und Gettermethoden. Somit bleibt das Prinzip der Kapselung gewahrt. Am Ende sollen in der Klasse XML_Kommunikation über die Methode bestellungVersenden(...) sämtliche Parameter für die Übergabe an den RPG-Kern typgerecht aufbereitet werden. Klasse BestellEingabeMaske (Abbildung 35, Seite XXXIX) Stellt die zentrale Komponente unserer „Mini-Applikation“ dar, die hier quellcodeseitig eingehender erläutert werden soll. Zu Programmbeginn wird als erstes eine Instanz der Klasse XML_Kommunikation erstellt. Im Anschluss erfolgt Deklaration der Maskenelemente Panels, Buttons, Labels, Comboboxen und Textfelder. Über die Methode xml.textKonstanteZuord("...") werden alle benötigten Textkonstanten zugewiesen. Außerdem werden verschiedene lokale Variablen, Objekte für Fehler-/Hinweis-Meldungen und der Folgeframe TeileMatchcodeMaske deklariert. Die eigentliche Maske wird nun im Konstruktor BestellEingabeMaske(...) erstellt. Es folgt die Vergabe der Bestellnummer und Hinzufügen diverser Listener. Danach kommt die Festlegung der einzelnen Parameter sämtlicher Maskenelemente in ihren spezifischen Ausprägungen: Aufteilung und Hintergrundfarben der Panels. Lage, Größe, Farbe und Schriftgestaltung der Labels, Textfeldern und Comboboxen. Platzierung der Buttons. Nicht zuletzt Festlegung von Größe und Position des gesamten Frames als solchen einschließlich hinzufügen des Titel-Icons. Listener reagieren auf entsprechende Events. Wir unterscheiden: Listener für Buttons, Item-Listeners zur Reaktion auf Klicks in Comboboxen, Fenster-Listener speziell zum Schließen des Windows und Key-Listener zur Reaktion auf die Enter-Taste. Klasse TeileMatchcodeMaske (Abbildung 34, Seite XXXVI) Für das Auswählen der Teilenummer aus einer Liste ist ein separates Fenster vorgesehen. Es ist ein Textfeld zur Matchcode-Eingabe eingerichtet. Anhand der Eingabe werden in Frage kommende Positionen in ein Array gestellt. Eine Liste mit ScrollLeiste dient der Wiedergabe auswählbarer Positionen. Nach Anklicken einer Position erfolgt automatisch Rückkehr zur Hauptbestellmaske. 22 5.3 Darstellung der neuen grafischen Eingabemaske Der GUI-Prototyp verfügt jetzt über alle geforderten Funktionen. Die Dialogabläufe können nunmehr durchgespielt werden. Nach Aufruf enthält zunächst lediglich die Bestellnummer einen Inhalt (Abbildung 36, Seite XLVII). Prinzipiell ist die Eingabereihenfolge beliebig. Jedoch ergeben nachfolgende Eingaben erst einen Sinn, wenn der zu bestellende Artikel festgelegt wurde. Direkteingabe der Teilenummer ist möglich. Falscheingaben werden mit einer Fehlermeldung quittiert (Abbildung 37, Seite XLVII). Alternativer Einstieg über Button in die Matchcode-Auswahl (Abbildung 38, Seite XLVIII). Der Matchcode-Button wird dabei deaktiviert, da sonst mehrfaches, aber sinnloses Öffnen des Matchcode-Windows möglich wäre. Erst nach Verlassen des Matchcode-Windows wird der Button erneut aktiviert. Was passiert, wenn bei noch geöffnetem Matchcode-Window im Hauptfenster [X] = „Window-Closing“ betätigt wird? Würde an der Stelle nicht dafür Sorge getragen, so bliebe das Matchcode-Window nach wie vor offen. Tatsächlich wird es aber ebenfalls geschlossen. Zum dem Zweck wird intern die Methode ’matchcode.setVisible(false)’ verwendet. Bei vorhandener Teilenummer werden die Teilestammdaten eingeblendet (Abbildung 39, Seite XLVIII). Lieferantenauswahl geschieht über eine Combobox (Abbildung 40, Seite XLIX). Auch hier nach erfolgter Auswahl Einblendung ergänzender Lieferantenstammdaten (Abbildung 41, Seite XLIX). Durch die Vorgehensweise der Einblendung bereits vorhandener Stammdaten werden Fehler bei eventueller erneuter Erfassung von Hand sowie redundante Datenhaltung vermieden. Dies setzt sich beim (hier zwar nicht implementierten) Bestellversand fort. Daten, wie Adresskopf, Emailadresse, unsere Kundennummer beim Lieferanten usw. stehen als bekannte Lieferantenstammdaten schon zur Verfügung. Wird in der Hauptmaske [Übernehmen] gedrückt, ist es zunächst notwendig, die Benutzereingaben zu überprüfen. Als Pflichtfelder festgelegte Eingaben, wie z.B. die Bestellmenge, dürfen nicht leer gelassen werden. Ebenso muss das Bestelldatum einer Prüfung unterzogen werden. Dieses soll einerseits kalendarisch korrekt sein, und darf andererseits auch nicht in der Vergangenheit liegen. In Bedarfsfall sind entsprechende Meldungen an den Benutzer auszugeben. Bei korrekten Eingaben erfolgt die Übergabe durch die XML-Schnittstelle. Im Prototyp symbolisch dargestellt durch Ausgabe in der Konsole (Abbildung 42, Seite L). 23 6 Schlussbetrachtungen Wir haben nun sowohl die Greenscreen-, als auch die GUI-Version aus verschiedenen Blickwinkeln durchleuchtet und Betrachtungen hinsichtlich Implementierung und ihrer Benutzung angestellt. Mit der neuen Bestellmaske steht nunmehr eine Grafikoberfläche zur Verfügung, die hinsichtlich ihrer Bedingung auf der Höhe der Zeit steht, und den modernen User als Zielgruppe anspricht. Wie sieht die realistische Einschätzung dieses Konzepts aus, und welche Schlüsse können gezogen werden? Bereits in der Einleitung wurde festgestellt, es gibt einige Anbieter von Geschäftanwendungen, die ihrer Legacy-AS/400-Applikation auf diese Weise mit verbesserter Optik neue Marktfähigkeit verliehen haben. Der gewöhnliche Anwender sieht im Alltag kaum noch einen nennenswerten Unterschied zu einer Microsoft Windows-Anwendung. Kritische Anmerkungen Stellen wir die Programmquellen unserer beiden Varianten gegenüber, ist zunächst festzustellen, dass die Java-Variante einen erheblich größeren Umfang hat als der RPG-Code. Bei Java können Hilfsmittel zur maschinellen Codierung von Getter- und Settermethoden eingesetzt werden. Auch leisten GUI-Builder entlastende Hilfestellung. Dennoch ist der erzeugte Code letztendlich doch vorhanden und muss als sog. Metrik ‚LOC’ (Lines of Code) in eine etwaige Aufwandsschätzung mit einfließen. Durch die Abhängigkeit vom Anwendungskern können die Möglichkeiten der objektorientierten Programmierung nicht voll ausgeschöpft werden. Auch zeigt die Praxis, dass sich die eingesetzte Middleware zur Kommunikation zwischen Anwendungs- und Präsentationsschicht oft als „Flaschenhals“ erweist, der bei den Antwortzeiten im Vergleich zum ehemaligen Greenscreen-Release wesentlich schlechter da steht. Man muss somit festhalten: Die alleinige „GUIsierung“ der Benutzeroberfläche zur Anwendungsmodernisierung steigert die Komplexität des Gesamtsystems, die Funktionalität der Geschäftsanwendung im Kern verbessert sich hierdurch aber eigentlich nicht wirklich, sondern stellt lediglich einen Kompromiss dar. 24 Stellenwert der iSeries in diesem Zusammenhang Abgesehen von COBOL ist bis dato RPG d i e Programmiersprache der AS/400. Der Zenit von RPG als solches ist allerdings, objektiv gesehen, bereits seit ein paar Jahren überschritten. Zur Erweiterung und Wartung bestehender Systeme stehen vielleicht noch ein knappes Jahrzehnt lang Programmierer zur Verfügung. Mischlösungen (wie die hier vorliegende), bei denen RPG den Applikationskern bildet, werden insofern auch von diesem Aspekt her nicht zukunftsträchtig sein. Hierin liegt ein gewisses Dilemma. Denn nach wie vor hat die i5 (AS/400) als Plattform ihre Berechtigung. Sie bietet Abwärtskompatibilität über Jahrzehnte, gilt als stabil und ausfallsicher, ist hochperformant, einfach administrierbar und erweiterbar. Trends Das i5/OS V6R1 verfügt über eine 64-Bit-JVM. Java-Programme sind schon seit längerer Zeit auch auf einer iSeries lauffähig. Bei gänzlichen Neuentwicklungen bietet es sich also an, auch die Anwendungsschicht komplett in Java auszuführen. Einen weiteren Ansatz bietet EGL (Enterprise Generation Language) von IBM. EGL ist eine Programmiersprache der 4. Generation (4GL) und zugleich eine Entwicklungsumgebung. Auf der Basis von EGL-Programmen lässt sich wahlweise Java-Code als auch System-i-naher Code generieren. Die in der Entwicklungsumgebung enthaltenen Editoren ermöglichen außerdem das Erstellen grafischer Oberflächen. EGL ist eingebettet in den WebSphere Development Studio Client (WDSC). IBM-WebSphere als Produktfamilie hat Lösungen für den Bereich „e-business“, ist vom Betriebssystem her plattformunabhängig und damit auch auf der AS/400 einsetzbar. Gleichwohl zeigen aber Entwicklungen auch in ganz andere Richtungen. Nämlich weg von unflexiblen monolithischen Blöcken und proprietären Insellösungen, hin zu lose gekoppelten Komponenten (Services), die im Sinne von SOA (Serviceorientierte Architektur), über Schnittstellen kommunizieren. Ziel ist es, baukastengleich unternehmensweite und unternehmensübergreifende Durchgängigkeit für alle Bereiche zu geschaffen. Noch eine Steigerung zeigt sich bei SaaS (Software as a Service) als ein Teilbereich von Cloud Computing. Welche Philosophien sich durchsetzen werden, entscheidet der Markt und letztendlich die Anwender, die das Maß der Dinge darstellen (sollten). 25 ANHANG Datenbank ( DB2 ) RPG-Programme für - Bestelldruck - Sachbearbeiterverwaltung - Lieferantenverwaltung usw. usw. und RPG-Programme für Ein-/Ausgabemasken ... - Lieferanten erfassen - Sachbearbeiter erfassen usw. usw. unter anderem auch eine Bestellerfassungsmaske Applikation einschließlich Bildschirmdarstellung vorher ERP-System Datenbank ( DB2 ) RPG-Programme für - Bestelldruck - Bestellung speichern - Sachbearbeiterverwaltung - Lieferantenverwaltung usw. usw. XML Java-Klassen für Eingabemasken ... - Lieferanten erfassen - Sachbearbeiter erfassen usw. usw. unter anderem auch eine Bestellerfassungsmaske Applikation grafischer Client nachher ERP-System Abbildung 1: Prinzip: Ersatz RPG-Greenscreen-Benutzeroberfläche durch GUI VII Abbildung 2: Greenscreen-Maske als Ausgangsbasis, Komplettdarstellung Abbildung 3: Greenscreen-Maske, Eingabe: Teilestamm-Matchcode VIII Abbildung 4: Greenscreen-Maske, Teilestamm Matchcode-Auswahl Abbildung 5: Greenscreen-Maske, Einblendung Teilestammdaten IX Abbildung 6: Greenscreen-Maske, Lieferantenauswahlliste Abbildung 7: Greenscreen-Maske, Einblendung Lieferantenstammdaten X Abbildung 8: Greenscreen-Maske, Aufruf Nachrichtendatei M1MSGF Abbildung 9: Greenscreen-Maske, Beispiel Textkonstante KON0009 XI Nachrichten ID FUN0003 FUN0005 FUN0007 FUN0008 FUN0009 FUN0011 FUN0012 FUN0013 FUN0014 KON0001 KON0002 KON0003 KON0004 KON0005 KON0006 KON0007 KON0008 KON0009 KON0010 KON0015 KON0017 KON0019 KON0020 KON0021 KON0022 KON0024 KON0025 KON0026 KON0027 KON0028 KON0029 KON0030 LOG0001 Abbildung 10: Bewertung 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Nachrichtentext F3=Verlassen F5=Lieferant F7=Übernehmen F8=Zahlungs-/Lieferbedingungen F9=anford. Abteilung/Sachbearb. F11=übernehmen F12=beenden F13=vorblättern F14=zurückblättern >> Direktbestellung erfassen << Teile-Nr.: Lieferant: ================================== Bestell-Nr.: Teile-Bezeichnung: ---------------------------------Bestellmenge: Bestelltermin: Zahlungsbedingungen: = Lieferbedingungen: Preis: je anfordernde Abteilung: Sachbearbeiter: Zusatztext: >> Lieferantenauswahl << >> Teilestamm Matchcode-Auswahl << manneSOFT Greenscreen-Maske, Übersicht alle Textkonstanten XII Abbildung 11: Greenscreen-Maske, Übersicht Displayfiles XIII Abbildung 12: Greenscreen-Maske, Displayfile für Hauptbildschirm MANNE1/QDSPSRC/M1BESTFM 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 0010.00 0011.00 0012.00 0013.00 0014.00 0015.00 0016.00 0017.00 0018.00 0019.00 0020.00 0021.00 0022.00 0023.00 0024.00 0025.00 0026.00 0027.00 0028.00 0029.00 0030.00 0031.00 0032.00 0033.00 0034.00 0035.00 0036.00 0037.00 0038.00 0039.00 0040.00 0041.00 0042.00 0043.00 0044.00 0045.00 0046.00 0047.00 0048.00 0049.00 0050.00 0051.00 0052.00 0053.00 0054.00 0055.00 0056.00 0057.00 0058.00 0059.00 0060.00 0061.00 0062.00 0063.00 0064.00 0065.00 0066.00 0067.00 A* A DSPSIZ(24 80 *DS3) A CHGINPDFT(HI CS UL) A INDARA A PRINT A*-----------------------------------------------------------------------A R BEST101 A* A* -- FUNKTIONSTASTEN --------------------------A OVERLAY A CA03(03) A CA05(05) A CA07(07) A CA08(08) A CA09(09) A MSGF019 78A O 22 2MSGID(KON0007 M1MSGF) A COLOR(WHT) A MSGF018 12A O 23 2MSGID(FUN0005 M1MSGF) A COLOR(BLU) A MSGF020 30A O +2MSGID(FUN0008 M1MSGF) A COLOR(BLU) A MSGF021 31A O +2MSGID(FUN0009 M1MSGF) A COLOR(BLU) A MSGF009 12A O 24 2MSGID(FUN0003 M1MSGF) A COLOR(BLU) A MSGF016 13A O +2MSGID(FUN0007 M1MSGF) A COLOR(BLU) A* A* -- LOGO -------------------------------------A MSGF011 10A O 1 2MSGID(LOG0001 M1MSGF) A COLOR(RED) A MSGF007 78A O 2 2MSGID(KON0007 M1MSGF) A COLOR(WHT) A* -- ÜBERSCHRIFT ------------------------------A MSGF001 50A O 1 25MSGID(KON0001 M1MSGF) A COLOR(WHT) A* -- BESTELL-NR -------------------------------A MSGF012 12A O 3 2MSGID(KON0008 M1MSGF) A DSBEST 8S 0O +1 A COLOR(PNK) A* -- LIEFERANT --------------------------------A MSGF006 10A O +16MSGID(KON0006 M1MSGF) A DSLINR 7S 0O +1 A COLOR(YLW) A MSGF015 1A O +1MSGID(KON0015 M1MSGF) A DSLIBZ 20A O +1 A MSGF014 78A O 4 2MSGID(KON0010 M1MSGF) A COLOR(WHT) A* -- TEILE-NR. --------------------------------A MSGF002 10A O 6 2MSGID(KON0002 M1MSGF) A DSTENR 15A B +1 A* -- TEILE-BEZEICHNUNG ------------------------A MSGF013 18A O +2MSGID(KON0009 M1MSGF) A DSTEBZ 30A O +1 A* -- BESTELLMENGE UND MASSEINHEIT -------------A MSGF017 13A O 8 2MSGID(KON0017 M1MSGF) A DSMENG 8S 2B +1 A DSMABZ 8A O +1 A* -- BESTELLTERMIN ----------------------------A MSGF022 14A O +2MSGID(KON0019 M1MSGF) A DSBETT 2S 0B +1 A DSBEMM 2S 0B +1 A DSBEJJ 4S 0B +1 A* -- PREIS ------------------------------------A MSGF027 6A O 10 2MSGID(KON0024 M1MSGF) A DSPREI 8A B +1 A DSWAEH 3A O +1 XIV 0068.00 0069.00 0070.00 0071.00 0072.00 0073.00 0074.00 0075.00 0076.00 0077.00 0078.00 0079.00 0080.00 0081.00 0082.00 0083.00 0084.00 0085.00 0086.00 0087.00 0088.00 0089.00 0090.00 0091.00 0092.00 0093.00 0094.00 0095.00 0096.00 0097.00 0098.00 0099.00 0100.00 0101.00 0102.00 0103.00 A A A A* A A A A A A* A A A A A A* A A A A A A* A A A A A A* A A A A A A* A A MSGF028 2A O +1MSGID(KON0025 M1MSGF) DSPROP 8S 0B +1 DSMAB2 8A O +1 -- ZAHLUNGSBEDINGUNGEN ----------------------MSGF023 22A O 12 2MSGID(KON0020 M1MSGF) DSZABE 3A O +1 COLOR(YLW) MSGF024 1A O +1MSGID(KON0021 M1MSGF) DSZABZ 32A O +1 -- LIEFERBEDINGUNGEN ------------------------MSGF025 22A O 13 2MSGID(KON0022 M1MSGF) DSLFBE 3A O +1 COLOR(YLW) MSGF026 1A O +1MSGID(KON0021 M1MSGF) DSLFBZ 32A O +1 -- ANFORDERNDE ABTEILUNG --------------------MSGF029 22A O 14 2MSGID(KON0026 M1MSGF) DSABTZ 3A O +1 COLOR(YLW) MSGF030 1A O +1MSGID(KON0021 M1MSGF) DSABTB 32A O +1 -- ANFORDERNDER SACHBEARBEITER --------------MSGF031 22A O 15 2MSGID(KON0027 M1MSGF) DSSABE 4A O +1 COLOR(YLW) MSGF032 1A O +1MSGID(KON0021 M1MSGF) DSSABZ 32A O +1 -- ZUSATZTEXT -------------------------------MSGF033 11A O 17 2MSGID(KON0028 M1MSGF) DSTEX1 60A B +1 DSTEX2 60A B 18 14 DSTEX3 60A B 19 14 DSTEX4 60A B 20 14 -- MELDUNGSZEILE ----------------------------DSMSGS 60A O 21 2 COLOR(RED) XV Abbildung 13: Greenscreen-Maske, Displayfile für Lieferantenauswahl MANNE1/QDSPSRC/M1LIWAFM 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 0010.00 0011.00 0012.00 0013.00 0014.00 0015.00 0016.00 0017.00 0018.00 0019.00 0020.00 0021.00 0022.00 0023.00 0024.00 0025.00 0026.00 0027.00 0028.00 0029.00 0030.00 0031.00 0032.00 0033.00 0034.00 0035.00 0036.00 0037.00 0038.00 0039.00 0040.00 0041.00 0042.00 0043.00 0044.00 0045.00 0046.00 0047.00 0048.00 0049.00 0050.00 0051.00 0052.00 0053.00 0054.00 0055.00 0056.00 0057.00 0058.00 0059.00 0060.00 0061.00 0062.00 0063.00 0064.00 0065.00 A* A DSPSIZ(24 80 *DS3) A CHGINPDFT(HI CS UL) A INDARA A PRINT A*-----------------------------------------------------------------------A R LIWA101 A* A* -- FUNKTIONSTASTEN --------------------------A OVERLAY A CA11(11) A CA12(12) A CA13(13) A CA14(14) A MSGF031 78A O 22 2MSGID(KON0007 M1MSGF) A COLOR(WHT) A MSGF032 14A O 23 2MSGID(FUN0011 M1MSGF) A COLOR(BLU) A MSGF033 11A O +2MSGID(FUN0012 M1MSGF) A COLOR(BLU) A MSGF037 15A O 24 2MSGID(FUN0013 M1MSGF) A COLOR(BLU) A MSGF038 19A O +2MSGID(FUN0014 M1MSGF) A COLOR(BLU) A* A* -- LOGO -------------------------------------A MSGF034 10A O 1 2MSGID(LOG0001 M1MSGF) A COLOR(RED) A MSGF035 78A O 2 2MSGID(KON0007 M1MSGF) A COLOR(WHT) A* -- ÜBERSCHRIFT ------------------------------A MSGF036 50A O 1 25MSGID(KON0029 M1MSGF) A COLOR(WHT) A* -- AUSWAHLBEREICH ---------------------------A DSWA00 1A B 3 2 A DSNA00 60A O +1 A DSWA01 1A B 4 2 A DSNA01 60A O +1 A DSWA02 1A B 5 2 A DSNA02 60A O +1 A DSWA03 1A B 6 2 A DSNA03 60A O +1 A DSWA04 1A B 7 2 A DSNA04 60A O +1 A DSWA05 1A B 8 2 A DSNA05 60A O +1 A DSWA06 1A B 9 2 A DSNA06 60A O +1 A DSWA07 1A B 10 2 A DSNA07 60A O +1 A DSWA08 1A B 11 2 A DSNA08 60A O +1 A DSWA09 1A B 12 2 A DSNA09 60A O +1 A DSWA10 1A B 13 2 A DSNA10 60A O +1 A DSWA11 1A B 14 2 A DSNA11 60A O +1 A DSWA12 1A B 15 2 A DSNA12 60A O +1 A DSWA13 1A B 16 2 A DSNA13 60A O +1 A DSWA14 1A B 17 2 A DSNA14 60A O +1 A DSWA15 1A B 18 2 XVI 0066.00 0067.00 0068.00 0069.00 0070.00 0071.00 0072.00 0073.00 0074.00 0075.00 0076.00 A A A A A A A A* A* A A Abbildung 14: DSNA15 DSWA16 DSNA16 DSWA17 DSNA17 DSWA18 DSNA18 60A 1A 60A 1A 60A 1A 60A O +1 B 19 2 O +1 B 20 2 O +1 B 21 2 O +1 -- MELDUNGSZEILE ----------------------------DSMSGS 60A O 21 2 COLOR(RED) Greenscreen-Maske, Displayfile für Teilestammauswahl MANNE1/QDSPSRC/M1TEWAFM 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 0010.00 0011.00 0012.00 0013.00 0014.00 0015.00 0016.00 0017.00 0018.00 0019.00 0020.00 0021.00 0022.00 0023.00 0024.00 0025.00 0026.00 0027.00 0028.00 0029.00 0030.00 0031.00 0032.00 0033.00 0034.00 0035.00 0036.00 0037.00 0038.00 0039.00 0040.00 0041.00 0042.00 0043.00 0044.00 0045.00 0046.00 0047.00 0048.00 0049.00 A* A DSPSIZ(24 80 *DS3) A CHGINPDFT(HI CS UL) A INDARA A PRINT A*-------------------------------------------------------------------A R TEWA101 A* A* -- FUNKTIONSTASTEN --------------------------A OVERLAY A CA11(11) A CA12(12) A CA13(13) A CA14(14) A MSGF031 78A O 22 2MSGID(KON0007 M1MSGF) A COLOR(WHT) A MSGF032 14A O 23 2MSGID(FUN0011 M1MSGF) A COLOR(BLU) A MSGF033 11A O +2MSGID(FUN0012 M1MSGF) A COLOR(BLU) A MSGF037 15A O 24 2MSGID(FUN0013 M1MSGF) A COLOR(BLU) A MSGF038 19A O +2MSGID(FUN0014 M1MSGF) A COLOR(BLU) A* A* -- LOGO -------------------------------------A MSGF034 10A O 1 2MSGID(LOG0001 M1MSGF) A COLOR(RED) A MSGF035 78A O 2 2MSGID(KON0007 M1MSGF) A COLOR(WHT) A* -- ÜBERSCHRIFT ------------------------------A MSGF036 50A O 1 25MSGID(KON0030 M1MSGF) A COLOR(WHT) A* -- AUSWAHLBEREICH ---------------------------A DSWA00 1A B 3 2 A DSTE00 60A O +1 A DSWA01 1A B 4 2 A DSTE01 60A O +1 A DSWA02 1A B 5 2 A DSTE02 60A O +1 A DSWA03 1A B 6 2 A DSTE03 60A O +1 A DSWA04 1A B 7 2 A DSTE04 60A O +1 A* A* -- MELDUNGSZEILE ----------------------------A DSMSGS 60A O 21 2 A COLOR(RED) A* XVII Abbildung 15: Greenscreen-Maske, RPG-Hauptprogramm MANNE1/QRPGLESRC/M1BEST 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 0010.00 0011.00 0012.00 0013.00 0014.00 0015.00 0016.00 0017.00 0018.00 0019.00 0020.00 0021.00 0022.00 0023.00 0024.00 0025.00 0026.00 0027.00 0028.00 0029.00 0030.00 0031.00 0032.00 0033.00 0034.00 0035.00 0036.00 0037.00 0038.00 0039.00 0040.00 0041.00 0042.00 0043.00 0044.00 0045.00 0046.00 0047.00 0048.00 0049.00 0050.00 0051.00 0052.00 0053.00 0054.00 0055.00 0056.00 0057.00 0058.00 0059.00 0060.00 0061.00 0062.00 0063.00 0064.00 0065.00 0066.00 0067.00 H/TITLE Erfassen Direktbestellung H************************************************************************** H* * H* (c) Copyright 2011 Manfred Schiefers - Stuttgart * H* * H************************************************************************** H* F************************************************************************** F*** DATEIBESCHREIBUNGEN *** F************************************************************************** FM1BESTFM CF E WORKSTN FM1LIWAFM CF E WORKSTN FM1TEWAFM CF E WORKSTN F* D************************************************************************** D*** DEKLARATIONEN *** D************************************************************************** DWKBENR S 8S 0 INZ(*ZEROS) DWKTEBZ S 30A INZ(*BLANKS) DWKLINR S 7S 0 INZ(*ZEROS) DWKLIBZ S 20A INZ(*BLANKS) DWKZABE S 3A INZ(*BLANKS) DWKZABZ S 32A INZ(*BLANKS) DWKLFBE S 3A INZ(*BLANKS) DWKLFBZ S 32A INZ(*BLANKS) DWKMABZ S 8A INZ(*BLANKS) DWKWAEH S 3A INZ(*BLANKS) DWKABTZ S 3A INZ(*BLANKS) DWKABTB S 32A INZ(*BLANKS) DWKSABE S 4A INZ(*BLANKS) DWKSABZ S 32A INZ(*BLANKS) DWKMSGS S 60A INZ(*BLANKS) DWKTENR S 13A INZ(*BLANKS) D C************************************************************************** C*** R E C H E N B E S T I M M U N G E N *** C************************************************************************** C *ENTRY PLIST C PARM PARAMETER 10 C* C* -------- BESTELLNUMMER VERGEBEN ----------------------C EXSR BESTVR C EVAL DSBEST = WKBENR C* C* -------- WARTESCHLEIFE -------------------------------C DOW 0 = 0 C* C IF DSTENR <> *BLANK C IF %SUBST(DSTENR:1:1) <> '?' C EXSR TELESE C EVAL DSTEBZ = WKTEBZ C EVAL DSMABZ = WKMABZ C EVAL DSMAB2 = WKMABZ C ELSE C EXSR TEWAHL C EVAL DSTENR = WKTENR C ENDIF C ELSE C EVAL DSTEBZ = *BLANK C EVAL DSMABZ = *BLANK C EVAL DSMAB2 = *BLANK C ENDIF C* C IF *IN03 = *ON C EXSR SRRETU C ENDIF C* XVIII 0068.00 0069.00 0070.00 0071.00 0072.00 0073.00 0074.00 0075.00 0076.00 0077.00 0078.00 0079.00 0080.00 0081.00 0082.00 0083.00 0084.00 0085.00 0086.00 0087.00 0088.00 0089.00 0090.00 0091.00 0092.00 0093.00 0094.00 0095.00 0096.00 0097.00 0098.00 0099.00 0100.00 0101.00 0102.00 0103.00 0104.00 0105.00 0106.00 0107.00 0108.00 0109.00 0110.00 0112.00 0113.00 0114.00 0115.00 0116.00 0117.00 0118.00 0119.00 0120.00 0121.00 0122.00 0124.00 0125.00 0126.00 C IF *IN05 = *ON C EXSR LIWAHL C EVAL DSLINR = WKLINR C IF DSLINR <> *ZERO C EXSR LILESE C EVAL DSLIBZ = WKLIBZ C EVAL DSWAEH = WKWAEH C ENDIF C ENDIF C* C IF *IN07 = *ON C EXSR SENDEN C EVAL DSMSGS = WKMSGS C ENDIF C* C IF *IN08 = *ON C EXSR ZAWAHL C EVAL DSZABE = WKZABE C EVAL DSZABZ = WKZABZ C EVAL DSLFBE = WKLFBE C EVAL DSLFBZ = WKLFBZ C ENDIF C* C IF *IN09 = *ON C EXSR SABEWA C EVAL DSABTZ = WKABTZ C EVAL DSABTB = WKABTB C EVAL DSSABE = WKSABE C EVAL DSSABZ = WKSABZ C ENDIF C* C EXFMT BEST101 C* C ENDDO C EXSR SRRETU C* C************************************************************************** C*** SR-RETURN Rückkehr zum Aufrufprogramm *** C************************************************************************** C SRRETU BEGSR C EVAL *INLR = *ON C RETURN C ENDSR D************************************************************************** D*** COPY-SOURCEN *** D************************************************************************** D/COPY QCPYSRC,M1BENR D/COPY QCPYSRC,M1TEWA D/COPY QCPYSRC,M1TEIL D/COPY QCPYSRC,M1LIWA D/COPY QCPYSRC,M1LIEF D/COPY QCPYSRC,M1ZABE D/COPY QCPYSRC,M1ABTW D/COPY QCPYSRC,M1SEND C************************************************************************** C*** ENDE DES PROGRAMMS C************************************************************************** Abbildung 16: Greenscreen-Maske, RPG-Startprogramm MANNE1/QRPGLESRC/M1START 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 DVariable DWKRTCD C C C C C* C C S S EVAL 10A 6A INZ(*BLANKS) Variable = 'Parameter' CALL PARM 'M1BEST' EVAL EVAL WKRTCD = 'OK' *INLR = *ON Variable XIX Abbildung 17: Greenscreen-Maske, Copysource Abteilung / Sachbearbeiter MANNE1/QCPYSRC/M1ABTW 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 C************************************************************************** C*** SR-SABEWA Abteilung / Sachbearbeiter wählen *** C************************************************************************** C SABEWA BEGSR C EVAL WKABTZ = 'A52' C EVAL WKABTB = 'Verfahrensentwicklung' C EVAL WKSABE = '0342' C EVAL WKSABZ = 'Frau Hennig-Burgmeister' C ENDSR Abbildung 18: Greenscreen-Maske, Copysource Bestellnummernvergabe MANNE1/QCPYSRC/M1BENR 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 C************************************************************************** C*** SR-BESTVR Bestellnummer vergeben *** C************************************************************************** C BESTVR BEGSR C EVAL WKBENR = 7856 C ENDSR Abbildung 19: Greenscreen-Maske, Copysource Lieferantenstammdaten MANNE1/QCPYSRC/M1LIEF 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 C************************************************************************** C*** SR-LILESE Lieferantenstammdaten lesen *** C************************************************************************** C LILESE BEGSR C EVAL WKLIBZ = 'KAISER+KRAFT' C EVAL WKWAEH = 'EUR' C ENDSR Abbildung 20: Greenscreen-Maske, Copysource Lieferantenauswahl MANNE1/QCPYSRC/M1LIWA 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 0010.00 0011.00 0012.00 0013.00 0014.00 0015.00 0016.00 C************************************************************************** C*** SR-LIWAHL Lieferant auswählen *** C************************************************************************** C LIWAHL BEGSR C* -------- BEISPIELDATEN ! -----------------------------C EVAL DSNA00 = '0000047 - Bierbrauer & Nagel' C EVAL DSNA01 = '0000078 - bürma Werner Machauer KG' C EVAL DSNA02 = '0000089 - Corporate Express global' C EVAL DSNA03 = '0000112 - Deko-Maier e.K.' C EVAL DSNA04 = '0000123 - Hafners Papierlädle' C EVAL DSNA05 = '0000156 - KAISER+KRAFT' C EVAL DSNA06 = '0000268 - PBS Network GmbH' C EVAL DSNA07 = '0000287 - ppm-stuttgart' C EVAL DSNA08 = '0000300 - Staples Advantage' C EVAL DSNA09 = '0000305 - büro-zubehör-handel' C EVAL DSNA10 = '0000308 - Scharr Büro GmbH' XX 0017.00 0018.00 0019.00 0020.00 0021.00 0022.00 0023.00 0024.00 0025.00 0026.00 0027.00 0028.00 0029.00 0030.00 0031.00 0032.00 0033.00 0034.00 0035.00 0036.00 0037.00 C C C C C C C C C* C C C C C C C C C C C C Abbildung 21: EVAL DSNA11 = '0000340 - Tobias Geibel Bürobedarf' EVAL DSNA12 = '0000401 - Deko Maier' EVAL DSNA13 = '0000402 - Trend Products Stuttgart' EVAL DSNA14 = '0000928 - OFFICE SERVICE' EVAL DSNA15 = '0001230 - Conipa Bürosysteme GmbH' EVAL DSNA16 = '0001308 - Der Tinten Pott' EVAL DSNA17 = '0001425 - Tintensparmarkt' EVAL DSNA18 = '0001433 - AW Printmedienzubehör' -------- WARTESCHLEIFE -------------------------------DOW 0 = 0 IF *IN12 = *ON LEAVE ENDIF IF *IN11 = *ON EVAL WKLINR = 156 EVAL WKLIBZ = 'KAISER+KRAFT' LEAVE ENDIF EXFMT LIWA101 ENDDO ENDSR Greenscreen-Maske, Copysource Bestellung versenden MANNE1/QCPYSRC/M1SEND 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 C************************************************************************** C*** SR-SENDEN Bestellung versenden *** C************************************************************************** C SENDEN BEGSR C EVAL WKMSGS = '- Bestellung wurde versendet -' C ENDSR Abbildung 22: Greenscreen-Maske, Copysource Teilestammdaten MANNE1/QCPYSRC/M1TEIL 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 C************************************************************************** C*** SR-TELESE Teilestammdaten lesen *** C************************************************************************** C TELESE BEGSR C EVAL WKTEBZ = 'Kopierpapier DIN A4, 80 g/mm²' C EVAL WKMABZ = 'Blatt' C ENDSR Abbildung 23: Greenscreen-Maske, Copysource Teilestammdaten-Matchcode MANNE1/QCPYSRC/M1TEWA 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 C************************************************************************** C*** SR-TEWAHL Teilestamm Matchcode-Auswahl *** C************************************************************************** C TEWAHL BEGSR C* -------- BEISPIELDATEN ! -----------------------------C EVAL DSTE00 = 'S0000-2356 - ' C +'Kopfschellen Größe 9 ' C EVAL DSTE01 = 'RR12-977 - ' C +'Koppelschiene AKG 612 ' XXI 0010.00 0011.00 0012.00 0013.00 0014.00 0015.00 0016.00 0017.00 0018.00 0019.00 0020.00 0021.00 0022.00 0023.00 0024.00 0025.00 0026.00 0027.00 C C C C C C C* C C C C C C C C C C C Abbildung 24: EVAL DSTE02 = 'K62-022 - ' +'Kopierpapier DIN A4, 80 g/mm²' EVAL DSTE03 = 'K62-023 - ' +'Kopierpapier DIN A3, 80 g/mm²' EVAL DSTE04 = 'ZZ96.940.01 - ' +'Kopierstift BLAU ' -------- WARTESCHLEIFE -------------------------------DOW 0 = 0 IF *IN12 = *ON LEAVE ENDIF IF *IN11 = *ON EVAL WKTENR = 'K62-022' LEAVE ENDIF EXFMT TEWA101 ENDDO ENDSR Greenscreen-Maske, Copysource Zahlungs-/Lieferbedingungen MANNE1/QCPYSRC/M1ZABE 0001.00 0002.00 0003.00 0004.00 0005.00 0006.00 0007.00 0008.00 0009.00 C************************************************************************** C*** SR-ZAWAHL Zahlungs-/Lieferbedingungen wählen *** C************************************************************************** C ZAWAHL BEGSR C EVAL WKZABE = 'Z31' C EVAL WKZABZ = '10 Tage 3 %, 30 Tage netto' C EVAL WKLFBE = 'L01' C EVAL WKLFBZ = 'frei Haus, einschl. Verpackung' C ENDSR Abbildung 25: GUI-Maske, Java-Packages XXII Abbildung 26: GUI-Maske, Komplettdarstellung XXIII Abbildung 27: Logo alt Abbildung 28: Logo neu XXIV Abbildung 29: GUI-Maske, Klasse XML_Kommunikation package Framework; //(c) Copyright 2011 Manfred Schiefers - Stuttgart //************************************************************************** //*** Kommunikation mit XML-Schnittstelle *** //************************************************************************** import Einkauf.BestellEingabeParameter; public class XML_Kommunikation { BestellEingabeParameter parameter; HinweisFenster meldung; // >>> B e s t e l l n u m m e r <<< public String naechsteBestellNr(){ int nBenr = 0; String sBenr =""; //*** todo: nächste Bestellnummer ermitteln // für Prototyp ... nBenr = 7856; //*** todo: nächste Bestellnummer ermitteln sBenr = Integer.toString(nBenr); return sBenr; }//naechsteBestellNr // >>> T e i l e n u m m e r <<< public String[] teilestammDateizugriff(){ String[] teileListe = new String[100]; //*** todo: Zugriff auf Datei TEILESTAMM // für Prototyp ... for ( int pos = 1; pos <= 99; pos++ ){ teileListe[pos] = ""; }//for teileListe[1] = "S0000-2356 - Kopfschellen Größe 9 teileListe[2] = "RR12-977 - Koppelschiene AKG 612 teileListe[3] = "K62-022 - Kopierpapier DIN A4, 80 g/mm² teileListe[4] = "K62-023 - Kopierpapier DIN A3, 80 g/mm² teileListe[5] = "ZZ96.940.01 - Kopierstift BLAU // Teilenummer (13-stellig) // Teilebezeichnung (30-stellig) // Maßeinheit (10-stellig) //*** todo: Zugriff auf Datei TEILESTAMM return teileListe; }//teilestammDateizugriff() kg"; Meter"; Blatt"; Blatt"; Stück"; public boolean teileNummerCheck(String pruefTenr){ boolean existiert = false; String[] datensatz = teilestammDateizugriff(); for ( int pos = 1; pos <= 99; pos++ ){ if (!datensatz[pos].equals("")){ if (pruefTenr.equals((datensatz[pos].substring(0,13)).trim())){ existiert = true; break; }//if }//if }//for return existiert; }//teileNummerCheck(String pruefTenr) public String[] teileMatchcodeAuswahlListe(String mCodeEingabe){ String teileEingabe = mCodeEingabe; //*** todo: Teilstammauswahl bereitstellen // für Prototyp ... String[] teileAuswahlListe = new String[100]; for ( int pos = 1; pos <= 99; pos++ ){ teileAuswahlListe[pos] = ""; }//for if (teileEingabe.length()>=2){ String mCodeTest = teileEingabe.substring(0,2); if (mCodeTest.equals("ko") || mCodeTest.equals("KO")){ XXV teileAuswahlListe = teilestammDateizugriff(); for ( int pos = 1; pos <= 99; pos++ ){ if (teileAuswahlListe[pos].equals("")) break; teileAuswahlListe[pos] = teileAuswahlListe[pos].substring(0,45); }//for }//if "KO" }//if Eingabelänge >= 2 //*** todo: Teilstammauswahl bereitstellen return teileAuswahlListe; }//teileMatchcodeAuswahlListe() public String holenTeileBezeichnung(String zuTenr){ String tebez = ""; //*** todo: Teilebezeichnung holen // für Prototyp ... String[] teileListe = new String[100]; String testtenr, testtebe; teileListe = teilestammDateizugriff(); for ( int zeile = 1; zeile <= 99; zeile++ ) { if (teileListe[zeile].equals("")) break; testtenr = (teileListe[zeile].substring(0,13)).trim(); testtebe = (teileListe[zeile].substring(16,45)).trim(); if (testtenr.equals(zuTenr)){ tebez = testtebe; break; }//if gefunden }//for //*** todo: Teilebezeichnung holen return tebez; }//holenTeileBezeichnung() public String holenTeileMasseinheit(String zuTenr){ String temass = ""; //*** todo: Maßeinheit aus Teilestamm holen // für Prototyp ... String[] teileListe = new String[100]; String testtenr, testmass; teileListe = teilestammDateizugriff(); for ( int zeile = 1; zeile <= 99; zeile++ ) { if (teileListe[zeile].equals("")) break; testtenr = (teileListe[zeile].substring(0,13)).trim(); testmass = teileListe[zeile].substring(50,(teileListe[zeile].length()))); if (testtenr.equals(zuTenr)){ temass = testmass.trim(); break; }//if gefunden }//for //*** todo: Maßeinheit aus Teilestamm holen return temass; }//holenTeileMasseinheit() // >>> L i e f e r a n t <<< public String[] lieferantenDateiZugriff(){ String[] liefListe = new String[20]; //*** todo: Zugriff auf Datei LIEFERANTENSTAMM // für Prototyp ... liefListe[1] = "0000047 - Bierbrauer & Nagel liefListe[2] = "0000078 - bürma Werner Machauer KG liefListe[3] = "0000089 - Corporate Express global liefListe[4] = "0000112 - Deko-Maier e.K. liefListe[5] = "0000123 - Hafners Papierlädle liefListe[6] = "0000156 - KAISER+KRAFT liefListe[7] = "0000268 - PBS Network GmbH liefListe[8] = "0000287 - ppm-stuttgart liefListe[9] = "0000300 - Staples Advantage liefListe[10] = "0000305 - büro-zubehör-handel liefListe[11] = "0000308 - Scharr Büro GmbH liefListe[12] = "0000340 - Tobias Geibel Bürobedarf liefListe[13] = "0000401 - Deko Maier liefListe[14] = "0000402 - Trend Products Stuttgart XXVI EUR"; CHF"; USD"; EUR"; EUR"; EUR"; EUR"; EUR"; EUR"; EUR"; EUR"; EUR"; EUR"; EUR"; liefListe[15] = "0000928 - OFFICE SERVICE liefListe[16] = "0001230 - Conipa Bürosysteme GmbH liefListe[17] = "0001308 - Der Tinten Pott liefListe[18] = "0001425 - Tintensparmarkt liefListe[19] = "0001433 - AW Printmedienzubehör // Lieferantennummer (7-stellig) // Lieferantenname (30-stellig) // Lieferanten-Währungscode (3-stellig) //*** todo: Zugrff auf Datei LIEFERANTENSTAMM return liefListe; }//lieferantenDateiZugriff CZK"; EUR"; EUR"; EUR"; EUR"; public String[] lieferantenAuswahlListe(){ String[] datensatz = new String[20]; String[] auswahl = new String[20]; datensatz = lieferantenDateiZugriff(); for ( int i=1; i<=19; i++ ) { auswahl[i] = datensatz[i].substring(0,35); }//for return auswahl; }//lieferantenAuswahlListe() public String lieferantenWaehrung(int liefIndex){ String[] datensatz = new String[20]; String waehrung = ""; datensatz = lieferantenDateiZugriff(); waehrung = datensatz[liefIndex].substring(41,44); return waehrung; }//lieferantenWaehrung() // >>> Z a h l u n g s b e d i n g u n g e n <<< public String[] zahlungsDateiZugriff(){ String[] zahlungsListe = new String[5]; //*** todo: Zugriff auf Datei ZAHLUNGSBEDINGUNGEN // für Prototyp ... zahlungsListe[1] = "Z31 - 10 Tage 3%, 30 Tage netto"; zahlungsListe[2] = "Z07 - 7 Tage - 2 %, 20 Tage netto"; zahlungsListe[3] = "Z02 - sofort - 2 %, 14 Tage netto"; zahlungsListe[4] = "Z15 - 2 % zum 15. des 2. Folgemonats"; // Zahlungsbedingung (40-stellig) //*** todo: Zugriff auf Datei ZAHLUNGSBEDINGUNGEN return zahlungsListe; }//zahlungsDateiZugriff public String[] zahlungsAuswahlListe(){ String[] datensatz = new String[5]; String[] auswahl = new String[5]; datensatz = zahlungsDateiZugriff(); for ( int i=1; i<=4; i++ ) { auswahl[i] = datensatz[i]; }//for return auswahl; }//zahlungsAuswahlListe() // >>> L i e f e r b e d i n g u n g e n <<< public String[] lieferBedDateiZugriff(){ String[] liefListe = new String[5]; //*** todo: Zugriff auf Datei LIEFERBEDINGUNGEN // für Prototyp ... liefListe[1] = "L01 - frei Haus, einschl. Verpackung"; liefListe[2] = "L25 - frei Haus, ohne Verpackung"; liefListe[3] = "L36 - ab Werk, einschl. Verpackung"; liefListe[4] = "L55 - unfrei"; // Lieferbedingung (40-stellig) //*** todo: Zugriff auf Datei LIEFERBEDINGUNGEN return liefListe; }//lieferBedDateiZugriff public String[] lieferBedAuswahlListe(){ String[] datensatz = new String[5]; String[] auswahl = new String[5]; datensatz = lieferBedDateiZugriff(); for ( int i=1; i<=4; i++ ) { XXVII auswahl[i] = datensatz[i]; }//for return auswahl; }//lieferBedAuswahlListe() // >>> A b t e i l u n g <<< public String[] abteilungDateiZugriff(){ String[] abtListe = new String[7]; //*** todo: Zugriff auf Datei ABTEILUNGEN // für Prototyp ... abtListe[1] = "A25 - Verfahrensentwicklung"; abtListe[2] = "A12 - Forschung & Entwicklung"; abtListe[3] = "A13 - Buchhaltung"; abtListe[4] = "A24 - Konstruktion"; abtListe[5] = "A60 - Vertrieb"; abtListe[6] = "A67 - Montage"; // Abteilung (40-stellig) //*** todo: Zugriff auf Datei ABTEILUNGEN return abtListe; }//abteilungDateiZugriff public String[] abteilungAuswahlListe(){ String[] datensatz = new String[7]; String[] auswahl = new String[7]; datensatz = abteilungDateiZugriff(); for ( int i=1; i<=6; i++ ) { auswahl[i] = datensatz[i]; }//for return auswahl; }//abteilungAuswahlListe() // >>> S a c h b e a r b e i t e r <<< public String[] sachbearDateiZugriff(){ String[] sachbearListe = new String[7]; //*** todo: Zugriff auf Datei SACHBEARBEITER // für Prototyp ... sachbearListe[1] = "O342 - Frau Hennig-Burgmeister"; sachbearListe[2] = "O428 - Herr Stuhler"; sachbearListe[3] = "O567 - Herr Schiefers"; sachbearListe[4] = "O991 - Frau Striebel"; sachbearListe[5] = "O212 - Herr Rauser"; sachbearListe[6] = "O127 - Frau Lehmann"; // Sachbearbeiter (40-stellig) //*** todo: Zugriff auf Datei SACHBEARBEITER return sachbearListe; }//sachbearDateiZugriff public String[] sachbearAuswahlListe(){ String[] datensatz = new String[7]; String[] auswahl = new String[7]; datensatz = sachbearDateiZugriff(); for ( int i=1; i<=6; i++ ) { auswahl[i] = datensatz[i]; }//for return auswahl; }//sachbearAuswahlListe() // >>> T e x t k o n s t a n t e n <<< public String textKonstanteZuord(String konstNr){ String konstInhalt = "??"+konstNr; //*** todo: Textkonstanten holen // für Prototyp ... if (konstNr.equals("FENR001")) konstInhalt = "erst Position anklicken, dann [ Übernehmen ]"; if (konstNr.equals("FENR002")) konstInhalt = "Geben Sie eine gültige Teilenummer ein."; if (konstNr.equals("FUN0003")) konstInhalt = "Verlassen"; if (konstNr.equals("FUN0005")) konstInhalt = "Übernehmen"; if (konstNr.equals("FUN0015")) konstInhalt = "Aktualisieren"; if (konstNr.equals("HIN0001")) konstInhalt = "HINWEIS"; if (konstNr.equals("HIN0002")) konstInhalt = "Bestellung wurde versendet."; if (konstNr.equals("KON0001")) konstInhalt = ">> Direktbestellung erfassen <<"; if (konstNr.equals("KON0002")) konstInhalt = " Teilenummer: "; XXVIII if (konstNr.equals("KON0006")) konstInhalt = "Lieferant:"; if (konstNr.equals("KON0008")) konstInhalt = " Bestell-Nr.: "; if (konstNr.equals("KON0009")) konstInhalt = " Teile-Bezeichnung: "; if (konstNr.equals("KON0017")) konstInhalt = "Bestellmenge: "; if (konstNr.equals("KON0019")) konstInhalt = "Bestelltermin: "; if (konstNr.equals("KON0020")) konstInhalt = "Zahlungsbedingungen: "; if (konstNr.equals("KON0022")) konstInhalt = "Lieferbedingungen: "; if (konstNr.equals("KON0024")) konstInhalt = "Preis: "; if (konstNr.equals("KON0025")) konstInhalt = " je "; if (konstNr.equals("KON0026")) konstInhalt = "anfordernde Abteilung: "; if (konstNr.equals("KON0027")) konstInhalt = "Sachbearbeiter: "; if (konstNr.equals("KON0028")) konstInhalt = "Zusatztext"; if (konstNr.equals("KON0030")) konstInhalt = ">> Teilestamm Matchcode-Auswahl <<"; if (konstNr.equals("KON0031")) konstInhalt = "Matchcode"; //*** todo: Textkonstanten holen return konstInhalt; }// textKonstanteZuord() // >>> B e s t e l l u n g v e r s e n d e n <<< public void bestellungVersenden(BestellEingabeParameter parameter){ //*** todo: Übergabe Bestelldaten / für Prototyp Ausgabe in Konsole ... System.out.println("Bestellung Übergabedaten ..."); System.out.println(""); System.out.println("<BestellNr.(BENR)> -->" + parameter.getDSBENR() + "<--"); System.out.println("<LieferantentNr.(LINR)> -->" + parameter.getDSLINR() + "<--"); System.out.println("<TeileNr.(TENR)> -->" + parameter.getDSTENR() + "<--"); System.out.println("<Bestellmenge(MENG)> -->" + parameter.getDSMENG() + "<--"); System.out.println("<Bestelltermin(BDAT> -->" + parameter.getDSDJAH() + parameter.getDSDMON() + parameter.getDSDTAG() + "<--"); System.out.println("<Preis(PREI)> -->" + parameter.getDSPREI() + "<--"); System.out.println("<je Menge(JEME)> -->" + parameter.getDSJEME() + "<--"); System.out.println("<Zahlungsbedingung(ZABE)> -->" + parameter.getDSZABE() + "<--"); System.out.println("<Lieferbedingung(LFBE)> -->" + parameter.getDSLFBE() + "<--"); System.out.println("<Abteilung(ABTB)> -->" + parameter.getDSABTB() + "<--"); System.out.println("<Sachbearbeiter(SABE)> -->" + parameter.getDSSABE() + "<--"); System.out.println("<Zusatztext1(ZUS1)> -->" + parameter.getDSZUS1() + "<--"); System.out.println("<Zusatztext2(ZUS2)> -->" + parameter.getDSZUS2() + "<--"); System.out.println("<Zusatztext3(ZUS3)> -->" + parameter.getDSZUS3() + "<--"); System.out.println("<Zusatztext4(ZUS4)> -->" + parameter.getDSZUS4() + "<--"); meldung = new HinweisFenster(textKonstanteZuord("HIN0001"), textKonstanteZuord("HIN0002"),100,320,300,70); //*** todo: Übergabe Bestelldaten }//bestellungVersenden() public void hinweisFensterSchliessen(){ meldung.setVisible(false); }//hinweisFensterSchliessen() }//class XML_Kommunikation XXIX Abbildung 30: GUI-Maske, Klasse HinweisFenster package Framework; //(c) Copyright 2011 Manfred Schiefers - Stuttgart //*************************************************************************** //*** Hinweisfenster *** //*************************************************************************** import java.awt.Frame; import java.awt.Image; import java.awt.Panel; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JLabel; public class HinweisFenster extends Frame{ private static final long serialVersionUID = 1L; // Maskenelemente Panel centerPanel; JLabel meldung; // -- MASKE -public HinweisFenster( String überschrift, String inhalt, int xpos, int ypos, int breit, int hoch ){ // Überschrift super(überschrift); // Panels centerPanel = new Panel(); add("Center",centerPanel); // WindowsListener hinzu MyWindowListener mwl = new MyWindowListener(); addWindowListener(mwl); // Meldung / Inhalt meldung = new JLabel(inhalt); centerPanel.add(meldung); // Framegröße setSize(breit, hoch); // Framegröße änderbar setResizable(false); // Frameposition setLocation(new Point(xpos, ypos)); // Titel-Icon Image icon; Toolkit toolkit = Toolkit.getDefaultToolkit(); icon = toolkit.getImage("logo.jpg"); setIconImage(icon); // Frame sichtbar setVisible(true); }// Maske // -- FENSTER-LISTENER -class MyWindowListener extends WindowAdapter{ // Fensterkreuz zu public void windowClosing(WindowEvent we){ setVisible(false); }//windowClosing }//class MyWindowListener }//class HinweisFenster XXX Abbildung 31: GUI-Maske, Klasse Fehlermeldung package Framework; //(c) Copyright 2011 Manfred Schiefers - Stuttgart //*************************************************************************** //*** Fehlermeldung ausgeben *** //*************************************************************************** import java.awt.Frame; import java.awt.Image; import java.awt.Panel; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JLabel; public class Fehlermeldung extends Frame implements ActionListener{ private static final long serialVersionUID = 1L; // Maskenelemente Panel centerPanel, buttonPanel; JButton okButton; JLabel meldung; // -- MASKE -public Fehlermeldung(String inhalt, int xpos, int ypos, int breit, int hoch){ // Überschrift super("ERROR"); // Panels centerPanel = new Panel(); buttonPanel = new Panel(); add("Center",centerPanel); add("South",buttonPanel); // WindowsListener hinzu MyWindowListener mwl = new MyWindowListener(); addWindowListener(mwl); // Buttons okButton = new JButton(" ok "); // Meldung / Inhalt meldung = new JLabel(inhalt); centerPanel.add(meldung); // OK-Knopf hinzu buttonPanel.add(okButton); okButton.setEnabled(true); // bearbeitbar ? okButton.addActionListener(this); // Framegröße setSize(breit, hoch); // Framegröße änderbar setResizable(false); // Frameposition setLocation(new Point(xpos, ypos)); // Titel-Icon Image icon; Toolkit toolkit = Toolkit.getDefaultToolkit(); icon = toolkit.getImage("logo.jpg"); setIconImage(icon); // Frame sichtbar setVisible(true); }// Maske // -- KNOPF-LISTENER -public void actionPerformed(ActionEvent e){ Object o = e.getSource(); if ( o == okButton ){ setVisible(false); }// if beenden }//actionPerformed() // -- FENSTER-LISTENER -class MyWindowListener extends WindowAdapter{ // Fensterkreuz zu public void windowClosing(WindowEvent we){ setVisible(false); }//windowClosing }//class MyWindowListener }//class Fehlermeldung XXXI Abbildung 32: GUI-Maske, Klasse BestellStart package Einkauf; //(c) Copyright 2011 Manfred Schiefers - Stuttgart //*************************************************************************** //*** Aufruf Bestell-Eingabe-Maske *** //*************************************************************************** import java.awt.Image; import java.awt.Toolkit; import java.io.IOException; import javax.swing.JFrame; import Framework.XML_Kommunikation; public class BestellStart extends JFrame{ private static final long serialVersionUID = 1L; public static BestellEingabeMaske maske1; public static BestellEingabeParameter parameter; public static XML_Kommunikation xml = new XML_Kommunikation(); public static String kon0001 = xml.textKonstanteZuord("KON0001"); //------ MAIN - Methode ------public static void main(String[] args ) throws IOException{ parameter = new BestellEingabeParameter( "", "", "", -1, "", "", "", "", "", "", "", "", -1, "", -1, "", -1, "", -1, "", "", "", "" ); eroeffnenBestellmaske(parameter); }//main() //------ Bestellmaske eröffnen -----public static void eroeffnenBestellmaske(BestellEingabeParameter parameter){ parameter.setTITEL(kon0001); try{ maske1 = new BestellEingabeMaske (parameter); Image icon; Toolkit toolkit = Toolkit.getDefaultToolkit(); icon = toolkit.getImage("logo.jpg"); maske1.setIconImage(icon); maske1.setVisible(true); }//try catch (IOException e){ }//catch }//eroeffnenBestellmaske() //------ Bestellmaske schließen -----public static void schliessenBestellmaske(){ maske1.setVisible(false); }//schliessenBestellmaske() }//class BestellStart XXXII Abbildung 33: GUI-Maske, Klasse BestellEingabeParameter package Einkauf; //(c) Copyright 2011 Manfred Schiefers - Stuttgart //************************************************************************** //*** Übergabeparameter Bestellmaskeneingaben *** //************************************************************************** public class BestellEingabeParameter { private String titel, dsbenr, dslinr, dstenr, dsmeng, dsdtag, dsdmon, dsdjah, dsprei, dsjeme, dszabe, dslfbe, dsabtb, dssabe, dszus1, dszus2, dszus3, dszus4; private int linrIndex, zabeIndex, lfbeIndex, abtbIndex, sabeIndex; public BestellEingabeParameter ( String titel, String dsbenr, String dslinr, int linrIndex, String dstenr, String dsmeng, String dsdtag, String dsdmon, String dsdjah, String dsprei, String dsjeme, String dszabe, int zabeIndex, String dslfbe, int lfbeIndex, String dsabtb, int abtbIndex, String dssabe, int sabeIndex, String dszus1, String dszus2, String dszus3, String dszus4 ){ this.titel = titel; this.dsbenr = dsbenr; this.dslinr = dslinr; this.linrIndex = linrIndex; this.dstenr = dstenr; this.dsmeng = dsmeng; this.dsdtag = dsdtag; this.dsdmon = dsdmon; this.dsdjah = dsdjah; this.dsprei = dsprei; this.dsjeme = dsjeme; this.dszabe = dszabe; this.zabeIndex = zabeIndex; this.dslfbe = dslfbe; this.lfbeIndex = lfbeIndex; this.dsabtb = dsabtb; this.abtbIndex = abtbIndex; this.lfbeIndex = lfbeIndex; this.dssabe = dssabe; this.sabeIndex = sabeIndex; this.dszus1 = dszus1; this.dszus2 = dszus2; this.dszus3 = dszus3; this.dszus4 = dszus4; }//Konstruktor BestellEingabeParameter public String getTITEL(){ return titel; }//getTITEL() public void setTITEL(String titel){ this.titel = titel; }//setTITEL() public String getDSBENR(){ return dsbenr; }//getDSBENR() public void setDSBENR(String dsbenr){ this.dsbenr = dsbenr; }//setDSBENR() public String getDSLINR(){ return dslinr; }//getDSLINR() public void setDSLINR(String dslinr){ this.dslinr = dslinr; }//setDSLINR() XXXIII public int getLINRINDEX(){ return linrIndex; }//getLINRINDEX() public void setLINRINDEX(int linrIndex){ this.linrIndex = linrIndex; }//setLINRINDEX() public String getDSTENR(){ return dstenr; }//getDSTENR() public void setDSTENR(String dstenr){ this.dstenr = dstenr; }//setDSTENR() public String getDSMENG(){ return dsmeng; }//getDSMENG() public void setDSMENG(String dsmeng){ this.dsmeng = dsmeng; }//setDSMENG() public String getDSDTAG(){ return dsdtag; }//getDSDTAG() public void setDSDTAG(String dsdtag){ this.dsdtag = dsdtag; }//setDSDTAG() public String getDSDMON(){ return dsdmon; }//getDSDMON() public void setDSDMON(String dsdmon){ this.dsdmon = dsdmon; }//setDSDMON() public String getDSDJAH(){ return dsdjah; }//getDSDJAH() public void setDSDJAH(String dsdjah){ this.dsdjah = dsdjah; }//setDSDJAH() public String getDSPREI(){ return dsprei; }//getDSPREI() public void setDSPREI(String dsprei){ this.dsprei = dsprei; }//setDSPREI() public String getDSJEME(){ return dsjeme; }//getDSJEME() public void setDSJEME(String dsjeme){ this.dsjeme = dsjeme; }//setDSJEME() public String getDSZABE(){ return dszabe; }//getDSZABE() public void setDSZABE(String dszabe){ this.dszabe = dszabe; }//setDSZABE() public int getZABEINDEX(){ return zabeIndex; }//getZABEINDEX() public void setZABEINDEX(int zabeIndex){ this.zabeIndex = zabeIndex; }//setZABEINDEX() XXXIV public String getDSLFBE(){ return dslfbe; }//getDSLFBE() public void setDSLFBE(String dslfbe){ this.dslfbe = dslfbe; }//setDSLFBE() public int getLFBEINDEX(){ return lfbeIndex; }//getLFBEINDEX() public void setLFBEINDEX(int lfbeIndex){ this.lfbeIndex = lfbeIndex; }//setLFBEINDEX() public String getDSABTB(){ return dsabtb; }//getDSABTB() public void setDSABTB(String dsabtb){ this.dsabtb = dsabtb; }//setDSABTB() public int getABTBINDEX(){ return abtbIndex; }//getABTBINDEX() public void setABTBINDEX(int abtbIndex){ this.abtbIndex = abtbIndex; }//setABTBINDEX() public String getDSSABE(){ return dssabe; }//getDSSABE() public void setDSSABE(String dssabe){ this.dssabe = dssabe; }//setDSSABE() public int getSABEINDEX(){ return sabeIndex; }//getSABEINDEX() public void setSABEINDEX(int sabeIndex){ this.sabeIndex = sabeIndex; }//setSABEINDEX() public String getDSZUS1(){ return dszus1; }//getDSZUS1() public void setDSZUS1(String dszus1){ this.dszus1 = dszus1; }//setDSZUS1() public String getDSZUS2(){ return dszus2; }//getDSZUS2() public void setDSZUS2(String dszus2){ this.dszus2 = dszus2; }//setDSZUS2() public String getDSZUS3(){ return dszus3; }//getDSZUS3() public void setDSZUS3(String dszus3){ this.dszus3 = dszus3; }//setDSZUS3() public String getDSZUS4(){ return dszus4; }//getDSZUS4() public void setDSZUS4(String dszus4){ this.dszus4 = dszus4; }//setDSZUS4() }//class BestellEingabeParameter XXXV Abbildung 34: GUI-Maske, Klasse TeileMatchcodeMaske package Teilestamm; //(c) Copyright 2011 Manfred Schiefers - Stuttgart //************************************************************************** //*** Teilenummern-Auswahl über Matchcode *** //************************************************************************** import java.awt.Color; import java.awt.Font; import java.awt.Frame; import java.awt.Image; import java.awt.List; import java.awt.Panel; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import import import import javax.swing.JButton; javax.swing.JLabel; javax.swing.JScrollPane; javax.swing.JTextField; import import import import import Einkauf.BestellEingabeParameter; Einkauf.BestellStart; Framework.Fehlermeldung; Framework.HinweisFenster; Framework.XML_Kommunikation; public class TeileMatchcodeMaske extends Frame implements ActionListener, ItemListener { private static final long serialVersionUID = 1L; // >>> Verbindung zur Server-Schnittstelle <<< XML_Kommunikation xml = new XML_Kommunikation(); // >>> M a s k e n e l e m e n t e <<< Panel topPanel, centerPanel, buttonPanel; JButton putButton, exitButton; JLabel mCodeLabel; JTextField mCode; List teile; // >>> String String String String T e x t fenr001 fun0003 fun0005 kon0031 k = = = = o n s t a n t e n <<< xml.textKonstanteZuord("FENR001"); xml.textKonstanteZuord("FUN0003"); xml.textKonstanteZuord("FUN0005"); xml.textKonstanteZuord("KON0031")+": "; // >>> V a r i a b l e n <<< BestellEingabeParameter parameter; String mCodeEingabe = ""; // Meldungen public Fehlermeldung fehler; public String fehlerText; public HinweisFenster hinweis; public String hinweisText; //------------------------- MASKE ---------------------------public TeileMatchcodeMaske(BestellEingabeParameter parameter) throws IOException { super(parameter.getTITEL()); this.parameter = parameter; // WindowsListener hinzu MyWindowListener mwl = new MyWindowListener(); addWindowListener(mwl); XXXVI // KeyListener MyKeyListener evt1 = new MyKeyListener(); // >>> P a n e l s <<< topPanel = new Panel(); topPanel.setBackground(Color.lightGray); centerPanel = new Panel(); centerPanel.setBackground(Color.WHITE); buttonPanel = new Panel(); buttonPanel.setBackground(Color.lightGray); add("North", topPanel); add("Center", centerPanel); add("South", buttonPanel); // >>> L a b e l s und T e x t f e l d e r <<< // -- Matchcodeeingabe mCodeLabel = new JLabel(kon0031); topPanel.add(mCodeLabel); mCode = new JTextField("", 14); mCode.setEnabled(true); mCode.setText(""); mCode.addKeyListener(evt1); mCode.setFont(new Font("Courier", Font.PLAIN, 14)); topPanel.add(mCode); // >>> L i s t e <<< teile = new List(10); // 10 Zeilen teile.setFont(new Font ("Courier",Font.PLAIN, 14)); teile.setBackground(Color.WHITE); teile.add(" JScrollPane scrollPane = new JScrollPane(teile); centerPanel.add(scrollPane); ",1); // >>> Main - B u t t o n s <<< exitButton = new JButton(fun0003); putButton = new JButton(fun0005); // Exitknopf hinzu buttonPanel.add(exitButton); exitButton.setEnabled(true); exitButton.addActionListener(this); // Übernahmeknopf hinzu buttonPanel.add(putButton); putButton.setEnabled(false); putButton.addActionListener(this); // >>> F r a m e g r ö ß e <<< setSize(500, 280); // >>> F r a m e p o s i t i o n <<< setLocation(new Point(270, 190)); // Framegröße änderbar setResizable(false); // Titel-Icon Image icon; Toolkit toolkit = Toolkit.getDefaultToolkit(); icon = toolkit.getImage("logo.jpg"); setIconImage(icon); // Frame sichtbar setVisible(true); }//Maske // >>> K N O P F - L I S T E N E R <<< public void actionPerformed(ActionEvent e) { Object o = e.getSource(); if (o == putButton) { int posi = teile.getSelectedIndex(); if (posi >= 0){ String angeklicktTeil = teile.getSelectedItem().toString(); parameter.setDSTENR((angeklicktTeil.substring(0,13)).trim()); BestellStart maske1 = new BestellStart(); maske1.schliessenBestellmaske(); XXXVII setVisible(false); maske1.eroeffnenBestellmaske(parameter); }//if Listenposition >= 0 else{ fehler = new Fehlermeldung(fenr001,560,300,300,100); }//else, nichts angeklickt }//if übernehmen if (o == exitButton) { setVisible(false); BestellStart maske1 = new BestellStart(); maske1.schliessenBestellmaske(); setVisible(false); maske1.eroeffnenBestellmaske(parameter); }//if zurück }//actionPerformed() // >>> I T E M - L I S T E N E R <<< public void itemStateChanged(java.awt.event.ItemEvent itemEvent) { }//ItemListener() // >>> F E N S T E R - L I S T E N E R <<< class MyWindowListener extends WindowAdapter { // Fensterkreuz zu public void windowClosing(WindowEvent we) { BestellStart maske1 = new BestellStart(); maske1.schliessenBestellmaske(); setVisible(false); maske1.eroeffnenBestellmaske(parameter); setVisible(false); }//windowClosing }//class MyWindowListener // >>> K E Y - L I S T E N E R <<< class MyKeyListener implements KeyListener { // Taste gedrückt public void keyPressed(KeyEvent evt1) { int key_int = evt1.getKeyCode(); // RETURN gedrückt if (key_int == KeyEvent.VK_ENTER) { mCodeEingabe = mCode.getText(); teile.removeAll(); String[] teileMatchcodeAuswahlListe = xml.teileMatchcodeAuswahlListe(mCodeEingabe); for ( int zeile = 1; zeile <= 99; zeile++ ) { if (teileMatchcodeAuswahlListe[zeile].equals("")) break; putButton.setEnabled(true); teile.add(teileMatchcodeAuswahlListe[zeile],zeile); }//for }// if VK_ENTER }// keyPressed(KeyEvent evt1) // Taste losgelassen public void keyReleased(KeyEvent evt1) { }// keyReleased(KeyEvent evt1) public void keyTyped(KeyEvent evt1) { }// keyTyped(KeyEvent evt1) }//class KeyListener }//class TeileMatchcodeMaske XXXVIII Abbildung 35: GUI-Maske, Klasse BestellEingabeMaske package Einkauf; //(c) Copyright 2011 Manfred Schiefers - Stuttgart //************************************************************************** //*** Direktbestellung / Eingabemaske *** //************************************************************************** import java.awt.Color; import java.awt.Font; import java.awt.Frame; import java.awt.Image; import java.awt.Panel; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import import import import javax.swing.JButton; javax.swing.JComboBox; javax.swing.JLabel; javax.swing.JTextField; import import import import Framework.Fehlermeldung; Framework.HinweisFenster; Framework.XML_Kommunikation; Teilestamm.TeileMatchcodeMaske; public class BestellEingabeMaske extends Frame implements ActionListener, ItemListener { private static final long serialVersionUID = 1L; // >>> Verbindung zur Server-Schnittstelle <<< XML_Kommunikation xml = new XML_Kommunikation(); // >>> M a s k e n e l e m e n t e <<< Panel topPanel, centerPanel, buttonPanel; JButton putButton, exitButton, matchButton; JLabel bestellNrLabel, bestellNrInhaltLabel, lieferantLabel, teileNummerLabel, teileBezLabel, bestellMengeLabel, bestellTerminLabel, preisLabel, jeLabel, zahlungsBedingungLabel, lieferBedingungLabel, abteilungLabel, sachbearLabel, zusatzLabel, dummyLabel01, dummyLabel02, dummyLabel03, dummyLabel04, dummyLabel05, dummyLabel06, dummyLabel07, dummyLabel08, dummyLabel09, dummyLabel10; JComboBox combo01, combo02, combo03, combo04, combo05; JTextField teileNrFeld, teileBezFeld, bestellMengeFeld, teileMassFeld, datumTagFeld, datumMonatFeld, datumJahrFeld, preisFeld, waehrungsFeld, jeMengeFeld, teileMas2Feld, zusatzText1Feld, zusatzText2Feld, zusatzText3Feld, zusatzText4Feld; // >>> String String String String String String String String String String String String String String String String T e x t fenr002 fun0003 fun0005 kon0002 kon0006 kon0008 kon0009 kon0017 kon0019 kon0020 kon0022 kon0024 kon0025 kon0026 kon0027 kon0028 k = = = = = = = = = = = = = = = = o n s t a n t e n <<< xml.textKonstanteZuord("FENR002"); xml.textKonstanteZuord("FUN0003"); xml.textKonstanteZuord("FUN0005"); xml.textKonstanteZuord("KON0002"); xml.textKonstanteZuord("KON0006"); xml.textKonstanteZuord("KON0008"); xml.textKonstanteZuord("KON0009"); xml.textKonstanteZuord("KON0017"); xml.textKonstanteZuord("KON0019"); xml.textKonstanteZuord("KON0020"); xml.textKonstanteZuord("KON0022"); xml.textKonstanteZuord("KON0024"); xml.textKonstanteZuord("KON0025"); xml.textKonstanteZuord("KON0026"); xml.textKonstanteZuord("KON0027"); xml.textKonstanteZuord("KON0028"); XXXIX String kon0030 = xml.textKonstanteZuord("KON0030"); String kon0031 = xml.textKonstanteZuord("KON0031"); // >>> V a r i a b l e n <<< BestellEingabeParameter parameter; String[] lieferantenListe = xml.lieferantenAuswahlListe(); int linrIndex;// Combo-Position Lieferantennummer String dsliwc;// Lieferantenwährungscode String dstebe;// Teilebezeichnung String dsmass;// TeileMaßeinheit String[] zahlungsBedingungListe = xml.zahlungsAuswahlListe(); int zabeIndex;// Combo-Position Zahlungsbedingungen String[] lieferBedingungListe = xml.lieferBedAuswahlListe(); int liefIndex;// Combo-Position Lieferbedingungen String[] abteilungListe = xml.abteilungAuswahlListe(); int abtIndex;// Combo-Position Abteilungen String[] sachbearListe = xml.sachbearAuswahlListe(); int sachbearIndex;// Combo-Position Lieferbedingungen boolean bestellt = false; // Meldungen public Fehlermeldung fehler; public String fehlerText; public HinweisFenster hinweis; public String hinweisText; // >>> F o l g e f r a m e TeileMatchcodeMaske matchcode; // ------------------------- MASKE ---------------------------public BestellEingabeMaske(BestellEingabeParameter parameter) throws IOException { super(parameter.getTITEL()); this.parameter = parameter; linrIndex = parameter.getLINRINDEX(); if (linrIndex < 0) linrIndex = 0; zabeIndex = parameter.getZABEINDEX(); if (zabeIndex < 0) zabeIndex = 0; liefIndex = parameter.getLFBEINDEX(); if (liefIndex < 0) liefIndex = 0; abtIndex = parameter.getABTBINDEX(); if (abtIndex < 0) abtIndex = 0; sachbearIndex = parameter.getSABEINDEX(); if (sachbearIndex < 0) sachbearIndex = 0; // -- Bestellnummer vergeben -if (parameter.getDSBENR().equals("") || parameter.getDSBENR() == null) { parameter.setDSBENR(xml.naechsteBestellNr()); }// if BestellNr. leer --> neu vergeben // WindowsListener hinzu MyWindowListener mwl = new MyWindowListener(); addWindowListener(mwl); // KeyListener MyKeyListener evt1 = new MyKeyListener(); // >>> P a n e l s <<< topPanel = new Panel(); topPanel.setBackground(Color.lightGray); centerPanel = new Panel(); centerPanel.setBackground(Color.WHITE); buttonPanel = new Panel(); buttonPanel.setBackground(Color.lightGray); add("North", topPanel); add("Center", centerPanel); add("South", buttonPanel); XL // >>> L a b e l s und T e x t f e l d e r <<< // -- Bestellnummer -bestellNrLabel = new JLabel(kon0008); topPanel.add(bestellNrLabel); bestellNrInhaltLabel = new JLabel(parameter.getDSBENR()); topPanel.add(bestellNrInhaltLabel); bestellNrInhaltLabel.setForeground(Color.RED); bestellNrInhaltLabel.setFont(new Font("ARIAL", Font.BOLD, 16)); dummyLabel01 = new JLabel(" + " "); topPanel.add(dummyLabel01); " // -- Lieferant -lieferantLabel = new JLabel(kon0006); topPanel.add(lieferantLabel); combo01 = new JComboBox(lieferantenListe); combo01.setEditable(false); combo01.setEnabled(true); combo01.setFont(new Font("Courier", Font.PLAIN, 14)); combo01.setSelectedIndex(linrIndex); topPanel.add(combo01); dummyLabel02 = new JLabel(" "); topPanel.add(dummyLabel02); // -- Teilenummer -teileNummerLabel = new JLabel(kon0002); centerPanel.add(teileNummerLabel); teileNrFeld = new JTextField("", 14); teileNrFeld.setEnabled(true); teileNrFeld.setText(parameter.getDSTENR()); teileNrFeld.addKeyListener(evt1); teileNrFeld.setFont(new Font("Courier", Font.PLAIN, 14)); centerPanel.add(teileNrFeld); matchButton = new JButton(kon0031); centerPanel.add(matchButton); matchButton.setEnabled(true); matchButton.addActionListener(this); // -- Teilebezeichnung -dstebe = xml.holenTeileBezeichnung(parameter.getDSTENR().trim()); teileBezLabel = new JLabel(" " + kon0009); centerPanel.add(teileBezLabel); teileBezFeld = new JTextField("", 14); teileBezFeld.setText(dstebe); teileBezFeld.addKeyListener(evt1); teileBezFeld.setFont(new Font("Courier", Font.PLAIN, 14)); teileBezFeld.setColumns(46); teileBezFeld.setDisabledTextColor(Color.BLUE); teileBezFeld.setEnabled(false); centerPanel.add(teileBezFeld); dummyLabel03 = new JLabel(" "); centerPanel.add(dummyLabel03); // -- Bestellmenge --bestellMengeLabel = new JLabel(kon0017); centerPanel.add(bestellMengeLabel); bestellMengeFeld = new JTextField("", 14); bestellMengeFeld.setEnabled(true); bestellMengeFeld.setText(parameter.getDSMENG()); bestellMengeFeld.addKeyListener(evt1); bestellMengeFeld.setFont(new Font("Courier", Font.PLAIN, 14)); centerPanel.add(bestellMengeFeld); // -- Maßeinheit --dsmass = xml.holenTeileMasseinheit(parameter.getDSTENR().trim()); teileMassFeld = new JTextField("", 14); teileMassFeld.setText(dsmass); teileMassFeld.addKeyListener(evt1); teileMassFeld.setFont(new Font("Courier", Font.PLAIN, 14)); teileMassFeld.setColumns(5); teileMassFeld.setDisabledTextColor(Color.BLUE); teileMassFeld.setEnabled(false); centerPanel.add(teileMassFeld); XLI // -- Bestelltermin -dummyLabel04 = new JLabel(" "); centerPanel.add(dummyLabel04); bestellTerminLabel = new JLabel(kon0019); centerPanel.add(bestellTerminLabel); datumTagFeld = new JTextField("", 14); datumTagFeld.setText(parameter.getDSDTAG()); datumTagFeld.addKeyListener(evt1); datumTagFeld.setFont(new Font("Courier", Font.PLAIN, 14)); datumTagFeld.setColumns(2); datumTagFeld.setEnabled(true); centerPanel.add(datumTagFeld); datumMonatFeld = new JTextField("", 14); datumMonatFeld.setText(parameter.getDSDMON()); datumMonatFeld.addKeyListener(evt1); datumMonatFeld.setFont(new Font("Courier", Font.PLAIN, 14)); datumMonatFeld.setColumns(2); datumMonatFeld.setEnabled(true); centerPanel.add(datumMonatFeld); datumJahrFeld = new JTextField("", 14); datumJahrFeld.setText(parameter.getDSDJAH()); datumJahrFeld.addKeyListener(evt1); datumJahrFeld.setFont(new Font("Courier", Font.PLAIN, 14)); datumJahrFeld.setColumns(4); datumJahrFeld.setEnabled(true); centerPanel.add(datumJahrFeld); // -- Preis -dummyLabel05 = new JLabel(" "); centerPanel.add(dummyLabel05); preisLabel = new JLabel(kon0024); centerPanel.add(preisLabel); preisFeld = new JTextField("", 14); preisFeld.setText(parameter.getDSPREI()); preisFeld.addKeyListener(evt1); preisFeld.setFont(new Font("Courier", Font.PLAIN, 14)); preisFeld.setColumns(8); preisFeld.setEnabled(true); centerPanel.add(preisFeld); // -- Währung --if (linrIndex > 0) { dsliwc = xml.lieferantenWaehrung(linrIndex); }// if else { dsliwc = ""; }// else waehrungsFeld = new JTextField("", 14); waehrungsFeld.setText(dsliwc); waehrungsFeld.setFont(new Font("Courier", Font.PLAIN, 14)); waehrungsFeld.setColumns(3); waehrungsFeld.setDisabledTextColor(Color.BLUE); waehrungsFeld.setEnabled(false); centerPanel.add(waehrungsFeld); combo01.addItemListener(this); // -- je Menge -jeLabel = new JLabel(kon0025); centerPanel.add(jeLabel); jeMengeFeld = new JTextField("", 14); jeMengeFeld.setEnabled(true); jeMengeFeld.setText(parameter.getDSJEME()); jeMengeFeld.addKeyListener(evt1); jeMengeFeld.setFont(new Font("Courier", Font.PLAIN, 14)); jeMengeFeld.setColumns(8); preisFeld.setEnabled(true); centerPanel.add(jeMengeFeld); teileMas2Feld = new JTextField("", 14); teileMas2Feld.setText(dsmass); teileMas2Feld.setFont(new Font("Courier", Font.PLAIN, 14)); teileMas2Feld.setColumns(5); teileMas2Feld.setDisabledTextColor(Color.BLUE); teileMas2Feld.setEnabled(false); centerPanel.add(teileMas2Feld); XLII // -- Zahlungsbedingungen -dummyLabel06 = new JLabel("________________________________" + "________________________________" + "________________________________" + "_____________________________ "); centerPanel.add(dummyLabel06); dummyLabel06.setForeground(Color.BLACK); zahlungsBedingungLabel = new JLabel(kon0020); centerPanel.add(zahlungsBedingungLabel); combo02 = new JComboBox(zahlungsBedingungListe); combo02.setEditable(false); combo02.setEnabled(true); combo02.setFont(new Font("Courier", Font.PLAIN, 14)); combo02.setSelectedIndex(zabeIndex); centerPanel.add(combo02); combo02.addItemListener(this); // -- Lieferbedingungen -dummyLabel07 = new JLabel(" + " " + " "); centerPanel.add(dummyLabel07); lieferBedingungLabel = new JLabel(kon0022); centerPanel.add(lieferBedingungLabel); combo03 = new JComboBox(lieferBedingungListe); combo03.setEditable(false); combo03.setEnabled(true); combo03.setFont(new Font("Courier", Font.PLAIN, 14)); combo03.setSelectedIndex(liefIndex); centerPanel.add(combo03); combo03.addItemListener(this); // -- anfordernde Abteilung -dummyLabel08 = new JLabel(" + " " + " " + " " + " centerPanel.add(dummyLabel08); abteilungLabel = new JLabel(kon0026); centerPanel.add(abteilungLabel); combo04 = new JComboBox(abteilungListe); combo04.setEditable(false); combo04.setEnabled(true); combo04.setFont(new Font("Courier", Font.PLAIN, 14)); combo04.setSelectedIndex(abtIndex); centerPanel.add(combo04); combo04.addItemListener(this); // -- Sachbearbeiter -dummyLabel09 = new JLabel(" + " " + " centerPanel.add(dummyLabel09); sachbearLabel = new JLabel(kon0027); centerPanel.add(sachbearLabel); combo05 = new JComboBox(sachbearListe); combo05.setEditable(false); combo05.setEnabled(true); combo05.setFont(new Font("Courier", Font.PLAIN, 14)); combo05.setSelectedIndex(sachbearIndex); centerPanel.add(combo05); combo05.addItemListener(this); XLIII " " "); " "); // -- Zusatztext -dummyLabel10 = new JLabel("_____________________________" + "_____________________________" + "_____________________________" + "_____________________________" + "_____________________________" + "_____________________________" + " centerPanel.add(dummyLabel10); dummyLabel10.setForeground(Color.BLACK); zusatzLabel = new JLabel(kon0028); centerPanel.add(zusatzLabel); zusatzLabel.setFont(new Font("Arial", Font.BOLD, 11)); zusatzLabel.setForeground(Color.BLUE); zusatzText1Feld = new JTextField("", 100); zusatzText1Feld.setEnabled(true); zusatzText1Feld.setText(parameter.getDSZUS1()); zusatzText1Feld.addKeyListener(evt1); zusatzText1Feld.setFont(new Font("Courier", Font.PLAIN, 14)); centerPanel.add(zusatzText1Feld); zusatzText2Feld = new JTextField("", 100); zusatzText2Feld.setEnabled(true); zusatzText2Feld.setText(parameter.getDSZUS2()); zusatzText2Feld.addKeyListener(evt1); zusatzText2Feld.setFont(new Font("Courier", Font.PLAIN, 14)); centerPanel.add(zusatzText2Feld); zusatzText3Feld = new JTextField("", 100); zusatzText3Feld.setEnabled(true); zusatzText3Feld.setText(parameter.getDSZUS3()); zusatzText3Feld.addKeyListener(evt1); zusatzText3Feld.setFont(new Font("Courier", Font.PLAIN, 14)); centerPanel.add(zusatzText3Feld); zusatzText4Feld = new JTextField("", 100); zusatzText4Feld.setEnabled(true); zusatzText4Feld.setText(parameter.getDSZUS4()); zusatzText4Feld.addKeyListener(evt1); zusatzText4Feld.setFont(new Font("Courier", Font.PLAIN, 14)); centerPanel.add(zusatzText4Feld); // >>> Main - B u t t o n s <<< exitButton = new JButton(fun0003); putButton = new JButton(fun0005); // Exitknopf hinzu buttonPanel.add(exitButton); exitButton.setEnabled(true); exitButton.addActionListener(this); // Übernahmeknopf hinzu buttonPanel.add(putButton); putButton.setEnabled(true); putButton.addActionListener(this); // >>> F r a m e g r ö ß e <<< setSize(850, 500); // >>> F r a m e p o s i t i o n <<< setLocation(new Point(60, 80)); // Framegröße änderbar setResizable(false); // Titel-Icon Image icon; Toolkit toolkit = Toolkit.getDefaultToolkit(); icon = toolkit.getImage("logo.jpg"); setIconImage(icon); // Frame sichtbar setVisible(true); }// Maske XLIV "); // >>> K N O P F - L I S T E N E R <<< public void actionPerformed(ActionEvent e) { Object o = e.getSource(); parameter.setDSMENG(bestellMengeFeld.getText()); parameter.setDSDTAG(datumTagFeld.getText()); parameter.setDSDMON(datumMonatFeld.getText()); parameter.setDSDJAH(datumJahrFeld.getText()); parameter.setDSPREI(preisFeld.getText()); parameter.setDSJEME(jeMengeFeld.getText()); parameter.setDSZUS1(zusatzText1Feld.getText()); parameter.setDSZUS2(zusatzText2Feld.getText()); parameter.setDSZUS3(zusatzText3Feld.getText()); parameter.setDSZUS4(zusatzText4Feld.getText()); if (o == matchButton) { matchButton.setEnabled(false); exitButton.setEnabled(false); putButton.setEnabled(false); combo01.setEnabled(false); parameter.setTITEL(kon0030); try { matchcode = new TeileMatchcodeMaske(parameter); }// try catch (IOException e1) { }// catch finally { }// finally }// if Matchcode if (o == putButton) { bestellt = true; xml.bestellungVersenden(parameter); }// if übernehmen if (o == exitButton) { if (bestellt) xml.hinweisFensterSchliessen(); setVisible(false); }// if zurück }// actionPerformed() // >>> I T E M - L I S T E N E R <<< public void itemStateChanged(java.awt.event.ItemEvent itemEvent) { String itemWahl = itemEvent.paramString().substring(24, 25); if (itemWahl.equals("0")) { String angeklicktLieferant = combo01.getSelectedItem().toString(); linrIndex = combo01.getSelectedIndex(); parameter.setDSLINR((angeklicktLieferant.substring(1, 8)).trim()); parameter.setLINRINDEX(linrIndex); dsliwc = xml.lieferantenWaehrung(linrIndex); waehrungsFeld.setText(dsliwc); }// if itemWahl=0 if (itemWahl.equals("Z")) { String angeklicktZahlungsbedingung = combo02.getSelectedItem() .toString(); zabeIndex = combo02.getSelectedIndex(); parameter.setDSZABE(angeklicktZahlungsbedingung.trim()); parameter.setZABEINDEX(zabeIndex); }// if itemWahl=Z if (itemWahl.equals("L")) { String angeklicktLieferbedingung = combo03.getSelectedItem() .toString(); liefIndex = combo03.getSelectedIndex(); parameter.setDSLFBE(angeklicktLieferbedingung.trim()); parameter.setLFBEINDEX(liefIndex); }// if itemWahl=L if (itemWahl.equals("A")) { String angeklicktAbteilung = combo04.getSelectedItem().toString(); abtIndex = combo04.getSelectedIndex(); parameter.setDSABTB(angeklicktAbteilung.trim()); parameter.setABTBINDEX(abtIndex); }// if itemWahl=A if (itemWahl.equals("O")) { String angeklicktSachbearbeiter = combo05.getSelectedItem() .toString(); sachbearIndex = combo05.getSelectedIndex(); parameter.setDSSABE(angeklicktSachbearbeiter.trim()); parameter.setSABEINDEX(sachbearIndex); }//if itemWahl=O }//ITEM-Listener() XLV // >>> F E N S T E R - L I S T E N E R <<< class MyWindowListener extends WindowAdapter { // Fensterkreuz zu public void windowClosing(WindowEvent we) { if (bestellt) xml.hinweisFensterSchliessen(); try { matchcode.setVisible(false); }// try catch (NullPointerException e) { }// catch setVisible(false); }// windowClosing }// class MyWindowListener // >>> K E Y - L I S T E N E R <<< class MyKeyListener implements KeyListener { // Taste gedrückt public void keyPressed(KeyEvent evt1) { int key_int = evt1.getKeyCode(); // RETURN gedrückt if (key_int == KeyEvent.VK_ENTER) { parameter.setDSTENR(teileNrFeld.getText().trim()); if (!(parameter.getDSTENR()).equals("")) { if (xml.teileNummerCheck(parameter.getDSTENR())) { dstebe = xml.holenTeileBezeichnung(parameter .getDSTENR()); teileBezFeld.setText(dstebe); dsmass = xml.holenTeileMasseinheit(parameter .getDSTENR()); teileMassFeld.setText(dsmass); teileMas2Feld.setText(dsmass); }// if Teilenummer ok else { fehler = new Fehlermeldung(fenr002, 80, 190, 300, 100); }// else Teilenummer falsch }// Teilenummer nicht leer else { dstebe = ""; teileBezFeld.setText(dstebe); dsmass = ""; teileMassFeld.setText(dsmass); }// Teilenummer leer }// if VK_ENTER }// keyPressed(KeyEvent evt1) // Taste losgelassen public void keyReleased(KeyEvent evt1) { }// keyReleased(KeyEvent evt1) public void keyTyped(KeyEvent evt1) { }// keyTyped(KeyEvent evt1) }// class KeyListener }// class BestellEingabeMaske XLVI Abbildung 36: GUI-Maske, leer Abbildung 37: GUI-Maske, Fehlermeldung XLVII Abbildung 38: GUI-Maske, Teilestamm Matchcode-Auswahl Abbildung 39: GUI-Maske, Einblendung Teilestammdaten XLVIII Abbildung 40: GUI-Maske, Lieferantenauswahlliste Abbildung 41: GUI-Maske, Einblendung Lieferantenstammdaten XLIX Abbildung 42: GUI-Maske, Konsolenausgabe L LITERATURVERZEICHNIS [Balzert, 2009] BALZERT, Helmut: Lehrbuch der Softwaretechnik: Basiskonzepte und Requirements Engineering, Springer, 2009 [Däßler, 2003] DÄßLER, Rolf: Das Einsteigerseminar MySQL 4, vmi 2003 [Deck, 2010] DECK, Klaus-Georg, NEUENDORF, Herbert: Java-Grundkurs für Wirtschaftsinformatiker, Vieweg +Teubner, 2010 [Dunkel, 2008] DUNKEL, Jürgen, EBERHART, Andreas, FISCHER, Stefan, KLEINER, Carsten, KOSCHEL, Arne: Systemarchitekturen für Verteilte Anwendungen: Client-Server, Multi-Tier, SOA, Event Driven Architectures, P2P, Grid, Web 2.0, Hanser Verlag, 2008 [Ebel, 2005] EBEL, Nadin: WebSphere/Domino Workplace Administration, Pearson Education, 2005 [Flanagan, 2003] FLANAGAN, David: Java in a nutshell: deutsche Ausgabe für Java 1.4, O'Reilly Germany, 2003 [Fottral, 2002] FOTTRAL, Jerry: Mastering the AS/400: A Practical, HandsOn Guide, System iNetwork, 2000 [Gulbins, 2002] GULBINS, Jürgen, SEYFRIED, Markus, STRACKZIMMERMANN, Hans: Dokumenten-Management: vom Imaging zum Business-Dokument, Springer, 2002 [Hellige, 2008] HELLIGE, Hans Dieter: Mensch-Computer-Interface: zur Geschichte und Zukunft der Computerbedienung, transcript Verlag, 2008 [Herczeg, 2005] HERCZEG, Michael: Software-Ergonomie: Grundlagen der Mensch-Computer-Kommunikation, Oldenbourg Wissenschaftsverlag, 2005 [Hoskins, 2003] HOSKINS, Jim, DIMMICK, Roger: Exploring IBM eServer iSeries and AS/400 Computers: The Instant Insider's Guide to IBM's Popular Midrange Computers, Maximum Press, 2003 LI [Klein, 2001] KLEIN, Martin: Einführung in die DIN-Normen, Vieweg + Teubner, 2001 [Kotz, 2008] KOTZ, Jürgen: Visual Basic 2008: Einstieg für Anspruchsvolle, Pearson Education, 2008 [Krüger, 2009] KRÜGER, Guido, STARK, Thomas: Handbuch der JavaProgrammierung, Pearson Education, 2009 [Louis, 2007] LOUIS, Dirk, MÜLLER, Peter: Das Java 6 Codebook, Pearson Education, 2007 [Kudraß, 2007] KUDRAß, Thomas: Taschenbuch Datenbanken, Hanser Verlag, 2007 [Malaga, 2000] MALAGA, Ernie, PENCE Doug, HAWKINS Ron: Das AS/400 Buch, I.T.P.-Fachbuch, 2000 [Masak, 2005] MASAK, Dieter: Moderne Enterprise Architekturen, Springer, 2005 [Missomelius, 2006] MISSOMELIUS, Petra: Digitale Medienkultur: Wahrnehmung- Konfiguration- Transformation, transcript Verlag, 2006 [Saier, 2007] SAIER, Stefanie: Web Usability- Gestaltungskriterien und Evaluationsverfahren, GRIN Verlag, 2007 [Schmidl, 2008] SCHMIDL, R., BECKER, Ch., POPOVIC, V.: ERP-Systeme im Mittelstand, GRIN Verlag, 2008 [Thum, 2008] THUM, Marcel: Grundlagen des Usability-Engineering, GRIN Verlag, 2008 [Vogel, 2008] VOGEL, Oliver, ARNOLD, Ingo, CHUGTHAI, Arif, IHLER, Edmund, KEHRER, Timo, MEHLIG, Uwe, ZDUN, Uwe: Software-Architektur: Grundlagen - Konzepte - Praxis, Spektrum, Akademischer Verlag, 2008 [Wirtz, 2008] WIRTZ, Klaus Werner: Objektorientierte Programmentwicklung mit Visual Basic .NET, Oldenbourg Wissenschaftsverlag, 2008 LII WEITERE QUELLEN [com, 10/2002] Computerwoche: Oxaion löst Frida ab http://www.computerwoche.de/heftarchiv/2002/43/1067041/ Version: 25.10.2002, Aufruf: 05.03.2011 [com, 11/2004] Computerwoche: GUI-Builder für Eclipse im Vergleich http://www.computerwoche.de/software/software-infrastruktur/550867/ Version: 11.11.2004, Aufruf: 14.03.2011 [com, 03/2006] Computerwoche: ERP-Vergleich: Oracle hat die Nase vorn, http://www.computerwoche.de/heftarchiv/2006/11/1208452/ Version: 08.03.2006, Aufruf: 05.03.2011 [com, 07/2006] Computerwoche: AS/400 verliert im ERP-Markt an Boden, http://www.computerwoche.de/heftarchiv/2006/31/1215429/ Version: 27.07.2006, Aufruf: 05.03.2011 [heise, 01/2008] heise online: IBMs Midrange-Betriebssystem i5/OS V6R1 läuft auf Power6 http://www.heise.de/ix/meldung/IBMs-Midrange-Betriebssystem-i5-OS-V6R1-laeuft-auf-Power6185220.html Version: 30.01.2008, Aufruf: 08.03.2011 [heute, 03/2011] heute.de: Internet Explorer 9 geht an den Start http://www.heute.de/ZDFheute/inhalt/3/0,3672,8220227,00.html Version: 13.03.2011, Aufruf: 13.03.2011 [infor, 2009] Infor Global Solutions, Pressemeldung: Infor trumpft bei der J A Burghaus GmbH mit Industrie-Know-how und i5/OS-Kompatibilität, http://www.infor.de/unternehmen/news/pressemeldungen/burghaus_xpert/;NO-RCT Version: 2009, Aufruf: 05.03.2011 LIII [man, 2002] SCHOLZ, Ingo, WETZEL, Doreen: Referat Thin-Client-Architekturen, Berufsakademie Mannheim http://ba-skripte.de/ba_mannheim_informationstechnik_2002/4_semester/seminar/thin_client.pdf Version: 2002, Aufruf: 05.03.2011 [pks, 2008] PKS Software GmbH, Pressemitteilung BoxID 150424: Migration von System i RPG-Anwendungen, http://www.pressebox.de/pressemeldungen/pks-software-gmbh/boxid/150424 Version: 2008, Aufruf: 05.03.2011 [qsc, 2010] QSC (Quality Software & Consulting): Wallstabe & Schneider steuert Projekte mit PM1, http://www.qsc-systems.com/cms/index.php?1bdioi7t-q9y6-emww-evxj-u0mt6twpyv3p090922100124 Version: 2010, Aufruf: 05.03.2011 LIV EIDESSTATTLICHE ERKLÄRUNG Ich versichere, dass ich diesen Projektbericht selbstständig verfasst, keine anderen als die angegebenen Quellen und Hilfsmittel benutzt sowie alle wörtlich oder sinngemäß übernommenen Stellen in der Arbeit gekennzeichnet habe. __________________________ ___________________________ (Ort, Datum) (Unterschrift) LV