Last Position

I have seen quite a few templates recently that are using our updatable variables to keep a track of the current record being processed. Regular readers will know my dislike for the updatable variables. Don't get me wrong, they have their place ... sometimes. It might be the way you set the dang things up that annoys me so much and I should take some blame for not chasing the dev team up to simplify the declaration and retrievel. Here's the code to define and assign a value to a variable x:

<?xdoxslt:set_variable($_XDOCTX, ’x’, 10)?>

now lets update the variable, adding 10 and then show it

<?xdoxslt:set_variable($_XDOCTX, 'x', xdoxslt:get_variable($_XDOCTX, 'x')+10)?>
<?xdoxslt:get_variable($_XDOCTX, 'x')?>

Too much right? Imagine using them to track the number of the current record. Folks are doing this in their templates. There is no need - the underlying standard for RTF templates is XSL and it has some neat native functions that can be used to track the current record and the last record.

- will return the current record counter. In XSL it starts at 1
- will return the last record counter

For some examples I indebted to Chris from UK Oracle Consulting. Chris will be out at Oracle World again this year so if you would like to hear how the Queen's English should be spoken drop by the demo grounds. I seem to have developed some mid-atlantic drawl - my family in the UK think Im lost to those danged Yankees! I do still pronounce butter with t's rather than d's but my kids are struggling to understand me when I ask for a 'glass of water' rather than 'wadder'. Enough language mangling already! Back to Chris' examples. He came up with the following XML data.


and some examples of position() and last()

.//LIST_G_ORDER_HEADERS/G_ORDER_HEADERS[position() != last()]/HEADER_ID RETURNS '123' and '456'

You'll have noticed the [ ] - these contain what are know as XPATH expressions. They are very powerful and well worth taking a look at - I'll try and cover XPATH more than we do in the documentation.
Leslie, our fab doc writer has just pointed out that I should have stated:
I will work with the doc writer to get some more in the documentation

I'll also try and get some more in here in the meantime :)

You can of course use them both in a conditional statement too:

<?if:position() = last()?>
Last Record!
<? end if ?>

Chris' third example is doing something similar but its using the condition within an XPATH expression, G_ORDER_HEADERS[position() != last()] - inside those square braces you do not need the 'if'.

So, throw out those updatable variable whenever you can and get native!


Hi Tim, Could you explain how the scope of updateable variables works? I am trying to use them to conditionally display something in the footer but can't seem to reference them. As far as I know I have to use them as position() and last() work within the current recordset. If I reference them within the footer they return the values for the main recordset, not for the transactions. I need to display certain values in the footer of the last page so am setting updateable variables within the transaction for-each loop to reference the current and last record. Cheers, Jon.

Posted by Jon Bartlett on August 21, 2008 at 04:20 PM MDT #

Hi Jon That would depend on where you declared them in the template. You are correct on the scope of position and last - they are limited to the current recordest being processed. What are you wanting to put in the footer on the final page? Tim

Posted by Tim on August 22, 2008 at 03:31 AM MDT #

Hi Tim, I Tried last() and found the result is different between R10. and R10. later. When I use last() in for-each-group , result is below... ========= A. BI Publisher -> It returns the number of all rows. B. BI Publisher / higher) -> It returns the distinct number that is grouped by some items. ========= Do y know wich is correct? -- result--- 10 110101 10 131102 10 212701 10 622101 10 633101 -- later result --- 5 110101 5 131102 5 212701 5 622101 5 633101 -- ========= ========= test data like below ========= 1107 1 R1G502 5002 ITA_TESTxxxxx 2008/08 01 TEST 110101 chach TEST1 0 2008-08-05T16:53:42.000+09:00 1198 2008-08-05T16:53:42.000+09:00 1198

Posted by kobito on August 24, 2008 at 10:22 PM MDT #

Hi Tim I tried last() and i found the defference of resutls between and later. Do y know which is correct? When i use lasr() in for-each-group, result is below. ==== A. BI Publisher -> It returns the number of all rows. B. BI Publisher / higher) -> It returns the distinct number that is grouped by some items. ==== ==== for-each-group:ROW;./ACCT_CODE last() ACCT_CODE end for-each-group ==== -- result--- 10 110101 10 131102 10 212701 10 622101 10 633101 -- later result --- 5 110101 5 131102 5 212701 5 622101 5 633101 est date is below. change # to < . and copy rows and modify ACCT_CODE. =============================== #ROWSET> #ROW> #REQUEST_ID>1107#/REQUEST_ID> #SORT_SEQUENCE>1#/SORT_SEQUENCE> #REPORT_CODE>R1G502#/REPORT_CODE> #SET_OF_BOOKS_ID>5002#/SET_OF_BOOKS_ID> #SET_OF_BOOKS_NAME>ITA_TESTxxxxx#/SET_OF_BOOKS_NAME> #ACCT_YYMM>2008/08#/ACCT_YYMM> #CORP_CODE>01#/CORP_CODE> #CORP_NAME>TEST#/CORP_NAME> #ACCT_CODE>110101#/ACCT_CODE> #ACCT_NAME>chach#/ACCT_NAME> #ACCT_CODE_FROM>#/ACCT_CODE_FROM> #ACCT_NAME_FROM>#/ACCT_NAME_FROM> #ACCT_CODE_TO>#/ACCT_CODE_TO> #ACCT_NAME_TO>#/ACCT_NAME_TO> #DIV_CODE_FROM>#/DIV_CODE_FROM> #DIV_NAME_FROM>#/DIV_NAME_FROM> #DIV_CODE_TO>#/DIV_CODE_TO> #DIV_NAME_TO>#/DIV_NAME_TO> #ACCT_DATE>#/ACCT_DATE> #DOC_SEQUENCE_VALUE>#/DOC_SEQUENCE_VALUE> #USER_JE_SOURCE_NAME>#/USER_JE_SOURCE_NAME> #FE_JE_NO>#/FE_JE_NO> #OPP_ACCT_CODE>#/OPP_ACCT_CODE> #OPP_ACCT_NAME> TEST1#/OPP_ACCT_NAME> #DR_AMOUNT>#/DR_AMOUNT> #CR_AMOUNT>#/CR_AMOUNT> #BALANCE_AMT>0#/BALANCE_AMT> #LINE_DESC>#/LINE_DESC> #DIV_CODE>#/DIV_CODE> #SUSP_ACCT_CLEAR_CODE>#/SUSP_ACCT_CLEAR_CODE> #SUSP_ACCT_CLEAR_NAME>#/SUSP_ACCT_CLEAR_NAME> #LAST_UPDATE_DATE>2008-08-05T16:53:42.000+09:00#/LAST_UPDATE_DATE> #LAST_UPDATED_BY>1198#/LAST_UPDATED_BY> #CREATION_DATE>2008-08-05T16:53:42.000+09:00#/CREATION_DATE> #CREATED_BY>1198#/CREATED_BY>#/ROW>

Posted by kobito on August 24, 2008 at 10:42 PM MDT #

Looks like the Yanks are not going to give Girardi a new contract until after the world series.

Posted by Jaime Nejman on August 24, 2010 at 02:00 AM MDT #

Hi All,I neeed the Following code to be printed line by line if any one one condition istrue...That maens if first line is true and 2nd and 3rd line lines are false and if 4th line is true then it should automatically be placed below Addrln1....This Should be true in all statements
<?xdofx:If A.ADDR_LN2!= '' AND A.NAME1 = '' Then A.ADDR_LN2 end If?>
<?xdofx:If A.ADDR_LN3!= '' Then A.ADDR_LN3 end If?>
<?xdofx:If A.ADDR_LN4!= '' AND A.ADDR_LN4!='United States' Then A.ADDR_LN4 end If?>
<?xdofx:If A.ADDR_LN5!= '' AND A.ADDR_LN5!='United States' Then A.ADDR_LN5 end If?>
<?xdofx:If A.ADDR_LN6!= '' AND A.ADDR_LN6!='United States' Then A.ADDR_LN6 end If?>
<?xdofx:If A.ADDR_LN7!= '' AND A.ADDR_LN7!='United States' Then A.ADDR_LN7 end If?>
<?xdofx:If A.ADDR_LN8!= '' AND A.ADDR_LN8!='United States' Then A.ADDR_LN8 end If?>
<?xdofx:If A.NAME1!= '' Then 'ATTN: '|| A.NAME1 end if?>

Posted by Nikhil on January 18, 2012 at 01:19 AM MST #

Post a Comment:
  • HTML Syntax: NOT allowed

Follow bipublisher on Twitter Find Us on Facebook BI Publisher Youtube ChannelDiscussion Forum

Join our BI Publisher community to get the most and keep updated with the latest news, How-to, Solutions! Share your feedback and let us hear your voice @bipublisher on Twitter, on our official Facebook page, and Youtube!


« April 2014