Multiple File Layouts

In the previous examples, the input file contained rowsets based on a single File Layout definition. However, PeopleTools provides the functionality to process input files containing rowsets that require several different File Layouts.

Note: You can use only fixed format files to implement multiple file layouts.

See the SetFileId method for details about handling multiple file layouts.

In this section, we discuss how to:

  • Read multiple file layouts.

  • Write multiple file layouts.

See SetFileId.

If your input file contains data based on more than one File Layout, it must contain an indicator, called a FileId that specifies:

  • When a different File Layout definition should be used.

  • Which File Layout definition should be used.

The FileId must be specified on a separate line and must precede every rowset that requires a layout different from the previous rowset. It isn’t considered part of the rowset.

In the following example, the file contains two FileId lines; they use a file record ID that distinguishes them from the rowset data—in this case, "999".

999 PRODUCT  /* The following rowset uses the PRODUCT layout */
001  /* Level 0 record data */
101  /* level 1 record data */
201  /* Level 2 record data */
201  /* Level 2 record data */
999 ORDER  /* The following two rowsets use the ORDER layout */
001  /* Level 0 record data */
111  /* Level 1 record data */
111  /* Level 1 record data */
001  /* Level 0 record data */
111  /* Level 1 record data */
111  /* Level 1 record data */

The FileId can contain any information you want that indicates which file layout to use; the "PRODUCT" and "ORDER" fields shown are just examples.

To read this file, you should do the following in your program:

  1. Use the SetFileId method to specify the file record ID value.

  2. Use the ReadRowset method to read the data.

  3. Check if the rowset is NULL.

    NULL indicates you’ve reached either the end of the file or a new rowset.

  4. Use the IsNewFileId property to check if the next line is a FileId file record (line).

  • If IsNewFileld is False, you’ve reached the end of the file.

  • If IsNewFileld is True, use the CurrentRecord property to determine which File Layout to use next.

The following example reads rowsets from a file. When it finds a new rowset (indicated by &IsNewFileld returning True) the value of &CurrentRecord is passed to a function that reads and evaluates the line, then returns the name of the new file layout. (The code for the function FindFileId is included at the start of the example.)

Local File &MYFILE;
Local Rowset &rsFile;
Local Record &rSomeRec1, &rSomeRec2;
Local SQL &SQL1;

Function FindFileID(&CurrentRecord As string) Returns string ;
   Evaluate RTrim(Substring(&CurrentRecord, 5, 50))
   When "SOME_REC1" 
      &FILELAYOUT = "SOME_REC1";
   When "SOME_REC2" 
      &FILELAYOUT = "SOME_REC2";
   End-Evaluate;
   Return &FILELAYOUT;
End-Function;

&rSomeRec1 = CreateRecord(Record.SOME_REC1);
&rSomeRec2 = CreateRecord(Record.SOME_REC2);
&SQL1 = CreateSQL("%Insert(:1)");
&MYFILE = GetFile("c:\temp\MULTI_FILE.out", "R", %FilePath_Absolute);

rem Set temporary first file layout;
&MYFILE.SetFileLayout(FileLayout.SOME_REC1);
&MYFILE.SetFileId("999", 1);

rem Read rowset to find actual first file ID;
&rsFile = &MYFILE.ReadRowset();
&CurrentRecord = &MYFILE.CurrentRecord;
&IsNewFileID = &MYFILE.IsNewFileId;
If &MYFILE.IsNewFileId Then
   &FILELAYOUT = FindFileID(&CurrentRecord);
   &MYFILE.SetFileLayout(@("FileLayout." | &FILELAYOUT));
   &MYFILE.SetFileId("999", 1);
End-If;

rem Read first 'real' rowset;
&rsFile = &MYFILE.ReadRowset();
&CurrentRecord = &MYFILE.CurrentRecord;
&IsNewFileID = &MYFILE.IsNewFileId;
While &rsFile <> Null Or
      &IsNewFileID
   If &MYFILE.IsNewFileId Then
      &FILELAYOUT = FindFileID(&CurrentRecord);
      &MYFILE.SetFileLayout(@("FileLayout." | &FILELAYOUT));
      &MYFILE.SetFileId("999", 1);
      If &IsNewFileID Then
         &rsFile = &MYFILE.ReadRowset();
         &CurrentRecord = &MYFILE.CurrentRecord;
         &IsNewFileID = &MYFILE.IsNewFileId;
      End-If;
   End-If;
   
   Evaluate &FILELAYOUT

   When "SOME_REC1" 
      &rsFile(1).SOME_REC1.CopyFieldsTo(&rSomeRec1);
      &rSomeRec1.ExecuteEdits(%Edit_Required);
      If Not &rSomeRec1.IsEditError Then
         &SQL1.Execute(&rSomeRec1);
      End-If;
      Break;
   When "SOME_REC2" 
      &rsFile(1).SOME_REC2.CopyFieldsTo(&rSomeRec2);
      &rSomeRec2.ExecuteEdits(%Edit_Required);
      If Not &rSomeRec2.IsEditError Then
         &SQL1.Execute(&rSomeRec2);
      End-If;
   End-Evaluate;
   
   &rsFile = &MYFILE.ReadRowset();
   &CurrentRecord = &MYFILE.CurrentRecord;
   &IsNewFileID = &MYFILE.IsNewFileId;
End-While;

&MYFILE.Close();

See SetFileId, ReadRowset, IsNewFileId.

If you’re writing files that contain data based on more than one File Layout definition, consider the following points:

  • If the file is going to a third-party vendor, you should work with the third-party to determine what their requirements are for specifying the different data formats.

  • If the file is going to be used by another PeopleSoft system, you must add the FileId between each rowset that requires a different layout. FileId file records are not part of any rowset. They should be designed so they won’t be mistaken for part of a rowset. You can create and write them to the file in many ways. The following are suggestions:

    • Build each line as a string, using any of the built-in string manipulation functions, then write them to the file using the File class WriteLine or WriteString methods.

    • Design a file layout consisting of a single file record definition for the FileId file records, then build the records using Record Class methods and functions, and write them to the file using the WriteRecord method.

The following code example writes each record from the level one scroll on a page to the file using a different File Layout. Between each WriteRowset the File ID file record is written to the file, describing the new File Layout being used.

Local File &MYFILE;
Local Rowset &FILEROWSET;
Local Record &REC1, &REC2;
Local SQL &SQL;

&MYFILE = GetFile("c:\temp\Records.txt", "W", %FilePath_Absolute);
If &MYFILE.IsOpen Then
   If &MYFILE.SetFileLayout(FileLayout.TREE_LEVEL) Then
      &REC1 = CreateRecord(Record.PSTREELEVEL);
      &FILEROWSET = &MYFILE.CreateRowset();
      &SQL = CreateSQL("%Selectall(:1)", &REC1);
      /* write first File ID to file */
      &MYFILE.WriteLine("999 FILE LAYOUT 1");
      While &SQL.Fetch(&REC1)
         &REC1.CopyFieldsTo(&FILEROWSET.GetRow(1).PSTREELEVEL);
         &MYFILE.WriteRowset(&FILEROWSET, True);
      End-While;
   Else
      /* file layout not found, do error processing */
   End-If;
   
   If &MYFILE.SetFileLayout(FileLayout.TREE_USERLEVEL) Then
      &REC2 = CreateRecord(Record.TREE_LEVEL_TBL);
      &FILEROWSET = &MYFILE.CreateRowset();
      &SQL = CreateSQL("%Selectall(:1)", &REC2);
      /* write second File ID to file */
      &MYFILE.WriteLine("999 FILE LAYOUT 2");
      While &SQL.Fetch(&REC2)
         &REC2.CopyFieldsTo(&FILEROWSET.GetRow(1).TREE_LEVEL_TBL);
         &MYFILE.WriteRowset(&FILEROWSET);
      End-While;
   Else
      /* file layout not found, do error processing */
   End-If;
Else
   /* file not opened, do error processing */
End-If;
&MYFILE.Close();

See WriteLine, WriteString, WriteRecord.

See Understanding Record Class.