These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Tables and Subtotals

BryanC
Registered: Jan 31 2008
Posts: 27

Hi All,

I'm pretty new to LiveCycle and Adobe form design in general, so I apologize if this is a simply answered question.

If I have a table of data (that I'll be passing to the form through the built in SAP interface) and I need to display dynamic subtotals, how do I do that?

Basically, I need to display a subtotal record for each new Sales Document in the table. The table has data at the sales document item level, so this subtotal record would be popping up dynamically based on the data.

Any help pointing me in the right direction would be very much appreciated.

My Product Information:
LiveCycle Designer, Windows
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
The easiest way is to use FormCalcu, there is a Sum() function. This function uses what's call a SOM expression to identify the fields that need to be summed. How the SOM expression is build depends entirely on your form design. The form hierarchy and the names of the subforms and fields is all important. You can read about using this function in the FormCalc Reference. Look for it on this web page.

http://kb.adobe.com/selfservice/viewContent.do?externalId=330467&sliceId=1

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

BryanC
Registered: Jan 31 2008
Posts: 27
Thanks for the pointer thomp, I think I almost have it figured out.

I'm still having some trouble with the finer points though. I've got the totals row showing when I want it to, but this value field is not calculating like I want it to. Any suggestions?

//each occurance of sales order item number should give me total rows in the tablevar total = Count(data.BodyPage.PageFlow.LineItems.Item.Row2[*].POSNR_VA) // this should give me the current sales order numbervar firstSO = data.BodyPage.PageFlow.LineItems.Item.Row1.VBELN_VA.value.#text //do once for each line in the tablefor i = 0upto total

step 1 do// get the value of the sales order number for the table row that matches the current loop pass var secondSO = data.BodyPage.PageFlow.LineItems.Item.Row1[i].VBELN_VA.value.#textvar secondSOTotal = data.BodyPage.PageFlow.LineItems.Item.Row1[i].BRGEW.value.#text// if the two are equal, increment our subtotal if (firstSO == secondSO) then$.value.#float = $.value.#float + secondSOTotalendif

endfor

This script is in a subtotal line that is only shown at the end of each sales order. The math of the output is not working in a way that makes sense to me - it looks like this:

S01 | ITEM1 | 100
S01 | ITEM2 | 102
*Subtotal | 204*
S02 | ITEM1 | 103
S02 | ITEM2 | 104
*Subtotal | 311*
S03 | ITEM1 | 104
S03 | ITEM2 | 106
*Subtotal | 316*
S04 | ITEM1 | 107
*Subtotal | 214*

It should look like this:

S01 | ITEM1 | 100
S01 | ITEM2 | 102
*Subtotal | 202*
S02 | ITEM1 | 103
S02 | ITEM2 | 104
*Subtotal | 207*
S03 | ITEM1 | 104
S03 | ITEM2 | 106
*Subtotal | 210*
S04 | ITEM1 | 107
*Subtotal | 107*

So it seems there are 2 different issues here

1) It looks like it's skipping the first item in the table when doing the subtotal calculation
2) For each row where the subtotal line shows up, it's double counting

What am I doing wrong?

Thanks in advance, and let me know if I've been unclear.
BryanC
Registered: Jan 31 2008
Posts: 27
I've got the double counting fixed. I changed the for statement to
for i = 1
from 0. Now the only issue left is why I can't get the first line included in the total. Anyone have any thoughts?
BryanC
Registered: Jan 31 2008
Posts: 27
Another update - I think I figured out why it's not working. However, I'm totally lost on how I'm going to fix it.

I think the problem is, when I try to access row number [0], which should be the first row in the table, it is accessing the current row. Consequently, the first row is not being accessed ever, and when I look at row [0], it double counts the current line.

I can think of a couple of hacks (like make sure that the first row the DB passes the form is blank, hide blank lines, and start the loop from index 1 - but wow, that's ugly).


HELP! How do I access the first row of the table from another row in the table?
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
Bryan, You have a very complex set of code here. This is beyond the scope of this forum and I thinks its probably overly complex for what you want to do. We don't know anything about your form, it's structure, or what it is you are trying to do with it, and there is not enough information here to figure it out. Nor do I want to figure it out. This forum is for simple to the point questions. Like the last line of your last post, it's perfect.

But other than that question it looks like you need either some training or to hire a consultant.

About the last question:
"How do I access the first row of the table from another row in the table?"

Tables in general are a messy way to organize your form. If you look in the hierarchy window you'll see that there are unnecessary subforms and levels of hierarchy. Cleaning this up will make scripting easier.

Regardless, the easy way to get the absolute path to the field you want to access is to click on it, then open the scripting window and select any event. The absolute SOM path to that element will appear at the top of the scripting window. Since the table element you are referencing the first row from shares many of the same path components you can use a relative path.

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

BryanC
Registered: Jan 31 2008
Posts: 27
Thom,

I'm sorry if I was overly complex and confusing. Obviously I thought I was being clear, however it is apparent that this was not the case.

Let me try one last time.

The table in question will be dynamic in size - the check box "Repeat Section for Each Data Item" is checked in the object/binding tab.

Let's say the table has two fields, FieldA and FieldB. There could be any number of rows in the table.

My issue is not accessing FieldA of the table from FieldB. My issue is accessing FieldA[0] from FieldA[1]. I have no problem accessing FieldA[1] from FieldA[2], but when I try to access field FieldA[0] it always hits the current table row, not the first table row.

Does that make sense? If not, I've obviously come to the wrong place for help. Not because you all don't have the expertise, but because I can't find a way to describe my problem to you.

Thanks in advance, and again I apologize for being confusing.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
Ok, so initially your form is empty and then data is imported into it by some means. The data causes the table to grow rows to match the imported data. Is this correct?

You have a script in one of the fields in the table row that needs to access the first row of the table. On which event is this script run? From your previous posts I'll assume that it's the calculation event.

I have an order form with repeatable rows for each oder item. The row subtotal field has a SOM hierarcy like this.

ItemList.ItemDetail[*].Amount

Where "ItemDetail" is the repeated subform.

The FormCalc calculation event looks like this:

Price * Quantity

very simple. If I want to access the first row in the calculation I can do this.

Price * Quantity + ItemDetail[0].Amount

If I load an "XDP" file containing several lines of data, the calculations all work out correctly. There is no problem accessing the first row in this way.

Nowhere in any of your posts do you describe your process or show the code containing a reference to the first row. Without this info there is no way to give you a more specific answer.

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

BryanC
Registered: Jan 31 2008
Posts: 27
thomp wrote:
Ok, so initially your form is empty and then data is imported into it by some means. The data causes the table to grow rows to match the imported data. Is this correct?
Yes, this is correct.

thomp wrote:
You have a script in one of the fields in the table row that needs to access the first row of the table. On which event is this script run? From your previous posts I'll assume that it's the calculation event.
I had the script in the initialize event - I moved it to the calculate event, but that didn't help.

thomp wrote:
Nowhere in any of your posts do you describe your process or show the code containing a reference to the first row. Without this info there is no way to give you a more specific answer.
In the code in my first post, during the first pass of the for loop, i will be equal to 0. When the below lines are executed during that first loop pass, it is looking at the first row.

       var secondSO = data.BodyPage.PageFlow.LineItems.Item.Row1[i].VBELN_VA.value.#textvar secondSOTotal = data.BodyPage.PageFlow.LineItems.Item.Row1[i].BRGEW.value.#text

That being said - let me see if I can paint a better picture of what is going on here. I'm going to try to simplify as much as I can - It is a very complex business requirement, and I don't want to confuse with too many details.

As you mentioned, the form is initially empty, and data is passed to it by an SAP system. I am passing delivery line items to the form. My form is structured like this:

LineItems
| HeaderRow
| Items [i](this is a grouping, and each occurance of the grouping maps to a record being passed to the form)[/i]
| | Row1 - VBELN_VA, BRGEW [i](sales order number and weight) [/i]
| | Row2 - POSNR_VA [i](sales order item)[/i]
| | Row3 - No Data worth mentioning here
| | FooterRow - SumGWeight [i](this field is the one that contains the script in my first post)[/i]

Two things that I should perhaps mention:
1) the footer row is not defined as a footer row in the Object/Row/Type field - it's defined as a body row and is part of the "Items" grouping, because I might need it to show up per line item.
2) there is a script in the FooterRow initialize event that hides the entire row if the current sales order number <> next sales order number in the table.What I am trying to get to is a subtotal by sales order number. If I just write
   Sum LineItems.Row1[*].BRGEW
as I understand it, I will get a total of all records. So, I came up with the code in my first post. Basically, what it should do is compare the current record with every other record in the table to see if the sales order number is the same. If it is, then we add that value to the current value.

Does that make sense? Is there anything I can clarify? Thanks for being patient.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
You need to hire a consultant

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

Gokul
Registered: Feb 26 2008
Posts: 2
Hi,

I am working as a software professional in one of the MNC which develops different banking products such as PB (Personal banking) BB (Business Banking) CB (Corporate Banking) etc.

At present I am working on ESSP Project (ESSP Enterprise sales and service product it's a banking product used at call centers and branch level as well)

I have a problem relating to PDF forms. In ESSP when a new account is to be open
Then we need to attach 3-4 forms (all are in PDF format) per account to get customer information we called it as NAO (New Account Opening) process.

The Problem that I am facing is as under and it's related to adobe reader 8.0

In the NAO process, For e.g. suppose a savings account is to be open and it requires 3-4 forms to be get fill up then for that we have to follow following steps.

Step 1) Select Product and then click on Forms
Step 2) Select all the forms under that product and click Fill Forms
Step 3) it will show the list of forms that we selected click on Continue
Steps4) upon clicking Continue button the first form in the list is populated in the IE
Browser, fill up that form and click Next button to fill up another form in the list.
Step 5) but upon clicking on Next It throws Exception Invalid FDF

Well One Important Thing that I want to add here is in the given example every thing is working fine if I use adobe reader 6.0 instead of adobe reader 8.0.

Is this a known problem and if so, is there a solution? What Version of Adobe reader (afetr 8.x) gives the fully support to javascript?What changes I need to do to work fine with adobe reader 8.0?

Any help is greatly appreciated, thanks in advance.
BryanC
Registered: Jan 31 2008
Posts: 27
thomp wrote:
You need to hire a consultant
Thanks anyway.

I'm really surprised that no one here has run into this before. It seems like a basic business requirement to me.
scottsheck
Registered: May 3 2007
Posts: 138
Byran,

When do you insert the subtotal rows, after all of the line items have been inserted or each time you come to where you want to add the subtotal?
BryanC
Registered: Jan 31 2008
Posts: 27
Scott -

I'm not inserting the subtotal row. The subtotal row is part of the items grouping, and is created once for each data item.

However, I've inserted a script in the initialize event of 'FooterRow' that hides the row if the current sales order number is = to the next sales order number.

if (data.BodyPage.PageFlow.LineItems.Item.Row1.VBELN_VA.value.#text ==data.BodyPage.PageFlow.LineItems.Item.Row1[+1].VBELN_VA.value.#text) then$.presence = "hidden"else$.presence = "visible"endif

Does that answer your question?
scottsheck
Registered: May 3 2007
Posts: 138
I see, I reread your previous emails. It looks like your first post should work. It should read the 0's element. In the Heirchary view, did you verify that the first item does start at 0?

Also, do you initialize your "$.value.#float" do zero somewhere? Maybe it's double-counting because it's not initialized to zero and therefore it's the current records value.
scottsheck
Registered: May 3 2007
Posts: 138
Also, since it's only very first line item that it seems to skip the first item, maybe you can stick in a dummy line item as a temporary solution until you can figure it out.
BryanC
Registered: Jan 31 2008
Posts: 27
scottsheck wrote:
I see, I reread your previous emails. It looks like your first post should work. It should read the 0's element. In the Heirchary view, did you verify that the first item does start at 0?
Yes, as far as I can tell the item should start at 0. Keep in mind, none of these are explicitly named [0], that is because the table grows to accommodate the data.

scottsheck wrote:
Also, do you initialize your "$.value.#float" do zero somewhere? Maybe it's double-counting because it's not initialized to zero and therefore it's the current records value.
Tried that, no luck.

scottsheck wrote:
Also, since it's only very first line item that it seems to skip the first item, maybe you can stick in a dummy line item as a temporary solution until you can figure it out.
That would work - if I set i = 1 rather than i = 0 at the beginning of the for loop, make sure the first line of the table is always empty, and make sure the first line of the table is hidden, it would work fine. I did think of that, but it seems a rather inelegant solution. You know what I mean?

Thanks for taking the time.
scottsheck
Registered: May 3 2007
Posts: 138
Sorry, I had just realized that your table is built on the fly so you can't see the heirarchy. I agree it's in inelegant solution, just thought I'd temporarily get you a short term fix so you could at least get it working and start using your PDF.

Not that you really need to debug the double-counting part, but maybe it can't hurt, so what if you create a temporary row4 which contains a text field and concatenate the row number and the value that you are summing. Then we can really see what the loop is summing. From your first post, it looks like it's doing exactly what you're suspecting, but you know how programming can be.
BryanC
Registered: Jan 31 2008
Posts: 27
scottsheck wrote:
Sorry, I had just realized that your table is built on the fly so you can't see the heirarchy. I agree it's in inelegant solution, just thought I'd temporarily get you a short term fix so you could at least get it working and start using your PDF.
Yep. Fortunately, we're months away from having to be live with this thing. It's actually a proof-of-concept to show that Adobe Forms will meet our business requirements. If I can't pull it off we'll likely be using SAP SmartForms for a lot of our output documents.

scottsheck wrote:
Not that you really need to debug the double-counting part, but maybe it can't hurt, so what if you create a temporary row4 which contains a text field and concatenate the row number and the value that you are summing. Then we can really see what the loop is summing. From your first post, it looks like it's doing exactly what you're suspecting, but you know how programming can be.
That's a good idea on the debugging. Off to try it, thanks.
BryanC
Registered: Jan 31 2008
Posts: 27
OK, so the results of the debug code were about what I was expecting.

I stuck this code in the if statement in the loop.

		data.BodyPage.PageFlow.LineItems.Item.FooterRow.Unused.value.#text =Concat(data.BodyPage.PageFlow.LineItems.Item.FooterRow.Unused.value.#text,"|",secondSOTotal,"-",i)

I actually have a field that is called Unused in the footer row that I made use of for this exercise.

Results:

S01 | ITEM1 | 100
S01 | ITEM2 | 102
Subtotal | 204 [b]|102.000-0|102.000-1[/b]
S02 | ITEM1 | 103
S02 | ITEM2 | 104
Subtotal | 311 [b]|104.000-0|103.000-2|104.000-3[/b]
S03 | ITEM1 | 105
S03 | ITEM2 | 106
Subtotal | 317 [b]|106.000-0|105.000-4|106.000-5[/b]
S04 | ITEM1 | 107
Subtotal | 214 [b]|107.000-0|107.000-6[/b]

As I suspected, during the first pass of the loop, when i=0, the form is looking at the current row, not the first row.
scottsheck
Registered: May 3 2007
Posts: 138
Great, this helps very much. It seems like referencing the zero element is 99% of the problem except for the 1st line item. I always wondered before why the loop started at 0; I thought possibly you had a subtable within a table.

I think part of the problem is that the loop needs to start at a nonzero number (except for the 1st lineitem), that is, at correct the starting row instead.

But if you can't find a way to determine this starting row, how about using your relative addressing in your loop going backward until you find a different order number (like in your footer script).
BryanC
Registered: Jan 31 2008
Posts: 27
I'm about to head out for the day - I'll sleep on that and see what I can do in the morning.

Thanks again for your help, I really appreciate it.
BryanC
Registered: Jan 31 2008
Posts: 27
OK, Did a simple test - took the loop out and just hardcoded it to look at the line previous using :

var firstSO = data.BodyPage.PageFlow.LineItems.Item.Row1.VBELN_VA.value.#text var secondSO = data.BodyPage.PageFlow.LineItems.Item.Row1[-1].VBELN_VA.value.#textvar secondSOTotal = data.BodyPage.PageFlow.LineItems.Item.Row1[-1].BRGEW.value.#textvar firstSOTotal = $.value.#float// if the two are equal, increment our subtotal if (firstSO == secondSO) then$.value.#float = firstSOTotal + secondSOTotalendif

Sure enough, the second row of the table (where ...Row1[-1]... would equate to ...Row1[0]...) looked at itself rather than the first table index.

Output:
S01 | ITEM1 | 100
S01 | ITEM2 | 102
Subtotal | 102 [b] Note this is the value from record 2, not record 1[/b]
S02 | ITEM1 | 103
S02 | ITEM2 | 104
Subtotal | 103 [b] Note here it hits record 3, or index - 1, as we would expect[/b]
S03 | ITEM1 | 105
S03 | ITEM2 | 106
Subtotal | 105
S04 | ITEM1 | 107

I'm really starting to think that this is either a bug, or broken as designed. I wonder if I rewrote it in javascript it would work.
scottsheck
Registered: May 3 2007
Posts: 138
I tend to agree with you. Maybe formcalc does have a problem in this case accessing the 0's element.
BryanC
Registered: Jan 31 2008
Posts: 27
ARG! I'm so close.

On the plus side, I'm pretty sure that what I'm trying to do is possible using Javascript. I know this because there is a second field (that I haven't mentioned previously) that just counts line items per sales order. I didn't mention it before because the script will be nearly identical and it was easier to display the issue using the weight field. I've got this count field working perfectly. Here is the code:

var SalesOrders = xfa.resolveNodes("data.BodyPage.PageFlow.LineItems.Item.Row1[*].VBELN_VA");var currentIndex = this.parent.index;var SalesOrder1 = SalesOrders.item(currentIndex).rawValue;var records = SalesOrders.length;for (var i = 0; i <= records; i++){var SalesOrder2 = SalesOrders.item(i).rawValue;if (SalesOrder1 == SalesOrder2)this.rawValue++;}

It works just like you would expect it to.

HOWEVER, on my weight subtotal field, I'm only getting 0.000 in every record. What am I doing wrong in the Javascript below?

var SalesOrders = xfa.resolveNodes("data.BodyPage.PageFlow.LineItems.Item.Row1[*].VBELN_VA");var Weights = xfa.resolveNodes("data.BodyPage.PageFlow.LineItems.Item.Row1[*].BRGEW");var currentIndex = this.parent.index;var SalesOrder1 = SalesOrders.item(currentIndex).rawValue;var records = SalesOrders.length;var subTotal; for (var i = 0; i <= records; i++){var SalesOrder2 = SalesOrders.item(i).rawValue;if (SalesOrder1 == SalesOrder2){subTotal = subTotal + Weights.item(i).rawValue;} } this.rawValue = subTotal;

Thanks!
scottsheck
Registered: May 3 2007
Posts: 138
Have you at least verified it's indeed getting into the IF statement?
BryanC
Registered: Jan 31 2008
Posts: 27
Yes. It reaches and evaluates the if statement without issue. If I change the summation to
this.rawValue = Weights.item(i).rawValue;
It works just fine, and puts the weight from the last record with a matching sales order number.

It's only when I try to calculate the running total by using
subTotal = subTotal + Weights.item(i).rawValue;...

this.rawValue = subTotal;

That I can't get it to work. It's got to be something simple that I'm not seeing.

Thanks

Also, since we're now to page 2, here's the latest version of the script. This way we don't have to flip between pages to look at the whole thing.

var SalesOrders = xfa.resolveNodes("data.BodyPage.PageFlow.LineItems.Item.Row1[*].VBELN_VA");var Weights = xfa.resolveNodes("data.BodyPage.PageFlow.LineItems.Item.Row1[*].BRGEW");var currentIndex = this.parent.index;var SalesOrder1 = SalesOrders.item(currentIndex).rawValue;var records = SalesOrders.length;var subTotal; for (var i = 0; i <= records; i++){var SalesOrder2 = SalesOrders.item(i).rawValue;if (SalesOrder1 == SalesOrder2){subTotal = subTotal + Weights.item(i).rawValue;} } this.rawValue = subTotal;
scottsheck
Registered: May 3 2007
Posts: 138
Initialize your variable subTotal using:

var subTotal=0;



As a test, I created a new form with the following javascript and it results in 10. If I don't initialize, then I get zero.

var subTotal=0;
for (var i = 0; i <= 9; i++)
{
subTotal = subTotal + 1;
}
this.rawValue = subTotal;



By the way, did switching to javascript solve your zero element problem?
BryanC
Registered: Jan 31 2008
Posts: 27
Got it!

Oddly enough, this last problem had nothing to do with the script and everything to do with the fact that the BRGEW column was defined as text rather than numeric. It let me assign text to a numeric field, but it wouldn't let me do the math.

And yes, switching to javascript did indeed fix my zero element problem.

Scott, if you're ever in Central Virginia, the first round is on me. Thanks so much for your help.

The final code, that actually worked, just in case someone comes searching for a similar problem. We wouldn't want them to just give up and hire a consultant...

var SalesOrders = xfa.resolveNodes("data.BodyPage.PageFlow.LineItems.Item.Row1[*].VBELN_VA");var Weights = xfa.resolveNodes("data.BodyPage.PageFlow.LineItems.Item.Row1[*].BRGEW");var currentIndex = this.parent.index;var SalesOrder1 = SalesOrders.item(currentIndex).rawValue;var records = SalesOrders.length; for (var i = 0; i < records; i++){var SalesOrder2 = SalesOrders.item(i).rawValue;if (SalesOrder1 == SalesOrder2){this.rawValue += Weights.item(i).rawValue;} }
BryanC
Registered: Jan 31 2008
Posts: 27
Interesting.

I contacted Stef Cameron via his blog - he asked me to try to recreate the issue in another, simpler form that I can send him. So far I've been unable to do so with very simple form reading an XML file. I need to try to make a more complex one, but haven't had the time yet. Unfortunately, I can't just send him the one I actually worked on - it's stored in the SAP system.
BryanC
Registered: Jan 31 2008
Posts: 27
Just sent you an e-mail.

Thanks