Monday, February 23, 2015

APEX IR XLSX Downloader V1.3.0

After a long time I have finally published Release 1.3 of my APEX IR XLSX Downloader.
And because I kept you waiting so long there's one goody included.

Added Features

  • The Interactive Report region ID is now automatically derived if not specified or set NULL.
  • Function get_version which emits the package release you are running.

Bugs Fixed

  • Column header wasn't filled if user didn't give a custom name for a function column in "Group By" view.
    Now the package puts similar names to what the APEX engine generates.

New Demo Application

There is also a new demo application available for download.
You can download it here and install into your own APEX workspace.

As always the source code can be found in the GitHub Repository.
ZIP files for all my GitHub projects can now be found on my GitHub Page.

Enjoy ;-)

Saturday, January 31, 2015

Oracle Application Express EA3 is now available

APEX EA3 is here

Just read this one on Twitter:
So head over to apexea.oracle.com, request your workspace and start testing all the new features.

I received my access within minutes, so be prepared to immediately have a reason for spending time on your computer. ;-)
First thing I did was checking out the "Universal Theme Sample Application".
Shakeeb did a very good job of explaining the Universal Theme Components.

Interestingly the beta documentation for APEX 5.0 was already made available.
A very nice move in my opinion. Click on the link above or use http://docs.oracle.com/cd/E59726_01/index.htm.

So long for now folks and enjoy your first weekend with APEX 5.0 EA3. ;-)

Friday, January 30, 2015

APEX jQuery Modal Dialog Oddities

Lately I have been working on creating a new version of my demo application for the APEX IR XLSX Downloader.
The package provides a set of configuration parameters which I thought would be nice to present to the user instead of being solely defined by the developer.
During that I encountered some oddities when using a jQuery Modal Dialog to render a region as a modal dialog.

Note: I'll show you the steps to reproduce and fix in a newly created application. But you can also just create a new page in an existing application.

Steps to reproduce and fix:
  1. Navigate to the page where you want to put the modal region containing form elements.
  2. Create a new region accepting all defaults
  3. Create a button in that region and set Action to "Defined by Dynamic Action"
  4. Create a new region accepting defaults except for "Display Attributes"
    Select "jQuery Modal Region Template" as "Region Template"
  5. Create at least one item which should save session state on the modal region.
    I used a text item and made it submit on enter for this example.
  6. Create the dynamic action reacting to button click.



  7. Run a simple test
    1. Run the page
    2. Click open Dialog button
    3. Enter something in the text field and hit enter.
    4. Now verify session state
    5. So we submitted the page with a new value in the item, but it doesn't look like it was pushed into session state.
  8. Finding the reason for session state not being updated.
    1. Analyze DOM before dialog open.
    2. Analyze DOM after dialog open.
  9. This tells us that the region gets moved outside of the <form> container, making the item invisible to APEX.
    Therefore no update in session state.
  10. Steps to fix DOM
    1. Create Dynamic Action which fires "Before Page Submit"
    2. Set action to "Execute Javascript Code":
      apex.jQuery( this.affectedElements ).dialog( "destroy" ).appendTo( 'form#wwvFlowForm' );
      
    3. Set "Affected Elements" identical to previous Dynamic Action.
  11. Test again with same steps as noted in 7.
    This should now work.


  12. Enjoy nicely working modal dialogs.

Tuesday, December 9, 2014

APEX IR XLSX Downloader V1.2.3

I have just published Release 1.2.3 of my APEX IR XLX Downloader.

André Meier had a look at my package after DOAG 2014 and pointed out some hick-ups he encountered while using it.
He also made a big effort to bring some proper code formatting and explicit conversions into the XLSX_BUILDER_PKG which is one of the libraries used.

A huge thank you to André, as many of the changes are based on his contribution.

Changes

  • XLSX_BUILDER_PKG
    • Explicit Conversions
    • Code Formatting
    • Better CLOB building using VARCHAR2 buffer (as shown in a previous post)
  • APEXIR_XLSX_PKG
    • If splitting report_columns string would produce a NULL index this is now taken care of and a warning is send to the APEX debug messages.

As always the source code can be found in the GitHub Repository.
ZIP files for all my GitHub projects can now be found on my GitHub Page.

The new demo application is currently under development and will be published soon.
I'm currently creating some sort of packaged application which will better showcase all the different options available.

Stay tuned for more to come.

Tuesday, November 25, 2014

APEX_IR.GET_REPORT Limitations & Wishlist

Luckily nowadays we as APEX developers have access to APEX_IR.GET_REPORT which gives us back the current query of an interactive report.
With that we can actually build really nice plugins enhancing the functionality.
However one thing you have to be aware of is that it will always give you the query of the "Report" view, so if you want to get the query behind the "Group By" view it's back to rebuilding the query manually.
Talking to Patrick Wolf during DOAG 2014 he asked me to write a blog post about it and showcase the behavior.
Therefore I have created a small demo on apexea.oracle.com using an interactive report and a dynamic action to see if the same behavior is also still in APEX 5.
The dynamic action gets the IR query using APEX_IR.GET_REPORT and also sets a read-only field to SYSDATE in order to show it actually fires on event "After Refresh".
You can check out the current behavior here.

So here's my wishlist for the APEX development team:

  • Please give us the query also for the other view-types available for an interactive report.
  • And if you want to supercharge the function give us an additional parameter for choosing whether we want the query for the currently displayed view-type or a specific one.
I imagine a possible function declaration like below:

FUNCTION get_report( p_page_id      IN NUMBER
                   , p_region_id    IN NUMBER
                   , p_report_id    IN NUMBER DEFAULT NULL
                   , p_view_mode_in IN VARCHAR2 DEFAULT NULL
                   )
  RETURN t_report;

So if you do not specify the fourth parameter you get the query for currently displayed view mode, similar to the third already available parameter.

Concatenating VARCHAR2 values into a CLOB

After an inspiring DOAG 2014 I was thinking about some performance improvements for my APEX IR XLSX Downloader.
The actual size of all the single files that need to be build isn't known beforehand but you have to plan for more than the maximum size of a VARCHAR2 variable so you need a CLOB.
However building a CLOB can be really slow if you treat it like a VARCHAR2 and just concat values together.
In addition if you are doing that multiple times you're actually asking for some performance trouble.

I remembered reading a blog post by Carsten Czarski a while ago and got the inspiration from there.
He also reviewed my initial code and helped me make it better.

Maybe you have similar tasks at hand and can benefit from the code.
How it works and how to use is enclosed in the code comments.

Update: Thanks to the comment by SSentinel below I could clean up the code.

/**
* Procedure concatenates a VARCHAR2 to a CLOB.
* It uses another VARCHAR2 as a buffer until it reaches 32767 characters.
* Then it flushes the current buffer to the CLOB and resets the buffer using
* the actual VARCHAR2 to add.
* Your final call needs to be done setting p_eof to TRUE in order to
* flush everything to the CLOB.
*
* @param p_clob        The CLOB buffer.
* @param p_vc_buffer   The intermediate VARCHAR2 buffer. (must be VARCHAR2(32767))
* @param p_vc_addition The VARCHAR2 value you want to append.
* @param p_eof         Indicates if complete buffer should be flushed to CLOB.
*/
PROCEDURE clob_vc_concat( p_clob IN OUT NOCOPY CLOB
                        , p_vc_buffer IN OUT NOCOPY VARCHAR2
                        , p_vc_addition IN VARCHAR2
                        , p_eof IN BOOLEAN DEFAULT FALSE
                        )
AS
BEGIN
  
  -- Standard Flow
  IF NVL(LENGTHB(p_vc_buffer), 0) + NVL(LENGTHB(p_vc_addition), 0) < 32767 THEN
    p_vc_buffer := p_vc_buffer || p_vc_addition;
  ELSE
    IF p_clob IS NULL THEN
      dbms_lob.createtemporary(p_clob, TRUE);
    END IF;
    dbms_lob.writeappend(p_clob, length(p_vc_buffer), p_vc_buffer);
    p_vc_buffer := p_vc_addition;
  END IF;
  
  -- Full Flush requested
  IF p_eof THEN
    IF p_clob IS NULL THEN
       p_clob := p_vc_buffer;
    ELSE
      dbms_lob.writeappend(p_clob, length(p_vc_buffer), p_vc_buffer);
    END IF;
    p_vc_buffer := NULL;
  END IF;

END clob_vc_concat;

Wednesday, November 19, 2014

APEX IR XLSX Downloader V1.2.2

I have just published release 1.2.2 of my APEX IR XLX Downloader.
While attending the DOAG 2014 Conference Dietmar Aust was trying out my package and guess what...
He ran into a bug, so thanks Dietmar for reporting this.

Bugfix

  • Columns without help text break the download.
As always the source code can be found on GitHub.
ZIP files for all my GitHub projects can now be found on my GitHub Page.
For a small demo visit my Demo Application on apex.oracle.com.