|Contents:||Main||Chapter||See Also:||Getting Started Manual||Advanced User Manual|
Ordinarily, you control the way EN1^DIP sorts output using the BY, FR, and TO input variables. This lets you sort based on field values, a previous sort stored in a SORT template, or on the records stored in a SEARCH template.
The BY(0) feature allows you to control the sort. With BY(0), you can force VA FileMan to sort using an existing compound index (i.e., one that indexes more than a single data field) for efficiency. Or, use of BY(0) allows you to pre-sort a list of record numbers in a global and pass this pre-sorted list to EN1^DIP. This lets you pre-sort reports in any way that you can use subscripts to sort a global. The only limitation is that the total number of subscripts in the global that you sort by must be seven or less.
The two main ways in which the BY(0) feature should be used are as follows:
(Optional; Required for BY(0) sorts) Set this variable to an open global root. The open global root should be the static part of a global; a list of record numbers must be stored at a descendent subscript level.
^DIZ(662001,"E","ALBERT",1009) ^DIZ(662001,"E","ANDREA",339) ^DIZ(662001,"E","ANDREW",552) --------------- ---------------- <-static part-> <-dynamic part->
In the example just above, you would set BY(0) to '^DIZ(662001,"E",'.
There can be intervening subscript levels between the static, fixed global root and the subscript level where the list of records numbers is stored. Any intervening subscript levels define a sort order. Use the L(0) input variable to tell FileMan the number of dynamic subscript levels it needs to sort through (see L(0) description below).
Alternatively, you can set BY(0) to the name of a SEARCH template, in [brackets]. This tells VA FileMan to sort on the list of record numbers contained in the corresponding SEARCH template entry in the ^DIBT global.
BY(0) affects your sorts as follows:
BY(0) for a VA FileMan Index
If you set BY(0) to sort based on an existing FileMan-maintained cross-reference, make sure the subscript you set L(0) to point to is in fact the location where FileMan stores its list of records (when sorting on a regular single-field index, L(0) should be 2).
BY(0) for a List of Records "On the Fly"
If you build your own list of sorted records on the fly in a temporary global (as opposed to setting BY(0) to a VA FileMan-maintained cross-reference) it's best not to let the final subscript of your static global reference be "B". For more information, see the discussion in the "Details and Features" section below.
NOTE: If you are using both the BY and BY(0) input variables, don't set BY to the name of a template; an error message will print or hard errors could result.
(Optional; Required if BY(0) is set to an open global root.)
Use L(0) to specify the number of dynamic subscript levels that exist beyond the static global root, including the subscript level containing the list of record numbers. The minimum value of L(0) is 1.
EN1^DIP lets you sort by up to 7 subscripts; therefore the maximum value of L(0) is 8.
For example, if BY(0) refers to a regular "E" index on a file -- '^DIZ(662001,"E",' -- you should set L(0)=2 -- that is, one for the subscript containing the (dynamic) value of the field being cross-referenced, plus one for the record number.
(Optional) To select only a subset of records at a given subscript level "n", you can use FR(0,n) and/or TO(0,n). For "n" equal to any of the "n" dynamic sorting subscript levels in the global specified by BY(0), you can set FR(0,n) to the sort-from value for that subscript level.
This restricts the printed records to those whose subscript values at subscript level n sort the same or greater than the value you set into FR(0,n). If FR(0,n) is undefined for any subscript n, the sort on that subscript level begins with the first value for that subscript.
NOTE: These values must be in internal format, as they are stored in the subscript of the index or global defined by BY(0).
(Optional) This variable contains the ending value (the sort-to value) for any of the "n" dynamic sorting subscripts in the global specified by BY(0). If TO(0,n) is undefined for any subscript "n", the sort on that subscript level ends with the last value for that subscript.
NOTE: These values must be in internal format, as they are stored in the subscript of the index or global defined by BY(0).
(Optional) Like the FR(0,n) and TO(0,n) variables, this variable array can be set for any of the "n" dynamic sorting subscripts in the global specified by BY(0). This array allows you to create subheaders for the sorting subscripts in the global. In order to create a sub-header, you must define a title for the subscript, as VA FileMan has no knowledge of the subscripts. Each entry in the array can have information in two ^-pieces.
The subheaders defined in DISPAR(0,n) cannot be suppressed.
(Optional) If a literal title is input to DISPAR(0,n) above, then you can also enter M code to transform the value of the subscript from the global before it is printed as a subheader. It acts like an OUTPUT transform. At the time of execution, the untransformed value will be in Y. The code should put the transformed value back into Y. Any other variables used in the code should be NEWed.
Suppose you have a simple MUMPS cross-reference that inverts dates so that the values in the cross-reference are 99999999-date. The cross-reference might look something like:
^DIZ(662001,"AC",97069889,2)="" ^DIZ(662001,"AC",97969898,3)="" ^DIZ(662001,"AC",97969798,1)="" ...etc.
If you wanted to sort all entries by this inverse date and to convert the date values into a readable format for the subheader, you would set up the variables for the EN^DIP call like this:
>S DIC="^DIZ(662001,",L=0,FLDS="your field list" >S BY(0)="^DIZ(662001,""AC""," >S L(0)=2 >S DISPAR(0,1)="^;""DATE""" >S DISPAR(0,1,"OUT")="S:Y Y=99999999-Y S Y=$$FMTE^XLFDT(Y)"
Suppose you have a list of record numbers in a global that looked like this:
^TMP($J,1)="" ^TMP($J,3)="" ^TMP($J,35)="" ^TMP($J,39)="" ...etc.
If you wanted to print those records sorted by the .01 field of the file, you would:
>S DIC="^DIZ(662001,",L=0,BY=.01,(FR,TO)="",FLDS="your field list" >S BY(0)="^TMP($J," >S L(0)=1
Suppose you have a MUMPS multifield-style cross-reference, with subscripts based on the values of two fields. The first field in the subscript is free-text, and the second is a number. The cross-reference might look like:
^DIZ(662001,"AD","ANY",4.99,5)="" ^DIZ(662001,"AD","ANYTHING",1.3,2)="" ^DIZ(662001,"AD","ANYTHING",1.45,1)="" ^DIZ(662001,"AD","SOMETHING",.4,10)="" ...etc.
You want to sort from value "A" to "AZ" on the free-text field and from 1 to 2 on the numeric field. Also, you want to print a subheader for the numeric field. You could set your variables like this:
>S DIC="^DIZ(662001,",L=0,FLDS="your field list" >S BY(0)="^DIZ(662001,""AD""," >S L(0)=3 >S FR(0,1)="A",TO(0,1)="AZ" >S FR(0,2)=1,TO(0,2)=2 >S DISPAR(0,2)="^;""NUMBER""" >S DISPAR(0,2,"OUT")="S Y=$J(Y,2)"
|Sorting on MUMPS Cross-References||
The BY(0) feature is designed to let you pre-sort your FileMan reports using MUMPS cross-references. As long as the MUMPS cross-reference has 0 to 7 dynamic (sorting) subscripts, followed by the record numbers stored in a final subscript level, you can order your reports based on that cross-reference using BY(0).
While you may have used MUMPS cross-references in the past only for sorting hard-coded reports, you may want to consider using them with FileMan-based reports as well.
|Sorting a Compound Cross-reference Defined in the INDEX file||The BY(0) feature will allow you to sort using a compound cross-reference on the new INDEX file (a compound cross-reference is one that indexes more than one data field). This feature will let you use any index that has no more than 7 data valued subscripts.|
|Sorting Using One or More Subscript Levels||
Each intervening subscript level between the static part of the open global root in BY(0) and the record number subscript level serves as one sort level, starting with the highest subscript level.
In Example 3 above, the records would sort by the value of the free-text field stored in the first dynamic subscript, and within that by the value of the numeric field stored in the second dynamic subscript.
|Additional Sorting with BY, FR, and TO||
When using BY(0), you can still sort in the usual way (setting BY, FR, and TO) to further sort and limit the range within the list provided by BY(0). Note that if you set BY(0), BY cannot contain the name of a SORT template. If your sort is complicated, see the documentation below on "Storing BY(0) specifications in SORT Templates."
VA FileMan selects only the list of records specified by BY(0) and its associated variables. FileMan accepts as-is the sort sequence created by any dynamic subscripts in the global specified in BY(0). Then within that sort sequence, it further sorts the records by the information provided in the BY, FR, and TO variables.
You can only sort by up to 7 sort levels in EN1^DIP, so the number of subscripts you sort by using BY(0) combined with the number of fields you sort by using BY must not total more than 7.
If BY(0) has been defined without BY, FR, and TO, the user will not be prompted for the SORT BY or FROM/TO ranges.
|Storing BY(0) Specifications in SORT Templates||
You can store the BY(0) information in a SORT template, in order to design more complicated sorts. This allows you to sort using the global described in the BY(0) variable, and within those subscripts, to sort by additional fields and to save the entire sort description into a template. You need programmer access to do this.
In FileMan's sort dialog (with programmer access), at the SORT BY: prompt, you can enter the characters BY(0) as shown in the example immediately below. When you enter BY(0), you are then prompted for the BY(0), L(0) and all related values, exactly the same as if they were entered as input variables to the EN1^DIP call.
Select OPTION: 2 PRINT FILE ENTRIES OUTPUT FROM WHAT FILE: ZZTAMI TEST// SORT BY: NAME// BY(0) BY(0): // ^DIZ(662001,"H", L(0): //2 Edit ranges or subheaders? NO// YES SUBSCRIPT LEVEL: 1// 1 FR(0,n): // 2690101 TO(0,n): // 2701231 DISPAR(0,n) PIECE ONE: // DISPAR(0,n) PIECE TWO: // ;"Date of Birth: " DISPAR(0,n,OUT): // S Y=$$FMTE^XLFDT(Y,1) Edit ranges or subheaders? NO// BY(0)=^DIZ(662001,"H", L(0)=2 SUB: 1 FR(0,1): 2690101 TO(0,1): 2701231 DISPAR(0,1) PIECE ONE: DISPAR(0,1) PIECE TWO: ;"Date of Birth: " DISPAR(0,1,OUT): S Y=$$FMTE^XLFDT(Y,1) OK? YES// Enter additional sort fields? NO// YES WITHIN BY(0), SORT BY: NAME START WITH NAME: FIRST// WITHIN NAME, SORT BY: STORE IN 'SORT' TEMPLATE: ZZTAMIBY0
When you enter BY(0), you are prompted for BY(0) and L(0). In addition, you're asked if you want to edit ranges or subheaders. This lets you enter the FR(0,n), TO(0,n), DISPAR(0,n) and DISPAR(0,n,"OUT") values for various subscript levels. This lets you specify all the aspects of sorting using BY(0). You can store this criteria in a SORT template. If you answer YES to "Enter additional sort fields?", you will be allowed to enter additional sort fields, exactly the same as you would when creating a SORT template without the BY(0) features.
The functionality of BY(0) interactively or in a SORT template is identical to its functionality in the EN1^DIP programmer call.
An error results if, in a call to EN1^DIP, you sort by a SORT template that contains BY(0) sort criteria, and also use BY(0) as an input variable.
NOTE: The sort ranges associated with subscripts in the BY(0) global or index can be set dynamically by setting the FR(0,n) and TO(0,n) input variables. These input variables will override any sort ranges set in the template.
The "SUBSCRIPT LEVEL" prompt refers to the position of the data value in the global or index. Thus, entering a value for FR(0,n) when the SUBSCRIPT LEVEL is 1, sets the "from" value for the first data valued subscript.
Use the documentation for the BY(0) and related input variables for additional help. Also be sure to use online ? and ?? help.
The following is an example of how to call EN1^DIP when the BY(0) information is contained in a template:
S DIC="^DIZ(16600,",L=0,BY="[ZZTEST]",FR(0,1)=70001,FLDS=.01 D EN1^DIP
You should not use BY(0) if you are merely setting it to the global location of an existing regular cross-reference. You will not gain any speed, because FileMan's built-in sort optimizer already knows to sort on regular cross-references.
Also, don't specify a field's regular cross-reference as the global reference in BY(0) to sort on, and then sort on the same field using BY, FR, and TO. This actually increases the amount of work FileMan needs to do!
|"On the Fly" Globals Whose Static Global Reference Ends with "B"||
If you build your own list of sorted records on the fly in a temporary global (as opposed to setting BY(0) to a VA FileMan-maintained cross-reference) it's best not to let the final subscript of your static global reference be "B".
This will avoid problems that might be caused by VA FileMan's special handling of the "B" index for mnemonic cross-references.
Reviewed/Updated: March 4, 2007