Dienstag, 21. Juni 2016

Forms 12c - Reports Server erstellen und starten

Heute muss ich direkt wieder Wissen über Forms 12c teilen, bislang war mir der Start eines Reports Servers nicht gelungen. Aber dank fachkundigem Wissen vom Kollegen Jan-Peter Timmermann habe ich es geschafft, dank der Informationen aus der Datei installation-fmw12c-forms-reports-2860049.pdf mit dem Titel "Installation von Oracle Fusion Middleware 12c - Forms & Reports".

Die erforderlichen Steps dafür:

1. der Managed Server WLS_REPORTS ist vorhanden und läuft

2. WLST (Weblogic Scripting Tool) starten und anmelden

3. connect("weblogic","weblogic_password","hostname:7001")
createReportsToolsInstance(instanceName='reptools1', machine='AdminServerMachine')

4. connect("weblogic","weblogic_password","hostname:7001")
createReportsServerInstance(instanceName='rep_server1', machine='AdminServerMachine')

5. Die erzeugten Reports Server werden per Default im abgesicherten Modus angelegt.
Versucht man, auf diese Reports Server zuzugreifen, ist eine Authentifizierung
erforderlich. Das kann man aber abschalten in der Datei rwserver.conf der entsprechenden Reports Server-Komponente durch Auskommentieren einer Zeile.

<!--security id="rwJaznSec" class="oracle.reports.server.RWJAZNSecurity"/-->

6. Nun kann über ein Batch-File der Reports Server gestartet werden (hier in Windows)
<domain_home>\bin\startComponent

startComponent.cmd rep_server1

7. Evtl. kommt noch beim Abfragen des Report-Servers die Fehlermeldung: REP-52262: Diagnostic output is disabled.

Dann muss noch eine Datei rwservlet.properties angepasst und um einen Eintrag ergänzt werden:
 <webcommandaccess>L2</webcommandaccess>

Ergebnis: das Reports Server rep_server1 läuft und kann abgefragt und benutzt werden:
http://hostname:9002/reports/rwservlet/showenv?server=rep_server1

Fazit: mit den Informationen aus der obigen Installationsanweisung und weiteren Quellen aus dem WWW kann relativ einfach unter der Version 12c Reports konfiguriert und gestartet werden. Endlich ist die erste Umgebung in einer Windows-VM komplett.

Viel Erfolg beim weiteren Forschen :-)
Holger

Montag, 6. Juni 2016

Forms mal generisch: alle Items eines Blockes verstecken und wieder einblenden

Dieser Beitrag kommt aus der praktischen Arbeit heraus gerade. Der Kunde hat die Anforderung: fast alle Items eines Datenblockes nach Klick auf einer Checkbox ausblenden und wieder einblenden danach. Da ich mir durchaus vorstellen kann, dass das auch woanders vorkommen könnte, möchte ich meine favorisierte Lösung vorstellen.

Die Lösung dazu ist entweder sehr trivial oder mit ein bisschen mehr Invest auch schöner, dafür aber anspruchsvoller umsetzbar.

Meine 1. Idee (trivialer Ansatz) war: alle Items nacheinander mit ihrem Namen ansprechen und dann ausblenden. Einfacher Ansatz, aber viel Tipperei, evtl. ein Item vergessen und Wiederholungen. Und ich stehe ja mehr auf Wiederverwendbarkeit und generische Ansätze.

Code dafür:
pkg_item.verstecken('BLOCK.ITEM1'); bis pkg_item.verstecken('BLOCK.ITEM32');
Dazu sollten auch alle Eingaben gelöscht werden.
:BLOCK.ITEM1 := NULL;

pkg_item.verstecken('BLOCK.ITEM1'); macht einfach
set_item_property ('BLOCK.ITEM1', visible, property_false);

Nun der generische und schönere Ansatz:
1. merken einiger Felder, die immer sichtbar sein sollen:
          v_currentblockp := 'BLOCK.';
          v_ausnahme_felder := v_currentblockp || 'ITEM12 ';
          v_ausnahme_felder := v_ausnahme_felder || v_currentblockp || 'ITEM13 ';

2. den Block durchgehen und alle Felder ausblenden und ggf mit COPY auf NULL setzen:
      LOOP
         v_currentitem2 := get_item_property(v_currentitem,nextitem);
         v_currentitem:= v_currentblockp || v_currentitem2;
         -- Ausstiegskriterium, wenn Current Item leer ist (also nur der Blockname)
         IF v_currentitem = v_currentblockp THEN
              EXIT;
         END IF;   
        
         -- Item darf nicht in der Ausnahmeliste sein(sonst wird es unsichtbar)
         IF INSTR(v_ausnahme_felder, v_currentitem ) = 0 THEN
           IF GET_ITEM_PROPERTY(v_currentitem,visible)= 'TRUE'  THEN
                  -- Felder leeren
                  IF GET_ITEM_PROPERTY(v_currentitem,ITEM_TYPE) IN
                       ('TEXT ITEM', 'LIST',  'DISPLAY_ITEM') THEN
                       COPY(NULL, v_currentitem);
                  END IF;  
                 
                 -- Felder verstecken (unsichtbar machen)                 
              pkg_item.verstecken(v_currentitem);
           END IF;         
         END IF;
      END LOOP;

3. das Sichtbar machen funktioniert ähnlich mit einer Besonderheit: der Block hat auch Felder, die sollen gar nicht sichtbar werden (Control-Items usw.). Um das Ganze mit einer Logik zu versehen, habe ich mir beim Start der Maske alle Felder gemerkt, die dann auch sichtbar sind und nicht zu meinen o.g. Ausnahmen gehören. Danach stehen in der Variable v_filter_items alle Felder, die ich nach einem Ausblenden auch wieder sichtbar machen will.

         IF INSTR(v_ausnahme_felder, v_currentitem ) = 0 THEN
           IF GET_ITEM_PROPERTY(v_currentitem,visible)= 'TRUE'  THEN
                 v_filter_items := v_filter_items || v_currentitem || ' ';
           END IF;         
         END IF;

Jetzt noch der Loop zum Sichtbar machen mit dem Zusatz auch die Felder wieder zu enablen:
     v_currentblockp := 'BLOCK.';
     LOOP
          v_currentitem2 := get_item_property(v_currentitem,nextitem);
         v_currentitem:= v_currentblockp || v_currentitem2;
         -- Ausstiegskriterium, wenn Current Item leer ist (also nur der Blockname)
         IF v_currentitem = v_currentblockp THEN
              EXIT;
         END IF;   
        
         -- Item muss aber in der Liste der sichtbaren Felder sein und nicht in der Ausnahmeliste
         IF  (INSTR(v_filter_items, v_currentitem ) != 0 AND INSTR(v_ausnahme_felder, v_currentitem ) = 0) THEN
           IF GET_ITEM_PROPERTY(v_currentitem,visible)= 'FALSE'  THEN
                  -- Felder wieder anzeigen und enablen
                  pkg_item.zeigen(v_currentitem);
                 
                  IF GET_ITEM_PROPERTY(v_currentitem,ITEM_TYPE) != 'DISPLAY ITEM' THEN
                       pkg_item.enable(v_currentitem);
                  END IF;  
           END IF;         
         END IF;
      END LOOP;

Ein Screenshot von der Maske mit den ausgeblendeten Feldern (diese ist nicht mehr schön, weil sie auch Frames enthält, die aber sichtbar bleiben sollen). Die Schaltflächen und die 4 Eingabefelder (weiß) sind in meinem Beispiel die Ausnahmefelder und von der Logik ausgenommen. Diese layouttechnisch unschöne Lösung war aber kostengünstiger als eine neue Version der Filtermaske.


Wie man erahnen kann, ist diese Lösung universell einsetzbar und auch noch weiter auszubauen. Ich denke daran, z.B. diese Felder konfigurierbar in einem DB-Schema zu speichern vielleicht. Damit wären dann user-spezifische Varianten zu erreichen.

Viele Grüße
Holger