Jump to content

Counting Multi-Line


Recommended Posts



Starting with multi-line files. I get the concept of the multi-line record and how to go through it with GetMultiLineRecords() to iterate through the collected records for each set, however how am I able to "pre-count" the total "collected sets" of the multi-line data file?


As an example I have a data file with 12 lines, and the file is defined in FusionPro as multi-line when an account number changes. There are three account changes in the file so FusionPro SHOULD tell me that there are 3 records in this file. When I open the preview window the number at the bottom states 3 ... as in three records.


However if I do either a ".totalRecordCount" or ".recordCount" on the input file name FusionPro will return the value of 12. I know that there are twelve LINES of data in the file, but since it is defined as a multi-line data file and FusionPro is already telling me in the preview window that it recognizes only three records shouldn't either of those functions return a value of 3?


How do I get this value in the beginning of a job process?


Link to comment
Share on other sites

I don't understand what you mean here:

However if I do either a ".totalRecordCount" or ".recordCount" on the input file name

What do you mean "on the input file name"? There is a property named "recordCount", which you can access on an object of type ExternalDataFileEx. There are two ways to obtain an object of that type: One, to call its constructor, i.e. "new ExternalDataFileEx", to create an XDF, where you can randomly access the records; and Two, to call the FusionPro.GetMultiLineRecords() function.


There is no such property "totalRecordCount" on the ExternalDataFileEx object. There is a global property FusionPro.Composition.totalRecordCount, but that's a different story. (More about that in a bit.)


If you call the recordCount property on an object returned by a call to "new ExternalDataFileEx", it will tell you the total number of records (lines) of data in the specified file. There's no concept of multi-line records in this context.


If you call the recordCount property on the object returned by FusionPro.GetMultiLineRecords(), it will tell you the number of sub-records of data for the current primary data record. In other words, it doesn't matter how many total records or lines are in that data source, nor how many total multi-line records there are; it's just reporting the number of sub-records that you need to deal with in the output record you're composing. For instance, if you're putting all the sub-records from the multi-line record into a table, that's how many rows you'll have in the table. The next primary output record that you compose may have a different number of sub-records for its table, and so on.


To your original question, the problem of knowing "How many total records will I be composing?" at the start of a FusionPro job is no different in a multi-record job than in any other job. In short, most of the time, you don't know, because FusionPro doesn't bother to read the entirety of what could be a huge input data file with hundreds of thousands of records in it before it starts, because that could be a huge penalty in terms of both time and memory. It just reads records of data one at a time, and composes them, until the data is exhausted. (It will estimate the total progress by getting the total size of a data file, then comparing the number of bytes it has read from it against that total as it goes, but it's just a rough estimate, especially for multi-line record jobs.)


Now, there is the FusionPro.Composition.totalRecordCount property. However, as the description in the Building Blocks notes, this property is "Valid only if preprocessing has been done." This preprocessing to determine the total number of records at the start of the composition is normally only done in specific cases, such as for stacked imposition, because it has to know the total number of records to calculate where to put the stacks.


If you're not using stacked imposition, you can force the preprocessing step by doing this in OnJobStart:

FusionPro.Composition.forcePreprocessing = true;

Then you will be able to access FusionPro.Composition.totalRecordCount.


However, there's one other caveat, which is that you can't access FusionPro.Composition.totalRecordCount in OnJobStart, because you've only told FusionPro that you want to do preprocessing there, but it hasn't yet actually done it yet. So you have to wait until OnRecordStart or another rule to access that count.


Which brings me to my other question to you: What exactly are you trying to accomplish? What do you need that total record count for?

Edited by Dan Korn
Link to comment
Share on other sites

O.K. I can give you the actual information now. I've been given permission.


I am creating an online template to produce business cards for Regional Directors and Managers for a national trucking company. Each card/data file is for 1 person but can have multiple locations for the dealerships that they are in charge of. The person that was in charge of creating the site interface that these regional managers are logging into designed the data file as a multiple line record. So I'm sort of stuck with that format.


The data files will list all the locations in "state order" for each rep. I've included a sample that I was given as to how they want the back to look and a sample of a data file that would be provided to make it.


I guess the real problem that I will be encountering is what condition can I use to let me know when the "State" value has changed? In my data example changing from "North Carolina" to "Virginia" so I can create the header names that they have. I'm able to get the individual addresses to come out, but the headers (and the gap between the two or possibly more states) is sort of baffling me for the moment.



However going back to my original post ... if I invoke the call

var myNewFile = new ExternalDataFileEx(FusionPro.Composition.inputFileName, ",");
totalRecs = myNewFile.recordCount;

the value for totalRecs will be 7. Because as you stated there are 7 lines of data in the data file. Is there any command that will return the value of "2" since in this particular data file, designated as multi-line, there are 2 groups of data sets (North Carolina and Virginia)?





Link to comment
Share on other sites

I see. You're actually composing just a single record of output.


So this isn't really a multi-line record job at all. In fact, it's not even a multi-record job. (In MarcomCentral, we would call a 1-up business card like this a single-record "versioned" job instead of a multi-record VDP job.)


Therefore, the multi-line record feature won't really work in this case, because all you would get from the FusionPro.GetMultiLineRecords() in your rule would be the lines for North Carolina. You wouldn't get the lines for Virginia until your next output record. So you wouldn't easily be able to access both sets of multi-line records (for both states) to put into the same text frame on your one output page.


The only way this would really be a multi-line record job is if you had another whole card in the data, and you told it start a new record when, say, the CardName field value changed. Then you would indeed be outputting multiple records (cards), where each card had data from multiple (sub-record) lines in the multi-line (primary) record. That's the "special sauce" of multi-line records.


(You do have an extra requirement, in that you have to do something special when a field value changes within the multi-line sub-record set, so you're kind of dealing with sub-sub-record sets of the sub-records. But that doesn't really affect how the data "drives" the output of the records; it's just a detail of how the data in the single output record is laid out.)


Let's start over. All we need to do is output all the lines of the data file, in order, in a single output record. And put out the state name when it changes. Right?


You could set the file as the data for the job, but it's not "driving" the number of output records. So I would just set the data source to None and read in the data as an XDF, something like this:

var data = new ExternalDataFileEx("RegionalCards.txt");
var state = "";
var r = [];
for (var i = 1; i <= data.recordCount; i++)
   var newState = data.GetFieldValue(i, "State");
   if (state != newState)
       state = newState;
       r.push("<span pointsize=12 bold=true>" + TaggedTextFromRaw(state) + "</span>");

           data.GetFieldValue(i, "Brand") + " - " +
           data.GetFieldValue(i, "AdvertisedName") + " | " +
           data.GetFieldValue(i, "Address") + " | " +
           data.GetFieldValue(i, "City") + ", " +
           data.GetFieldValue(i, "State") + " " +
           data.GetFieldValue(i, "Zip")));

return r.join("<br>\n");

You can see I've rolled my own logic to determine when the state changes, but it's not very hard. I'll let you come up with a mapping from the two-letter state abbreviation to the full state name.

Edited by Dan Korn
Link to comment
Share on other sites

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.

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...