Jump to content

Multiple Records in an Output file Sample


Recommended Posts

I'm trying to recreate the sample given in the RulesSystemsGuide(pg 106). I've followed the instructions exactly. And I've not been able to get the composition to produce any results at all. I don't know what I'm missing. My only guess is that the "path" to the external .txt file is not linking to it properly. Are there any issues with this and OSX 10.5.8?

 

I've copied and pasted everything verbatim and recreated the fake list, yet I can't get any results.

Please help! I have a job that is in the shop where we need to use this feature.

 

I just need someone to point me in the direction of what I'm doing wrong.

 

Thanks in advance

 

P.S. I've attached my test files.

multirecordSample.zip

Link to comment
Share on other sites

I'm sorry that's not at all what I was asking. My goal is to create the "Multiple Records in one output" as seen on pages 105-108 in the RULES system guide.

 

Thanks for taking the time though.

 

Do you/anyone know how to use javascript/global/rules to link to an external data file so that I can accomplish what I stated in my first post?

 

I know full well how to use Fusion Pro to do the simple 1 record:1 page output work that you turned my file into.

 

I just want to know why I can't get results when I follow the example in the "guide."

Link to comment
Share on other sites

THANK YOU!!!!!

You have no idea how much work you just saved us! haha!

 

I was not aware that the value inside of that was specifying the delimiter. FYI, You might want to edit the "RulesSystemGuide" PDF for future release to reflect this. It shows a txt file and ","

 

 

THANKS AGAIN DAN!

Link to comment
Share on other sites

Hey Dan,

 

One question:

In regards to the sample thread you referenced:

What if you wanted to group "CID's" into their own text frame. Could you split them up via the same javascript rule? We already have the code in place that cross references the our three lists. We just have "items" that the buyer has ordered for recipients that can't all be returned to the same frame.

 

For example: I would like to get

 

One Text frame return

123 LCD TV $1495.00

123 Surround Speakers $279.00

123 Tax $141.92

 

 

Second Frame...

456 Home Media Server $2,499.00

456 Universal Remote $50.00

456 Media Zone Network Adapter $79.99

456 Wireless Keyboard/Mouse Combo $109.00

456 Tax $219.04

Link to comment
Share on other sites

Hey Dan,

 

One question:

In regards to the sample thread you referenced:

What if you wanted to group "CID's" into their own text frame. Could you split them up via the same javascript rule? We already have the code in place that cross references the our three lists. We just have "items" that the buyer has ordered for recipients that can't all be returned to the same frame.

 

For example: I would like to get

 

One Text frame return

123 LCD TV $1495.00

123 Surround Speakers $279.00

123 Tax $141.92

 

 

Second Frame...

456 Home Media Server $2,499.00

456 Universal Remote $50.00

456 Media Zone Network Adapter $79.99

456 Wireless Keyboard/Mouse Combo $109.00

456 Tax $219.04

Sure, you can do this all pretty much in one rule, a couple of different ways.

 

You can do something like in this thread to iterate through the data file once and save the items into a series of arrays, then access them later.

 

For instance, in the sample job in question, we can do this in OnJobStart:

var externalDF = new ExternalDataFileEx('secondary-input-file_Purchases.txt', '\t');

if (!externalDF.valid)
   throw 'Failed to link to the external data file in OnJobStart';

function Product(CID, name, price) // Object constructor
{
   this.CID = CID;
   this.name = name;
   this.price = price;
}

SortedItems = new Object; // global

var numRecsExtDF = externalDF.recordCount;
for (var recordWalker=1; recordWalker <= numRecsExtDF; recordWalker++)
{
   var key = externalDF.GetFieldValue(recordWalker, 'CID');
   var product = new Product(key, externalDF.GetFieldValue(recordWalker, 'Product-Purchased'),
                               externalDF.GetFieldValue(recordWalker, 'Price'));
   if (!SortedItems[key])
       SortedItems[key] = [];
   SortedItems[key].push(product);
}

This is kind of an "AJAX-y" way of looking at the data, as a set of objects.

 

Then you can add this function in the JavaScript Globals:

function GetItemsForCustomer(CID)
{
 if (FusionPro.inValidation)
   Rule("OnJobStart");

 var returnStr = '';

 var SelectedItems = SortedItems[CID];
 if (SelectedItems)
 {
   for (var i in SelectedItems)
   {        
       var product = SelectedItems[i];
       //Check to see if this is a TAX item.  If it is, let's format it differently
       if (product.name == 'Tax')
           returnStr += '<br>\n<b>Total Tax - ' + product.price + '</b>';
       else //OK - so this is a normal product - not a Tax item
           returnStr += product.name + ' - ' + product.price + '<br>\n';
   }
 }

 return returnStr;
}

Then the logic in the main rule becomes simply this:

return GetItemsForCustomer(Field("CustomerID"));

So, once you're at this point, it's pretty easy to make more one-line rules like that to get the items for any arbitrary customer.

 

If you still really want to set the text in three separate frames from a single rule, you can do that in OnRecordStart, like so:

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

for (var key in SortedItems)
   FusionPro.Composition.AddVariable("Items-" + key, GetItemsForCustomer(key), true);

And simply insert variables such as "Items-123" into the text frames.

 

Or, if you name the text frames themselves as "Items-123" etc., you can do something like this on OnRecordStart:

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

for (var key in SortedItems)
   FindTextFrame("Items-" + key).content = GetItemsForCustomer(key);

But that might be more than what you were looking for. ;) The point is that there are a lot of tools at your disposal.

Link to comment
Share on other sites

Wow... That is a lot. Not sure I understand it all. I'm not sure if I really need to return info to separate frames from a single rule. I'll explain what we are trying to accomplish and see if you could suggest a good route.

 

We have a buyer, ship to, and an item list.

We have an order form with the buyer list being used as input data and populating the name,address etc at the top. On the left we have previous "ship to" recipients which have corresponding purchased "items" on the right.

We've got the "Ship to's" flowing in properly because that's easy and we are just letting it fill in as the data has the records. The "Items" is the scary beast that we can't tame. They are a maximum of five lines and min of one per "ship to." So depending on how many are tied to the "ship to" we need it to place those accordingly. I'll attach our sample doc.

 

Thanks so much for your help. If we can't get this figured out ASAP we may be calling for some support.

 

I can't imagine this is that difficult to those who know JavaScript well.

PleaseHelp.zip

Link to comment
Share on other sites

Oh, I see. It's not just that each "buyer" has a set of items, it's that each buyer has a set of "ship-to"s, and in turn, each ship-to has a set of items. So there are three sets of data here, not two.

 

In your output, you want to have one page of output for each buyer (each record in the primary data file), and on each page, a list of "ship-to"s, and for each "ship-to," a list of items. Right?

 

So, having three data sources to merge together makes this job a bit more complicated than any of the samples we've looked at so far, which only had to merge two data sources.

 

I've attached a modified version of your template which I think does what you want. (You may need to change some of the fonts; I just used the default font.)

 

Notice how in the "Items" rule, there are two "for" loops, one nested inside the other, so that we can find the items which match both the "BUYERCUSTNO" and the "SHIPTOCUSTNO." (In programmer speak, this might be called a double-key lookup, or a two-dimensional data array. A database person would call it a relational database with three tables.)

 

I've also used the <p verticalstart=topofcolumn> trick to "jump" to the next connected text frame, which is how I get each set of items into a different frame (although, as noted in my previous post, there are other ways this can be done). And I added some helper functions to reduce the amount of repetitive code and make everything more readable.

 

The same strategy of iterating through the data files once and storing the data in objects as in my previous post would also work here, and would probably make everything compose a bit faster for larger data sets, but I haven't done that.

 

Also, another bit of advice: You'd be better off typesetting the entire document, including the "static" parts of the form such as the labels "COMPANY:", "STREET ADDRESS:", etc. instead of trying to line up your composed text with the elements on the background PDF and having to do tricks to put things in different frames. This approach would have other advantages as well: you only end up with actual information on the page and no empty lines; you can create a repeatable component for each "ship to" person and set of items; etc. Your best bet may be to generate a table, which will also allow you to add more "ship-to"s and items to an additional page if necessary. But I'll leave that to you.

template2-Dan.pdf

Link to comment
Share on other sites

Dan, Thank you so much for taking the time. I see the benefit that you speak of, but unfortunately we're doing this job as a hybrid and cannot have the static elements on the imprint. So we're rather stuck between the proverbial rock and hard place. I think what you have accomplished with this will work great.

 

Now if only we had a quarter of that JavaScript skillz that you have ;)

Link to comment
Share on other sites

Is the only way to perform an overflow page with multiple overflow text frames by controlling via JavaScript? I realize that if I make an overflow page, I can only assign one frame at a time to be overflow destinations. I need two for this job so that if the Ship-to is more than 3(possible up to 5 in the data) then it will create the pages on-demand and both "ship-to" and "items" will fill it out.

 

BTW: Your code help above is awesome. Works like a charm for our job.

Link to comment
Share on other sites

Is the only way to perform an overflow page with multiple overflow text frames by controlling via JavaScript? I realize that if I make an overflow page, I can only assign one frame at a time to be overflow destinations. I need two for this job so that if the Ship-to is more than 3(possible up to 5 in the data) then it will create the pages on-demand and both "ship-to" and "items" will fill it out.

Well, you don't need any JavaScript to use an overflow page, but I see what you're saying. Yes, you can only have one overflow destination on an Overflow page. You can have multiple frames on a Body page which are connected to multiple frames on other Body pages, but that's not really what you want in this case either.

 

I think the solution is to output all of the data as a table, with the "ship-to" and "items" in separate columns, and have that overlay the static background. Then the table can overflow to more pages. Or, you could use a Repeatable Component (Template Page) which includes separate text frames for each "ship-to" and the associated items.

Link to comment
Share on other sites

  • 3 weeks later...

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...