Jump to content

Recommended Posts

Posted

Is there some validation check, property setting, trigger or whatever the wording might be to let FusionPro understand when an OverFlow Page becomes necessary and when it is not?

 

If I have a 3 page document with page 1 as my main page containing a multi-paragraph letter and other graphics, can I have an OverFlow Page as page 2 and then an "unused" Blank Page as page 3. If the text from the first page is long enough to cause the OverFlow Page to activate with all its graphics and text flows, then page 3 (blank) will remain unused. However if the text from page 1 is not long enough to cause the OverFlow Page to activate then a rule within OnRecordStart will cause the unused page 3 (blank) to be set to true and activate that as my second page.

 

Another thought (question) would be can I program conditional OverFlow Pages? If this condition is true then activate OverFlow Page 1, else activate OverFlow Page 2?

.

Posted (edited)

As far as built in functionality for determining when an OverFlow page is used, I don't think there is any. I tried utilizing FusionPro.Composition.totalPages & FusionPro.Composition.GetBodyPageUsage but those didn't seem to work. That being said, it seems like you could determine if an OverFlow page is needed by using text measure on the frame that's set to overflow to another page and turn on the third page conditionally from OnRecordStart like so:

function useOverFlow(frameName){
   var text = FindTextFrame(frameName).content;
   var tm = new FusionProTextMeasure;
   tm.useTags = true;
   tm.maxWidth = GetSettableTextWidth(FindTextFrame(frameName));
   tm.CalculateTextExtent(text);
   return tm.textHeight > GetSettableTextHeight(FindTextFrame(frameName));
}

FusionPro.Composition.SetBodyPageUsage("Page3",useOverFlow("Frame Name"));

 

I guess the caveat here is that the "content" of the text frame literally returns your variable rule names rather than the contents that the rules generate. Meaning, if your text frame contains rule (for example: "My Table") that you've created to insert a table (for instance) the markup looks like:

<variable name="My Table">

so in order to get an accurate measurement of the height, we'd have add this line to the function:

function useOverFlow(frameName){
   var text = FindTextFrame(frameName).content;
   [color="Red"]text = text.replace(/<variable name="([^"]*)">/g,function(a,b){return RuleOrField(b);});[/color]
   var tm = new FusionProTextMeasure;
   tm.useTags = true;
   tm.maxWidth = GetSettableTextWidth(FindTextFrame(frameName));
   tm.CalculateTextExtent(text);
   return tm.textHeight > GetSettableTextHeight(FindTextFrame(frameName));
}

Edited by step
Added more detail
  • 2 months later...
Posted

STEP,

 

It's been a while since you posted this and I've just now been able to get around to testing your suggestion. First of all I want to thank you...your suggestion worked...almost. For some reason when I used your statement for

FusionPro.Composition.SetBodyPageUsage("Page3",useOverFlow("Frame Name"));

it didn't work as expected. It activated Page3 at the same time the OverFlow page was activated. I had to "negate" the rule and program it as

FusionPro.Composition.SetBodyPageUsage("Page3",!(useOverFlow("Frame Name")));

before it would work correctly.

 

Close enough for me. :D

 

Now that I have it functioning like I need it to I went back to take a look at what you did. I understand all the steps except the rule that contains the regular expression string. What is that string actually processing and how is it affecting the overall string that is being "replaced" in that rule command. Also what is the "function(a,b)" part?

 

You've given me the fish...and I'm grateful...but now I'd like to get one on my own.

.

Posted (edited)
If the text from the first page is long enough to cause the OverFlow Page to activate with all its graphics and text flows, then page 3 (blank) will remain unused. However if the text from page 1 is not long enough to cause the OverFlow Page to activate then a rule within OnRecordStart will cause the unused page 3 (blank) to be set to true and activate that as my second page.

If I'm understanding correctly, you don't need to "check" whether an Overflow page is used, or write any JavaScript code at all, to accomplish this. All you need to do is change Page 3 to be an Overflow page. Then, in the Overflow Options dialog, specify Page 2 as "New Left Page," Page 3 as "New Right Page," and set the "Add Pages" mode to "So Last Added Page Is Odd." (Or maybe "So Last Added Page Is Even;" you may need to experiment a bit.)

 

Or, even easier: Don't use Overflow pages at all. Just use two Body pages, and flow the text from one to the other. If the content doesn't flow to the second page, then that page will be blank, right?

Another thought (question) would be can I program conditional OverFlow Pages? If this condition is true then activate OverFlow Page 1, else activate OverFlow Page 2?

The only way to do this is to have two separate sets of Body and Overflow pages, and then use FusionPro.Composition.SetPageUsage to activate whichever Body Page you need based on the condition in OnRecordStart.

Edited by Dan Korn
Posted
For some reason when I used your statement for
FusionPro.Composition.SetBodyPageUsage("Page3",useOverFlow("Frame Name"));

it didn't work as expected. It activated Page3 at the same time the OverFlow page was activated. I had to "negate" the rule and program it as

FusionPro.Composition.SetBodyPageUsage("Page3",!(useOverFlow("Frame Name")));

before it would work correctly.

Yeah, sorry about that. I thought you wanted the 3rd page to print only when the overflow page was being used. Whoops.

 

Now that I have it functioning like I need it to I went back to take a look at what you did. I understand all the steps except the rule that contains the regular expression string. What is that string actually processing and how is it affecting the overall string that is being "replaced" in that rule command. Also what is the "function(a,b)" part?

 

You've given me the fish...and I'm grateful...but now I'd like to get one on my own.

.

The function (useOverFlow) is being passed the name of a frame and from that it pulls in (quite literally) the contents of that frame. If you've ever created a "formatted text" resource with rules or fields and then view the source it will look something like this:

<p style="(no style)" br="false" override="true" quad="L" findent="0" lindent="0" rindent="0" leadbefore="0" leadafter="0" widows="2" kerning="true" hyphenate="true" skipifempty="false" skipifemptyvar="false" noparabreakoncopyfit="false"><tracking newsize="0"><f name="Helvetica"><z newsize="12.0"><color name="Black">This is my rule: <variable name="My Rule">

 

And that's essentially the format that the text frames are in as well. The nice thing about using the contents like that, is that you are able to pass tagged text to the TextMeasure object in the "useOverFlow" function rather than specifying every font, leading, etc. The down side is that TextMeasure is interpreting the "variable" tags literally rather than showing the actual content of the variable. So if you had a rule that was returning tagged text, the measurement would be off. So the replace string is searching the contents of the frame for those tags and then replacing them with their actual content using the "FieldOrRule()" function.

 

As far as the RegExp goes, it's looking (globally) for '<variable name"' followed by anything that's not a quote until it gets to a ">' and it's capturing everything inside the quotes:

 

[color="red"][^[/color]"[color="red"]][/color]

Matches: a character that isn't a "

 

[^"][color="Red"]*[/color]

Matches: as many characters that aren't quotes in a row as it can

 

[color="red"]([/color][^"]*[color="red"])[/color]

Captures: as many characters that aren't quotes in a row as it can

 

Then the replace function is basically taking the found match and piping it into this function with params 'a' and 'b':

function(a,b){
return RuleOrField(b);
}

Where 'a' is the whole match ('<variable="name">') and 'b' is the captured element ( denoted by the parentheses in the RegExp – name).

 

Hopefully my explanation didn't make that more confusing :)

Posted
Then the replace function is basically taking the found match and piping it into this function with params 'a' and 'b':

function(a,b){
return RuleOrField(b);
}

Where 'a' is the whole match ('<variable="name">') and 'b' is the captured element ( denoted by the parentheses in the RegExp – name).

Using a function as the second parameter to String.replace to handle matched substrings is detailed here:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter

Posted
If I'm understanding correctly, you don't need to "check" whether an Overflow page is used, or write any JavaScript code at all, to accomplish this. All you need to do is change Page 3 to be an Overflow page. Then, in the Overflow Options dialog, specify Page 2 as "New Left Page," Page 3 as "New Right Page," and set the "Add Pages" mode to "So Last Added Page Is Odd." (Or maybe "So Last Added Page Is Even;" you may need to experiment a bit.)

 

Or, even easier: Don't use Overflow pages at all. Just use two Body pages, and flow the text from one to the other. If the content doesn't flow to the second page, then that page will be blank, right?

Actually Dan what I needed was a conditional set of Overflow pages. Each document (record) MUST BE two pages long. The only "variable element" in the document is a table that grows as more items are purchased by each customer in the data file (up to 20 items). As the table grows it will push the page to a second side. On that second side there are other disclaimers and element items other than just the letter that are to be duplicated on the back as they appear on the front. That was the problem that I had...knowing when the table would grow large enough to cause an overflow to the second side to occur. When the overflow was needed then put the disclaimers and graphics on the back in their proper places while the letter would flow to the back as well. If the letter did not need to overflow and all fit on the front then only a blank page with a page counter at the bottom left was needed. No graphics, no disclaimer, no extras.

 

There are several "versions" of the base letter and each version would overflow at a different length of the table and sometimes a table entry itself would wrap around in the row cell because the entry was so long to need more space than the single cell line would allow making the table slightly deeper. I attempted to come up with some sort of formula to count a certain number of lines for each letter, table and other elements and when a "page line limit" was reached then I would turn on and turn off the proper back page. I've enclosed a sample of two records...one that overflows and one that doesn't.

 

Everything would have been so much easier if there was some type of rule, frame property or check to determine if the "Overflow Page" or even the overflow frame/text box on the page was activated or not. STEP's formula at least gives me something that is measurable for a conditional statement. It may not be "perfect"...but I'm not doing government work here. :rolleyes:

 

Thank you for your help STEP.

.

Posted
Actually Dan what I needed was a conditional set of Overflow pages. Each document (record) MUST BE two pages long. The only "variable element" in the document is a table that grows as more items are purchased by each customer in the data file (up to 20 items). As the table grows it will push the page to a second side. On that second side there are other disclaimers and element items other than just the letter that are to be duplicated on the back as they appear on the front. That was the problem that I had...knowing when the table would grow large enough to cause an overflow to the second side to occur. When the overflow was needed then put the disclaimers and graphics on the back in their proper places while the letter would flow to the back as well. If the letter did not need to overflow and all fit on the front then only a blank page with a page counter at the bottom left was needed. No graphics, no disclaimer, no extras.

I see. I'm just brainstorming.

 

Your original post mentioned a completely blank third page. Another way you could accomplish that is to use Imposition, and set the Pages Per Record to 2, and for any records that fall short of two pages, blank pages should be automatically inserted.

There are several "versions" of the base letter and each version would overflow at a different length of the table and sometimes a table entry itself would wrap around in the row cell because the entry was so long to need more space than the single cell line would allow making the table slightly deeper. I attempted to come up with some sort of formula to count a certain number of lines for each letter, table and other elements and when a "page line limit" was reached then I would turn on and turn off the proper back page. I've enclosed a sample of two records...one that overflows and one that doesn't.

Thanks, the output is worth 1000 words.

 

Usually, something like this is accomplished with "footer" rows in the table. When the table continues to a new column or frame, the header and footer rows are repeated. (Of course, the footer rows "flow" with the rest of the table, and are not "fixed" at a particular position on the page as in your example.)

 

We've seen jobs such as pharmaceutical ads and inserts, which have very strict requirements for footnotes to be placed on the same page as the text which references them. But in your example output, it seems that the footnotes on the second page aren't relevant to anything on that page. So the requirement seems strange to me, but I guess the customer is always right.

Everything would have been so much easier if there was some type of rule, frame property or check to determine if the "Overflow Page" or even the overflow frame/text box on the page was activated or not.

The problem is that OnRecordStart is just as its name implies: It's run before the record is composed, and before all other rules are evaluated to determine what gets typeset. Perhaps another callback is needed to "hook" into the composition at the time that Overflow pages are added, kind of like OnCopyfit. Although, quite frankly, I've very rarely heard of a need for this. On the other hand, jobs keep getting more complex.

Posted

Now I'm really puzzled. Even more than normal.

 

I've implemented all the suggestions that you and STEP have mentioned in this forum and I have a template that works but only when I do it one up. Again, as soon as I put any kind of imposition on this FusionPro encounters a Fatal Error and stops (on both Server and Desktop versions). I get the dreaded Error Code 1096. The .msg file mentions something about not being able to implement a SetPageUsage command so FP doesn't know what to impose.

 

If it didn't know what SetPageUsage to use on the 2-up why oh why did it know what SetPageUsage to use on the 1-up from the same file?

 

I would like to send the file to you but it is way too big for this forum space to allow.

 

Dan, I'm sending this to FusionProSupport@PTI.com via email and will give it the name "AGL_LetterFiles". Will you be able to take a look at it in the near future?

.

Posted
Now I'm really puzzled. Even more than normal.

 

I've implemented all the suggestions that you and STEP have mentioned in this forum and I have a template that works but only when I do it one up. Again, as soon as I put any kind of imposition on this FusionPro encounters a Fatal Error and stops (on both Server and Desktop versions). I get the dreaded Error Code 1096. The .msg file mentions something about not being able to implement a SetPageUsage command so FP doesn't know what to impose.

It would be helpful if you could at least post the actual error message instead of paraphrasing it.

 

Also, if your signature is accurate, you're using a fairly old version of FusionPro. I know there have been fixes for some bugs where trying to add pages would result in the 1096 error in FusionPro 9.

If it didn't know what SetPageUsage to use on the 2-up why oh why did it know what SetPageUsage to use on the 1-up from the same file?

That's hard to say from the information you've provided so far.

I would like to send the file to you but it is way too big for this forum space to allow.

I would think you could create a minimal example, without much in the way of resources, or even actual text frame contents, which would be small enough to attach.

Dan, I'm sending this to FusionProSupport@PTI.com via email and will give it the name "AGL_LetterFiles". Will you be able to take a look at it in the near future?

I'm not sure whether it will be routed to me. (I'm pretty busy trying to come up with an Acrobat DC plug-in.) But if I did look at it, the very first thing I would try is composing it with the version of FusionPro I have installed, which is basically 9.3 (with some changes that are not yet released). If it works in that version, then that's probably as far as I would go, and the suggestion would be to upgrade, as it's very unlikely that we would make changes to a three-year-old version of the software.

Posted

How could I rewrite the code line

FusionPro.Composition.SetBodyPageUsage("Page3",!(useOverFlow("Frame Name")));

to be more to the likes of if the result of useOverFlow is true activate "Page2", if false activate "Page3"?

 

I know there is a way to do it in a single line of code but I'm not too sure of the structure.

.

Posted
How could I rewrite the code line
FusionPro.Composition.SetBodyPageUsage("Page3",!(useOverFlow("Frame Name")));

to be more to the likes of if the result of useOverFlow is true activate "Page2", if false activate "Page3"?

 

I know there is a way to do it in a single line of code but I'm not too sure of the structure.

There's no way to set the activation for two pages with a single call. You need to call FusionPro.Composition.SetBodyPageUsage for each page whose usage you need to set.

 

However, if you set both pages to be either initially used, or initially unused, in the Page Usage dialog, then you would only need one call to FusionPro.Composition.SetBodyPageUsage to activate or deactivate one of them as needed.

Posted (edited)
How could I rewrite the code line
FusionPro.Composition.SetBodyPageUsage("Page3",!(useOverFlow("Frame Name")));

to be more to the likes of if the result of useOverFlow is true activate "Page2", if false activate "Page3"?

 

I know there is a way to do it in a single line of code but I'm not too sure of the structure.

.

 

You could modify the useOverFlow function to return the page number rather than a boolean value:

function useOverFlow(frameName){
   var text = FindTextFrame(frameName).content;
   var tm = new FusionProTextMeasure;
   tm.useTags = true;
   tm.maxWidth = GetSettableTextWidth(FindTextFrame(frameName));
   tm.CalculateTextExtent(text);
   return (tm.textHeight > GetSettableTextHeight(FindTextFrame(frameName))) ? "Page2" : "Page3";
}

 

Then your SetBodyPageUsage function could be modified to this:

FusionPro.Composition.SetBodyPageUsage(useOverFlow("Frame Name"),true);

Assuming, as Dan said, both "Page2" and "Page3" are both initially set to false.

 

Or don't modify the function at all and just add a 'pg' variable:

var pg = (useOverFlow("Frame Name")) ? "Page2" : "Page3";
FusionPro.Composition.SetBodyPageUsage(pg,true);

Edited by step
  • 1 month later...
Posted

Hey STEP!

 

I've encoded your suggesting and made a tweak or two and everything is working fine. However a "situation" is recurring and I think that I've figured out what is causing it. Can you suggest a way to incorporate it into your code?

 

When the letter grows and flows to the next page, I set a rule to print "Over" at the bottom right of the first page.

sidebar - This client must believe that people are sooooo dumb that they
don't know the letter would continue on the back of the same page!

To make matters worse, they don't just want one or two lines to flow to the back, they want the entire paragraph to skip to the back. That's fine because I can put a "keep with next paragraph" tag in the text. However the bottom closing section contains an in-line signature. That signature is taking up two lines, but FusionPro must be thinking that it is only one rule so it should only take up one line. Every once in a while when the letter grows to barely over the bottom of the first page the signature block and preceding paragraph flow to the back of the first page as it should...but FusionPro still thinks that everything should fit in the text box entirely on the front of the first page. It doesn't put the tag for "Over" in the bottom corner, and it activates the blank back page from the rule that I put in place that when the result from your original rule is False (i.e. everything fits on the front) add a blank page to keep the page count even for imposition purposes. I've enclosed samples of correct and incorrect.

 

Since the "Over" coding is passed only when your rule believes that the amount of text is too big for the text box on the front page, the only thing I can think of that FusionPro may not be taking into consideration is that the signature graphic takes up two lines and not just one. Can you think of a way to fake out your original rule to have it think that the contents of the text going in is one line longer than what is actually going in? This might compensate for the signature graphic being two lines and not just one.

function useOverFlow(frameName){
   var text = FindTextFrame(frameName).content;
   text = text.replace(/<variable name="([^"]*)">/g,function(a,b){return RuleOrField(b);});
   var tm = new FusionProTextMeasure;
   tm.useTags = true;
   tm.maxWidth = GetSettableTextWidth(FindTextFrame(frameName));
   tm.CalculateTextExtent(text);
   return tm.textHeight > GetSettableTextHeight(FindTextFrame(frameName));
}

Posted (edited)

Hey DAVID!

 

You could revise the function to add an extra line to "fool" TextMeasure if you really wanted to but honestly, that's probably more work than it's worth and it sounds like more of a band-aid fix than actually accessing the real issue. Without having seen your actual template file to see how you're generating that output, my assumption is that all of the content on the first page is generated by a rule (or a compilation of rules) that are being put into a single text frame that will overflow to the back. Based on that assumption, and the varying point-sizes, fonts, etc, creating a reliable way to add an extra line for padding is not as easy as getting the height of a line and padding the settable frame height constant. What you could do is something like this:

function useOverFlow(frameName){
   var text = FindTextFrame(frameName).content;
   [color="Red"]var frameHeight = (GetSettableTextHeight(FindTextFrame(frameName))*0.95);[/color]
   text = text.replace(/<variable name="([^"]*)">/g,function(a,b){return RuleOrField(b);});
   var tm = new FusionProTextMeasure;
   tm.useTags = true;
   tm.maxWidth = GetSettableTextWidth(FindTextFrame(frameName));
   tm.CalculateTextExtent(text);
   return tm.textHeight > frameHeight;
}

That's telling the function that the amount of space the frame has is 95% of its actual value. So it will think it's out of room when there is actually 5% left and trigger all of your dependent code. You could tinker with that value until you get the results you want.

 

But if I had to pick a culprit without seeing the template/rules, I'd place the blame solely on the inline graphic file. AND I would bet money that you're creating that inline graphic with some code that looks like this:

var graphic = CreateResource("/path/to/my/sig.pdf",'graphic');

Typically that is fine. If you were to just return that 'graphic' variable it would validate as 'Resource("/path/to/my/sig.pdf").' That is quite literally how TextMeasure will read that and it will return the measurement of that string rather than the height of the graphic itself. So if that's the case you have two options to get an accurate measurement of the graphic:

1. Change where you're defining the graphic to this:

var graphic = CreateResource("/path/to/my/sig.pdf",'graphic').content;

2. Or add this line to the 'useOverflow' function (which will essentially do the first option for you):

function useOverFlow(frameName){
   var text = FindTextFrame(frameName).content;
   text = text.replace(/<variable name="([^"]*)">/g,function(a,b){return RuleOrField(b);});
   [color="Red"]text = text.replace(/Resource\(([^\)]*)\)/g,'<graphic file=$1>');[/color]
   var tm = new FusionProTextMeasure;
   tm.useTags = true;
   tm.maxWidth = GetSettableTextWidth(FindTextFrame(frameName));
   tm.CalculateTextExtent(text);
   return tm.textHeight > GetSettableTextHeight(FindTextFrame(frameName));
}

 

I hope that helps!

Edited by step
grammar
  • 11 months later...
Posted

Hi Step

I realize this thread is over a year old, but I think this is (or is very close to) what I need in my current project. This is the same project you've been helping me on with the pie charts, only now it's about the table. If anyone is interested...TSC_Mockup.zip.

 

The end result is to have each record have an even amount of pages.

My table starts on page three. On this page I have two text frames that are linked together, with an overflow page that it can "grow" to. In the Overflow Options dialog box, I have it set to add pages "So Last Added Page Is Even". This works as I need it to, but only (obviously) if the table grows to the overflow page. Where I'm having trouble is if the table doesn't exceed past page 3, add an extra blank page at the end of the record.

 

In my OnRecordStart rule, I've tried

var pageCount = FusionPro.Composition.totalPages;

if(pageCount %2 != 0)
{
       FusionPro.Composition.SetBodyPageUsage("ExtraPage", true);
}

however it wasn't working. So now I'm trying what you suggested for this gentleman's post:

function useOverFlow(Table){
   var text = FindTextFrame(Table).content;
   text = text.replace(/<variable name="([^"]*)">/g,function(a,b){return RuleOrField(b);});
   var tm = new FusionProTextMeasure;
   tm.useTags = true;
   tm.maxWidth = GetSettableTextWidth(FindTextFrame(Table));
   tm.CalculateTextExtent(text);
   return tm.textHeight > GetSettableTextHeight(FindTextFrame(Table));

FusionPro.Composition.SetBodyPageUsage("ExtraPage",useOverFlow("Table"));
}

 

When this didn't work, I tried "negating" the rule just as DSweet did,

FusionPro.Composition.SetBodyPageUsage("ExtraPage",!(useOverFlow("Table")));

but to no avail. What am I missing?

 

RECAP:

I have a variable length table that starts on page 3. This table needs to grow to x amount of pages. If the table ends on an even page, leave as is. If the table ends on an odd page, add a blank page at the the end.

Posted
Can you supply the MultipleCustomerExternal.txt file? Preferably with a record or two that causes the issues you're mentioning in this thread?
Posted

The function that I wrote relies on TextMeasure to determine whether or not the extra page is needed. I don't think that tables work with TextMeasure. I'm also not sure how the height of two linked text frames is interpreted by the "GetSettableTextHeight" function. There may be ways around that but for your table, I think you'd be safe in counting your rows and if it exceeds a certain amount, you'll know that the table is going to activate the overflow page.

 

So for example, let's say you determine that you can fit 50 records onto page 3 before needing to add a fourth page. You can add a global variable to your job (recs) and make a few minor tweaks to your code:

Table:

if(FusionPro.inValidation)
   Rule("OnJobStart");
var border='<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">';
var myTable = '<table margins="left:30;right:0;bottom:30;top:30" columns=6 ShadeStyle="By:Row;First:1,Green,10;Next:1, white,0"><column width=4200><column width=3200><column width=14000><column width=1800><column width=2500><column width=4000>';
myTable += '<row type="header"><p br=false cellalignment=middle quad=C><cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">Date<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">SKU<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">Description<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">Tax<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">QTY<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">Retail Item Price';//in row tag   margins="left:50;right:50;top:50;bottom:50"
//myTable += '<rulings top:thin,black;>';
[color="Red"]rows = 0;
[/color]var numRecsExtDF = externalTable.recordCount;
var prevStore = '';
   for(var i=1; i <= numRecsExtDF; i++)
   {
       if (externalTable.GetFieldValue(i, 'MdbId') == Field("CID"))
       {
           [color="red"]rows++;[/color]
           var store = externalTable.GetFieldValue(i, 'StoreCode');
           if(store != prevStore)
           {
               myTable += '<row><cell shading="Gray,50" hstraddle="6" rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=C><b>' + "STORE # " + externalTable.GetFieldValue(i, 'StoreCode') + '</b>';//goes before <b>   <p br=false quad=C cellalignment=middle>
               prevStore = store;
           }
           myTable += '<row><p br=false cellalignment=middle quad=C><cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">' + externalTable.GetFieldValue(i, 'TransactionDate');//in cell tag    margins="left:0;right:0;top:0;bottom:0"
           myTable += '<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=C>'+ externalTable.GetFieldValue(i, 'SkuCode');//in cell tag  margins="left:0;right:0"
           myTable += '<cell margins="left:300" rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=L>'+ externalTable.GetFieldValue(i, 'SkuDescription');//goes after <cell>   <p br=false quad=L>      in cell tag   margins="left:300;right:300"
           if(externalTable.GetFieldValue(i, 'IsTaxExempted') == "1")
           {
               myTable += '<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=C>'+ "Y";//goes after <cell>    <p br=false quad=C>      in cell tag  margins="left:0;right:0"
           }
           else
           {
               myTable += '<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=C>'+ "N";//goes after <cell>    <p br=false quad=C>      in cell tag  margins="left:0;right:0"
           }
           myTable += '<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">'+ externalTable.GetFieldValue(i, 'UnitsSold')//in cell tag    margins="left:0;right:0"
           myTable += '<cell margins="right:100;" rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=R>'+ externalTable.GetFieldValue(i, 'NetSalesAmt')//in cell tag   margins="left:0;right:300"
       }

   } 
   myTable += '<row><cell rulings="Right:Thin,Black;Left:Thin,Black" shading="White,100" hstraddle="6">'+"Total Non-taxable Purchases (Tax=N)........$"+Field("Total Non Taxable Purchases");//goes after <cell>  <p br=false quad=R>
   myTable += '<row><cell rulings="Right:Thin,Black;Left:Thin,Black" shading="White,100" hstraddle="6">'+"Total Taxable Purchases (Tax=Y)........$"+Field("Total Taxable Purchases");//goes after <cell>  <p br=false quad=R>
   myTable += '<row><cell rulings="Right:Thin,Black;Left:Thin,Black;Bottom:Thin,Black" shading="White,100" hstraddle="6">'+"Total Purchases (not including sales tax)........$"+Field("Total Purchases");//goes after <cell>  <p br=false quad=R>
myTable += '</table>';
return myTable;

OnRecordStart:

Rule('Table');
FusionPro.Composition.SetBodyPageUsage('ExtraPage', rows < 50);

 

Of course with FP9, you can easily find all of the external data records that match the "CID" field by using the "findRecords" function which makes it a little easier:

if(FusionPro.inValidation)
   Rule("OnJobStart");

var border='<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">';
var myTable = '<table margins="left:30;right:0;bottom:30;top:30" columns=6 ShadeStyle="By:Row;First:1,Green,10;Next:1, white,0"><column width=4200><column width=3200><column width=14000><column width=1800><column width=2500><column width=4000>';
myTable += '<row type="header"><p br=false cellalignment=middle quad=C><cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">Date<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">SKU<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">Description<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">Tax<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">QTY<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">Retail Item Price';//in row tag   margins="left:50;right:50;top:50;bottom:50"

var prevStore = '';

[color="red"]var recs = externalTable.FindRecords('MdbId', Field("CID"));
rows = recs.length;[/color]

for ([color="red"]var i in recs[/color]) {
   [color="red"]var rec = recs[i];[/color]
   var store = externalTable.GetFieldValue(rec, 'StoreCode');
   if(store != prevStore)
   {
       myTable += '<row><cell shading="Gray,50" hstraddle="6" rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=C><b>' + "STORE # " + externalTable.GetFieldValue(rec, 'StoreCode') + '</b>';//goes before <b>   <p br=false quad=C cellalignment=middle>
       prevStore = store;
   }
       myTable += '<row><p br=false cellalignment=middle quad=C><cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">' + externalTable.GetFieldValue(rec, 'TransactionDate');//in cell tag    margins="left:0;right:0;top:0;bottom:0"
       myTable += '<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=C>'+ externalTable.GetFieldValue(rec, 'SkuCode');//in cell tag  margins="left:0;right:0"
       myTable += '<cell margins="left:300" rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=L>'+ externalTable.GetFieldValue(rec, 'SkuDescription');//goes after <cell>   <p br=false quad=L>      in cell tag   margins="left:300;right:300"
   if(externalTable.GetFieldValue(rec, 'IsTaxExempted') == "1")
   {
       myTable += '<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=C>'+ "Y";//goes after <cell>    <p br=false quad=C>      in cell tag  margins="left:0;right:0"
   }
   else
   {
       myTable += '<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=C>'+ "N";//goes after <cell>    <p br=false quad=C>      in cell tag  margins="left:0;right:0"
   }
   myTable += '<cell rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black">'+ externalTable.GetFieldValue(rec, 'UnitsSold')//in cell tag    margins="left:0;right:0"
   myTable += '<cell margins="right:100;" rulings="Top:Thin,Black;Bottom:Thin,Black;Left:Thin,Black;Right:Thin,Black"><p br=false quad=R>'+ externalTable.GetFieldValue(rec, 'NetSalesAmt')//in cell tag   margins="left:0;right:300"
}
myTable += '<row><cell rulings="Right:Thin,Black;Left:Thin,Black" shading="White,100" hstraddle="6">'+"Total Non-taxable Purchases (Tax=N)........$"+Field("Total Non Taxable Purchases");//goes after <cell>  <p br=false quad=R>
myTable += '<row><cell rulings="Right:Thin,Black;Left:Thin,Black" shading="White,100" hstraddle="6">'+"Total Taxable Purchases (Tax=Y)........$"+Field("Total Taxable Purchases");//goes after <cell>  <p br=false quad=R>
myTable += '<row><cell rulings="Right:Thin,Black;Left:Thin,Black;Bottom:Thin,Black" shading="White,100" hstraddle="6">'+"Total Purchases (not including sales tax)........$"+Field("Total Purchases");//goes after <cell>  <p br=false quad=R>
myTable += '</table>';
return myTable;

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...