Translate

Donnerstag, 21. Juni 2018

ODTUG - Kscope #LetsWreckThisTogether APEX Talks - recorded LIVESTREAM (1:27:25 hrs)


sorry for cross-posting - aber in DE mögen das nicht alle mitbekommen haben...

Free replay from ODTUG Kscope18 Deep Dive

Did you miss the Oracle APEX / JavaScript talks from the ODTUG #Kscope18 "deep dive" on Thursday? No worries, you can watch the replay!

These are 6 short, highly-informative & entertaining sessions from globally-recognized leaders in the APEX community. Every APEX developer on the planet should watch this at least once. You'll thank me later.

https://livestream.com/ODTUG/events/8217224/videos/176293911

Jeder Speaker hatte 12 Min. Zeit...

Moderator: Dietmar Aust, Opal Consulting

Speaker: (topic) - Min. NN Startpunkt des Beitrags im 90 Min. video

Peter Raganitsch,  (Ground Use of JS)

Vincent Morneau, Insum (organize JS code, structures {namespace.module.function} ) recommending code editor "intellisense" - Min. 14

Menno Hoogendijk, Qualogy (widget architecture) - Min 30

John Scott - (Perfomance) - Min. 44:30

Kai Donato, MT AG - (Debugging) - Min. 57

Dan McGhan - how to start with JS - quoting experts advices  - Std. 1:13

Dienstag, 1. Mai 2018

APEX 18.1 und Jasper Reports 6.5.1

Business Case:
"Schön, Business adequat, Template basiert drucken" (pdf, rtf..) aus APEX heraus..
Listen, Rechnungen, Briefe, Newsletter (??)  u.ä.

Jasper Reports wird als OpenSource da schon ordentlich beworben. Also mal ran...
Opal Consulting (Dietmar Aust) - hat da bereits 2012 etwas drüber geschrieben und eine sehr hilfreiche Test-Application zur Verfügung gestellt (hier).

Es braucht schon etwas Geduld, um die Integration von APEX (18.1) und Jasper Reports zum fliegen zu bringen.
Man stösst auf allerlei altes "Geraffel" (e.g. iReports und die "Inkompatibilität" mit JDK 8, usw.)...

Bis ich dann die folgende Konfiguration zum Laufen (oder fliegen) bekam:

1. Download Jasper Reports Studio (hat scheinbar TIBCO, der große "Integrierer" jetzt gekauft...) von dieser Site:
https://community.jaspersoft.com/project/jaspersoft-studio/releases

Das ganze ist Eclipse basiert... und ließ sich erstaunlicherweise smart installieren und starten (im Gegensatz zu iReport 5.6 (dem Vorgänger), wo erst ein altes (1.7 u45) JDK/JRE nötig war.
So müllt man sich dann voll mit den verschiedenen Java Versionen... - aber Ok, der iReport 5.6 (Netbeans basiert) wird auch nicht weiter supported von der Community - und Netbeans hat Schuld an der "alten" Java Version..(einer muss ja Schuld haben).

2. Für "Connection" zur DB gibt es zwar einen Oracle JDBC Driver, dessen "OJDBC6.jar"aber nicht enthalten ist (wahrscheinlich lizenzrechtliche Gründe).
Also: download des Treibers von:
http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html (11.2.)
oder für 12.1 usw.:
http://www.oracle.com/technetwork/database/application-development/jdbc/downloads/index.html

3. Installation des "externen JAR" ... in Jasper Reports Studio:
.. in "Projects" --> Properties:

--> ersten Eintrag rechts "add JARs..." - ich habe das .jar mit in ein Verzeichnis von JasperRports gelegt




4. Data Adapter anlegen:



... und es funzte sogleich - kaum macht man es richtig... cool.

4. eclipse und die Project Jar files: - interessant zu sehen....



5. Über den Project Explorer legt man ein neues Projekt an:


Ein 6-Min. Video zur Einführung der Komponenten und zur Erstellung eines Reports von Jaspersoft gibt es auf Youtube (inkl. Data Connection, Design Report, usw.) 

Kurzform: Myreport --> New --> Jasper Report --> Wizard startet... - Report Template (oder blank) auswählen --> "Report_File" (Name vergeben) vom Typ .jrxml... --> Next --> Data-Source wählen und mit "select * from Table" alle Spalten der Tabelle verfügbar machen
--> 
Über den Data Field Wizard die Spalten auswählen....--> Next "Group By" Wizard (einsetzen oder)  "Next" --> Finish ("Congratulations"-Meldung). --> Ergebnis:


wenn man dann auf "Preview" klickt, erscheint:



6. Nun das Ganze für APEX .... (18.1)

Dazu muss ich den Report kompilieren (rechte Maustaste) auf dem DEMO_Customers.jrxml... und es wird ein Demo_customers.jasper generiert.
Beide Dateien auf den Jasper Report Server kopieren... - zusätzlich die "coffee.jpg" und "coffee_stain.png", da diese im Header des Templates genutzt werden.
Wie? Rechte Maustaste: Copy Files_to.... --> lokal kopieren und dann per FTP auf den JR Server hochladen.
Da ich mit Maxapex.com arbeite, konnte ich keine JR Server Verbindung herstellen (da geht es nur per FTP) - aber es scheint mir, dass man nach der Erstellung einer Connection zum JR Server (Erstellung wie eine Connection zu einer Data-Source) auch direkt dorthin hochladen kann mit "export" (z.B. bei lokaler Installation).

7. APEX 18.1
Dietmar Aust's Test-Application 
"JasperReportsIntegration Test (v1.3.0.2)" herunterladen, unzippen und als Application importieren.


entsprechend das Setup anpassen, bis alle Haken rechts grün sind.

Dann zur "Testpage" wechseln und die eigenen Parameter eintragen:


Zu Step 3. und 4. oben: der Jasper Reports Server lag bei mir (bei Maxapex.com) auf dem Server und ist deshalb ROT.


Der erste Button "Show report directly" brachte bei mir Fehler mit einem doppelten // for report...
Über den 2.Button "Show report (through APEX proxy)" den Report als pdf oder rtf oder xls/csv aufrufen:



Update 22.6.2018:

Zur Parameterübergabe siehe bitte den "alten" BLOG von Dietmar Aust.

Ich habe lange "rumprobiert".... - hier die Lösung:

Den von Dietmar erwähnten Prozess (siehe unten) auf der Seite, wo man drucken möchte hinzufügen, auf die eigenen Werte anpassen und dann per Button auslösen, dann erscheint der PDF- Report auf der Folgeseite.

Die Steps:
1. Selektliste der (bei mir) Kunden mit Return Value ID anlegen P1_KUNDE_ID
2. Interactive/Classic Report darunter anlegen mit
select * from SERVICES where KUNDE_ID = :P1_KUNDE_ID
damit der Benutzer sieht, was er ausgewählt hat (z.B. Services oder Kontakte des Kunden)
.. diese Auswhl möcht ich nun im CI des Kunden etwas nett ausdrucken...
3. Button anlegen: "Drucken"
4. Process anlegen mit u.e. pl/sql. - condition: when Button pressed: Drucken
(PS: die anderen JS und pl/sql Funktionen auf der Seite 5 USAGE von Dietmar Aust kann man ignorieren - ist aber gut zum Setup und Testen.

Hier der von mir angepasste pl/sql Prozess (von Dietmar Aust):



declare

l_additional_parameters varchar2(32767);

begin

-- set the url for the j2ee application

-- better retrieve that from a configuration table

xlib_jasperreports.set_report_url(:G_REPORT_URL);

-- construct addional parameter list

l_additional_parameters := 'parameter1=' ||apex_util.url_encode(:p1_KUNDE_ID);
-- l_additional_parameters := l_additional_parameters || '&parameter1=' || apex_util.url_encode(:p1_filter_object_type);

-- call the report and pass parameters

xlib_jasperreports.show_report (p_rep_name => 'DYNAMO_A171909/test5',

-- p_rep_format => xlib_jasperreports.c_rep_format_pdf,

p_rep_format => 'pdf',

p_data_source => :p1_data_source,

p_additional_params => l_additional_parameters);


-- stop rendering of the current APEX page

apex_application.g_unrecoverable_error := true;



end;


das Package xlib_jaspereports bringt die Installation der JRI Lösung von Dietmar Aust mit!

Re: xlib_jasperreports.set_report_url(:G_REPORT_URL);
 

die Jasper reports server URL habe ich hier als Globale Variable bei der Application angelegt: mit: http://servername:port
/JasperReportsIntegration/report









Re: xlib_jasperreports.show_report (p_rep_name => 'DYNAMO_A171909/test5',

Hier habe ich die Erfahrung gemacht, dass ich noch den Usernamen dazunehmen musste vor dem Namen des Reports (test5).

re: p_data_source => :p1_data_source,
Ich habe hier auf der Seite ein Feld, wo ich den Datasourcewert als Source/Default eingetragen habe - man könnte die Datasource aber auch als 'meineDatasource' hier eintragen (oder als Globale Variable).

Jasper Reports Studio:
 
Für die Parameter muss man das SQL natürlich anpassen:

1. Im Design Modus des JasperReports unten links im Outline Pane auf "Parameter"  mit echter Maustaste: Create Parameter - einen Parameter anlegen: "parameter1" - die Properties dazu findet man unten rechts - Typ muss sein: java.class.String



2. Danach erneut im Outline Pane mit rechter Maustaste auf den Namen des Reports klicken und "Dataset and Query" aufrufen.



3. Dataset und Query Dialog

Zunächst oben die Datasource wählen - dann hat man Zugriff auf die Tabellen und kann rechts daneben im TEXT-Modues gleich normales SQL schreiben:

SELECT *
FROM user_objects
WHERE OBJECT_TYPE  = $P{parameter1}

Es gibt unten im Dialog auch einen "Run-Modus" , der bei mir MIT einem Parameter keine Daten anzeigte. 


Zurück im Haupt-Design-Editor kann man mit "Preview" den Report Testen. Für den Parameter kommt dann ein extra-Pane hoch, wo man die Query-Werte eingeben kann, die später über die URL an den Jasper Report Server gegeben werden.

Tipp: um zu testen, ob die Parameter-Übergabe aus APEX heraus geklappt hat, habe ich im Header einfach den "parameter1" mit reingenommen (von unten links einfach in den Report reinziehen). 

Viel Erfolg!

PS: ein SEHR umfassendes und informatives PDF hat Markus Hohloch zusammengestellt.
Inkl. der Parameter-Übergabe.
Ein großes Danke dafür Markus !!!
Es gibt auch eine APEX Demo (Apex-experts) dafür, die aber derzeitig (1.5.2018) nicht läuft.




Freitag, 23. Februar 2018

Item type "Shuttle" - break-up entries in a report

If you use the item of type "shuttle" you enable the user to select items from an LOV and move them from left (unselected) to the right (selected):

Item of type: shuttle 
The content of the column in the table looks as follows:


In my (standard-) report it looks as follows:


My business requirement/challenge: start  a new line by '<'br'>' or 'char(10)'   instead of using ":"

So I replace in my SQL this line  U_BERUFE ,
 with:                                            replace(U_BERUFE,':','<br>' ) as U_BERUFE,

and we have:

I hope you can make use of it, if needed.
Good luck !

Donnerstag, 4. Januar 2018

maintenance information for application down-time

Environment APEX 5.1 (but will work for older versions as well)

In reply to APEX community forum question 

"show a different page for maintenance purposes"

I like to explain my maintenance solution.

I created a "maintenance Info"-Region on the Login page, which is shown during maintenance time (and the app/server is not down) and can be maintained by the Admin/developer without using APEX Developer but from the UI itself.

I experienced, that "system parameters" are quite useful, if the Admin can change them without using the APEX Developer.

6 Steps and you are set:

1. create a table named SYSTEM_PARAMETERS for the SYSTEM_PARAMETERS with a structure like:

ID, name(varchar 50), active (varchar 10 for: yes/no), from (datetime), to (datetime), Info_text_for_users (varchar 500), remarks (varchar 500)

2. create two pages with type form and report to maintain the data

3. On the Login-page 101 create a new region called: "maintenance_region"

4. for the region "maintenance region" create a "server-side-conditon of type "Rows returned" and SQL:

select 1 from SYSTEM_PARAMETERS
WHERE id = '1' --- maintenance works
and active  = 'Yes'

So, when there is a maintenance period switch your system parameter to YES and this region is shown.

5. For the existing "Login_region" create the same as above, but ofcourse set 

... and active = 'No'

6. create a field  P101_INFO_TEXT_FOR_USERS in the "maintenance_region" with type text and 
Source: "Sql Query rerturing single row"  with 
SQL:
select text from SYSTEM_PARAMETERS where id = '1'

In addition (optionally) it proofs well to have "General Info" (like News) region on page No. 1 of the application for announcements such as maintenance and other news. A few days before maintenance starts, I usually do announce that. This region can be maintained by the Admins as well and will work similar as the above (table with text/content and valid from/to columns).

Now, as maintenance is carried out (and the application actually is not down), the Admin excluded himself from the application, as the Login region with username/password is not shown anymore...
Workaround: copy page 101 to 102 (before you do the above 6 steps) and when you like to enter (e.g. for testing) your app, you can use page 102 by manipulating the login_url.

Hope that finds your interest.


Dienstag, 7. November 2017

Change APEX_USER password for end users

Environment APEX 5.1.3

Business case: How can the end user change his password?
(in reply to Dennis question in the APEX forum)

Prerequisite: APEX_AUTHENTICATION (default) = APEX_USER created in the workspace

The documention is straight forward:

https://docs.oracle.com/cd/E71588_01/AEAPI/CHANGE_CURRENT_USER_PW-Procedure.htm#AEAPI102


The procedure example code is:

BEGIN
    APEX_UTIL.CHANGE_CURRENT_USER_PW ('secret99'); 
END;
Step by step:

1. create a new page - type "blank" - let's say: Page 9
2. create a region named: Password change region
3. create an item named: P9_NEW_PWD of type "text field"
4. create a button named: "change Password"
5. in Page Processing - Processing - create a procedure named "change_password" of type pl/sql
6. in "PL/SQL Code" enter the above PL/SQL code
7. replace 'secret99' by :P9_NEW_PWD so it looks:

BEGIN
    APEX_UTIL.CHANGE_CURRENT_USER_PW (:P9_NEW_PWD);
END;
8. and last steps:
- the PL/SQL procedure "change_password" selected
- right hand in region "Success message" enter in: "Password changed successfully (:-)"
- in region "error message" key in "nothing done - error"
- in region "Server side condition" and "When Button pressed" select: "change Password"

SAVE everything - Test

That's it.

Result:


What does the procedure do?
It just uses your username (:APP_USER or &APP_USER. ) and replaces the corresponding password with the new Password.

I hope that helps.

BTW: there es another procedure to change the password:
https://docs.oracle.com/cd/E71588_01/AEAPI/RESET_PASSWORD-Procedure.htm#AEAPI29920

There, the user must key in his present password and can enter a new password.

The example code of the procedure:

apex_util.reset_password (
    p_old_password => :P111_OLD_PASSWORD,
    p_new_password => :P111_NEW_PASSWORD );



Donnerstag, 2. November 2017

APEX 5 - Interactive Report - Delete Row feature

In the last post I focussed on Insert and Set value features within the IR.

Now I came across this very straight forward approach on "Delete" ROW... from Farzad.
Thanks so much for your Input!

http://farzadsoltani.com/2017/03/14/checkboxes-interactive-reports-ajax-apex/

Crossposting - sorry - but in short:

Farzard makes use of the  APEX_ITEM.CHECKBOX2

Code:

select 
  CHECKBOX_TABLE.SRL as SRL, 
  CHECKBOX_TABLE.NAME as NAME, 
  APEX_ITEM.CHECKBOX2(p_idx => 1, 
                  p_value => SRL, 
                  p_attributes => 'class="boxes"') AS SELECTOR 
from CHECKBOX_TABLE

Then he creates a pl/sql Process like:

BEGIN 
 FOR I IN 1..APEX_APPLICATION.G_F01.COUNT 
 LOOP DELETE CHECKBOX_TABLE 
 WHERE SRL = APEX_APPLICATION.G_F01(I); 
 END LOOP; 
 htp.p('{ "message": "' || APEX_APPLICATION.G_F01.COUNT || ' rows deleted" }'); 
END;

Thirdly he adds a AJAX Callback... - pls see his posting above.
Sorry for x-posting, but I found this as a need solution and completes the added IR features.

Bernhard


Freitag, 27. Oktober 2017

IR with Checkbox select/unselect to A) set values or B) copy specific records

My environment: APEX 5.1.2.00.09 - DB 11.2

My Business case:
Select records in the IR based on the checkbox and copy these - and assign some new values
(here: Date :P107_GUELTIG_AB,  - means: valid from...)

First build the checkbox for the IR based on Jeffs input:


Jeff uses a combination of DA, JQuery and Javascript and the u.m. pl/sql to set a value

Thanks to Jeff!

A) Process type pl/sql code - to set a value within the report/table. :

DECLARE
  MELD_ID WWV_FLOW_GLOBAL.VC_ARR2;
BEGIN
  MELD_ID := APEX_APPLICATION.G_F01;
  FOR IDX IN 1 .. MELD_ID.COUNT
  LOOP
    IF MELD_ID(IDX) IS NOT NULL THEN
      UPDATE MELDUNGEN
      SET ABGERECHNET='Ja'
      WHERE MELD_ID =MELD_ID(IDX);
        END IF;
  END LOOP;
END;

----
Then to my business case:

Select records in the IR based on the checkbox and copy these - and assign some new values (here: Date :P107_GUELTIG_AB,  - means: valid from...)

B) So have modified the above to copy the selected records/values to another (or the same) table:

Process: type pl/sql code

Syntax:

DECLARE
  LST_DEF_ID WWV_FLOW_GLOBAL.VC_ARR2;
BEGIN
  LST_DEF_ID := APEX_APPLICATION.G_F01;
  FOR IDX IN 1 .. LST_DEF_ID.COUNT
  LOOP
    IF LST_DEF_ID(IDX) IS NOT NULL THEN
 --- here insert starts...
insert into LEISTUNGEN_DEFAULT DEF
(
DEF."LST_DEF_ID",
DEF.KD_FK,
DEF.KD_GR_FK, 
DEF."KD_LST_FK", 
DEF."DEF_BETRAG", 
DEF."DEF_ZEIT", 
DEF."DEF_BEZ_KD", 
DEF."DEF_UMFASST_BEMERKUNGEN", 
DEF."DEF_BEMERKUNGEN", 
DEF."DEF_GUELTIG_VON", 
DEF."DEF_AKTIV"  
)
select
LEISTUNGEN_DEFAULT_SEQ.nextval,
--- some ID's to set
:P107_AK_KD_ID,
:P107_KD_GR_ID,
DEF."KD_LST_FK", 
DEF."DEF_BETRAG", 
DEF."DEF_ZEIT", 
DEF."DEF_BEZ_KD", 
DEF."DEF_UMFASST_BEMERKUNGEN", 
DEF."DEF_BEMERKUNGEN", 
---- Date Picker field on the page
:P107_GUELTIG_AB, 
DEF.DEF_AKTIV  
from LEISTUNGEN_DEFAULT DEF
where  DEF."LST_DEF_ID" = LST_DEF_ID(IDX);
    END IF;
  END LOOP;
END;

To make it working you have to add a Date Picker (or other) field on your page