<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://brwiki2.brulescorp.com/brwiki2/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=66.17.154.248</id>
	<title>BR Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://brwiki2.brulescorp.com/brwiki2/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=66.17.154.248"/>
	<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Special:Contributions/66.17.154.248"/>
	<updated>2026-04-17T02:14:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=User-defined_function&amp;diff=2673</id>
		<title>User-defined function</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=User-defined_function&amp;diff=2673"/>
		<updated>2013-04-16T20:56:15Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: Redirected page to User Defined Functions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#redirect[[User Defined Functions]]&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Library_Facility&amp;diff=2657</id>
		<title>Library Facility</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Library_Facility&amp;diff=2657"/>
		<updated>2013-04-15T19:33:00Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: /* Comparison of User-Defined Function Features */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Business Rules!]] now includes a comprehensive &#039;&#039;&#039;Library&#039;&#039;&#039; Facility. Similar to [[DLL]] (Dynamic Link Libraries), the Business Rules! Library Facility enables [[user-defined functions]] to be placed in a program (&amp;quot;library&amp;quot;) that is separate from the main program. The library may be loaded &amp;quot;resident&amp;quot; (staying loaded regardless of the status of the main program), it may be loaded &amp;quot;present&amp;quot; (remaining active in current memory as long as the main program is active), or it may be loaded &amp;quot;as needed&amp;quot; (loaded when needed to execute a function, then unloaded as soon as the function has been executed).&lt;br /&gt;
&lt;br /&gt;
A library is any [[Business Rules! program]] that contains library functions. A library must be identified to Business Rules! before a program can execute any of its functions. When a library is identified, Business Rules! adds its name to an internal table of library names. This table identifies the names of all the libraries that should be searched whenever a library function that is not yet linked to a library is called.&lt;br /&gt;
&lt;br /&gt;
Business Rules! places no limits on the number of libraries that may be loaded into memory at one time. Business Rules! provides for maximum memory usage and performance flexibility by allowing libraries to be identified and loaded into memory via three different methods: the resident method, the present method and the as-needed method. See the separate descriptions below for specific information about each type of library.&lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
&lt;br /&gt;
Some of the significant advantages of placing user-defined functions in a library rather than keeping them in the main program are as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Reduces the size of executables - its no longer necessary to include a standard set of user-defined functions in every program in your application. For some applications (which may include literally hundreds of copies of the exact same code), the potential savings in disk space are tremendous.&lt;br /&gt;
&lt;br /&gt;
:2.) Saves maintenance time - If you&#039;re in the habit of duplicating user-defined functions in every single program that needs them, you know what kind of effort it takes to make (and distribute to your clients) even a one-line change to a function. With Business Rules Library Facility, you make the change only once, and you replace only one program at the client&#039;s site.&lt;br /&gt;
&lt;br /&gt;
:3.) Encourages use of programming standards - The use of library functions for a standard routine is a great way to encourage programming consistency and the setting of standards among your programmers.&lt;br /&gt;
&lt;br /&gt;
==Library Function==&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;&#039;library function&#039;&#039;&#039; is a specially defined [[user-defined function]]; it exists in a program which is frequently separate from the main program, but it may exist in the main program as well.&lt;br /&gt;
&lt;br /&gt;
To qualify as a library function, a user-defined function must simply utilize the DEF statement&#039;s LIBRARY keyword. The following is an example of a library function definition:&lt;br /&gt;
&lt;br /&gt;
 52400 DEF LIBRARY FNRESLIB2&lt;br /&gt;
 52500 PRINT &amp;quot;This is a library function&amp;quot;&lt;br /&gt;
 52600 FNEND&lt;br /&gt;
&lt;br /&gt;
Executing a library function is a two-step process. First, the program executing the library function must name the function in a LIBRARY statement, which establishes either named or unnamed linkage. Second, the program must call the library function; this may be accomplished using any of the same methods that is available for calling other user-defined functions. In the following example, line 01000 uses the LIBRARY statement to establish named linkage between the function FNPRESLIB2 and the library PRESLIB. Line 01100 causes the library PRESLIB to be loaded into present memory (if the library does not already exist in memory), then executes FNPRESLIB2.&lt;br /&gt;
&lt;br /&gt;
 01000 LIBRARY &amp;quot;PRESLIB&amp;quot;: FNPRESLIB2&lt;br /&gt;
 01100 LET FNPRESLIB2&lt;br /&gt;
&lt;br /&gt;
===Implementation Considerations===&lt;br /&gt;
&lt;br /&gt;
Business Rules Facility was carefully designed to offer a great deal of power and flexibility. Before you begin implementing this capability into your existing applications and ongoing development, ADS recommends that you consider the following:&lt;br /&gt;
&lt;br /&gt;
:1.)  Should your libraries remain resident?&lt;br /&gt;
Business Rules allows for libraries to remain resident in memory (providing maximum performance) or to be loaded and released as needed (providing best utilization of memory). Be sure to select the method or combination of methods that&#039;s best for your applications.&lt;br /&gt;
&lt;br /&gt;
:2.) Will you use multiple versions of the same function?&lt;br /&gt;
Since maintaining more than one version of a function is one method of controlling program options, Business Rules&#039; rule for library selection has been established with care. You should carefully review these rules and the ways in which multiple libraries can be of use to you as you plan your implementation.&lt;br /&gt;
&lt;br /&gt;
Until you feel comfortable with the intricacies of the Business Rules Library Facility, ADS recommends that you give every library function a name that is unique from every other library function.&lt;br /&gt;
&lt;br /&gt;
:3.) Do your existing functions utilize global program variables?&lt;br /&gt;
Unlike local user-defined functions, library functions that exist in a program separate from the main program cannot access main program variables globally. They have to be specifically passed. You should carefully review your usage of global variables before moving local functions into separate libraries.&lt;br /&gt;
&lt;br /&gt;
===As needed Library===&lt;br /&gt;
&lt;br /&gt;
An as-needed library is loaded and unloaded as needed for execution of specific functions. Loading a library only when it is needed allows the program to conserve memory usage.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Global Variables in an as-needed library are cleared each time a function call to the library is completed and the library is subsequently unloaded from memory.&lt;br /&gt;
&lt;br /&gt;
Programs can indicate that a library is to be loaded as needed by specifying the LIBRARY statement with both the RELEASE parameter and function names. This causes Business Rules to establish named linkage between the specified function(s) and the specified library, but it does not actually load the library. (The library is loaded only when one of the as-needed library&#039;s functions is actually called.) In the following example, line 00280 establishes linkage between the library ASNLIB and the function FNASNLIB1. Line 00290 causes the following to occur:&lt;br /&gt;
&lt;br /&gt;
:1.) Load ASNLIB into memory,&lt;br /&gt;
:2.) Execute the function FNASNLIB1,&lt;br /&gt;
:3.) Remove ASNLIB from memory.&lt;br /&gt;
&lt;br /&gt;
 00280 LIBRARY RELEASE,&amp;quot;ASNLIB&amp;quot;: FNASNLIB1&lt;br /&gt;
 00290 LET FNASNLIB1&lt;br /&gt;
&lt;br /&gt;
===Linkage Reassignment and Detachment===&lt;br /&gt;
&lt;br /&gt;
Once Business Rules has established linkage between a specific function and a specific library, the linkage remains active until a specific event causes it to become reassigned or detached.&lt;br /&gt;
&lt;br /&gt;
;REASSIGNMENT:&lt;br /&gt;
As noted previously, the LIBRARY statement may be used to establish linkage between a function and the library from which it is to be called. When the named LIBRARY statement is used, linkage is directly established between the named library and the named function(s). When the unnamed LIBRARY statement is used, Business Rules searches for the function according to some pre-set guidelines and assigns linkage to the first library within which the function definition is found.&lt;br /&gt;
&lt;br /&gt;
Once a function has actually been linked to a library, the only way to subsequently establish linkage between the same function name and a different library is to execute another LIBRARY statement that names the same function and a different library. When all of a present library&#039;s linked functions are reassigned; the library is automatically removed from memory. When all of a resident library&#039;s linked functions are reassigned; the library may be removed from memory with the CLEAR command.&lt;br /&gt;
&lt;br /&gt;
In the following example, lines 01100 and 01200 load the libraries PRESLIB1 and PRESLIB2 into present memory. Line 01300 uses a named library statement to establish linkage between PRESLIB1 and the function FNASSIGN, and line 01400 actually executes FNASSIGN from the PRESLIB1 library. Line 1500 then re-assigns linkage of FNASSIGN to the library PRESLIB2, and line 1600 executes FNASSIGN from the PRESLIB2 library.&lt;br /&gt;
&lt;br /&gt;
 01100 LIBRARY &amp;quot;PRESLIB1&amp;quot;:&lt;br /&gt;
 01200 LIBRARY &amp;quot;PRESLIB2&amp;quot;:&lt;br /&gt;
 01300 LIBRARY &amp;quot;PRESLIB1&amp;quot;: FNASSIGN&lt;br /&gt;
 01400 LET FNASSIGN&lt;br /&gt;
 01500 LIBRARY &amp;quot;PRESLIB2&amp;quot;: FNASSIGN&lt;br /&gt;
 01600 LET FNASSIGN&lt;br /&gt;
&lt;br /&gt;
;DETACHMENT:&lt;br /&gt;
Regardless of how a library is loaded (resident, present or as needed), all linkages are detached at the time that the main program ends.&lt;br /&gt;
&lt;br /&gt;
There is no other way to completely detach a linkage other than ending the main program.&lt;br /&gt;
&lt;br /&gt;
===Present Library===&lt;br /&gt;
&lt;br /&gt;
A present library is a library that is loaded to remain in memory as long as the main program is active or until all linkages that have been established for the library are reassigned.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Global Variables in a present library are cleared when the main program ends.&lt;br /&gt;
&lt;br /&gt;
A library can be loaded present through three different methods: &lt;br /&gt;
&lt;br /&gt;
1.The first method is to specify a LIBRARY statement that identifies a library name but no function names. When this method is used, the library is loaded at the time that the LIBRARY statement is executed. For example, when the following statement is executed, the CURLIB library is immediately loaded into memory:&lt;br /&gt;
&lt;br /&gt;
 00210 LIBRARY &amp;quot;CURLIB&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
2.The second method of loading a library present is to specify the LIBRARY statement with both a library name and function names. When this method is used, the library is loaded the first time one of the specified functions is called. In the following example, line 00210 establishes linkage between the function FNCURLIB1 and the library CURLIB.&lt;br /&gt;
&lt;br /&gt;
Line 00220 causes the following to occur:&lt;br /&gt;
&lt;br /&gt;
:1.) The library CURLIB is loaded as a present library,&lt;br /&gt;
:2.) The function FNCURLIB is executed.&lt;br /&gt;
&lt;br /&gt;
 00210 LIBRARY &amp;quot;CURLIB&amp;quot;: FNCURLIB1&lt;br /&gt;
 00220 LET FNCURLIB1&lt;br /&gt;
&lt;br /&gt;
3.The third way to end up with a library loaded present is to execute a CLEAR STATUS command on a library that has already been loaded resident and has attached functions, thus turning it into a present library.&lt;br /&gt;
&lt;br /&gt;
===Resident Library===&lt;br /&gt;
&lt;br /&gt;
A resident library is a library program that is loaded to remain in memory, regardless of the status of the main program. It does not get removed from memory until it is explicitly cleared or until the Business Rules session is terminated. Loading a library resident saves the overhead associated with loading a library each time it is needed.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Business Rules allows resident libraries to handle their own global variables in any of three different ways:&lt;br /&gt;
&lt;br /&gt;
:1.) Globals may be cleared when the main program ends,&lt;br /&gt;
:2.) Globals may be retained irrespective of the status of the main program, or&lt;br /&gt;
:3.) Globals may be cleared after each function call to the resident library.&lt;br /&gt;
&lt;br /&gt;
The resident status of a resident library can be removed (thus changing the library into a present library) through the use of the CLEAR STATUS command.&lt;br /&gt;
&lt;br /&gt;
A library can be made resident through use of the enhanced LOAD command. However, it is important to understand that functions cannot be executed from any library -even a library that has been loaded into resident memory -until a LIBRARY statement names the functions to be executed and establishes linkage (either named or unnamed) between the named function and the resident library.&lt;br /&gt;
&lt;br /&gt;
In the following example, line 00130 causes RESLIB to be loaded into memory as a resident library. Line 00140 establishes named linkage between the function FNRESLIB1 and the RESLIB library. Line 00150 executes the function FNRESLIB1.&lt;br /&gt;
&lt;br /&gt;
 00130 EXECUTE &amp;quot;LOAD RESLIB,RESIDENT&amp;quot;&lt;br /&gt;
 00140 LIBRARY &amp;quot;RESLIB&amp;quot;: FNRESLIB1&lt;br /&gt;
 00150 LET FNRESLIB1&lt;br /&gt;
&lt;br /&gt;
==Comparison of User-Defined Function Features==&lt;br /&gt;
&lt;br /&gt;
The following table illustrates the similarities and differences between regular user-defined functions (non-library) and library user-defined functions.&lt;br /&gt;
&lt;br /&gt;
[[Image:Lib1.jpg]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Lib2.jpg]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Lib3.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Variable Usage==&lt;br /&gt;
&lt;br /&gt;
Before you start placing all your existing user-defined functions into separate libraries, you should fully understand how library functions deal with global variables.&lt;br /&gt;
&lt;br /&gt;
This section will focus on three main points:&lt;br /&gt;
&lt;br /&gt;
:1.) How a main program and a library function can communicate,&lt;br /&gt;
:2.) How functions within a library communicate, and&lt;br /&gt;
:3.) When global variables are cleared for a library program.&lt;br /&gt;
&lt;br /&gt;
===How main programs and library functions communicate===&lt;br /&gt;
&lt;br /&gt;
Business Rules programs communicate with regular user-defined functions via passed parameters, the returned function value, and global variables (variables not passed in the parameter list). All of these same communication options are available for library functions that are defined within the main program. However, only the first two options are available to library functions that are separate from the main program. These functions cannot access the main program&#039;s global variables because global variables are only available to routines and functions, which are defined within the same program. As a result, user-defined functions, which are held within a main program, may need to be reviewed for their global variable usage before they are changed to library functions and placed into a separate library program.&lt;br /&gt;
&lt;br /&gt;
If a program needs to communicate a large number of standard values to a library function, consider using an initialization function to pass the values to the library program. Then have the initialization function assign the passed values to global variables in the library so they will be available to all functions in the library.&lt;br /&gt;
&lt;br /&gt;
===How functions within a library communicate===&lt;br /&gt;
Within each library, all functions share variables which are global to that library, and library global variables generally retain their values between function calls. (The exception is when the RELEASE keyword is used on the LIBRARY statement, which is accepted both for resident and as-needed libraries; in this case, global variables are cleared after each function call.)&lt;br /&gt;
&lt;br /&gt;
The point at which globals are cleared for a library program varies according to several factors. See below for more information.&lt;br /&gt;
&lt;br /&gt;
===When global Variables are cleared===&lt;br /&gt;
The point at which a library&#039;s global variables are cleared depends on how the library was loaded and -in the case of resident libraries-what options are used.&lt;br /&gt;
&lt;br /&gt;
{\b Main program library} - For library functions that are defined within the main program, globals are cleared when a new main program is started or when the current main program is explicitly removed from memory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resident library&#039;&#039;&#039; - When a library is loaded resident, global variables may be cleared in any of three ways:&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Default&#039;&#039;&#039;||By default, Business Rules clears a resident library&#039;s global variables when the main program ends.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Retain&#039;&#039;&#039;||When the OPTION RETAIN statement is used in a resident library program, the library retains its global variables irrespective of when the main program ends. The only way to clear globals when this statement is used is to CLEAR the library from memory or to reload it with the LOAD RESIDENT command. Remember that the library must be loaded resident for the OPTION RETAIN statement to have any affect.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Release&#039;&#039;&#039;||When a resident library is named on a LIBRARY statement with the RELEASE keyword, the library&#039;s global variables are cleared after each function call to the library. This capability is provided so that the decision to load a library resident or as-needed can be made on a case-by-case basis; the program code can remain the same (because Business Rules handles the variables the same) regardless of whether the library is loaded resident or as-needed.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
{\b Present library} - When a library is loaded present, global variables are cleared when the main program ends.&lt;br /&gt;
&lt;br /&gt;
{\b As-needed library} - When a library is loaded as-needed, global variables are cleared after each function call to the library.&lt;br /&gt;
&lt;br /&gt;
The following table summarizes the information presented above. The keywords used in the &amp;quot;When globals are cleared&amp;quot; column are the same keywords used in the STATUS LIBRARY display (second column from right) to identify when variables for the listed library will be cleared. (See the &amp;quot;STATUS&amp;quot; command in the Commands chapter for complete information about this display.) The keywords are defined as follows:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;RUN&#039;&#039;&#039;||Globals are cleared when new main program is run.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;END&#039;&#039;&#039;||Globals are cleared when main program ends.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;EXIT&#039;&#039;&#039;||Globals are cleared after each function call to the library.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;RETAIN&#039;&#039;&#039;||Globals are retained, irrespective of main program status.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Help0188.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Additional Processing Consideration==&lt;br /&gt;
&lt;br /&gt;
Active procedures and opened files are not affected by library function calls, unless the library issues commands that specifically affect them. This includes PROCERR settings.&lt;br /&gt;
&lt;br /&gt;
A nice aspect of library functions is the capability of a program to call a library function, which, in turn, calls a function in the main program. This supports the concept of manager functions that provide overall functionality while the main program fills in the details that may vary from program to program.&lt;br /&gt;
&lt;br /&gt;
The way to permit library routines to be overridden (functionally replaced) by corresponding functions in the main program is to have the library include those functions in a LIBRARY statement that doesn&#039;t specify a library name. Then have the library execute that statement after the main program has started. The library will then attach the library function in the main program instead of its own, even if a copy of the function exists in the library, because the main program is always regarded as having been loaded last for purposes of resolving unnamed library searches.&lt;br /&gt;
&lt;br /&gt;
Note that if a LIBRARY statement within a resident library creates linkage and then the main program ends, the linkage is broken and that LIBRARY statement must be re-executed before the function can be called again by the resident library.&lt;br /&gt;
&lt;br /&gt;
With respect to speed, parameters should be passed by reference (using the &amp;amp; in front of the variable name in the DEF statement) wherever possible. This avoids needless allocation of memory and copying of data, which is a significant part of function call processing.&lt;br /&gt;
&lt;br /&gt;
If you want to avoid the processing time required to load a library until a function within it is called, simply name the library and function on the same LIBRARY statement. However, if you want to be sure that the named functions exist within the library, first load the library with a statement that contains no function names. This will cause the library to be loaded at the time the LIBRARY statement is executed. Then when the LIBRARY statement containing the function list is encountered, the library (which is now in memory) will be checked for the presence of each function.&lt;br /&gt;
&lt;br /&gt;
It should be emphasized that executing a LOAD command does not establish function linkage. A subsequent LIBRARY statement must be processed to establish such linkage.&lt;br /&gt;
&lt;br /&gt;
When replacing a resident library with a different library, the first library should be cleared with a CLEAR command to free its memory before loading the second library.&lt;br /&gt;
&lt;br /&gt;
Updating a library (with the REPLACE command) has no effect on application environments until the library is (re)loaded.&amp;lt;br&amp;gt;&lt;br /&gt;
If a LIBRARY statement contains the name of a local function that is defined as non-library, a &amp;quot;duplicate function definition&amp;quot; error is generated when the program is run or saved.&lt;br /&gt;
&lt;br /&gt;
If a LIBRARY statement refers to a library without RELEASE and another statement refers to the same program with RELEASE, an error is generated. Also RELEASE cannot be specified for any library with the OPTION RETAIN statement.&lt;br /&gt;
&lt;br /&gt;
If a function in the main program, defined with the LIBRARY keyword, is called from within a library (a condition referred to as library loopback), the main program uses a fresh for-next stack.&amp;lt;br&amp;gt;&lt;br /&gt;
Therefore, pre-existing for-next processes are not recognized until the library returns normally to the main program.&lt;br /&gt;
&lt;br /&gt;
If more than one DEF LIBRARY statement for the same function name appears in a program, the lowest numbered definition will be used. More than one non-library DEF for the same variable is no longer permitted.&lt;br /&gt;
&lt;br /&gt;
Memory fragmentation can occur if a library is loaded resident while other programs are in memory, and then the main program chains leaving files open through either the CHAIN FILES statement, or having files open NOCLOSE. To avoid this problem, if you use CHAIN FILES or NOCLOSE, load your resident libraries before running application programs.&lt;br /&gt;
&lt;br /&gt;
Alternate libraries can be interrogated with function key 9 during a program pause.&lt;br /&gt;
&lt;br /&gt;
===Editing Active Libraries===&lt;br /&gt;
&lt;br /&gt;
When both a main program and a library program that is separate from the main program are active ( a function in the library program is currently being executed), the LIST command will display the contents of the library program. When functions in multiple library programs are active, the program with the most recently called function will be displayed.&lt;br /&gt;
&lt;br /&gt;
It is important to note that the only way to save changes made to a library program that has been activated by a main program is to list the library to a file and reload it from source later on. Because of this, it makes sense to develop a new library function first within the main program. Then once you&#039;ve completed the testing and debugging process, you can break it out and test it as a separate library function.&lt;br /&gt;
&lt;br /&gt;
===Linkage===&lt;br /&gt;
&lt;br /&gt;
When used to its full potential, the Business Rules Library Facility enables multiple versions of the same function (with the same name) to exist in different libraries, all of which may be loaded into memory. The actual library that is used for a specific function call is determined according to Business Rules rule for linkage, which is the process of associating a function name with a library name.&amp;lt;br&amp;gt;&lt;br /&gt;
Business Rules keeps tracks of established linkages in a table that it references each time a function is called.&lt;br /&gt;
&lt;br /&gt;
The LIBRARY statement may be used to establish linkage in one of two ways: the named method, or the unnamed method. These methods are defined as follows:&lt;br /&gt;
&lt;br /&gt;
;Named&lt;br /&gt;
The LIBRARY statement explicitly links one or more specific functions to a specific library. This is the most efficient and foolproof method for assuring that the library function you wish to use gets executed.&lt;br /&gt;
&lt;br /&gt;
In the following example, the functions FNRESLIB1 through FNRESLIB5 are explicitly linked to the library MAIN. When any of these functions is called, Business Rules will automatically execute them from the MAIN library. (Regardless of whether or not any other library currently in memory also contains functions by the same name.)&lt;br /&gt;
&lt;br /&gt;
 50300 LIBRARY &amp;quot;MAIN&amp;quot;:FNRESLIB1,FNRESLIB2,FNRESLIB3,FNRESLIB4,FNRESLIB5&lt;br /&gt;
&lt;br /&gt;
;Unnamed&lt;br /&gt;
The LIBRARY statement names the desired library functions and leaves it to Business Rules to determine which of the currently identified libraries they should be linked to. This determination is made according to the pre-set guidelines described below. The unnamed method of linkage is useful when your development methodology involves using multiple versions of the same function to control program options and features.&lt;br /&gt;
&lt;br /&gt;
When the unnamed method is used, Business Rules first searches the main program, then each library that is currently either resident or present (in last loaded, first searched order) for each function listed on the LIBRARY statement. Once Business Rules finds the function, the linkage is established, and -unless the linkage is explicitly changed with another LIBRARY statement or detached because the main program ends -all future calls to the same function will continue to utilize the same linkage. Note that Business Rules does not search as-needed libraries when the unnamed method of establishing linkage is used. Also, it is important to understand that it can take significantly longer to establish linkage using the unnamed method of linkage than with the named method of linkage.&lt;br /&gt;
&lt;br /&gt;
In the following example, line 01000 loads RESLIB as a resident library. Lines 01100 and 01200 load PRESLIB1 and PRESLIB2 as present libraries, and line 01300 names ASNLIB as an as-needed library. The LIBRARY statement on line 01400 establishes unnamed linkage for the function FNALIBI. When line 01500 is executed, Business Rules searches the currently loaded programs in the following order for FNALIBI: Main program, PRESLI2, PRESLIB1, RESLIB. Note that ASNLIB is not considered for this search because it is not currently loaded in memory.&lt;br /&gt;
&lt;br /&gt;
 01000 EXECUTE &amp;quot;LOAD RESLIB,RESIDENT&amp;quot;&lt;br /&gt;
 01100 LIBRARY &amp;quot;PRESLIB1&amp;quot;:&lt;br /&gt;
 01200 LIBRARY &amp;quot;PRESLIB2&amp;quot;:&lt;br /&gt;
 01300 LIBRARY RELEASE,&amp;quot;ASNLIB&amp;quot;: FNASNLIB1&lt;br /&gt;
 01400 LIBRARY : FNALIBI&lt;br /&gt;
 01500 LET FNALIBI&lt;br /&gt;
&lt;br /&gt;
===Status Library===&lt;br /&gt;
&lt;br /&gt;
Business Rules STATUS LIBRARY command may be used to display a table that identifies all the linkages that are currently active for each library. See &amp;quot;STATUS&amp;quot; in the Commands chapter for more information. For information about releasing and/or changing library linkages, see the term Linkage reassignment and detachment below.&lt;br /&gt;
&lt;br /&gt;
==Sample Program==&lt;br /&gt;
&lt;br /&gt;
The following two sample sections of code are, for convenience purposes, labeled &amp;quot;Main Program&amp;quot; and &amp;quot;Library&amp;quot;. The Main Program references two functions (FNSEND and FNRECEIVE), which are located in the Library. Line 50 of the Main Program establishes the function linkage; line 70 prompts for a message; and line 110 calls the FNSEND function, which is defined on line 30 of the Library.&lt;br /&gt;
&lt;br /&gt;
FNSEND opens the communications port and sends the operator-specified message to the terminal connected to the port. The Main Program then calls the FNRECEIVE function, which is defined on line 80 of the Library. This function waits up to 15 seconds for a response (by default), returns the response in the parameter, and returns its length as a function value. Finally, the Main Program prints the response or the message &amp;quot;No Response&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
&lt;br /&gt;
 00010 ! MAIN PROGRAM&lt;br /&gt;
 00020 !&lt;br /&gt;
 00030 DIM MESG$*60, RESPONSE$*120&lt;br /&gt;
 00040 !&lt;br /&gt;
 00050 LIBRARY &amp;quot;TOOLS\LIB1&amp;quot;: FNSEND, FNRECEIVE&lt;br /&gt;
 00060 !&lt;br /&gt;
 00070 PRINT &amp;quot;Specify Message&amp;quot;&lt;br /&gt;
 00080 LINPUT MESG$&lt;br /&gt;
 00090 IF LEN(MESG$) = 0 THEN STOP&lt;br /&gt;
 00100 !&lt;br /&gt;
 00110 LET FNSEND(MESG$)&lt;br /&gt;
 00120 !&lt;br /&gt;
 00130 IF FNRECEIVE(RESPONSE$) THEN !:PRINT RESPONSE$ !:ELSE !:PRINT &amp;quot;No Response&amp;quot;&lt;br /&gt;
 00140 GOTO 70&lt;br /&gt;
&lt;br /&gt;
 Library:&lt;br /&gt;
 00010 ! LIB1&lt;br /&gt;
 00020 !&lt;br /&gt;
 00030 DEF LIBRARY, FNSEND(MESSAGE$*60)&lt;br /&gt;
 00040  IF NOT COMM OPENED THEN !:OPEN #40: &amp;quot;NAME=COM2:, FORMAT=ASYNC,BAUD=2400&amp;quot;,DISPLAY, OUTIN !:COMM OPENED = 1&lt;br /&gt;
 00050  PRINT #40: MESSAGES$&lt;br /&gt;
 00060 FNEND&lt;br /&gt;
 00070 !&lt;br /&gt;
 00080 DEF LIBRARY FNRECEIVE(&amp;amp;RESP$)&lt;br /&gt;
 00090  LINPUT #40: RESP$ IOERR 100&lt;br /&gt;
 00100  FNRECEIVE = LEN(RESP$)&lt;br /&gt;
 00110 FNEND&lt;br /&gt;
&lt;br /&gt;
===Tips for implementing Library Functions in Existing Applications===&lt;br /&gt;
&lt;br /&gt;
As mentioned above, it is important that you consider your current usage of global variables before converting your existing user-defined functions into library functions and placing them into a separate program. This section provides some examples of how you can modify existing applications to utilize library functions, even if the existing applications currently access or modify user-defined function variables from outside the function. Other examples shown in this section demonstrate how you can turn an entire program (such as a client maintenance program) into a library function that a user can invoke at will from within another program (such as order entry) and provide some tips on implementing libraries for programs that use [[FNSNAP]]! tools.&lt;br /&gt;
&lt;br /&gt;
;Example 1:&lt;br /&gt;
Separating main program logic from user-defined functions&amp;lt;br&amp;gt;&lt;br /&gt;
The following is a very simple example of a program that uses a user-defined function.&lt;br /&gt;
&lt;br /&gt;
;ORIGINAL PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page, plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
The steps you would need to take to separate the function into a separate library and enable the main program to call the function would be as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Place the user-defined functions into their own program.&lt;br /&gt;
:2.) Modify the DEF line for each of the functions in the new library program to utilize the LIBRARY keyword (demonstrated in line 02000 of the library program below).&lt;br /&gt;
:3.) Delete the separated functions from the main programs that are to use the new library.&lt;br /&gt;
:4.) Add a LIBRARY statement to the main program that names each function that is to be called from the library program (demonstrated in line 00005 of the main program below).&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;howto1nl&amp;quot; : FNDOCEST&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,lus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
;Example 2:&lt;br /&gt;
Function uses global variables established by main program&lt;br /&gt;
&lt;br /&gt;
In the following program, the global variable PAGEEST is established by the main program logic on line 00020. This same global variable is accessed by the user-defined function at line 02010.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
As there is no way for a main program to share its global variables with a library function contained in a separate program, this program must be modified before it can be separated into &amp;quot;main&amp;quot; and &amp;quot;library&amp;quot; programs. In the following example, line 02000 has been modified (as shown in italics) to pass the PAGEEST variable by reference, thereby causing the library function to use the main program&#039;s copy of the variable.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
;Example 3:&lt;br /&gt;
Existing program queries function variable from outside function&amp;lt;br&amp;gt;&lt;br /&gt;
This example shows the same starting program as shown in Example 1, except that line 00040 has been added to demonstrate a situation where the main program logic queries (without changing) a variable that has been established by the user-defined function. This programming technique also is not allowed when functions are separated into library programs,&lt;br /&gt;
as there is just one way (via the function variable) for a separate library function to pass a value back to the main program.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST&lt;br /&gt;
 00040 IF WRITETIME&amp;gt;8 THEN PRINT &amp;quot;Total days: &amp;quot;;WRITETIME/8&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
When starting new programming projects that are to utilize Business Rules Libraries, ADS recommends against the programming technique shown here. However, if your programs already use this technique and you want to utilize the benefits of libraries with as little work as possible, you could change the programs in the manner shown below.&lt;br /&gt;
&lt;br /&gt;
The following two code sections show the original program as it would be when split into main program and library, and with a &amp;quot;rigged&amp;quot; technique for the program to get the value of the queried variable from the library. The &amp;quot;rig&amp;quot; is that all references to the WRITETIME variable in the main logic have been changed to FNWRITETIME, and FNWRITETIME has been added to the library to query the value of WRITETIME and pass it back to the main program. Note that there is a limitation to this technique: the program must be loaded into either resident memory (without use of RELEASE on the LIBRARY statement) or present memory for it to work. This is because the technique relies on the library&#039;s global variables remaining active even after function calls to it have been completed.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;howto2nl&amp;quot; : FNDOCEST,FNWRITETIME&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 IF FNWRITETIME&amp;gt;8 THEN PRINT &amp;quot;Total days: &amp;quot;;FNWRITETIME/8&lt;br /&gt;
&lt;br /&gt;
;LIBRARY:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page, plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is:&amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
 03000 DEF LIBRARY FNWRITETIME=WRITETIME&lt;br /&gt;
&lt;br /&gt;
;Example 4:&lt;br /&gt;
Existing program queries or modifies function variable from outside function&amp;lt;br&amp;gt;&lt;br /&gt;
In the following example, line 00120 of the main program logic modifies the value of TOTTIME, which is established by the FNDOCEST function. It is important that this modified value be communicated back to the function, because line 02030 of the function uses it for subsequent calls. Note also that lines 00100 and 00130 of the main program logic also query (without modifying) the value of TOTTIME.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages for chapter 1:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 PRINT &amp;quot;Enter estimated number of pages for chapter 2:&amp;quot;&lt;br /&gt;
 00050 INPUT PAGEEST&lt;br /&gt;
 00060 PRINT &amp;quot;Is subject matter highly technical? (Y/N)&amp;quot;&lt;br /&gt;
 00070 INPUT TECHLEVEL$&lt;br /&gt;
 00080 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00090 IF UPRC$(TECHLEVEL$)=&amp;quot;Y&amp;quot; THEN&lt;br /&gt;
 00100  LET SURPLUS=TOTTIME*.2&lt;br /&gt;
 00110  PRINT &amp;quot;Surplus time for technical matter: &amp;quot;;SURPLUS;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00120  LET TOTTIME+=SURPLUS&lt;br /&gt;
 00130  PRINT &amp;quot;Total time is &amp;quot;;TOTTIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00140 END IF&lt;br /&gt;
&lt;br /&gt;
;LIBRARY:&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030  PRINT &amp;quot;Accumulated total is: &amp;quot;;TOTTIME+=WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02040 FNEND&lt;br /&gt;
&lt;br /&gt;
As noted for the previous example in this section, programming practices such as this are not recommended for new development that is to utilize the Library Facility. These examples are supplied to help you quickly modify existing programs so they can utilize the benefits of libraries.&lt;br /&gt;
&lt;br /&gt;
The next two programs (main and library) show how the original program was changed to work with libraries.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;HOWTO3NL&amp;quot; : FNDOCEST,FNADD TOTTIME&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages for chapter 1:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 PRINT &amp;quot;Enter estimated number of pages for chapter 2:&amp;quot;&lt;br /&gt;
 00050 INPUT PAGEEST&lt;br /&gt;
 00060 PRINT &amp;quot;Is subject matter highly technical? (Y/N)&amp;quot;&lt;br /&gt;
 00070 INPUT TECHLEVEL$&lt;br /&gt;
 00080 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00090 IF UPRC$(TECHLEVEL$)=&amp;quot;Y&amp;quot; THEN&lt;br /&gt;
 00100  LET SURPLUS=FNADD TOTTIME(0)*.2&lt;br /&gt;
 00110  PRINT &amp;quot;Surplus time for technical matter: &amp;quot;;SURPLUS;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00130  PRINT &amp;quot;Total time is &amp;quot;;FNADD TOTTIME(SURPLUS);&amp;quot;hours&amp;quot;&lt;br /&gt;
 00140 END IF&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030  PRINT &amp;quot;Accumulated total is: &amp;quot;;TOTTIME+=WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02040 FNEND&lt;br /&gt;
 03000 DEF LIBRARY&lt;br /&gt;
 FNADD TOTTIME(ADDTOTTIME)=TOTTIME+=ADDTOTTIME&lt;br /&gt;
&lt;br /&gt;
Once the required steps of separating the two programs, adding the necessary LIBRARY statement to the main program and adding the LIBRARY keyword to the DEF statement in the library program were completed for the above code, the following steps were conducted to enable the main program and function to communicate the value of TOTTIME. Note that there is a limitation to the technique shown: the library program must be loaded into either resident memory (without use of RELEASE on the LIBRARY statement) or present memory for it to work. This is because it relies on the library&#039;s global variables remaining active even after function calls to it have been completed.&lt;br /&gt;
&lt;br /&gt;
:1.) The FNADD TOTTIME function was added to the library program (line 03000). This function takes a variable (representing the amount to add to TOTTIME) that is passed by the main program. It adds the passed variable to TOTTIME, and also assigns the new value of TOTTIME to the function variable FNADD TOTTIME.&lt;br /&gt;
:2.) The FNADD TOTTIME function name was added to the LIBRARY statement on line 00005 of the main program.&lt;br /&gt;
:3.) Line 00120 of the main program was removed, and line 00130 was modified to call the FNADD TOTTIME library function instead of modifying TOTTIME directly. The value of SURPLUS is passed to FNADD TOTTIME; FNADD TOTTIME takes over the job of modifying the value of TOTTIME and making sure that both the main program and the library program know its new value.&lt;br /&gt;
:4.) Line 00100 of the main program was changed to call the FNADD TOTTIME function as well. Since this line only needs to query the value of TOTTIME, it passes a value of 0 as the amount to add to TOTTIME.&lt;br /&gt;
&lt;br /&gt;
;Example 5:&lt;br /&gt;
Turning an existing program into a user-invokable library function&amp;lt;br&amp;gt;&lt;br /&gt;
Business Rules Library Facility makes it very easy to turn an entire program into a library function that a user can invoke at will from within another program. For example, consider a standard application that includes both a client maintenance (MNTCUST) program and an order entry program (ORDERS). You would like to give users the ability to invoke the client maintenance program from within the order entry program whenever they press F4. The steps required to do this are as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Modify MNTCUST by placing the entire original program into a user-defined library function and adding a few lines that cause the program to call itself as a library function whenever it is executed as the main program.&lt;br /&gt;
:a.) Move any user-defined functions that exist within the main body of the program to the end of the program (or to a separate library).&lt;br /&gt;
:b.) Add lines such as the following to the top of the program. NOTE that the (program name) in line 00030 represents the name of the program (such as a main menu) from which you currently normally invoke the client maintenance program.&lt;br /&gt;
&lt;br /&gt;
 00010 LIBRARY &amp;quot;MNTCUST&amp;quot; : FNMNTCUST&lt;br /&gt;
 00020 LET FNMNTCUST&lt;br /&gt;
 00030 CHAIN (program name)&lt;br /&gt;
 00040 DEF LIBRARY FNMNTCUST&lt;br /&gt;
&lt;br /&gt;
:c.) Add the following line to the end of the main body of the program (prior to any user-defined function definitions):&lt;br /&gt;
&lt;br /&gt;
 80000 FNEND&lt;br /&gt;
&lt;br /&gt;
:2.) Modify ORDERS as follows:&lt;br /&gt;
&lt;br /&gt;
:a.) Change the screen to include a label that identifies the operation of the F4 key.&lt;br /&gt;
:b.) Change the program to check for pressing of the F4 key.&lt;br /&gt;
:c.) Change the program to execute the following whenever F4 is pressed. Note that the LIBRARY statement in line 50000 utilizes the &amp;quot;RELEASE&amp;quot; keyword: this causes the MNTCUST library to be loaded into memory on an as-needed basis only. Thus the only time that the on-the-fly client maintenance feature uses system resources is when the user actually requests the capability by pressing F4.&lt;br /&gt;
&lt;br /&gt;
 50000 LIBRARY RELEASE, &amp;quot;MNTCUST&amp;quot; :FNMNTCUST&lt;br /&gt;
 50010 LET FNMNTCUST&lt;br /&gt;
&lt;br /&gt;
;Example 6:&lt;br /&gt;
Tips for moving [[FNSNAP]]! functions into separate libraries for users of [[FNSNAP]]! programming tools, modifying existing programs to use libraries will involve a combination of the techniques demonstrated above. Every developers programs are different, so this section cannot give you a beginning-to-end list of steps to complete to accomplish the task, but the following are some steps you can start with:&lt;br /&gt;
&lt;br /&gt;
:1.) Place the FNSNAP! functions into their own program. (This example uses MAIN\\FNSNAP as the path and location of the new program.)&lt;br /&gt;
:2.) Modify the DEF line for each of the functions in FNSNAP to utilize the LIBRARY keyword. For example:&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 60150 DEF FNOK&lt;br /&gt;
&lt;br /&gt;
To this:&lt;br /&gt;
&lt;br /&gt;
 60150 DEF LIBRARY FNOK&lt;br /&gt;
&lt;br /&gt;
:3.) Add the following FNFNSNAP INIT function to the FNSNAP program. This function sets all the global variables that are used by the FNSNAP functions (in the past, FNSNAP! users were instructed to add these variable settings to the start of their programs). FNFNSNAP INIT also executes a LIBRARY statement for the FNSNAP program. This LIBRARY statement establishes linkage for all the functions in the FNSNAP program that are called by other functions in the same program.&lt;br /&gt;
&lt;br /&gt;
 00121 DEF LIBRARY FNFNSNAP INIT&lt;br /&gt;
 00122 LET DATFMT$=&amp;quot;MM-DD-CCYY&amp;quot; !:LET FULLSCR=0 !:LET MAXSROWS=22 !:LET WINDEV=OWINDEV=69 !:LET MGA$=&amp;quot;24,2,C 78,&amp;quot; !:IF NOT SSAV THEN LET SSAV=101 !:!Common Variables required by FNSNAP! !:&lt;br /&gt;
 00124 LIBRARY &amp;quot;MAIN\FNSNAP&amp;quot; : FNRELPART,FNSAVPART, FNPM, FNAUTO, FNOK, FNWIN,FNCLSWIN, FNZERO, FNTIMMILREG, FNSSAV,FNSAVSCR, FNSETBAD, FNPURGE, FNFLDSEL$&lt;br /&gt;
 00130 FNEND !:&lt;br /&gt;
:4.) Delete the separated functions from the main programs that are to use the FNSNAP library.&lt;br /&gt;
&lt;br /&gt;
:5.) Add the following program line to each of the main programs that are to use the FNSNAP library. This statement establishes linkage between the functions to be called and the program they are located in, and it calls the FNFNSNAP INIT function, which sets the library&#039;s global values:&lt;br /&gt;
&lt;br /&gt;
 00160 LIBRARY &amp;quot;MAIN\FNSNAP&amp;quot;:FNFNSNAP INIT, FNSSAV, FNPOPWIN,FNPOPBAR, FNWINDEV, FNPOPWIN INIT,FNPOPBAR INIT, FNCO$, FNMGCLR, FNTOP,FNOK, FNSAVSCR, FNSCRMGR, FNSAVPART,FNRELPART, FNCLRPART, FNZERO, FNNULL$,FNTIMMILREG, FNDIALOG$, FNWIN, FNCLSWIN,FNNOKEY, FNPOPUP, FNPM, FNAUTO,FNPFKEYLINE !:LET FNFNSNAP INIT !:!&lt;br /&gt;
&lt;br /&gt;
==Error Processing==&lt;br /&gt;
&lt;br /&gt;
If an error is not trapped in a library function, the error is reported back to the calling program. At this time the following system variables are set:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;LINE&#039;&#039;&#039;||The line number of the calling program function call.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;ERR&#039;&#039;&#039;||The error number that occurred in the library function.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;CNT&#039;&#039;&#039;||The appropriate value as if the error occurred in the calling program.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If an error occurs while attempting to match parameters between a function call and the function definition, CNT is set to the number of parameters successfully matched.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:User Defined Functions and Libraries]]&lt;br /&gt;
[[Category:Facility]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Library_Facility&amp;diff=2656</id>
		<title>Library Facility</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Library_Facility&amp;diff=2656"/>
		<updated>2013-04-15T19:29:36Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: /* Present Library */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Business Rules!]] now includes a comprehensive &#039;&#039;&#039;Library&#039;&#039;&#039; Facility. Similar to [[DLL]] (Dynamic Link Libraries), the Business Rules! Library Facility enables [[user-defined functions]] to be placed in a program (&amp;quot;library&amp;quot;) that is separate from the main program. The library may be loaded &amp;quot;resident&amp;quot; (staying loaded regardless of the status of the main program), it may be loaded &amp;quot;present&amp;quot; (remaining active in current memory as long as the main program is active), or it may be loaded &amp;quot;as needed&amp;quot; (loaded when needed to execute a function, then unloaded as soon as the function has been executed).&lt;br /&gt;
&lt;br /&gt;
A library is any [[Business Rules! program]] that contains library functions. A library must be identified to Business Rules! before a program can execute any of its functions. When a library is identified, Business Rules! adds its name to an internal table of library names. This table identifies the names of all the libraries that should be searched whenever a library function that is not yet linked to a library is called.&lt;br /&gt;
&lt;br /&gt;
Business Rules! places no limits on the number of libraries that may be loaded into memory at one time. Business Rules! provides for maximum memory usage and performance flexibility by allowing libraries to be identified and loaded into memory via three different methods: the resident method, the present method and the as-needed method. See the separate descriptions below for specific information about each type of library.&lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
&lt;br /&gt;
Some of the significant advantages of placing user-defined functions in a library rather than keeping them in the main program are as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Reduces the size of executables - its no longer necessary to include a standard set of user-defined functions in every program in your application. For some applications (which may include literally hundreds of copies of the exact same code), the potential savings in disk space are tremendous.&lt;br /&gt;
&lt;br /&gt;
:2.) Saves maintenance time - If you&#039;re in the habit of duplicating user-defined functions in every single program that needs them, you know what kind of effort it takes to make (and distribute to your clients) even a one-line change to a function. With Business Rules Library Facility, you make the change only once, and you replace only one program at the client&#039;s site.&lt;br /&gt;
&lt;br /&gt;
:3.) Encourages use of programming standards - The use of library functions for a standard routine is a great way to encourage programming consistency and the setting of standards among your programmers.&lt;br /&gt;
&lt;br /&gt;
==Library Function==&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;&#039;library function&#039;&#039;&#039; is a specially defined [[user-defined function]]; it exists in a program which is frequently separate from the main program, but it may exist in the main program as well.&lt;br /&gt;
&lt;br /&gt;
To qualify as a library function, a user-defined function must simply utilize the DEF statement&#039;s LIBRARY keyword. The following is an example of a library function definition:&lt;br /&gt;
&lt;br /&gt;
 52400 DEF LIBRARY FNRESLIB2&lt;br /&gt;
 52500 PRINT &amp;quot;This is a library function&amp;quot;&lt;br /&gt;
 52600 FNEND&lt;br /&gt;
&lt;br /&gt;
Executing a library function is a two-step process. First, the program executing the library function must name the function in a LIBRARY statement, which establishes either named or unnamed linkage. Second, the program must call the library function; this may be accomplished using any of the same methods that is available for calling other user-defined functions. In the following example, line 01000 uses the LIBRARY statement to establish named linkage between the function FNPRESLIB2 and the library PRESLIB. Line 01100 causes the library PRESLIB to be loaded into present memory (if the library does not already exist in memory), then executes FNPRESLIB2.&lt;br /&gt;
&lt;br /&gt;
 01000 LIBRARY &amp;quot;PRESLIB&amp;quot;: FNPRESLIB2&lt;br /&gt;
 01100 LET FNPRESLIB2&lt;br /&gt;
&lt;br /&gt;
===Implementation Considerations===&lt;br /&gt;
&lt;br /&gt;
Business Rules Facility was carefully designed to offer a great deal of power and flexibility. Before you begin implementing this capability into your existing applications and ongoing development, ADS recommends that you consider the following:&lt;br /&gt;
&lt;br /&gt;
:1.)  Should your libraries remain resident?&lt;br /&gt;
Business Rules allows for libraries to remain resident in memory (providing maximum performance) or to be loaded and released as needed (providing best utilization of memory). Be sure to select the method or combination of methods that&#039;s best for your applications.&lt;br /&gt;
&lt;br /&gt;
:2.) Will you use multiple versions of the same function?&lt;br /&gt;
Since maintaining more than one version of a function is one method of controlling program options, Business Rules&#039; rule for library selection has been established with care. You should carefully review these rules and the ways in which multiple libraries can be of use to you as you plan your implementation.&lt;br /&gt;
&lt;br /&gt;
Until you feel comfortable with the intricacies of the Business Rules Library Facility, ADS recommends that you give every library function a name that is unique from every other library function.&lt;br /&gt;
&lt;br /&gt;
:3.) Do your existing functions utilize global program variables?&lt;br /&gt;
Unlike local user-defined functions, library functions that exist in a program separate from the main program cannot access main program variables globally. They have to be specifically passed. You should carefully review your usage of global variables before moving local functions into separate libraries.&lt;br /&gt;
&lt;br /&gt;
===As needed Library===&lt;br /&gt;
&lt;br /&gt;
An as-needed library is loaded and unloaded as needed for execution of specific functions. Loading a library only when it is needed allows the program to conserve memory usage.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Global Variables in an as-needed library are cleared each time a function call to the library is completed and the library is subsequently unloaded from memory.&lt;br /&gt;
&lt;br /&gt;
Programs can indicate that a library is to be loaded as needed by specifying the LIBRARY statement with both the RELEASE parameter and function names. This causes Business Rules to establish named linkage between the specified function(s) and the specified library, but it does not actually load the library. (The library is loaded only when one of the as-needed library&#039;s functions is actually called.) In the following example, line 00280 establishes linkage between the library ASNLIB and the function FNASNLIB1. Line 00290 causes the following to occur:&lt;br /&gt;
&lt;br /&gt;
:1.) Load ASNLIB into memory,&lt;br /&gt;
:2.) Execute the function FNASNLIB1,&lt;br /&gt;
:3.) Remove ASNLIB from memory.&lt;br /&gt;
&lt;br /&gt;
 00280 LIBRARY RELEASE,&amp;quot;ASNLIB&amp;quot;: FNASNLIB1&lt;br /&gt;
 00290 LET FNASNLIB1&lt;br /&gt;
&lt;br /&gt;
===Linkage Reassignment and Detachment===&lt;br /&gt;
&lt;br /&gt;
Once Business Rules has established linkage between a specific function and a specific library, the linkage remains active until a specific event causes it to become reassigned or detached.&lt;br /&gt;
&lt;br /&gt;
;REASSIGNMENT:&lt;br /&gt;
As noted previously, the LIBRARY statement may be used to establish linkage between a function and the library from which it is to be called. When the named LIBRARY statement is used, linkage is directly established between the named library and the named function(s). When the unnamed LIBRARY statement is used, Business Rules searches for the function according to some pre-set guidelines and assigns linkage to the first library within which the function definition is found.&lt;br /&gt;
&lt;br /&gt;
Once a function has actually been linked to a library, the only way to subsequently establish linkage between the same function name and a different library is to execute another LIBRARY statement that names the same function and a different library. When all of a present library&#039;s linked functions are reassigned; the library is automatically removed from memory. When all of a resident library&#039;s linked functions are reassigned; the library may be removed from memory with the CLEAR command.&lt;br /&gt;
&lt;br /&gt;
In the following example, lines 01100 and 01200 load the libraries PRESLIB1 and PRESLIB2 into present memory. Line 01300 uses a named library statement to establish linkage between PRESLIB1 and the function FNASSIGN, and line 01400 actually executes FNASSIGN from the PRESLIB1 library. Line 1500 then re-assigns linkage of FNASSIGN to the library PRESLIB2, and line 1600 executes FNASSIGN from the PRESLIB2 library.&lt;br /&gt;
&lt;br /&gt;
 01100 LIBRARY &amp;quot;PRESLIB1&amp;quot;:&lt;br /&gt;
 01200 LIBRARY &amp;quot;PRESLIB2&amp;quot;:&lt;br /&gt;
 01300 LIBRARY &amp;quot;PRESLIB1&amp;quot;: FNASSIGN&lt;br /&gt;
 01400 LET FNASSIGN&lt;br /&gt;
 01500 LIBRARY &amp;quot;PRESLIB2&amp;quot;: FNASSIGN&lt;br /&gt;
 01600 LET FNASSIGN&lt;br /&gt;
&lt;br /&gt;
;DETACHMENT:&lt;br /&gt;
Regardless of how a library is loaded (resident, present or as needed), all linkages are detached at the time that the main program ends.&lt;br /&gt;
&lt;br /&gt;
There is no other way to completely detach a linkage other than ending the main program.&lt;br /&gt;
&lt;br /&gt;
===Present Library===&lt;br /&gt;
&lt;br /&gt;
A present library is a library that is loaded to remain in memory as long as the main program is active or until all linkages that have been established for the library are reassigned.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Global Variables in a present library are cleared when the main program ends.&lt;br /&gt;
&lt;br /&gt;
A library can be loaded present through three different methods: &lt;br /&gt;
&lt;br /&gt;
1.The first method is to specify a LIBRARY statement that identifies a library name but no function names. When this method is used, the library is loaded at the time that the LIBRARY statement is executed. For example, when the following statement is executed, the CURLIB library is immediately loaded into memory:&lt;br /&gt;
&lt;br /&gt;
 00210 LIBRARY &amp;quot;CURLIB&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
2.The second method of loading a library present is to specify the LIBRARY statement with both a library name and function names. When this method is used, the library is loaded the first time one of the specified functions is called. In the following example, line 00210 establishes linkage between the function FNCURLIB1 and the library CURLIB.&lt;br /&gt;
&lt;br /&gt;
Line 00220 causes the following to occur:&lt;br /&gt;
&lt;br /&gt;
:1.) The library CURLIB is loaded as a present library,&lt;br /&gt;
:2.) The function FNCURLIB is executed.&lt;br /&gt;
&lt;br /&gt;
 00210 LIBRARY &amp;quot;CURLIB&amp;quot;: FNCURLIB1&lt;br /&gt;
 00220 LET FNCURLIB1&lt;br /&gt;
&lt;br /&gt;
3.The third way to end up with a library loaded present is to execute a CLEAR STATUS command on a library that has already been loaded resident and has attached functions, thus turning it into a present library.&lt;br /&gt;
&lt;br /&gt;
===Resident Library===&lt;br /&gt;
&lt;br /&gt;
A resident library is a library program that is loaded to remain in memory, regardless of the status of the main program. It does not get removed from memory until it is explicitly cleared or until the Business Rules session is terminated. Loading a library resident saves the overhead associated with loading a library each time it is needed.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Business Rules allows resident libraries to handle their own global variables in any of three different ways:&lt;br /&gt;
&lt;br /&gt;
:1.) Globals may be cleared when the main program ends,&lt;br /&gt;
:2.) Globals may be retained irrespective of the status of the main program, or&lt;br /&gt;
:3.) Globals may be cleared after each function call to the resident library.&lt;br /&gt;
&lt;br /&gt;
The resident status of a resident library can be removed (thus changing the library into a present library) through the use of the CLEAR STATUS command.&lt;br /&gt;
&lt;br /&gt;
A library can be made resident through use of the enhanced LOAD command. However, it is important to understand that functions cannot be executed from any library -even a library that has been loaded into resident memory -until a LIBRARY statement names the functions to be executed and establishes linkage (either named or unnamed) between the named function and the resident library.&lt;br /&gt;
&lt;br /&gt;
In the following example, line 00130 causes RESLIB to be loaded into memory as a resident library. Line 00140 establishes named linkage between the function FNRESLIB1 and the RESLIB library. Line 00150 executes the function FNRESLIB1.&lt;br /&gt;
&lt;br /&gt;
 00130 EXECUTE &amp;quot;LOAD RESLIB,RESIDENT&amp;quot;&lt;br /&gt;
 00140 LIBRARY &amp;quot;RESLIB&amp;quot;: FNRESLIB1&lt;br /&gt;
 00150 LET FNRESLIB1&lt;br /&gt;
&lt;br /&gt;
==Comparison of User-Defined Function Features==&lt;br /&gt;
&lt;br /&gt;
The following table illustrates the similarities and differences between regular user-defined functions (non-library) and library user-defined functions.&lt;br /&gt;
&lt;br /&gt;
[[Image:Help0185.jpg]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Help0186.jpg]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Help0187.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Variable Usage==&lt;br /&gt;
&lt;br /&gt;
Before you start placing all your existing user-defined functions into separate libraries, you should fully understand how library functions deal with global variables.&lt;br /&gt;
&lt;br /&gt;
This section will focus on three main points:&lt;br /&gt;
&lt;br /&gt;
:1.) How a main program and a library function can communicate,&lt;br /&gt;
:2.) How functions within a library communicate, and&lt;br /&gt;
:3.) When global variables are cleared for a library program.&lt;br /&gt;
&lt;br /&gt;
===How main programs and library functions communicate===&lt;br /&gt;
&lt;br /&gt;
Business Rules programs communicate with regular user-defined functions via passed parameters, the returned function value, and global variables (variables not passed in the parameter list). All of these same communication options are available for library functions that are defined within the main program. However, only the first two options are available to library functions that are separate from the main program. These functions cannot access the main program&#039;s global variables because global variables are only available to routines and functions, which are defined within the same program. As a result, user-defined functions, which are held within a main program, may need to be reviewed for their global variable usage before they are changed to library functions and placed into a separate library program.&lt;br /&gt;
&lt;br /&gt;
If a program needs to communicate a large number of standard values to a library function, consider using an initialization function to pass the values to the library program. Then have the initialization function assign the passed values to global variables in the library so they will be available to all functions in the library.&lt;br /&gt;
&lt;br /&gt;
===How functions within a library communicate===&lt;br /&gt;
Within each library, all functions share variables which are global to that library, and library global variables generally retain their values between function calls. (The exception is when the RELEASE keyword is used on the LIBRARY statement, which is accepted both for resident and as-needed libraries; in this case, global variables are cleared after each function call.)&lt;br /&gt;
&lt;br /&gt;
The point at which globals are cleared for a library program varies according to several factors. See below for more information.&lt;br /&gt;
&lt;br /&gt;
===When global Variables are cleared===&lt;br /&gt;
The point at which a library&#039;s global variables are cleared depends on how the library was loaded and -in the case of resident libraries-what options are used.&lt;br /&gt;
&lt;br /&gt;
{\b Main program library} - For library functions that are defined within the main program, globals are cleared when a new main program is started or when the current main program is explicitly removed from memory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resident library&#039;&#039;&#039; - When a library is loaded resident, global variables may be cleared in any of three ways:&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Default&#039;&#039;&#039;||By default, Business Rules clears a resident library&#039;s global variables when the main program ends.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Retain&#039;&#039;&#039;||When the OPTION RETAIN statement is used in a resident library program, the library retains its global variables irrespective of when the main program ends. The only way to clear globals when this statement is used is to CLEAR the library from memory or to reload it with the LOAD RESIDENT command. Remember that the library must be loaded resident for the OPTION RETAIN statement to have any affect.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Release&#039;&#039;&#039;||When a resident library is named on a LIBRARY statement with the RELEASE keyword, the library&#039;s global variables are cleared after each function call to the library. This capability is provided so that the decision to load a library resident or as-needed can be made on a case-by-case basis; the program code can remain the same (because Business Rules handles the variables the same) regardless of whether the library is loaded resident or as-needed.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
{\b Present library} - When a library is loaded present, global variables are cleared when the main program ends.&lt;br /&gt;
&lt;br /&gt;
{\b As-needed library} - When a library is loaded as-needed, global variables are cleared after each function call to the library.&lt;br /&gt;
&lt;br /&gt;
The following table summarizes the information presented above. The keywords used in the &amp;quot;When globals are cleared&amp;quot; column are the same keywords used in the STATUS LIBRARY display (second column from right) to identify when variables for the listed library will be cleared. (See the &amp;quot;STATUS&amp;quot; command in the Commands chapter for complete information about this display.) The keywords are defined as follows:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;RUN&#039;&#039;&#039;||Globals are cleared when new main program is run.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;END&#039;&#039;&#039;||Globals are cleared when main program ends.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;EXIT&#039;&#039;&#039;||Globals are cleared after each function call to the library.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;RETAIN&#039;&#039;&#039;||Globals are retained, irrespective of main program status.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Help0188.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Additional Processing Consideration==&lt;br /&gt;
&lt;br /&gt;
Active procedures and opened files are not affected by library function calls, unless the library issues commands that specifically affect them. This includes PROCERR settings.&lt;br /&gt;
&lt;br /&gt;
A nice aspect of library functions is the capability of a program to call a library function, which, in turn, calls a function in the main program. This supports the concept of manager functions that provide overall functionality while the main program fills in the details that may vary from program to program.&lt;br /&gt;
&lt;br /&gt;
The way to permit library routines to be overridden (functionally replaced) by corresponding functions in the main program is to have the library include those functions in a LIBRARY statement that doesn&#039;t specify a library name. Then have the library execute that statement after the main program has started. The library will then attach the library function in the main program instead of its own, even if a copy of the function exists in the library, because the main program is always regarded as having been loaded last for purposes of resolving unnamed library searches.&lt;br /&gt;
&lt;br /&gt;
Note that if a LIBRARY statement within a resident library creates linkage and then the main program ends, the linkage is broken and that LIBRARY statement must be re-executed before the function can be called again by the resident library.&lt;br /&gt;
&lt;br /&gt;
With respect to speed, parameters should be passed by reference (using the &amp;amp; in front of the variable name in the DEF statement) wherever possible. This avoids needless allocation of memory and copying of data, which is a significant part of function call processing.&lt;br /&gt;
&lt;br /&gt;
If you want to avoid the processing time required to load a library until a function within it is called, simply name the library and function on the same LIBRARY statement. However, if you want to be sure that the named functions exist within the library, first load the library with a statement that contains no function names. This will cause the library to be loaded at the time the LIBRARY statement is executed. Then when the LIBRARY statement containing the function list is encountered, the library (which is now in memory) will be checked for the presence of each function.&lt;br /&gt;
&lt;br /&gt;
It should be emphasized that executing a LOAD command does not establish function linkage. A subsequent LIBRARY statement must be processed to establish such linkage.&lt;br /&gt;
&lt;br /&gt;
When replacing a resident library with a different library, the first library should be cleared with a CLEAR command to free its memory before loading the second library.&lt;br /&gt;
&lt;br /&gt;
Updating a library (with the REPLACE command) has no effect on application environments until the library is (re)loaded.&amp;lt;br&amp;gt;&lt;br /&gt;
If a LIBRARY statement contains the name of a local function that is defined as non-library, a &amp;quot;duplicate function definition&amp;quot; error is generated when the program is run or saved.&lt;br /&gt;
&lt;br /&gt;
If a LIBRARY statement refers to a library without RELEASE and another statement refers to the same program with RELEASE, an error is generated. Also RELEASE cannot be specified for any library with the OPTION RETAIN statement.&lt;br /&gt;
&lt;br /&gt;
If a function in the main program, defined with the LIBRARY keyword, is called from within a library (a condition referred to as library loopback), the main program uses a fresh for-next stack.&amp;lt;br&amp;gt;&lt;br /&gt;
Therefore, pre-existing for-next processes are not recognized until the library returns normally to the main program.&lt;br /&gt;
&lt;br /&gt;
If more than one DEF LIBRARY statement for the same function name appears in a program, the lowest numbered definition will be used. More than one non-library DEF for the same variable is no longer permitted.&lt;br /&gt;
&lt;br /&gt;
Memory fragmentation can occur if a library is loaded resident while other programs are in memory, and then the main program chains leaving files open through either the CHAIN FILES statement, or having files open NOCLOSE. To avoid this problem, if you use CHAIN FILES or NOCLOSE, load your resident libraries before running application programs.&lt;br /&gt;
&lt;br /&gt;
Alternate libraries can be interrogated with function key 9 during a program pause.&lt;br /&gt;
&lt;br /&gt;
===Editing Active Libraries===&lt;br /&gt;
&lt;br /&gt;
When both a main program and a library program that is separate from the main program are active ( a function in the library program is currently being executed), the LIST command will display the contents of the library program. When functions in multiple library programs are active, the program with the most recently called function will be displayed.&lt;br /&gt;
&lt;br /&gt;
It is important to note that the only way to save changes made to a library program that has been activated by a main program is to list the library to a file and reload it from source later on. Because of this, it makes sense to develop a new library function first within the main program. Then once you&#039;ve completed the testing and debugging process, you can break it out and test it as a separate library function.&lt;br /&gt;
&lt;br /&gt;
===Linkage===&lt;br /&gt;
&lt;br /&gt;
When used to its full potential, the Business Rules Library Facility enables multiple versions of the same function (with the same name) to exist in different libraries, all of which may be loaded into memory. The actual library that is used for a specific function call is determined according to Business Rules rule for linkage, which is the process of associating a function name with a library name.&amp;lt;br&amp;gt;&lt;br /&gt;
Business Rules keeps tracks of established linkages in a table that it references each time a function is called.&lt;br /&gt;
&lt;br /&gt;
The LIBRARY statement may be used to establish linkage in one of two ways: the named method, or the unnamed method. These methods are defined as follows:&lt;br /&gt;
&lt;br /&gt;
;Named&lt;br /&gt;
The LIBRARY statement explicitly links one or more specific functions to a specific library. This is the most efficient and foolproof method for assuring that the library function you wish to use gets executed.&lt;br /&gt;
&lt;br /&gt;
In the following example, the functions FNRESLIB1 through FNRESLIB5 are explicitly linked to the library MAIN. When any of these functions is called, Business Rules will automatically execute them from the MAIN library. (Regardless of whether or not any other library currently in memory also contains functions by the same name.)&lt;br /&gt;
&lt;br /&gt;
 50300 LIBRARY &amp;quot;MAIN&amp;quot;:FNRESLIB1,FNRESLIB2,FNRESLIB3,FNRESLIB4,FNRESLIB5&lt;br /&gt;
&lt;br /&gt;
;Unnamed&lt;br /&gt;
The LIBRARY statement names the desired library functions and leaves it to Business Rules to determine which of the currently identified libraries they should be linked to. This determination is made according to the pre-set guidelines described below. The unnamed method of linkage is useful when your development methodology involves using multiple versions of the same function to control program options and features.&lt;br /&gt;
&lt;br /&gt;
When the unnamed method is used, Business Rules first searches the main program, then each library that is currently either resident or present (in last loaded, first searched order) for each function listed on the LIBRARY statement. Once Business Rules finds the function, the linkage is established, and -unless the linkage is explicitly changed with another LIBRARY statement or detached because the main program ends -all future calls to the same function will continue to utilize the same linkage. Note that Business Rules does not search as-needed libraries when the unnamed method of establishing linkage is used. Also, it is important to understand that it can take significantly longer to establish linkage using the unnamed method of linkage than with the named method of linkage.&lt;br /&gt;
&lt;br /&gt;
In the following example, line 01000 loads RESLIB as a resident library. Lines 01100 and 01200 load PRESLIB1 and PRESLIB2 as present libraries, and line 01300 names ASNLIB as an as-needed library. The LIBRARY statement on line 01400 establishes unnamed linkage for the function FNALIBI. When line 01500 is executed, Business Rules searches the currently loaded programs in the following order for FNALIBI: Main program, PRESLI2, PRESLIB1, RESLIB. Note that ASNLIB is not considered for this search because it is not currently loaded in memory.&lt;br /&gt;
&lt;br /&gt;
 01000 EXECUTE &amp;quot;LOAD RESLIB,RESIDENT&amp;quot;&lt;br /&gt;
 01100 LIBRARY &amp;quot;PRESLIB1&amp;quot;:&lt;br /&gt;
 01200 LIBRARY &amp;quot;PRESLIB2&amp;quot;:&lt;br /&gt;
 01300 LIBRARY RELEASE,&amp;quot;ASNLIB&amp;quot;: FNASNLIB1&lt;br /&gt;
 01400 LIBRARY : FNALIBI&lt;br /&gt;
 01500 LET FNALIBI&lt;br /&gt;
&lt;br /&gt;
===Status Library===&lt;br /&gt;
&lt;br /&gt;
Business Rules STATUS LIBRARY command may be used to display a table that identifies all the linkages that are currently active for each library. See &amp;quot;STATUS&amp;quot; in the Commands chapter for more information. For information about releasing and/or changing library linkages, see the term Linkage reassignment and detachment below.&lt;br /&gt;
&lt;br /&gt;
==Sample Program==&lt;br /&gt;
&lt;br /&gt;
The following two sample sections of code are, for convenience purposes, labeled &amp;quot;Main Program&amp;quot; and &amp;quot;Library&amp;quot;. The Main Program references two functions (FNSEND and FNRECEIVE), which are located in the Library. Line 50 of the Main Program establishes the function linkage; line 70 prompts for a message; and line 110 calls the FNSEND function, which is defined on line 30 of the Library.&lt;br /&gt;
&lt;br /&gt;
FNSEND opens the communications port and sends the operator-specified message to the terminal connected to the port. The Main Program then calls the FNRECEIVE function, which is defined on line 80 of the Library. This function waits up to 15 seconds for a response (by default), returns the response in the parameter, and returns its length as a function value. Finally, the Main Program prints the response or the message &amp;quot;No Response&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
&lt;br /&gt;
 00010 ! MAIN PROGRAM&lt;br /&gt;
 00020 !&lt;br /&gt;
 00030 DIM MESG$*60, RESPONSE$*120&lt;br /&gt;
 00040 !&lt;br /&gt;
 00050 LIBRARY &amp;quot;TOOLS\LIB1&amp;quot;: FNSEND, FNRECEIVE&lt;br /&gt;
 00060 !&lt;br /&gt;
 00070 PRINT &amp;quot;Specify Message&amp;quot;&lt;br /&gt;
 00080 LINPUT MESG$&lt;br /&gt;
 00090 IF LEN(MESG$) = 0 THEN STOP&lt;br /&gt;
 00100 !&lt;br /&gt;
 00110 LET FNSEND(MESG$)&lt;br /&gt;
 00120 !&lt;br /&gt;
 00130 IF FNRECEIVE(RESPONSE$) THEN !:PRINT RESPONSE$ !:ELSE !:PRINT &amp;quot;No Response&amp;quot;&lt;br /&gt;
 00140 GOTO 70&lt;br /&gt;
&lt;br /&gt;
 Library:&lt;br /&gt;
 00010 ! LIB1&lt;br /&gt;
 00020 !&lt;br /&gt;
 00030 DEF LIBRARY, FNSEND(MESSAGE$*60)&lt;br /&gt;
 00040  IF NOT COMM OPENED THEN !:OPEN #40: &amp;quot;NAME=COM2:, FORMAT=ASYNC,BAUD=2400&amp;quot;,DISPLAY, OUTIN !:COMM OPENED = 1&lt;br /&gt;
 00050  PRINT #40: MESSAGES$&lt;br /&gt;
 00060 FNEND&lt;br /&gt;
 00070 !&lt;br /&gt;
 00080 DEF LIBRARY FNRECEIVE(&amp;amp;RESP$)&lt;br /&gt;
 00090  LINPUT #40: RESP$ IOERR 100&lt;br /&gt;
 00100  FNRECEIVE = LEN(RESP$)&lt;br /&gt;
 00110 FNEND&lt;br /&gt;
&lt;br /&gt;
===Tips for implementing Library Functions in Existing Applications===&lt;br /&gt;
&lt;br /&gt;
As mentioned above, it is important that you consider your current usage of global variables before converting your existing user-defined functions into library functions and placing them into a separate program. This section provides some examples of how you can modify existing applications to utilize library functions, even if the existing applications currently access or modify user-defined function variables from outside the function. Other examples shown in this section demonstrate how you can turn an entire program (such as a client maintenance program) into a library function that a user can invoke at will from within another program (such as order entry) and provide some tips on implementing libraries for programs that use [[FNSNAP]]! tools.&lt;br /&gt;
&lt;br /&gt;
;Example 1:&lt;br /&gt;
Separating main program logic from user-defined functions&amp;lt;br&amp;gt;&lt;br /&gt;
The following is a very simple example of a program that uses a user-defined function.&lt;br /&gt;
&lt;br /&gt;
;ORIGINAL PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page, plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
The steps you would need to take to separate the function into a separate library and enable the main program to call the function would be as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Place the user-defined functions into their own program.&lt;br /&gt;
:2.) Modify the DEF line for each of the functions in the new library program to utilize the LIBRARY keyword (demonstrated in line 02000 of the library program below).&lt;br /&gt;
:3.) Delete the separated functions from the main programs that are to use the new library.&lt;br /&gt;
:4.) Add a LIBRARY statement to the main program that names each function that is to be called from the library program (demonstrated in line 00005 of the main program below).&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;howto1nl&amp;quot; : FNDOCEST&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,lus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
;Example 2:&lt;br /&gt;
Function uses global variables established by main program&lt;br /&gt;
&lt;br /&gt;
In the following program, the global variable PAGEEST is established by the main program logic on line 00020. This same global variable is accessed by the user-defined function at line 02010.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
As there is no way for a main program to share its global variables with a library function contained in a separate program, this program must be modified before it can be separated into &amp;quot;main&amp;quot; and &amp;quot;library&amp;quot; programs. In the following example, line 02000 has been modified (as shown in italics) to pass the PAGEEST variable by reference, thereby causing the library function to use the main program&#039;s copy of the variable.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
;Example 3:&lt;br /&gt;
Existing program queries function variable from outside function&amp;lt;br&amp;gt;&lt;br /&gt;
This example shows the same starting program as shown in Example 1, except that line 00040 has been added to demonstrate a situation where the main program logic queries (without changing) a variable that has been established by the user-defined function. This programming technique also is not allowed when functions are separated into library programs,&lt;br /&gt;
as there is just one way (via the function variable) for a separate library function to pass a value back to the main program.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST&lt;br /&gt;
 00040 IF WRITETIME&amp;gt;8 THEN PRINT &amp;quot;Total days: &amp;quot;;WRITETIME/8&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
When starting new programming projects that are to utilize Business Rules Libraries, ADS recommends against the programming technique shown here. However, if your programs already use this technique and you want to utilize the benefits of libraries with as little work as possible, you could change the programs in the manner shown below.&lt;br /&gt;
&lt;br /&gt;
The following two code sections show the original program as it would be when split into main program and library, and with a &amp;quot;rigged&amp;quot; technique for the program to get the value of the queried variable from the library. The &amp;quot;rig&amp;quot; is that all references to the WRITETIME variable in the main logic have been changed to FNWRITETIME, and FNWRITETIME has been added to the library to query the value of WRITETIME and pass it back to the main program. Note that there is a limitation to this technique: the program must be loaded into either resident memory (without use of RELEASE on the LIBRARY statement) or present memory for it to work. This is because the technique relies on the library&#039;s global variables remaining active even after function calls to it have been completed.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;howto2nl&amp;quot; : FNDOCEST,FNWRITETIME&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 IF FNWRITETIME&amp;gt;8 THEN PRINT &amp;quot;Total days: &amp;quot;;FNWRITETIME/8&lt;br /&gt;
&lt;br /&gt;
;LIBRARY:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page, plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is:&amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
 03000 DEF LIBRARY FNWRITETIME=WRITETIME&lt;br /&gt;
&lt;br /&gt;
;Example 4:&lt;br /&gt;
Existing program queries or modifies function variable from outside function&amp;lt;br&amp;gt;&lt;br /&gt;
In the following example, line 00120 of the main program logic modifies the value of TOTTIME, which is established by the FNDOCEST function. It is important that this modified value be communicated back to the function, because line 02030 of the function uses it for subsequent calls. Note also that lines 00100 and 00130 of the main program logic also query (without modifying) the value of TOTTIME.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages for chapter 1:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 PRINT &amp;quot;Enter estimated number of pages for chapter 2:&amp;quot;&lt;br /&gt;
 00050 INPUT PAGEEST&lt;br /&gt;
 00060 PRINT &amp;quot;Is subject matter highly technical? (Y/N)&amp;quot;&lt;br /&gt;
 00070 INPUT TECHLEVEL$&lt;br /&gt;
 00080 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00090 IF UPRC$(TECHLEVEL$)=&amp;quot;Y&amp;quot; THEN&lt;br /&gt;
 00100  LET SURPLUS=TOTTIME*.2&lt;br /&gt;
 00110  PRINT &amp;quot;Surplus time for technical matter: &amp;quot;;SURPLUS;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00120  LET TOTTIME+=SURPLUS&lt;br /&gt;
 00130  PRINT &amp;quot;Total time is &amp;quot;;TOTTIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00140 END IF&lt;br /&gt;
&lt;br /&gt;
;LIBRARY:&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030  PRINT &amp;quot;Accumulated total is: &amp;quot;;TOTTIME+=WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02040 FNEND&lt;br /&gt;
&lt;br /&gt;
As noted for the previous example in this section, programming practices such as this are not recommended for new development that is to utilize the Library Facility. These examples are supplied to help you quickly modify existing programs so they can utilize the benefits of libraries.&lt;br /&gt;
&lt;br /&gt;
The next two programs (main and library) show how the original program was changed to work with libraries.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;HOWTO3NL&amp;quot; : FNDOCEST,FNADD TOTTIME&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages for chapter 1:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 PRINT &amp;quot;Enter estimated number of pages for chapter 2:&amp;quot;&lt;br /&gt;
 00050 INPUT PAGEEST&lt;br /&gt;
 00060 PRINT &amp;quot;Is subject matter highly technical? (Y/N)&amp;quot;&lt;br /&gt;
 00070 INPUT TECHLEVEL$&lt;br /&gt;
 00080 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00090 IF UPRC$(TECHLEVEL$)=&amp;quot;Y&amp;quot; THEN&lt;br /&gt;
 00100  LET SURPLUS=FNADD TOTTIME(0)*.2&lt;br /&gt;
 00110  PRINT &amp;quot;Surplus time for technical matter: &amp;quot;;SURPLUS;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00130  PRINT &amp;quot;Total time is &amp;quot;;FNADD TOTTIME(SURPLUS);&amp;quot;hours&amp;quot;&lt;br /&gt;
 00140 END IF&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030  PRINT &amp;quot;Accumulated total is: &amp;quot;;TOTTIME+=WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02040 FNEND&lt;br /&gt;
 03000 DEF LIBRARY&lt;br /&gt;
 FNADD TOTTIME(ADDTOTTIME)=TOTTIME+=ADDTOTTIME&lt;br /&gt;
&lt;br /&gt;
Once the required steps of separating the two programs, adding the necessary LIBRARY statement to the main program and adding the LIBRARY keyword to the DEF statement in the library program were completed for the above code, the following steps were conducted to enable the main program and function to communicate the value of TOTTIME. Note that there is a limitation to the technique shown: the library program must be loaded into either resident memory (without use of RELEASE on the LIBRARY statement) or present memory for it to work. This is because it relies on the library&#039;s global variables remaining active even after function calls to it have been completed.&lt;br /&gt;
&lt;br /&gt;
:1.) The FNADD TOTTIME function was added to the library program (line 03000). This function takes a variable (representing the amount to add to TOTTIME) that is passed by the main program. It adds the passed variable to TOTTIME, and also assigns the new value of TOTTIME to the function variable FNADD TOTTIME.&lt;br /&gt;
:2.) The FNADD TOTTIME function name was added to the LIBRARY statement on line 00005 of the main program.&lt;br /&gt;
:3.) Line 00120 of the main program was removed, and line 00130 was modified to call the FNADD TOTTIME library function instead of modifying TOTTIME directly. The value of SURPLUS is passed to FNADD TOTTIME; FNADD TOTTIME takes over the job of modifying the value of TOTTIME and making sure that both the main program and the library program know its new value.&lt;br /&gt;
:4.) Line 00100 of the main program was changed to call the FNADD TOTTIME function as well. Since this line only needs to query the value of TOTTIME, it passes a value of 0 as the amount to add to TOTTIME.&lt;br /&gt;
&lt;br /&gt;
;Example 5:&lt;br /&gt;
Turning an existing program into a user-invokable library function&amp;lt;br&amp;gt;&lt;br /&gt;
Business Rules Library Facility makes it very easy to turn an entire program into a library function that a user can invoke at will from within another program. For example, consider a standard application that includes both a client maintenance (MNTCUST) program and an order entry program (ORDERS). You would like to give users the ability to invoke the client maintenance program from within the order entry program whenever they press F4. The steps required to do this are as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Modify MNTCUST by placing the entire original program into a user-defined library function and adding a few lines that cause the program to call itself as a library function whenever it is executed as the main program.&lt;br /&gt;
:a.) Move any user-defined functions that exist within the main body of the program to the end of the program (or to a separate library).&lt;br /&gt;
:b.) Add lines such as the following to the top of the program. NOTE that the (program name) in line 00030 represents the name of the program (such as a main menu) from which you currently normally invoke the client maintenance program.&lt;br /&gt;
&lt;br /&gt;
 00010 LIBRARY &amp;quot;MNTCUST&amp;quot; : FNMNTCUST&lt;br /&gt;
 00020 LET FNMNTCUST&lt;br /&gt;
 00030 CHAIN (program name)&lt;br /&gt;
 00040 DEF LIBRARY FNMNTCUST&lt;br /&gt;
&lt;br /&gt;
:c.) Add the following line to the end of the main body of the program (prior to any user-defined function definitions):&lt;br /&gt;
&lt;br /&gt;
 80000 FNEND&lt;br /&gt;
&lt;br /&gt;
:2.) Modify ORDERS as follows:&lt;br /&gt;
&lt;br /&gt;
:a.) Change the screen to include a label that identifies the operation of the F4 key.&lt;br /&gt;
:b.) Change the program to check for pressing of the F4 key.&lt;br /&gt;
:c.) Change the program to execute the following whenever F4 is pressed. Note that the LIBRARY statement in line 50000 utilizes the &amp;quot;RELEASE&amp;quot; keyword: this causes the MNTCUST library to be loaded into memory on an as-needed basis only. Thus the only time that the on-the-fly client maintenance feature uses system resources is when the user actually requests the capability by pressing F4.&lt;br /&gt;
&lt;br /&gt;
 50000 LIBRARY RELEASE, &amp;quot;MNTCUST&amp;quot; :FNMNTCUST&lt;br /&gt;
 50010 LET FNMNTCUST&lt;br /&gt;
&lt;br /&gt;
;Example 6:&lt;br /&gt;
Tips for moving [[FNSNAP]]! functions into separate libraries for users of [[FNSNAP]]! programming tools, modifying existing programs to use libraries will involve a combination of the techniques demonstrated above. Every developers programs are different, so this section cannot give you a beginning-to-end list of steps to complete to accomplish the task, but the following are some steps you can start with:&lt;br /&gt;
&lt;br /&gt;
:1.) Place the FNSNAP! functions into their own program. (This example uses MAIN\\FNSNAP as the path and location of the new program.)&lt;br /&gt;
:2.) Modify the DEF line for each of the functions in FNSNAP to utilize the LIBRARY keyword. For example:&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 60150 DEF FNOK&lt;br /&gt;
&lt;br /&gt;
To this:&lt;br /&gt;
&lt;br /&gt;
 60150 DEF LIBRARY FNOK&lt;br /&gt;
&lt;br /&gt;
:3.) Add the following FNFNSNAP INIT function to the FNSNAP program. This function sets all the global variables that are used by the FNSNAP functions (in the past, FNSNAP! users were instructed to add these variable settings to the start of their programs). FNFNSNAP INIT also executes a LIBRARY statement for the FNSNAP program. This LIBRARY statement establishes linkage for all the functions in the FNSNAP program that are called by other functions in the same program.&lt;br /&gt;
&lt;br /&gt;
 00121 DEF LIBRARY FNFNSNAP INIT&lt;br /&gt;
 00122 LET DATFMT$=&amp;quot;MM-DD-CCYY&amp;quot; !:LET FULLSCR=0 !:LET MAXSROWS=22 !:LET WINDEV=OWINDEV=69 !:LET MGA$=&amp;quot;24,2,C 78,&amp;quot; !:IF NOT SSAV THEN LET SSAV=101 !:!Common Variables required by FNSNAP! !:&lt;br /&gt;
 00124 LIBRARY &amp;quot;MAIN\FNSNAP&amp;quot; : FNRELPART,FNSAVPART, FNPM, FNAUTO, FNOK, FNWIN,FNCLSWIN, FNZERO, FNTIMMILREG, FNSSAV,FNSAVSCR, FNSETBAD, FNPURGE, FNFLDSEL$&lt;br /&gt;
 00130 FNEND !:&lt;br /&gt;
:4.) Delete the separated functions from the main programs that are to use the FNSNAP library.&lt;br /&gt;
&lt;br /&gt;
:5.) Add the following program line to each of the main programs that are to use the FNSNAP library. This statement establishes linkage between the functions to be called and the program they are located in, and it calls the FNFNSNAP INIT function, which sets the library&#039;s global values:&lt;br /&gt;
&lt;br /&gt;
 00160 LIBRARY &amp;quot;MAIN\FNSNAP&amp;quot;:FNFNSNAP INIT, FNSSAV, FNPOPWIN,FNPOPBAR, FNWINDEV, FNPOPWIN INIT,FNPOPBAR INIT, FNCO$, FNMGCLR, FNTOP,FNOK, FNSAVSCR, FNSCRMGR, FNSAVPART,FNRELPART, FNCLRPART, FNZERO, FNNULL$,FNTIMMILREG, FNDIALOG$, FNWIN, FNCLSWIN,FNNOKEY, FNPOPUP, FNPM, FNAUTO,FNPFKEYLINE !:LET FNFNSNAP INIT !:!&lt;br /&gt;
&lt;br /&gt;
==Error Processing==&lt;br /&gt;
&lt;br /&gt;
If an error is not trapped in a library function, the error is reported back to the calling program. At this time the following system variables are set:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;LINE&#039;&#039;&#039;||The line number of the calling program function call.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;ERR&#039;&#039;&#039;||The error number that occurred in the library function.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;CNT&#039;&#039;&#039;||The appropriate value as if the error occurred in the calling program.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If an error occurs while attempting to match parameters between a function call and the function definition, CNT is set to the number of parameters successfully matched.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:User Defined Functions and Libraries]]&lt;br /&gt;
[[Category:Facility]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Library_Facility&amp;diff=2655</id>
		<title>Library Facility</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Library_Facility&amp;diff=2655"/>
		<updated>2013-04-15T19:29:05Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: Created page with &amp;quot;Business Rules! now includes a comprehensive &amp;#039;&amp;#039;&amp;#039;Library&amp;#039;&amp;#039;&amp;#039; Facility. Similar to DLL (Dynamic Link Libraries), the Business Rules! Library Facility enables [[user-defin...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Business Rules!]] now includes a comprehensive &#039;&#039;&#039;Library&#039;&#039;&#039; Facility. Similar to [[DLL]] (Dynamic Link Libraries), the Business Rules! Library Facility enables [[user-defined functions]] to be placed in a program (&amp;quot;library&amp;quot;) that is separate from the main program. The library may be loaded &amp;quot;resident&amp;quot; (staying loaded regardless of the status of the main program), it may be loaded &amp;quot;present&amp;quot; (remaining active in current memory as long as the main program is active), or it may be loaded &amp;quot;as needed&amp;quot; (loaded when needed to execute a function, then unloaded as soon as the function has been executed).&lt;br /&gt;
&lt;br /&gt;
A library is any [[Business Rules! program]] that contains library functions. A library must be identified to Business Rules! before a program can execute any of its functions. When a library is identified, Business Rules! adds its name to an internal table of library names. This table identifies the names of all the libraries that should be searched whenever a library function that is not yet linked to a library is called.&lt;br /&gt;
&lt;br /&gt;
Business Rules! places no limits on the number of libraries that may be loaded into memory at one time. Business Rules! provides for maximum memory usage and performance flexibility by allowing libraries to be identified and loaded into memory via three different methods: the resident method, the present method and the as-needed method. See the separate descriptions below for specific information about each type of library.&lt;br /&gt;
&lt;br /&gt;
==Advantages==&lt;br /&gt;
&lt;br /&gt;
Some of the significant advantages of placing user-defined functions in a library rather than keeping them in the main program are as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Reduces the size of executables - its no longer necessary to include a standard set of user-defined functions in every program in your application. For some applications (which may include literally hundreds of copies of the exact same code), the potential savings in disk space are tremendous.&lt;br /&gt;
&lt;br /&gt;
:2.) Saves maintenance time - If you&#039;re in the habit of duplicating user-defined functions in every single program that needs them, you know what kind of effort it takes to make (and distribute to your clients) even a one-line change to a function. With Business Rules Library Facility, you make the change only once, and you replace only one program at the client&#039;s site.&lt;br /&gt;
&lt;br /&gt;
:3.) Encourages use of programming standards - The use of library functions for a standard routine is a great way to encourage programming consistency and the setting of standards among your programmers.&lt;br /&gt;
&lt;br /&gt;
==Library Function==&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;&#039;library function&#039;&#039;&#039; is a specially defined [[user-defined function]]; it exists in a program which is frequently separate from the main program, but it may exist in the main program as well.&lt;br /&gt;
&lt;br /&gt;
To qualify as a library function, a user-defined function must simply utilize the DEF statement&#039;s LIBRARY keyword. The following is an example of a library function definition:&lt;br /&gt;
&lt;br /&gt;
 52400 DEF LIBRARY FNRESLIB2&lt;br /&gt;
 52500 PRINT &amp;quot;This is a library function&amp;quot;&lt;br /&gt;
 52600 FNEND&lt;br /&gt;
&lt;br /&gt;
Executing a library function is a two-step process. First, the program executing the library function must name the function in a LIBRARY statement, which establishes either named or unnamed linkage. Second, the program must call the library function; this may be accomplished using any of the same methods that is available for calling other user-defined functions. In the following example, line 01000 uses the LIBRARY statement to establish named linkage between the function FNPRESLIB2 and the library PRESLIB. Line 01100 causes the library PRESLIB to be loaded into present memory (if the library does not already exist in memory), then executes FNPRESLIB2.&lt;br /&gt;
&lt;br /&gt;
 01000 LIBRARY &amp;quot;PRESLIB&amp;quot;: FNPRESLIB2&lt;br /&gt;
 01100 LET FNPRESLIB2&lt;br /&gt;
&lt;br /&gt;
===Implementation Considerations===&lt;br /&gt;
&lt;br /&gt;
Business Rules Facility was carefully designed to offer a great deal of power and flexibility. Before you begin implementing this capability into your existing applications and ongoing development, ADS recommends that you consider the following:&lt;br /&gt;
&lt;br /&gt;
:1.)  Should your libraries remain resident?&lt;br /&gt;
Business Rules allows for libraries to remain resident in memory (providing maximum performance) or to be loaded and released as needed (providing best utilization of memory). Be sure to select the method or combination of methods that&#039;s best for your applications.&lt;br /&gt;
&lt;br /&gt;
:2.) Will you use multiple versions of the same function?&lt;br /&gt;
Since maintaining more than one version of a function is one method of controlling program options, Business Rules&#039; rule for library selection has been established with care. You should carefully review these rules and the ways in which multiple libraries can be of use to you as you plan your implementation.&lt;br /&gt;
&lt;br /&gt;
Until you feel comfortable with the intricacies of the Business Rules Library Facility, ADS recommends that you give every library function a name that is unique from every other library function.&lt;br /&gt;
&lt;br /&gt;
:3.) Do your existing functions utilize global program variables?&lt;br /&gt;
Unlike local user-defined functions, library functions that exist in a program separate from the main program cannot access main program variables globally. They have to be specifically passed. You should carefully review your usage of global variables before moving local functions into separate libraries.&lt;br /&gt;
&lt;br /&gt;
===As needed Library===&lt;br /&gt;
&lt;br /&gt;
An as-needed library is loaded and unloaded as needed for execution of specific functions. Loading a library only when it is needed allows the program to conserve memory usage.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Global Variables in an as-needed library are cleared each time a function call to the library is completed and the library is subsequently unloaded from memory.&lt;br /&gt;
&lt;br /&gt;
Programs can indicate that a library is to be loaded as needed by specifying the LIBRARY statement with both the RELEASE parameter and function names. This causes Business Rules to establish named linkage between the specified function(s) and the specified library, but it does not actually load the library. (The library is loaded only when one of the as-needed library&#039;s functions is actually called.) In the following example, line 00280 establishes linkage between the library ASNLIB and the function FNASNLIB1. Line 00290 causes the following to occur:&lt;br /&gt;
&lt;br /&gt;
:1.) Load ASNLIB into memory,&lt;br /&gt;
:2.) Execute the function FNASNLIB1,&lt;br /&gt;
:3.) Remove ASNLIB from memory.&lt;br /&gt;
&lt;br /&gt;
 00280 LIBRARY RELEASE,&amp;quot;ASNLIB&amp;quot;: FNASNLIB1&lt;br /&gt;
 00290 LET FNASNLIB1&lt;br /&gt;
&lt;br /&gt;
===Linkage Reassignment and Detachment===&lt;br /&gt;
&lt;br /&gt;
Once Business Rules has established linkage between a specific function and a specific library, the linkage remains active until a specific event causes it to become reassigned or detached.&lt;br /&gt;
&lt;br /&gt;
;REASSIGNMENT:&lt;br /&gt;
As noted previously, the LIBRARY statement may be used to establish linkage between a function and the library from which it is to be called. When the named LIBRARY statement is used, linkage is directly established between the named library and the named function(s). When the unnamed LIBRARY statement is used, Business Rules searches for the function according to some pre-set guidelines and assigns linkage to the first library within which the function definition is found.&lt;br /&gt;
&lt;br /&gt;
Once a function has actually been linked to a library, the only way to subsequently establish linkage between the same function name and a different library is to execute another LIBRARY statement that names the same function and a different library. When all of a present library&#039;s linked functions are reassigned; the library is automatically removed from memory. When all of a resident library&#039;s linked functions are reassigned; the library may be removed from memory with the CLEAR command.&lt;br /&gt;
&lt;br /&gt;
In the following example, lines 01100 and 01200 load the libraries PRESLIB1 and PRESLIB2 into present memory. Line 01300 uses a named library statement to establish linkage between PRESLIB1 and the function FNASSIGN, and line 01400 actually executes FNASSIGN from the PRESLIB1 library. Line 1500 then re-assigns linkage of FNASSIGN to the library PRESLIB2, and line 1600 executes FNASSIGN from the PRESLIB2 library.&lt;br /&gt;
&lt;br /&gt;
 01100 LIBRARY &amp;quot;PRESLIB1&amp;quot;:&lt;br /&gt;
 01200 LIBRARY &amp;quot;PRESLIB2&amp;quot;:&lt;br /&gt;
 01300 LIBRARY &amp;quot;PRESLIB1&amp;quot;: FNASSIGN&lt;br /&gt;
 01400 LET FNASSIGN&lt;br /&gt;
 01500 LIBRARY &amp;quot;PRESLIB2&amp;quot;: FNASSIGN&lt;br /&gt;
 01600 LET FNASSIGN&lt;br /&gt;
&lt;br /&gt;
;DETACHMENT:&lt;br /&gt;
Regardless of how a library is loaded (resident, present or as needed), all linkages are detached at the time that the main program ends.&lt;br /&gt;
&lt;br /&gt;
There is no other way to completely detach a linkage other than ending the main program.&lt;br /&gt;
&lt;br /&gt;
===Present Library===&lt;br /&gt;
&lt;br /&gt;
A present library is a library that is loaded to remain in memory as long as the main program is active or until all linkages that have been established for the library are reassigned.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Global Variables in a present library are cleared when the main program ends.&lt;br /&gt;
&lt;br /&gt;
A library can be loaded present through three different methods: &lt;br /&gt;
#.The first method is to specify a LIBRARY statement that identifies a library name but no function names. When this method is used, the library is loaded at the time that the LIBRARY statement is executed. For example, when the following statement is executed, the CURLIB library is immediately loaded into memory:&lt;br /&gt;
&lt;br /&gt;
 00210 LIBRARY &amp;quot;CURLIB&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
#.The second method of loading a library present is to specify the LIBRARY statement with both a library name and function names. When this method is used, the library is loaded the first time one of the specified functions is called. In the following example, line 00210 establishes linkage between the function FNCURLIB1 and the library CURLIB.&lt;br /&gt;
&lt;br /&gt;
Line 00220 causes the following to occur:&lt;br /&gt;
&lt;br /&gt;
:1.) The library CURLIB is loaded as a present library,&lt;br /&gt;
:2.) The function FNCURLIB is executed.&lt;br /&gt;
&lt;br /&gt;
 00210 LIBRARY &amp;quot;CURLIB&amp;quot;: FNCURLIB1&lt;br /&gt;
 00220 LET FNCURLIB1&lt;br /&gt;
&lt;br /&gt;
#.The third way to end up with a library loaded present is to execute a CLEAR STATUS command on a library that has already been loaded resident and has attached functions, thus turning it into a present library.&lt;br /&gt;
&lt;br /&gt;
===Resident Library===&lt;br /&gt;
&lt;br /&gt;
A resident library is a library program that is loaded to remain in memory, regardless of the status of the main program. It does not get removed from memory until it is explicitly cleared or until the Business Rules session is terminated. Loading a library resident saves the overhead associated with loading a library each time it is needed.&lt;br /&gt;
&lt;br /&gt;
Each library has its own global variables that are separate from the main program&#039;s variables. Business Rules allows resident libraries to handle their own global variables in any of three different ways:&lt;br /&gt;
&lt;br /&gt;
:1.) Globals may be cleared when the main program ends,&lt;br /&gt;
:2.) Globals may be retained irrespective of the status of the main program, or&lt;br /&gt;
:3.) Globals may be cleared after each function call to the resident library.&lt;br /&gt;
&lt;br /&gt;
The resident status of a resident library can be removed (thus changing the library into a present library) through the use of the CLEAR STATUS command.&lt;br /&gt;
&lt;br /&gt;
A library can be made resident through use of the enhanced LOAD command. However, it is important to understand that functions cannot be executed from any library -even a library that has been loaded into resident memory -until a LIBRARY statement names the functions to be executed and establishes linkage (either named or unnamed) between the named function and the resident library.&lt;br /&gt;
&lt;br /&gt;
In the following example, line 00130 causes RESLIB to be loaded into memory as a resident library. Line 00140 establishes named linkage between the function FNRESLIB1 and the RESLIB library. Line 00150 executes the function FNRESLIB1.&lt;br /&gt;
&lt;br /&gt;
 00130 EXECUTE &amp;quot;LOAD RESLIB,RESIDENT&amp;quot;&lt;br /&gt;
 00140 LIBRARY &amp;quot;RESLIB&amp;quot;: FNRESLIB1&lt;br /&gt;
 00150 LET FNRESLIB1&lt;br /&gt;
&lt;br /&gt;
==Comparison of User-Defined Function Features==&lt;br /&gt;
&lt;br /&gt;
The following table illustrates the similarities and differences between regular user-defined functions (non-library) and library user-defined functions.&lt;br /&gt;
&lt;br /&gt;
[[Image:Help0185.jpg]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Help0186.jpg]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Help0187.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Variable Usage==&lt;br /&gt;
&lt;br /&gt;
Before you start placing all your existing user-defined functions into separate libraries, you should fully understand how library functions deal with global variables.&lt;br /&gt;
&lt;br /&gt;
This section will focus on three main points:&lt;br /&gt;
&lt;br /&gt;
:1.) How a main program and a library function can communicate,&lt;br /&gt;
:2.) How functions within a library communicate, and&lt;br /&gt;
:3.) When global variables are cleared for a library program.&lt;br /&gt;
&lt;br /&gt;
===How main programs and library functions communicate===&lt;br /&gt;
&lt;br /&gt;
Business Rules programs communicate with regular user-defined functions via passed parameters, the returned function value, and global variables (variables not passed in the parameter list). All of these same communication options are available for library functions that are defined within the main program. However, only the first two options are available to library functions that are separate from the main program. These functions cannot access the main program&#039;s global variables because global variables are only available to routines and functions, which are defined within the same program. As a result, user-defined functions, which are held within a main program, may need to be reviewed for their global variable usage before they are changed to library functions and placed into a separate library program.&lt;br /&gt;
&lt;br /&gt;
If a program needs to communicate a large number of standard values to a library function, consider using an initialization function to pass the values to the library program. Then have the initialization function assign the passed values to global variables in the library so they will be available to all functions in the library.&lt;br /&gt;
&lt;br /&gt;
===How functions within a library communicate===&lt;br /&gt;
Within each library, all functions share variables which are global to that library, and library global variables generally retain their values between function calls. (The exception is when the RELEASE keyword is used on the LIBRARY statement, which is accepted both for resident and as-needed libraries; in this case, global variables are cleared after each function call.)&lt;br /&gt;
&lt;br /&gt;
The point at which globals are cleared for a library program varies according to several factors. See below for more information.&lt;br /&gt;
&lt;br /&gt;
===When global Variables are cleared===&lt;br /&gt;
The point at which a library&#039;s global variables are cleared depends on how the library was loaded and -in the case of resident libraries-what options are used.&lt;br /&gt;
&lt;br /&gt;
{\b Main program library} - For library functions that are defined within the main program, globals are cleared when a new main program is started or when the current main program is explicitly removed from memory.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resident library&#039;&#039;&#039; - When a library is loaded resident, global variables may be cleared in any of three ways:&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Default&#039;&#039;&#039;||By default, Business Rules clears a resident library&#039;s global variables when the main program ends.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Retain&#039;&#039;&#039;||When the OPTION RETAIN statement is used in a resident library program, the library retains its global variables irrespective of when the main program ends. The only way to clear globals when this statement is used is to CLEAR the library from memory or to reload it with the LOAD RESIDENT command. Remember that the library must be loaded resident for the OPTION RETAIN statement to have any affect.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;Release&#039;&#039;&#039;||When a resident library is named on a LIBRARY statement with the RELEASE keyword, the library&#039;s global variables are cleared after each function call to the library. This capability is provided so that the decision to load a library resident or as-needed can be made on a case-by-case basis; the program code can remain the same (because Business Rules handles the variables the same) regardless of whether the library is loaded resident or as-needed.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
{\b Present library} - When a library is loaded present, global variables are cleared when the main program ends.&lt;br /&gt;
&lt;br /&gt;
{\b As-needed library} - When a library is loaded as-needed, global variables are cleared after each function call to the library.&lt;br /&gt;
&lt;br /&gt;
The following table summarizes the information presented above. The keywords used in the &amp;quot;When globals are cleared&amp;quot; column are the same keywords used in the STATUS LIBRARY display (second column from right) to identify when variables for the listed library will be cleared. (See the &amp;quot;STATUS&amp;quot; command in the Commands chapter for complete information about this display.) The keywords are defined as follows:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;RUN&#039;&#039;&#039;||Globals are cleared when new main program is run.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;END&#039;&#039;&#039;||Globals are cleared when main program ends.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;EXIT&#039;&#039;&#039;||Globals are cleared after each function call to the library.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;RETAIN&#039;&#039;&#039;||Globals are retained, irrespective of main program status.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Image:Help0188.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Additional Processing Consideration==&lt;br /&gt;
&lt;br /&gt;
Active procedures and opened files are not affected by library function calls, unless the library issues commands that specifically affect them. This includes PROCERR settings.&lt;br /&gt;
&lt;br /&gt;
A nice aspect of library functions is the capability of a program to call a library function, which, in turn, calls a function in the main program. This supports the concept of manager functions that provide overall functionality while the main program fills in the details that may vary from program to program.&lt;br /&gt;
&lt;br /&gt;
The way to permit library routines to be overridden (functionally replaced) by corresponding functions in the main program is to have the library include those functions in a LIBRARY statement that doesn&#039;t specify a library name. Then have the library execute that statement after the main program has started. The library will then attach the library function in the main program instead of its own, even if a copy of the function exists in the library, because the main program is always regarded as having been loaded last for purposes of resolving unnamed library searches.&lt;br /&gt;
&lt;br /&gt;
Note that if a LIBRARY statement within a resident library creates linkage and then the main program ends, the linkage is broken and that LIBRARY statement must be re-executed before the function can be called again by the resident library.&lt;br /&gt;
&lt;br /&gt;
With respect to speed, parameters should be passed by reference (using the &amp;amp; in front of the variable name in the DEF statement) wherever possible. This avoids needless allocation of memory and copying of data, which is a significant part of function call processing.&lt;br /&gt;
&lt;br /&gt;
If you want to avoid the processing time required to load a library until a function within it is called, simply name the library and function on the same LIBRARY statement. However, if you want to be sure that the named functions exist within the library, first load the library with a statement that contains no function names. This will cause the library to be loaded at the time the LIBRARY statement is executed. Then when the LIBRARY statement containing the function list is encountered, the library (which is now in memory) will be checked for the presence of each function.&lt;br /&gt;
&lt;br /&gt;
It should be emphasized that executing a LOAD command does not establish function linkage. A subsequent LIBRARY statement must be processed to establish such linkage.&lt;br /&gt;
&lt;br /&gt;
When replacing a resident library with a different library, the first library should be cleared with a CLEAR command to free its memory before loading the second library.&lt;br /&gt;
&lt;br /&gt;
Updating a library (with the REPLACE command) has no effect on application environments until the library is (re)loaded.&amp;lt;br&amp;gt;&lt;br /&gt;
If a LIBRARY statement contains the name of a local function that is defined as non-library, a &amp;quot;duplicate function definition&amp;quot; error is generated when the program is run or saved.&lt;br /&gt;
&lt;br /&gt;
If a LIBRARY statement refers to a library without RELEASE and another statement refers to the same program with RELEASE, an error is generated. Also RELEASE cannot be specified for any library with the OPTION RETAIN statement.&lt;br /&gt;
&lt;br /&gt;
If a function in the main program, defined with the LIBRARY keyword, is called from within a library (a condition referred to as library loopback), the main program uses a fresh for-next stack.&amp;lt;br&amp;gt;&lt;br /&gt;
Therefore, pre-existing for-next processes are not recognized until the library returns normally to the main program.&lt;br /&gt;
&lt;br /&gt;
If more than one DEF LIBRARY statement for the same function name appears in a program, the lowest numbered definition will be used. More than one non-library DEF for the same variable is no longer permitted.&lt;br /&gt;
&lt;br /&gt;
Memory fragmentation can occur if a library is loaded resident while other programs are in memory, and then the main program chains leaving files open through either the CHAIN FILES statement, or having files open NOCLOSE. To avoid this problem, if you use CHAIN FILES or NOCLOSE, load your resident libraries before running application programs.&lt;br /&gt;
&lt;br /&gt;
Alternate libraries can be interrogated with function key 9 during a program pause.&lt;br /&gt;
&lt;br /&gt;
===Editing Active Libraries===&lt;br /&gt;
&lt;br /&gt;
When both a main program and a library program that is separate from the main program are active ( a function in the library program is currently being executed), the LIST command will display the contents of the library program. When functions in multiple library programs are active, the program with the most recently called function will be displayed.&lt;br /&gt;
&lt;br /&gt;
It is important to note that the only way to save changes made to a library program that has been activated by a main program is to list the library to a file and reload it from source later on. Because of this, it makes sense to develop a new library function first within the main program. Then once you&#039;ve completed the testing and debugging process, you can break it out and test it as a separate library function.&lt;br /&gt;
&lt;br /&gt;
===Linkage===&lt;br /&gt;
&lt;br /&gt;
When used to its full potential, the Business Rules Library Facility enables multiple versions of the same function (with the same name) to exist in different libraries, all of which may be loaded into memory. The actual library that is used for a specific function call is determined according to Business Rules rule for linkage, which is the process of associating a function name with a library name.&amp;lt;br&amp;gt;&lt;br /&gt;
Business Rules keeps tracks of established linkages in a table that it references each time a function is called.&lt;br /&gt;
&lt;br /&gt;
The LIBRARY statement may be used to establish linkage in one of two ways: the named method, or the unnamed method. These methods are defined as follows:&lt;br /&gt;
&lt;br /&gt;
;Named&lt;br /&gt;
The LIBRARY statement explicitly links one or more specific functions to a specific library. This is the most efficient and foolproof method for assuring that the library function you wish to use gets executed.&lt;br /&gt;
&lt;br /&gt;
In the following example, the functions FNRESLIB1 through FNRESLIB5 are explicitly linked to the library MAIN. When any of these functions is called, Business Rules will automatically execute them from the MAIN library. (Regardless of whether or not any other library currently in memory also contains functions by the same name.)&lt;br /&gt;
&lt;br /&gt;
 50300 LIBRARY &amp;quot;MAIN&amp;quot;:FNRESLIB1,FNRESLIB2,FNRESLIB3,FNRESLIB4,FNRESLIB5&lt;br /&gt;
&lt;br /&gt;
;Unnamed&lt;br /&gt;
The LIBRARY statement names the desired library functions and leaves it to Business Rules to determine which of the currently identified libraries they should be linked to. This determination is made according to the pre-set guidelines described below. The unnamed method of linkage is useful when your development methodology involves using multiple versions of the same function to control program options and features.&lt;br /&gt;
&lt;br /&gt;
When the unnamed method is used, Business Rules first searches the main program, then each library that is currently either resident or present (in last loaded, first searched order) for each function listed on the LIBRARY statement. Once Business Rules finds the function, the linkage is established, and -unless the linkage is explicitly changed with another LIBRARY statement or detached because the main program ends -all future calls to the same function will continue to utilize the same linkage. Note that Business Rules does not search as-needed libraries when the unnamed method of establishing linkage is used. Also, it is important to understand that it can take significantly longer to establish linkage using the unnamed method of linkage than with the named method of linkage.&lt;br /&gt;
&lt;br /&gt;
In the following example, line 01000 loads RESLIB as a resident library. Lines 01100 and 01200 load PRESLIB1 and PRESLIB2 as present libraries, and line 01300 names ASNLIB as an as-needed library. The LIBRARY statement on line 01400 establishes unnamed linkage for the function FNALIBI. When line 01500 is executed, Business Rules searches the currently loaded programs in the following order for FNALIBI: Main program, PRESLI2, PRESLIB1, RESLIB. Note that ASNLIB is not considered for this search because it is not currently loaded in memory.&lt;br /&gt;
&lt;br /&gt;
 01000 EXECUTE &amp;quot;LOAD RESLIB,RESIDENT&amp;quot;&lt;br /&gt;
 01100 LIBRARY &amp;quot;PRESLIB1&amp;quot;:&lt;br /&gt;
 01200 LIBRARY &amp;quot;PRESLIB2&amp;quot;:&lt;br /&gt;
 01300 LIBRARY RELEASE,&amp;quot;ASNLIB&amp;quot;: FNASNLIB1&lt;br /&gt;
 01400 LIBRARY : FNALIBI&lt;br /&gt;
 01500 LET FNALIBI&lt;br /&gt;
&lt;br /&gt;
===Status Library===&lt;br /&gt;
&lt;br /&gt;
Business Rules STATUS LIBRARY command may be used to display a table that identifies all the linkages that are currently active for each library. See &amp;quot;STATUS&amp;quot; in the Commands chapter for more information. For information about releasing and/or changing library linkages, see the term Linkage reassignment and detachment below.&lt;br /&gt;
&lt;br /&gt;
==Sample Program==&lt;br /&gt;
&lt;br /&gt;
The following two sample sections of code are, for convenience purposes, labeled &amp;quot;Main Program&amp;quot; and &amp;quot;Library&amp;quot;. The Main Program references two functions (FNSEND and FNRECEIVE), which are located in the Library. Line 50 of the Main Program establishes the function linkage; line 70 prompts for a message; and line 110 calls the FNSEND function, which is defined on line 30 of the Library.&lt;br /&gt;
&lt;br /&gt;
FNSEND opens the communications port and sends the operator-specified message to the terminal connected to the port. The Main Program then calls the FNRECEIVE function, which is defined on line 80 of the Library. This function waits up to 15 seconds for a response (by default), returns the response in the parameter, and returns its length as a function value. Finally, the Main Program prints the response or the message &amp;quot;No Response&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
&lt;br /&gt;
 00010 ! MAIN PROGRAM&lt;br /&gt;
 00020 !&lt;br /&gt;
 00030 DIM MESG$*60, RESPONSE$*120&lt;br /&gt;
 00040 !&lt;br /&gt;
 00050 LIBRARY &amp;quot;TOOLS\LIB1&amp;quot;: FNSEND, FNRECEIVE&lt;br /&gt;
 00060 !&lt;br /&gt;
 00070 PRINT &amp;quot;Specify Message&amp;quot;&lt;br /&gt;
 00080 LINPUT MESG$&lt;br /&gt;
 00090 IF LEN(MESG$) = 0 THEN STOP&lt;br /&gt;
 00100 !&lt;br /&gt;
 00110 LET FNSEND(MESG$)&lt;br /&gt;
 00120 !&lt;br /&gt;
 00130 IF FNRECEIVE(RESPONSE$) THEN !:PRINT RESPONSE$ !:ELSE !:PRINT &amp;quot;No Response&amp;quot;&lt;br /&gt;
 00140 GOTO 70&lt;br /&gt;
&lt;br /&gt;
 Library:&lt;br /&gt;
 00010 ! LIB1&lt;br /&gt;
 00020 !&lt;br /&gt;
 00030 DEF LIBRARY, FNSEND(MESSAGE$*60)&lt;br /&gt;
 00040  IF NOT COMM OPENED THEN !:OPEN #40: &amp;quot;NAME=COM2:, FORMAT=ASYNC,BAUD=2400&amp;quot;,DISPLAY, OUTIN !:COMM OPENED = 1&lt;br /&gt;
 00050  PRINT #40: MESSAGES$&lt;br /&gt;
 00060 FNEND&lt;br /&gt;
 00070 !&lt;br /&gt;
 00080 DEF LIBRARY FNRECEIVE(&amp;amp;RESP$)&lt;br /&gt;
 00090  LINPUT #40: RESP$ IOERR 100&lt;br /&gt;
 00100  FNRECEIVE = LEN(RESP$)&lt;br /&gt;
 00110 FNEND&lt;br /&gt;
&lt;br /&gt;
===Tips for implementing Library Functions in Existing Applications===&lt;br /&gt;
&lt;br /&gt;
As mentioned above, it is important that you consider your current usage of global variables before converting your existing user-defined functions into library functions and placing them into a separate program. This section provides some examples of how you can modify existing applications to utilize library functions, even if the existing applications currently access or modify user-defined function variables from outside the function. Other examples shown in this section demonstrate how you can turn an entire program (such as a client maintenance program) into a library function that a user can invoke at will from within another program (such as order entry) and provide some tips on implementing libraries for programs that use [[FNSNAP]]! tools.&lt;br /&gt;
&lt;br /&gt;
;Example 1:&lt;br /&gt;
Separating main program logic from user-defined functions&amp;lt;br&amp;gt;&lt;br /&gt;
The following is a very simple example of a program that uses a user-defined function.&lt;br /&gt;
&lt;br /&gt;
;ORIGINAL PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page, plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
The steps you would need to take to separate the function into a separate library and enable the main program to call the function would be as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Place the user-defined functions into their own program.&lt;br /&gt;
:2.) Modify the DEF line for each of the functions in the new library program to utilize the LIBRARY keyword (demonstrated in line 02000 of the library program below).&lt;br /&gt;
:3.) Delete the separated functions from the main programs that are to use the new library.&lt;br /&gt;
:4.) Add a LIBRARY statement to the main program that names each function that is to be called from the library program (demonstrated in line 00005 of the main program below).&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;howto1nl&amp;quot; : FNDOCEST&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,lus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
;Example 2:&lt;br /&gt;
Function uses global variables established by main program&lt;br /&gt;
&lt;br /&gt;
In the following program, the global variable PAGEEST is established by the main program logic on line 00020. This same global variable is accessed by the user-defined function at line 02010.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
As there is no way for a main program to share its global variables with a library function contained in a separate program, this program must be modified before it can be separated into &amp;quot;main&amp;quot; and &amp;quot;library&amp;quot; programs. In the following example, line 02000 has been modified (as shown in italics) to pass the PAGEEST variable by reference, thereby causing the library function to use the main program&#039;s copy of the variable.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
;Example 3:&lt;br /&gt;
Existing program queries function variable from outside function&amp;lt;br&amp;gt;&lt;br /&gt;
This example shows the same starting program as shown in Example 1, except that line 00040 has been added to demonstrate a situation where the main program logic queries (without changing) a variable that has been established by the user-defined function. This programming technique also is not allowed when functions are separated into library programs,&lt;br /&gt;
as there is just one way (via the function variable) for a separate library function to pass a value back to the main program.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST&lt;br /&gt;
 00040 IF WRITETIME&amp;gt;8 THEN PRINT &amp;quot;Total days: &amp;quot;;WRITETIME/8&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF FNDOCEST&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
&lt;br /&gt;
When starting new programming projects that are to utilize Business Rules Libraries, ADS recommends against the programming technique shown here. However, if your programs already use this technique and you want to utilize the benefits of libraries with as little work as possible, you could change the programs in the manner shown below.&lt;br /&gt;
&lt;br /&gt;
The following two code sections show the original program as it would be when split into main program and library, and with a &amp;quot;rigged&amp;quot; technique for the program to get the value of the queried variable from the library. The &amp;quot;rig&amp;quot; is that all references to the WRITETIME variable in the main logic have been changed to FNWRITETIME, and FNWRITETIME has been added to the library to query the value of WRITETIME and pass it back to the main program. Note that there is a limitation to this technique: the program must be loaded into either resident memory (without use of RELEASE on the LIBRARY statement) or present memory for it to work. This is because the technique relies on the library&#039;s global variables remaining active even after function calls to it have been completed.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;howto2nl&amp;quot; : FNDOCEST,FNWRITETIME&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 IF FNWRITETIME&amp;gt;8 THEN PRINT &amp;quot;Total days: &amp;quot;;FNWRITETIME/8&lt;br /&gt;
&lt;br /&gt;
;LIBRARY:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page, plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is:&amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030 FNEND&lt;br /&gt;
 03000 DEF LIBRARY FNWRITETIME=WRITETIME&lt;br /&gt;
&lt;br /&gt;
;Example 4:&lt;br /&gt;
Existing program queries or modifies function variable from outside function&amp;lt;br&amp;gt;&lt;br /&gt;
In the following example, line 00120 of the main program logic modifies the value of TOTTIME, which is established by the FNDOCEST function. It is important that this modified value be communicated back to the function, because line 02030 of the function uses it for subsequent calls. Note also that lines 00100 and 00130 of the main program logic also query (without modifying) the value of TOTTIME.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages for chapter 1:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 PRINT &amp;quot;Enter estimated number of pages for chapter 2:&amp;quot;&lt;br /&gt;
 00050 INPUT PAGEEST&lt;br /&gt;
 00060 PRINT &amp;quot;Is subject matter highly technical? (Y/N)&amp;quot;&lt;br /&gt;
 00070 INPUT TECHLEVEL$&lt;br /&gt;
 00080 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00090 IF UPRC$(TECHLEVEL$)=&amp;quot;Y&amp;quot; THEN&lt;br /&gt;
 00100  LET SURPLUS=TOTTIME*.2&lt;br /&gt;
 00110  PRINT &amp;quot;Surplus time for technical matter: &amp;quot;;SURPLUS;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00120  LET TOTTIME+=SURPLUS&lt;br /&gt;
 00130  PRINT &amp;quot;Total time is &amp;quot;;TOTTIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00140 END IF&lt;br /&gt;
&lt;br /&gt;
;LIBRARY:&lt;br /&gt;
 02000 DEF FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030  PRINT &amp;quot;Accumulated total is: &amp;quot;;TOTTIME+=WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02040 FNEND&lt;br /&gt;
&lt;br /&gt;
As noted for the previous example in this section, programming practices such as this are not recommended for new development that is to utilize the Library Facility. These examples are supplied to help you quickly modify existing programs so they can utilize the benefits of libraries.&lt;br /&gt;
&lt;br /&gt;
The next two programs (main and library) show how the original program was changed to work with libraries.&lt;br /&gt;
&lt;br /&gt;
;MAIN PROGRAM:&lt;br /&gt;
 00005 LIBRARY &amp;quot;HOWTO3NL&amp;quot; : FNDOCEST,FNADD TOTTIME&lt;br /&gt;
 00010 PRINT &amp;quot;Enter estimated number of pages for chapter 1:&amp;quot;&lt;br /&gt;
 00020 INPUT PAGEEST&lt;br /&gt;
 00030 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00040 PRINT &amp;quot;Enter estimated number of pages for chapter 2:&amp;quot;&lt;br /&gt;
 00050 INPUT PAGEEST&lt;br /&gt;
 00060 PRINT &amp;quot;Is subject matter highly technical? (Y/N)&amp;quot;&lt;br /&gt;
 00070 INPUT TECHLEVEL$&lt;br /&gt;
 00080 LET FNDOCEST(PAGEEST)&lt;br /&gt;
 00090 IF UPRC$(TECHLEVEL$)=&amp;quot;Y&amp;quot; THEN&lt;br /&gt;
 00100  LET SURPLUS=FNADD TOTTIME(0)*.2&lt;br /&gt;
 00110  PRINT &amp;quot;Surplus time for technical matter: &amp;quot;;SURPLUS;&amp;quot;hours&amp;quot;&lt;br /&gt;
 00130  PRINT &amp;quot;Total time is &amp;quot;;FNADD TOTTIME(SURPLUS);&amp;quot;hours&amp;quot;&lt;br /&gt;
 00140 END IF&lt;br /&gt;
&lt;br /&gt;
;LIBRARY PROGRAM:&lt;br /&gt;
 02000 DEF LIBRARY FNDOCEST(&amp;amp;PAGEEST)&lt;br /&gt;
 02010  LET WRITETIME=(PAGEEST*2)*1.15 ! Two hours per page,plus 15% for index&lt;br /&gt;
 02020  PRINT &amp;quot;Documentation estimate is: &amp;quot;;WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02030  PRINT &amp;quot;Accumulated total is: &amp;quot;;TOTTIME+=WRITETIME;&amp;quot;hours&amp;quot;&lt;br /&gt;
 02040 FNEND&lt;br /&gt;
 03000 DEF LIBRARY&lt;br /&gt;
 FNADD TOTTIME(ADDTOTTIME)=TOTTIME+=ADDTOTTIME&lt;br /&gt;
&lt;br /&gt;
Once the required steps of separating the two programs, adding the necessary LIBRARY statement to the main program and adding the LIBRARY keyword to the DEF statement in the library program were completed for the above code, the following steps were conducted to enable the main program and function to communicate the value of TOTTIME. Note that there is a limitation to the technique shown: the library program must be loaded into either resident memory (without use of RELEASE on the LIBRARY statement) or present memory for it to work. This is because it relies on the library&#039;s global variables remaining active even after function calls to it have been completed.&lt;br /&gt;
&lt;br /&gt;
:1.) The FNADD TOTTIME function was added to the library program (line 03000). This function takes a variable (representing the amount to add to TOTTIME) that is passed by the main program. It adds the passed variable to TOTTIME, and also assigns the new value of TOTTIME to the function variable FNADD TOTTIME.&lt;br /&gt;
:2.) The FNADD TOTTIME function name was added to the LIBRARY statement on line 00005 of the main program.&lt;br /&gt;
:3.) Line 00120 of the main program was removed, and line 00130 was modified to call the FNADD TOTTIME library function instead of modifying TOTTIME directly. The value of SURPLUS is passed to FNADD TOTTIME; FNADD TOTTIME takes over the job of modifying the value of TOTTIME and making sure that both the main program and the library program know its new value.&lt;br /&gt;
:4.) Line 00100 of the main program was changed to call the FNADD TOTTIME function as well. Since this line only needs to query the value of TOTTIME, it passes a value of 0 as the amount to add to TOTTIME.&lt;br /&gt;
&lt;br /&gt;
;Example 5:&lt;br /&gt;
Turning an existing program into a user-invokable library function&amp;lt;br&amp;gt;&lt;br /&gt;
Business Rules Library Facility makes it very easy to turn an entire program into a library function that a user can invoke at will from within another program. For example, consider a standard application that includes both a client maintenance (MNTCUST) program and an order entry program (ORDERS). You would like to give users the ability to invoke the client maintenance program from within the order entry program whenever they press F4. The steps required to do this are as follows:&lt;br /&gt;
&lt;br /&gt;
:1.) Modify MNTCUST by placing the entire original program into a user-defined library function and adding a few lines that cause the program to call itself as a library function whenever it is executed as the main program.&lt;br /&gt;
:a.) Move any user-defined functions that exist within the main body of the program to the end of the program (or to a separate library).&lt;br /&gt;
:b.) Add lines such as the following to the top of the program. NOTE that the (program name) in line 00030 represents the name of the program (such as a main menu) from which you currently normally invoke the client maintenance program.&lt;br /&gt;
&lt;br /&gt;
 00010 LIBRARY &amp;quot;MNTCUST&amp;quot; : FNMNTCUST&lt;br /&gt;
 00020 LET FNMNTCUST&lt;br /&gt;
 00030 CHAIN (program name)&lt;br /&gt;
 00040 DEF LIBRARY FNMNTCUST&lt;br /&gt;
&lt;br /&gt;
:c.) Add the following line to the end of the main body of the program (prior to any user-defined function definitions):&lt;br /&gt;
&lt;br /&gt;
 80000 FNEND&lt;br /&gt;
&lt;br /&gt;
:2.) Modify ORDERS as follows:&lt;br /&gt;
&lt;br /&gt;
:a.) Change the screen to include a label that identifies the operation of the F4 key.&lt;br /&gt;
:b.) Change the program to check for pressing of the F4 key.&lt;br /&gt;
:c.) Change the program to execute the following whenever F4 is pressed. Note that the LIBRARY statement in line 50000 utilizes the &amp;quot;RELEASE&amp;quot; keyword: this causes the MNTCUST library to be loaded into memory on an as-needed basis only. Thus the only time that the on-the-fly client maintenance feature uses system resources is when the user actually requests the capability by pressing F4.&lt;br /&gt;
&lt;br /&gt;
 50000 LIBRARY RELEASE, &amp;quot;MNTCUST&amp;quot; :FNMNTCUST&lt;br /&gt;
 50010 LET FNMNTCUST&lt;br /&gt;
&lt;br /&gt;
;Example 6:&lt;br /&gt;
Tips for moving [[FNSNAP]]! functions into separate libraries for users of [[FNSNAP]]! programming tools, modifying existing programs to use libraries will involve a combination of the techniques demonstrated above. Every developers programs are different, so this section cannot give you a beginning-to-end list of steps to complete to accomplish the task, but the following are some steps you can start with:&lt;br /&gt;
&lt;br /&gt;
:1.) Place the FNSNAP! functions into their own program. (This example uses MAIN\\FNSNAP as the path and location of the new program.)&lt;br /&gt;
:2.) Modify the DEF line for each of the functions in FNSNAP to utilize the LIBRARY keyword. For example:&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 60150 DEF FNOK&lt;br /&gt;
&lt;br /&gt;
To this:&lt;br /&gt;
&lt;br /&gt;
 60150 DEF LIBRARY FNOK&lt;br /&gt;
&lt;br /&gt;
:3.) Add the following FNFNSNAP INIT function to the FNSNAP program. This function sets all the global variables that are used by the FNSNAP functions (in the past, FNSNAP! users were instructed to add these variable settings to the start of their programs). FNFNSNAP INIT also executes a LIBRARY statement for the FNSNAP program. This LIBRARY statement establishes linkage for all the functions in the FNSNAP program that are called by other functions in the same program.&lt;br /&gt;
&lt;br /&gt;
 00121 DEF LIBRARY FNFNSNAP INIT&lt;br /&gt;
 00122 LET DATFMT$=&amp;quot;MM-DD-CCYY&amp;quot; !:LET FULLSCR=0 !:LET MAXSROWS=22 !:LET WINDEV=OWINDEV=69 !:LET MGA$=&amp;quot;24,2,C 78,&amp;quot; !:IF NOT SSAV THEN LET SSAV=101 !:!Common Variables required by FNSNAP! !:&lt;br /&gt;
 00124 LIBRARY &amp;quot;MAIN\FNSNAP&amp;quot; : FNRELPART,FNSAVPART, FNPM, FNAUTO, FNOK, FNWIN,FNCLSWIN, FNZERO, FNTIMMILREG, FNSSAV,FNSAVSCR, FNSETBAD, FNPURGE, FNFLDSEL$&lt;br /&gt;
 00130 FNEND !:&lt;br /&gt;
:4.) Delete the separated functions from the main programs that are to use the FNSNAP library.&lt;br /&gt;
&lt;br /&gt;
:5.) Add the following program line to each of the main programs that are to use the FNSNAP library. This statement establishes linkage between the functions to be called and the program they are located in, and it calls the FNFNSNAP INIT function, which sets the library&#039;s global values:&lt;br /&gt;
&lt;br /&gt;
 00160 LIBRARY &amp;quot;MAIN\FNSNAP&amp;quot;:FNFNSNAP INIT, FNSSAV, FNPOPWIN,FNPOPBAR, FNWINDEV, FNPOPWIN INIT,FNPOPBAR INIT, FNCO$, FNMGCLR, FNTOP,FNOK, FNSAVSCR, FNSCRMGR, FNSAVPART,FNRELPART, FNCLRPART, FNZERO, FNNULL$,FNTIMMILREG, FNDIALOG$, FNWIN, FNCLSWIN,FNNOKEY, FNPOPUP, FNPM, FNAUTO,FNPFKEYLINE !:LET FNFNSNAP INIT !:!&lt;br /&gt;
&lt;br /&gt;
==Error Processing==&lt;br /&gt;
&lt;br /&gt;
If an error is not trapped in a library function, the error is reported back to the calling program. At this time the following system variables are set:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;LINE&#039;&#039;&#039;||The line number of the calling program function call.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;ERR&#039;&#039;&#039;||The error number that occurred in the library function.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;CNT&#039;&#039;&#039;||The appropriate value as if the error occurred in the calling program.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If an error occurs while attempting to match parameters between a function call and the function definition, CNT is set to the number of parameters successfully matched.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:User Defined Functions and Libraries]]&lt;br /&gt;
[[Category:Facility]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=User_Defined_Functions&amp;diff=2654</id>
		<title>User Defined Functions</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=User_Defined_Functions&amp;diff=2654"/>
		<updated>2013-04-15T19:11:21Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: Created page with &amp;quot;A &amp;#039;&amp;#039;&amp;#039;User Defined Function&amp;#039;&amp;#039;&amp;#039; in Business Rules! is an extremely useful tool.  Using a function you can perform a series of similar tasks on one or more variables and retu...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A &#039;&#039;&#039;User Defined Function&#039;&#039;&#039; in [[Business Rules!]] is an extremely useful tool.  Using a function you can perform a series of similar tasks on one or more variables and return the changed variable, a result of the interaction of those variables on one another, or a combination of both.  Generally a function is created by using a [[DEF]] statement.  If the function only needs one line of code then there are no additional lines, the function stands on its own.  More likely, however, is a multilined function, these also start with a DEF clause followed by various BR statements and end with an [[FNEND]] statement.&lt;br /&gt;
&lt;br /&gt;
The lines of code between the DEF and the FNEND statements follow the same rules as &amp;quot;normal&amp;quot; BR code with a few exceptions relating to variables passed in to the function.  If a variable is passed into a function it can be &amp;quot;by reference&amp;quot; or &amp;quot;by value&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
See also the [[Library Facility]].&lt;br /&gt;
&lt;br /&gt;
====By Value====&lt;br /&gt;
&lt;br /&gt;
A By Value function variable can be passed to a function, but is not returned by the function.  That is, any changes made to the variable in the called function have no affect on the variable in the calling program. The calling program passes just the value or content of the variable into the function, not the actual variable, so the called function has no way to change the real variable. When calling a function, if a parameter is being passed By Value, you may substitute a literal instead of a variable.&lt;br /&gt;
&lt;br /&gt;
====By Reference====&lt;br /&gt;
&lt;br /&gt;
A By Reference function variable is sent to the function and whatever changes the function makes on the variable are returned to (occur within) the calling program.  By Reference variables are designated in the DEF statement with a leading ampersand &amp;quot;&amp;amp;&amp;quot;.  The calling program passes a memory reference to the variable itself, giving the function access to modify the variable.  Matrices passed to a function are always passed By Reference, because it is much faster to pass just a reference to a large array into a function than it would be to pass the entire array By Value.&lt;br /&gt;
&lt;br /&gt;
If a function definition lists a parameter as By Reference (you see the &amp;quot;&amp;amp;&amp;quot; in the def statement), then BR will not allow you to pass a literal as that parameter into the function. Instead you must pass an actual calling program variable.&lt;br /&gt;
&lt;br /&gt;
====Matrix changes====&lt;br /&gt;
&lt;br /&gt;
As mentioned above a [[Mat|matrix]] is always passed By Reference.  It can be redimensioned, changed in many ways and then used by the calling program in it&#039;s changed state. &lt;br /&gt;
&lt;br /&gt;
The only time when this will not happen is when the matrix is non-existent in the function call.  A non-existent matrix is one that has been marked as an &amp;quot;Optional&amp;quot; variable in the DEF statement and no matrix was named in the program call to the function.  The non-existent matrix can not then be re-dimensioned because it does not exist.  If you want to re-dimension a matrix and have it passed  out of the function then it is necessary to use a &amp;quot;dummy&amp;quot; matrix passed in so that the function does not use a NULL array by default.&lt;br /&gt;
&lt;br /&gt;
====Library Function====&lt;br /&gt;
&lt;br /&gt;
A function can either be a part of the program that is loaded, similar to a sub-routine, or it can be a library function that is either present in the program or located in another named program.  A library function definition differs from a function definition because it includes the word library between the DEF and the name of the function.  The program code for a library function is otherwise the same as a function.&lt;br /&gt;
&lt;br /&gt;
In order to use a library function the library and the library function name must be designated in the program that calls the library function. (Libraries may call other libraries.)  This is done with a &amp;quot;LIBRARY&amp;quot; statement.&lt;br /&gt;
&lt;br /&gt;
 LIBRARY &amp;quot;E:\\WB\\vol002\\fnsnap.dll&amp;quot;:FNPRINTBOX,FNDRAWBOX&lt;br /&gt;
&lt;br /&gt;
The above statement says that the library functions FNPRINTBOX and FNDRAWBOX are located in the Business Rules! program &amp;quot;[[FNSNAP.dll]]&amp;quot; that has been named with a dll suffix, rather than a .BR or .WB suffix, located in the &amp;quot;wb\\vol002&amp;quot; directory of drive E:.  Note that Business Rules! automatically assigns a .BR or .WB suffix to programs when they are initially created, but  a [[Business Rules!|BR]] program can have any suffix that you assign to it.&lt;br /&gt;
&lt;br /&gt;
===Library Variables===&lt;br /&gt;
&lt;br /&gt;
Any variable used with a program or library is common to all the functions, sub-routines and mainline routines within that program or library.  This means that if, in library SAMPLE.br, library function FNFIRST uses a variable &amp;quot;X&amp;quot; to count how many times a routine is processed and it turns out that that number is 10,  and library function FNSECOND, also included in SAMPLE.br, uses the variable &amp;quot;X&amp;quot; which it expects is initialized to zero because that function has not used it before, unexpected results will occur because the value of &amp;quot;X&amp;quot; is now 10, not zero.  If FNSECOND were located in a different library, then the value of &amp;quot;X&amp;quot; set by FNFIRST would not be visible to it and FNSECOND would not use the value of 10, but might use a value  previously set by FNSECOND.  &lt;br /&gt;
&lt;br /&gt;
It is good practice to avoid such problems by declaring &#039;work&#039; variables as optional parameters within function definitions. Optional parameters are listed after required parameters and the two groups are separated with a semicolon (;). Listing work variables as optional parameters avoids both present and future variable name conflicts with other routines or functions.&lt;br /&gt;
&lt;br /&gt;
===Library Sub-routines===&lt;br /&gt;
&lt;br /&gt;
Sub-routines in programs are very useful.  They can be used from different parts of the program without the necessity of duplicating code.  They can also be used to keep complex manipulations out of the main logic of a program to make it easier to understand.  Sub-routines can be used in functions, library functions, and libraries as well.  Two library functions residing in the same library can each use the same sub-routine, located outside of the [[DEF]] / [[FNEND]] boundaries.  This is true as long as the sub-routine is located within the same library as the library function(s) making use of it.&lt;br /&gt;
&lt;br /&gt;
===Library Status===&lt;br /&gt;
&lt;br /&gt;
Once a library has been created and it is being named in a program it can be loaded as a &amp;quot;RESIDENT&amp;quot;, library, a &amp;quot;CURRENT&amp;quot; library or a &amp;quot;RELEASE&amp;quot; library.&lt;br /&gt;
&lt;br /&gt;
====Resident Library====&lt;br /&gt;
&lt;br /&gt;
A resident library once loaded remains in memory and can be called by any program that is subsequently loaded.  It retains its variable values from program to program. It is only removed with a clear command or by exiting the [[Business Rules!|BR]] session.&lt;br /&gt;
&lt;br /&gt;
 00100 library resident &amp;quot;E:\\wb\\vol002\\getdates.br&amp;quot;:FNDATE&lt;br /&gt;
&lt;br /&gt;
====Current Library====&lt;br /&gt;
&lt;br /&gt;
The default load of a library is a current library.  It is active while the program that loads it is in memory and retains its variables only while that program is active.  A current library, because it terminates when a program ends, cannot call a resident library.&lt;br /&gt;
&lt;br /&gt;
 00100 library &amp;quot;E:\\wb\\vol002\\getdates.br&amp;quot;:FNDATE&lt;br /&gt;
&lt;br /&gt;
====Release Library====&lt;br /&gt;
&lt;br /&gt;
A library that is designated as release only maintains its variables while a call to it is active.  As soon as the function reaches the FNEND statement and passes information back to the calling function or routine the variables are cleared.  A released library, since it does not occupy memory when not active cannot call a current or a resident library.&lt;br /&gt;
&lt;br /&gt;
 00100 library release &amp;quot;E:\\wb\\vol002\\getdates.br&amp;quot;:FNDATE&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:User Defined Functions and Libraries]]&lt;br /&gt;
[[Category:Basics]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=PEM_File&amp;diff=2653</id>
		<title>PEM File</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=PEM_File&amp;diff=2653"/>
		<updated>2013-04-15T18:47:02Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: Created page with &amp;quot;The &amp;#039;&amp;#039;&amp;#039;PEM Files&amp;#039;&amp;#039;&amp;#039; are used in Properties, Events, and Methods (PEM) and .NET controls.  ===BR Directory=== *pemnet.dll *brconvert.dll *vcdlltest.exe (used fo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;PEM Files&#039;&#039;&#039; are used in [[Properties, Events, and Methods (PEM) and .NET controls]].&lt;br /&gt;
&lt;br /&gt;
===BR Directory===&lt;br /&gt;
*[[pemnet.dll]]&lt;br /&gt;
*[[brconvert.dll]]&lt;br /&gt;
*[[vcdlltest.exe]] (used for testing)&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
Use the following files to install the necessary system programs.&lt;br /&gt;
&lt;br /&gt;
*[[dotnetfx20.exe]] (Windows 2000) or [[dotnetfx35.exe]] (Windows XP or Vista) - to install/upgrade dot net&lt;br /&gt;
*[[vcredist_x86.exe]] - to install a required dot net support library&lt;br /&gt;
&lt;br /&gt;
There are two main groups of supporting Dll&#039;s needed to use .Net controls with BR:&lt;br /&gt;
&lt;br /&gt;
#VC++ shared libraries.  These can be tested with [[vcdlltest.exe]] and installed with vcredist_x86.exe.&lt;br /&gt;
&lt;br /&gt;
#The .Net framework.  If you are using Windows 2000, you will need to use dotnetfx20.exe.  If you are using windows XP or Vista use dotnetfx35.exe.&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Properties_Events_and_Methods&amp;diff=2652</id>
		<title>Category:Properties Events and Methods</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Category:Properties_Events_and_Methods&amp;diff=2652"/>
		<updated>2013-04-15T18:44:42Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See also: [[Properties, Events, and Methods (PEM) and .NET controls]]&lt;br /&gt;
&lt;br /&gt;
External controls can now be placed on BR windows:&lt;br /&gt;
&lt;br /&gt;
  PRINT FIELDS &amp;quot;row,col,comp[onent] rows/cols,[,INDEPENDENT]&amp;quot;: control-id$,mat properties$ [, mat events$]&lt;br /&gt;
&lt;br /&gt;
INDEPENDENT will signify that the control is independently enabled and is not subject to the normal enabling restrictions associated with FIELDS operations. &lt;br /&gt;
&lt;br /&gt;
control-id$ should be in the format &amp;quot;mycontrol:class-name&amp;quot;&lt;br /&gt;
mat properties$ will have property assignments (e.g. color=blue)&lt;br /&gt;
mat events$ will have event assignments to fkey values (TypChanged=1035)&lt;br /&gt;
  - to clear pevious settings use TypChanged= -1&lt;br /&gt;
  - setting events is optional&lt;br /&gt;
&lt;br /&gt;
The above form cannot be used in the same statement as other controls.&lt;br /&gt;
&lt;br /&gt;
The following forms can be used in the same FIELDS array as other controls:&lt;br /&gt;
 &lt;br /&gt;
 PRINT FIELDS &amp;quot;row,col,comp[onent] [rows/cols]&amp;quot;: mat properties$&lt;br /&gt;
&lt;br /&gt;
 INPUT FIELDS &amp;quot;row,col,comp[onent] rows/cols&amp;quot;: mat properties$&lt;br /&gt;
&lt;br /&gt;
Input Processing&lt;br /&gt;
&#039;&#039;&#039;Mat properties$&#039;&#039;&#039; has property names or property assignments. &lt;br /&gt;
Any assigned values will be ignored. The array will be populated with property assignments for all specified properties.&lt;br /&gt;
&lt;br /&gt;
The syntax for retrieving all of the names:&lt;br /&gt;
 INPUT FIELDS &amp;quot;row,col,comp[onent] rows/cols,PROPERTY_NAMES,depth&amp;quot;: mat properties$&lt;br /&gt;
 INPUT FIELDS &amp;quot;row,col,comp[onent] rows/cols,EVENT_NAMES&amp;quot;: mat events$&lt;br /&gt;
 INPUT FIELDS &amp;quot;row,col,comp[onent] rows/cols,METHOD_NAMES&amp;quot;: mat methods$&lt;br /&gt;
&lt;br /&gt;
To set or get individual properties:&lt;br /&gt;
 set$(&amp;quot;#fileno,row,col&amp;quot;,&amp;quot;city=Los Angeles&amp;quot;)&lt;br /&gt;
 set$(&amp;quot;#fileno,row,col&amp;quot;,&amp;quot;address.city=Los Angeles&amp;quot;)&lt;br /&gt;
 get$(&amp;quot;#fileno,row,col&amp;quot;,&amp;quot;city&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
To invoke a method:&lt;br /&gt;
 INVOKE(&amp;quot;#fileno,row,col&amp;quot;,method-name$, mat args$)&lt;br /&gt;
&lt;br /&gt;
==PEM Data Conversion==&lt;br /&gt;
&lt;br /&gt;
BR offers only two data types - [[string]] and [[numeric]].  Many other types are required by various controls available for outside resources. &lt;br /&gt;
&lt;br /&gt;
Concerning .NET and other objects, BR provides conversion routines for the purpose of working with various data types. For example you may express colors as is done in HTML (#xxyyzz) and have them converted to and from a structure with RGB values for use by a .NET object. &lt;br /&gt;
&lt;br /&gt;
These conversion routines are in a separate [[DLL]] that is automatically invoked based on the field&#039;s [[class]] type when a property value is sent or received by BR via a properties array, or a [[GET]], [[SET]] or [[INVOKE]] parameter.  The DLL used to perform these conversions is included in the [[object toolbox DLL group]] located in the BR directory. &lt;br /&gt;
&lt;br /&gt;
The first release of the DLL supports the following object types:&lt;br /&gt;
 // conversion class for System.Drawing.Color&lt;br /&gt;
 // conversion class for System.String&lt;br /&gt;
 // conversion class for System.Int32&lt;br /&gt;
&lt;br /&gt;
If there is a class that you would like to see a conversion routine for that does not exist and you wish to write one, this must implement the interface (DLL data type name) brconvert.BrConversion which has 2 methods: &lt;br /&gt;
&lt;br /&gt;
    int objectToString(System.String string, out System.Object value)&lt;br /&gt;
    int stringToObject(System.Object value, out System.String string)&lt;br /&gt;
&lt;br /&gt;
You must also prepend the name of the class with brconvert.BR so if you were going to make a conversion class for System.Drawing.Color the conversion class would need to be named:&lt;br /&gt;
&lt;br /&gt;
    brconvert.BRSystem.Drawing.Color.&lt;br /&gt;
&lt;br /&gt;
==PEM File Requirements==&lt;br /&gt;
&lt;br /&gt;
{{:PEM File}}&lt;br /&gt;
&lt;br /&gt;
[[Category:4.20]]&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Border_Spec&amp;diff=1716</id>
		<title>Border Spec</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Border_Spec&amp;diff=1716"/>
		<updated>2013-02-04T19:06:41Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: /* Syntax */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &amp;quot;BORDER=spec&amp;quot; parameter represents an inserable syntax that specifies the visual characteristics of the window border, within the [[Open Window]] statement. The BORDER= keyword must be followed by one of four border specifications (as of 4.3 these work with CON GUI ON as well). &lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
[[image:Borderspec.png|500px]]&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
*&amp;quot;B&amp;quot; indicates that the border is to be blank; &lt;br /&gt;
*&amp;quot;D&amp;quot; indicates a double-line border; &lt;br /&gt;
*&amp;quot;H&amp;quot; indicates that a shadowed or highlighted border be used; &lt;br /&gt;
*and &amp;quot;S&amp;quot; indicates that a single-lined border be used. &lt;br /&gt;
&amp;quot;Corners&amp;quot; and &amp;quot;8 chars&amp;quot; border specifications may be used for custom-designed window borders. See [[Screen I/O]] for illustrations and more information about border types and border graphics specifications. However, as of 4.3, Border=H and &amp;quot;8 chars&amp;quot; are no longer supported except that a new [[Option (Config)|OPTION]] 62 permits S, D, B, H or an eight character string followed by a colon and then attributes. For example: &lt;br /&gt;
             BORDER=S|D|B|H|8-chars[:attributes]&lt;br /&gt;
While the colon is actually optional, it is recommended for readability when attributes are included.&lt;br /&gt;
&lt;br /&gt;
Also within the BORDER= syntax, the &amp;quot;attributes&amp;quot; parameter may be specified immediately after the border specification (no spaces). The attributes specified here will affect the visual display of the border itself. See [[Definitions]] for the correct syntax to be used with the &amp;quot;attributes&amp;quot; parameter.&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Border_Spec&amp;diff=1715</id>
		<title>Border Spec</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Border_Spec&amp;diff=1715"/>
		<updated>2013-02-04T19:06:08Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: /* Syntax */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &amp;quot;BORDER=spec&amp;quot; parameter represents an inserable syntax that specifies the visual characteristics of the window border, within the [[Open Window]] statement. The BORDER= keyword must be followed by one of four border specifications (as of 4.3 these work with CON GUI ON as well). &lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
[[image:Borderspec.png|300px]]&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
*&amp;quot;B&amp;quot; indicates that the border is to be blank; &lt;br /&gt;
*&amp;quot;D&amp;quot; indicates a double-line border; &lt;br /&gt;
*&amp;quot;H&amp;quot; indicates that a shadowed or highlighted border be used; &lt;br /&gt;
*and &amp;quot;S&amp;quot; indicates that a single-lined border be used. &lt;br /&gt;
&amp;quot;Corners&amp;quot; and &amp;quot;8 chars&amp;quot; border specifications may be used for custom-designed window borders. See [[Screen I/O]] for illustrations and more information about border types and border graphics specifications. However, as of 4.3, Border=H and &amp;quot;8 chars&amp;quot; are no longer supported except that a new [[Option (Config)|OPTION]] 62 permits S, D, B, H or an eight character string followed by a colon and then attributes. For example: &lt;br /&gt;
             BORDER=S|D|B|H|8-chars[:attributes]&lt;br /&gt;
While the colon is actually optional, it is recommended for readability when attributes are included.&lt;br /&gt;
&lt;br /&gt;
Also within the BORDER= syntax, the &amp;quot;attributes&amp;quot; parameter may be specified immediately after the border specification (no spaces). The attributes specified here will affect the visual display of the border itself. See [[Definitions]] for the correct syntax to be used with the &amp;quot;attributes&amp;quot; parameter.&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Open_Window&amp;diff=1714</id>
		<title>Open Window</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Open_Window&amp;diff=1714"/>
		<updated>2013-02-04T19:05:20Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: /* Supplemental Syntax (&amp;quot;BORDER= spec&amp;quot;) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See also: [[Parent=None]] and [[Picture]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;OPEN window&#039;&#039;&#039; (OPE) [[statement]] specifies the characteristics for a window and activates the window for input/output. OPEN window can specify the following window characteristics: screen placement and dimensions, border type and attributes, attributes to be used for the text area of the window, and a caption to be displayed within the top border of the window.&lt;br /&gt;
&lt;br /&gt;
:1.) When a file is opened for both SHR and INPUT, Business Rules will no longer change the time and date of the file. As a result of this change, when a file is to be opened both for OUTIN and for INPUT, the OPEN for OUTIN must be executed first. Otherwise an error [[0608]] will result. This will affect current programs.&lt;br /&gt;
:2.) The OPEN window statement now allows for flexibility in the specification of window coordinates. Previously all four coordinates of the window had to be specified in terms of two exact row positions and two exact column positions. With release 3.50, only one exact row position and one exact column position must be specified. Business Rules will automatically calculate the other row and/or column position according to the values of the ROWS= and COLS= parameters, which indicate the desired length or width of the window.&lt;br /&gt;
&lt;br /&gt;
The ROWS= parameter may be used in place of either the SROW= or the EROW= parameter, but not both. Likewise, the COLS= parameter may be used in place of either the SCOL= or the ECOL= parameter, but not both. The following examples show some of the possibilities that are available using this syntax option. Each statement opens a 10 row by 10 column window in the upper left corner of the screen. (NOTE: ROWS= and COLS= parameters are shown in lowercase for emphasis; case makes no difference in actual syntax.)&lt;br /&gt;
&lt;br /&gt;
 00010 OPEN #1:&amp;quot;rows=10,cols=10,EROW=10,ECOL=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00020 OPEN #1:&amp;quot;rows=10,SCOL=1,EROW=10,cols=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00030 OPEN #1:&amp;quot;rows=10,SCOL=1,EROW=10,ECOL=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00040 OPEN #1:&amp;quot;SROW=1,cols=10,rows=10,EROW=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00050 OPEN #1:&amp;quot;SROW=1,cols=10,EROW=10,ECOL=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00060 OPEN #1:&amp;quot;SROW=1,SCOL=1,rows=10,cols=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00070 OPEN #1:&amp;quot;SROW=1,SCOL=1,rows=10,ECOL=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00080 OPEN #1:&amp;quot;SROW=1,SCOL=1,EROW=10,cols=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
&lt;br /&gt;
:3.) The OPEN window statement&#039;s BORDER parameter now accepts S (drop-shadow) as an attribute for the border. See &amp;quot;S Attribute&amp;quot; in the [[BRConfig.sys]] Specification section for more information.&lt;br /&gt;
:4.) The NOCLOSE parameter in any OPEN statement will leave that file open when a program ends or chains to another program. The only way this file is closed is by explicitly closing the file, CLEAR ALL, or by exiting from Business Rules.&lt;br /&gt;
&lt;br /&gt;
 00010 OPEN #1:&amp;quot;NAME=TEST,NOCLOSE&amp;quot;,INTERNAL,RELATIVE,INPUT&lt;br /&gt;
&lt;br /&gt;
===Comments and Examples===&lt;br /&gt;
Business Rules creates two different types of windows: windows that are opened as separate input/output files, and field help windows. The OPEN window statement allows you to create the first type, windows that accept input and output. For information about field help windows, see [[Screen I/O]].&lt;br /&gt;
&lt;br /&gt;
Windows can also be opened separately from the main window. OPEN #0 is reserved for this. Also see [[Parent=Window]] for more information.&lt;br /&gt;
&lt;br /&gt;
Regarding window  size : (as of 4.3) when opening separate windows, &#039;NAME=window-name&#039; indicates that BR is to save the position of the window at the time it is closed and restore it to that position when it is reopened, even across sessions. Replacement or overlaying windows can use the same window names to position themselves wherever and at whatever character size the user has changed it to. So once a window has been opened with a particular name, subsequent opens ignore ROW= and COL= and instead use the user positioned values. &lt;br /&gt;
&lt;br /&gt;
As a result window positioning and size priority is as follows:&lt;br /&gt;
        :1. NAME= window-name&lt;br /&gt;
        :2. (for window zero only) un-named save font size and position.&lt;br /&gt;
        :3. SROW, SCOL, MAXIMIZE, NOMAXIMIZE, ABSOLUTE, RELATIVE, FONTSIZE&lt;br /&gt;
&lt;br /&gt;
Another attribute (that doesn&#039;t get saved) is OVERRIDE, which indicates that the SROW and SCOL (etc) settings in the OPEN statement are to be used even if NAME= is also specified. When OVERRIDE is specified in OPENDFLT, it only applies to the first OPEN of window #0. In all other cases Name= trumps SROW etc settings.&lt;br /&gt;
&lt;br /&gt;
All of the above specifications apply to Window zero except it cannot be &lt;br /&gt;
opened RELATIVE.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NOMAXIMIZE&amp;quot; also removes the maximize button from the window.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NO_TASK_BAR&amp;quot; suppresses the task bar icon. This feature &lt;br /&gt;
is available on any window.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;MODAL&amp;quot; uses the same task bar icon as it&#039;s parent window. This ignores &lt;br /&gt;
any clicks on its parent window.&lt;br /&gt;
&lt;br /&gt;
===Input Across Multiple Windows===&lt;br /&gt;
As of 4.3, BR allows for input across multiple windows, as in the following example:&lt;br /&gt;
&lt;br /&gt;
 00010  (R)INPUT FIELDS  #121: “10, 10, C 20, UH; 10, 12, PIC(##/##/##), UH;#124,10, 10, C 30, UH”: aaa$, bbb$, ccc$&lt;br /&gt;
&lt;br /&gt;
This will input the first two fields on window #121 and the third field on window #124.  The ‘#window-number,’ prefix may appear in any row or col FIELDS specification and overrides the window number that follows the PRINT/INPUT/RINPUT keyword.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
[[Image:Openwindow.png|900px]]&lt;br /&gt;
&lt;br /&gt;
===Defaults===&lt;br /&gt;
:1.) No border.&lt;br /&gt;
:2.) N (normal).&lt;br /&gt;
:3.) No caption.&lt;br /&gt;
:4.) Center caption.&lt;br /&gt;
:5.) Interrupt the program if an error occurs and ON is not active.&lt;br /&gt;
:6.) N (normal).&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
&amp;quot;Wind-num&amp;quot; is a file number for the window being opened. It must be a numeric  expression or integer that equals a value from 1 to 999, inclusive. No other open file or open window may use the same value. Open windows do not count against the operating system limit on open files.&lt;br /&gt;
&lt;br /&gt;
From this point, there are two possible paths through the OPEN window syntax. The top path will be described first.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;SROW = row&amp;quot; parameter identifies the starting row for the window. The &amp;quot;row&amp;quot; portion of this parameter can be any integer within the size of the main BR window. If a border is specified for the window, it must be 1 more than the desired starting place, to account for a one row border. The value of &amp;quot;row&amp;quot; cannot exceed the value of the ending row.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;SCOL = column&amp;quot; parameter identifies the starting column for the window. The &amp;quot;column&amp;quot; portion for this parameter can be any integer within the size of the main BR window. If a border is specified for the window, it must be 1 more than the desired starting place, to account for a one colomn border. The value of &amp;quot;column&amp;quot; cannot exceed the value of the ending column.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;EROW = row&amp;quot; parameter identifies the ending row for the window. The &amp;quot;row&amp;quot; portion of this parameter can be any integer (unless a border is specified for the window -then the value must be one less than the desired ending row, to account for a one row border) It cannot precede the starting row value.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;ECOL = column&amp;quot; parameter identifies the ending column for the window. The &amp;quot;column&amp;quot; portion of this parameter can be any integer (unless a border is specified for the window-then the value must be one less than the desired ending column, to account for a one column border) It cannot precede the starting column value.&lt;br /&gt;
&lt;br /&gt;
The optional &amp;quot;ROWS=int&amp;quot; parameter can be used instead of either &amp;quot;SROW=row&amp;quot; or &amp;quot;EROW=row&amp;quot; to specify the number of rows desired (instead of a specific starting or ending row). &lt;br /&gt;
&lt;br /&gt;
The optional &amp;quot;COLS=int&amp;quot; parameter can be used instead of either &amp;quot;SCOL=col&amp;quot; or &amp;quot;ECOL=col&amp;quot; to specify the number of columns desired (instead of a specific starting or ending column).&lt;br /&gt;
&lt;br /&gt;
Note that when opening a #0 window, only &amp;quot;ROWS=int&amp;quot; and &amp;quot;COLS=int&amp;quot; parameters are necessary, the others are not. See [[Parent=None]] for more information.&lt;br /&gt;
&lt;br /&gt;
To specify a border, see the discussion on the supplemental BORDER=Spec syntax and parameters below.&lt;br /&gt;
&lt;br /&gt;
Otherwise, continuing with the main syntax for OPEN window, the next available parameter is &amp;quot;N=attributes&amp;quot;. This parameter identifies the attributes that are to affect the entire inner portion of the window. However, the attribute specified takes effect only after a PRINT NEWPAGE has been sent to the window. The B (blink) attribute is not available for this parameter.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ABSOLUTE&amp;quot; and &amp;quot;RELATIVE&amp;quot; qualify SROW and SCOL to specify the position of a new independent window. RELATIVE (the default) indicates positioning relative to window zero (the main console), and ABSOLUTE indicates positioning relative to the screen. Using negative values    positions an independent window to the left of or above the main console. BR will attempt to honor the request keeping the new window viewable up to the maximum size of the screen. Window zero ositioning is always ABSOLUTE. To position a window on a second monitor, specify a starting position to the right of the last position of the first monitor. &lt;br /&gt;
&lt;br /&gt;
The &amp;quot;CAPTION=&amp;quot; keyword is used to identify text that is to appear in the top border of the window. It may optionally be followed by either a less-than (&amp;lt;) symbol for flush left text or a greater-than (&amp;gt;) symbol for flush right text. When no symbol is specified, the text is centered. The &amp;quot;title&amp;quot; parameter represents the text that is to be displayed.&lt;br /&gt;
&lt;br /&gt;
All of the parameters described above (excluding the wind-num parameter) comprise the file definition string. The alternative to coding these parameters directly in the OPEN window statement is to reference them with the &amp;quot;string expression&amp;quot; parameter found in the bottom path of the syntax diagram.&lt;br /&gt;
&lt;br /&gt;
No matter which path you choose for providing the file definition, two of the remaining parameters in the syntax diagram must be included in your OPEN window statement. &amp;quot;DISPLAY&amp;quot; identifies the window file as a display file, and one of the &amp;quot;INPUT&amp;quot;, &amp;quot;OUTPUT&amp;quot; or &amp;quot;OUTIN&amp;quot; parameters must be used to indicate how the window will be used.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;error-cond line-ref&amp;quot; parameter allows for error processing. See [[Error Conditions]] for more information.&lt;br /&gt;
&lt;br /&gt;
===Supplemental Syntax (&amp;quot;BORDER= spec&amp;quot;)===&lt;br /&gt;
{{:BorderSpec}}&lt;br /&gt;
&lt;br /&gt;
===Technical Considerations===&lt;br /&gt;
:1.) Relevant error conditions are: [[ERROR]], [[EXIT]] and [[IOERR]].&lt;br /&gt;
:2.) Open window files do not count against your operating system limit on open files.&lt;br /&gt;
:3.) Using [[CONFIG]] SCREEN N xx to change the normal attribute of a window will only take affect on windows that are opened after the CONFIG SCREEN specification is executed. This applies only to the N (normal) attribute.&lt;br /&gt;
:4.) Unix / Linux terminals - See [[Terminal Consideration]] for special considerations when using windows with Unix / Linux terminals.&lt;br /&gt;
:5.) SROW and SCOL are based on FONTSIZE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Statements]]&lt;br /&gt;
[[Category:Window File Processing Statements]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Syntax&amp;diff=1713</id>
		<title>Syntax</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Syntax&amp;diff=1713"/>
		<updated>2013-02-04T19:04:50Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: /* Syntax Diagrams */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Parts Of A Business Rules Statement==&lt;br /&gt;
&lt;br /&gt;
===Statements (Immediate Mode/Procedure Files)===&lt;br /&gt;
&lt;br /&gt;
A typical [[Business Rules!]] statement consists of the following:&lt;br /&gt;
#A [[line number]].&lt;br /&gt;
#A [[line label]] (optional).&lt;br /&gt;
#A primary keyword.&lt;br /&gt;
#One or more secondary keywords or phrases along with their associated values (sometimes optional).&lt;br /&gt;
#One or more &amp;quot;error-cond line-ref&amp;quot; conditions (optional).&lt;br /&gt;
#Remark or comment (optional).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Optional&amp;quot; items may be included but are not required.&lt;br /&gt;
&lt;br /&gt;
Notice that the listed elements refer to a typical statement. Some statements consist mainly of a primary keyword [[RETURN]] or [[RETRY]] for instance, only the line number and optional programmer&#039;s remarks or a line label are permitted with these two statements. See the syntax diagrams for each [[Statements|Statement]] for specific details.&lt;br /&gt;
&lt;br /&gt;
====Analysis of an Example Statement====&lt;br /&gt;
&lt;br /&gt;
The following formatted Print statement will be used to describe the components of a statement:&lt;br /&gt;
&lt;br /&gt;
 00020 BIG: PRINT USING F1: A$,T(5) CONV 00520 ! remarks&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;00120&#039;&#039;&#039;||is a line number.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;BIG&#039;&#039;&#039;||is a line label.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;PRINT&#039;&#039;&#039;||is a primary keyword. Primary keywords specify the type of operation that you wish to perform.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;USING F1&#039;&#039;&#039;||is a secondary phrase. This phrase consists of the secondary keyword USING and the line reference F1 (a line label). Secondary keywords and secondary phrases add detail to the instructions in the statement.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;A$ and T(5)&#039;&#039;&#039;||are references to [[Variable|variables]].&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;CONV 520&#039;&#039;&#039;||is an &amp;quot;error-cond line-ref&amp;quot; specification. It transfers control of the program to line 00520 if a CONV error occurs during execution of line 00120.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;! remarks&#039;&#039;&#039;||is an optional comment that follows the statement. An exclamation point signals the start of this remark; any comment the programmer wishes to make may follow. Note that certain statement keywords, for example, [[DATA]], do not allow for comments on the same line, in which case comments must be placed on an adjacent line alone.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Each command in a procedure file may be followed by at least one space, an exclamation point (!) and a comment. Business Rules will ignore everything after the exclamation point.&lt;br /&gt;
&lt;br /&gt;
Remarks may also reside on their own line in a procedure file, as follows:&lt;br /&gt;
&lt;br /&gt;
 LOAD MENU.BR&lt;br /&gt;
 ! Load the program MENU.BR&lt;br /&gt;
 RUN&lt;br /&gt;
&lt;br /&gt;
====Line labels -  Procedure Files====&lt;br /&gt;
&lt;br /&gt;
{{:Line Label (procedure)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line numbers====&lt;br /&gt;
&lt;br /&gt;
{{:Line number}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line labels - Program files====&lt;br /&gt;
&lt;br /&gt;
{{:Line Label (program)}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Multiple statements====&lt;br /&gt;
&lt;br /&gt;
{{:Multiple statements}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Line Continuation====&lt;br /&gt;
&lt;br /&gt;
{{:Line Continuation}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Comments====&lt;br /&gt;
&lt;br /&gt;
{{:Comment}}&lt;br /&gt;
&lt;br /&gt;
===Syntax Diagrams===&lt;br /&gt;
&lt;br /&gt;
Diagrams are used throughout this manual to explain the syntax of Business Rules commands, statements, and various other syntactical specifications. This section explains how to read the conventions used in the diagrams.&lt;br /&gt;
&lt;br /&gt;
Syntax diagrams provide a road map through a command or statement&#039;s syntax. Following the main line of the diagram will eventually bring you to the end of the syntax, although you may wish to take allowable detours to obtain certain features. Syntax diagrams always follow a logical pattern.&lt;br /&gt;
&lt;br /&gt;
If they require you to pass through a particular parameter, then that parameter is required. If they allow you to bypass a particular parameter, then that parameter is optional.&lt;br /&gt;
&lt;br /&gt;
Although all syntax diagrams (whether for a command, statement or other specification) must be read the same way, the actual specification you are working with may be subject to other requirements or options as well. A statement, for example, must always reside on a line with a line number. See the parts at the end of this section for information about these additional requirements and options.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;array-name&amp;quot; parameter is a name representing either a numeric or a string [[array]]. For rules regarding these names, see [[Variable]].&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;BAUD&amp;quot; parameter sets the transmission speed in bits per second. See the [[Open communications]] statement for details.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;BORDER=spec&amp;quot; parameter represents an insertable syntax which is used in the OPEN window statement to identify a border type for the window being opened. See the OPEN window statement for additional information and the syntax diagram.&lt;br /&gt;
&lt;br /&gt;
The [[BUFSIZE]] parameter specifies the size of the buffer for DOS versions of Business Rules. The default is 2000 bytes, which is low for high-speed data transmission. To avoid losing data with rates of 2400 bps or higher; an increased BUFSIZE is recommended.&lt;br /&gt;
&lt;br /&gt;
In Business Rules, Unix and Linux versions ignore the BUFSIZE parameter, as the operating systems handle the buffering for these versions instead.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Column&amp;quot; (not to be confused with &amp;quot;columns&amp;quot;) is an integer {\b value} from 1 to 80, which indicates a column number on the screen.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Columns&amp;quot; (not to be confused with &amp;quot;column&amp;quot;) is an integer {\b constant}, which indicates the maximum size for the second through seventh dimensions of an array.&lt;br /&gt;
&lt;br /&gt;
Concatenation is the joining of two or more strings. In Business Rules, the ampersand (&amp;amp;) is the concatenation operator. Concatenation may be used in any output or assignment statement to join any number of string expressions.&lt;br /&gt;
&lt;br /&gt;
In the following example, lines 100 and 110 illustrate the concatenation of three strings. Lines 120 and 130 use concatenation and the string functions RTRM$, LTRM$ and RPT$ to print and center X$ on the 80-column screen:&lt;br /&gt;
&lt;br /&gt;
 00100 LET LINE$ = A$ &amp;amp; B$ &amp;amp; C$&lt;br /&gt;
 00110 PRINT RTRM$(CITY$) &amp;amp; &amp;quot;, &amp;quot; &amp;amp; STATE$&lt;br /&gt;
 00120 LET X$ = RTRM$(LTRM$(X$))&lt;br /&gt;
 00130 PRINT RPT$(&amp;quot; &amp;quot;,(80-LEN(X$))/2) &amp;amp; X$&lt;br /&gt;
&lt;br /&gt;
The printing and centering in lines 120 and 130 can be performed more efficiently with the CC format specifications as follows:&lt;br /&gt;
&lt;br /&gt;
 00140 PRINT USING 150: X$&lt;br /&gt;
 00150 FORM CC 80&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;corners&amp;quot; parameter is used to specify custom-designed borders for both I/O windows and field help windows. Two characters must be specified for this parameter: the character to be used for the top left corner of the window and the character to be used for the bottom right corner of the window. Business Rules fills in the rest of the characters for you&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Drive&amp;quot; is a DOS-like drive letter, which must be followed by a colon. The drive parameter may specify certain special devices such as a printer or modem.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Drive-num&amp;quot; is a digit, which indicates a System/23 drive; Business Rules translates it into a DOS drive letter. This parameter may not be specified with a redirection symbol (&amp;gt;) or when a drive letter is specified.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;error-cond line-ref&amp;quot; parameter is replaced with one or more pairs of specifications. &amp;quot;Error-cond&amp;quot; is a specific error condition and &amp;quot;line-ref&amp;quot; is a line number or line label to which control should be transferred if that error occurs. See the Error Conditions chapter for more information about the various error conditions.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Field-length&amp;quot; is an integer value, which identifies the number of columns in the specified field. This parameter is required as a part of any numeric format specification except PIC.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Field-spec&amp;quot; represents an insertable syntax that is used to provide field definitions for the full screen processing statements. For additional information and a syntax diagram, see the Screen I/O chapter.&lt;br /&gt;
&lt;br /&gt;
====Filenames====&lt;br /&gt;
&amp;quot;Filename&amp;quot; is a name consisting of up to eight alphabetic, numeric or underscore characters and an optional period and extension of up to three consecutive letters. Wildcard characters (* and ?) may be used in file names specified with the COPY, DIR, DROP, and FREE commands. Version 3.9 will support long filenames (greater than the 8.3 format) with a variety of alternatives with respect to case sensitivity.   Unix defaults to case sensitive, and DOS/Windows defaults to case insensitive.   Business Rules! defaults to lower case on all platforms, unless overridden by a FILENAMES configuration statement.&lt;br /&gt;
&lt;br /&gt;
The file name requirements for all types of files are identical. However, one item to be aware of is that procedure files which use an extension of .$$$ will automatically delete themselves after closing. See the Procedures chapter for additional information.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;File-num&amp;quot; is a numeric expression or an integer that equals 255 or any number from zero to 127. A file number matches a logical file to a physical file or device. File numbers are defined in OPEN statements, then used in I/O statements for that file or device.&lt;br /&gt;
&lt;br /&gt;
Two special file numbers which do not require OPEN statements are 0 (for input or output to the screen) and 255 (for output to the printer).&lt;br /&gt;
&lt;br /&gt;
No file numbers are required when INPUT, LINPUT, RINPUT, or PRINT are used for I/O from the keyboard or to the display screen. File-num is always immediately preceded by a pound symbol (#).&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;&amp;gt;file-ref&amp;quot; parameter causes all information which would normally be printed on the screen to be sent to the file specified in the file-ref (see the &amp;quot;file-ref description for information about the correct syntax). One special case is the RUN command in which &amp;quot;&amp;gt;file-ref&amp;quot; redirects printer output to a file. Wherever &amp;quot;&amp;gt;file- ref&amp;quot; is indicated, &amp;quot;&amp;gt;&amp;gt;file-ref&amp;quot; (with two redirection arrows) may also be specified.&lt;br /&gt;
&lt;br /&gt;
Using one redirection arrow causes the screen information to write directly over any contents that currently exist in the specified file.  Using two redirection arrows cause the information that would normally go to the screen to be appended to the end of the specified file. The TYPE command with the &amp;gt;&amp;gt;file-ref parameter may thus be used to append a display file to another file. Likewise, the LIST command may be used with &amp;gt;&amp;gt;file-ref to append the contents of a program to another program which has been saved in source.&lt;br /&gt;
&lt;br /&gt;
(Be careful about line numbers when using this technique, as line numbers that are duplicated in the same file will replace one another upon loading from source.)&lt;br /&gt;
&lt;br /&gt;
Fixed-point numbers are numbers with a decimal point in a fixed position.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Floating point form-spec&amp;quot; represents a format specification from the following group: D, S, or L. These format specifications are fast, but non-portable. See the File I/O chapter for more information.&lt;br /&gt;
&lt;br /&gt;
Floating-point numbers are numbers, which allow the decimal point to &amp;quot;float&amp;quot; to any position. The Business Rules syntax is nEm, where n is a numeric constant indicating the sign and significant digits in the number, E represents base 10, and m is a signed integer representing the power to which 10 is raised.&lt;br /&gt;
&lt;br /&gt;
The largest and smallest numbers available to the system vary according to the hardware and operating system being used. The system function INF can be used to print the largest possible number on any given system; 1/INF generates the smallest number. For all DOS, Unix and Linux versions available at the time of writing, the largest number is 1.000E+307; similarly, the smallest number is 1.000E-307. Some caution should be used in working with numbers near these extremes (e.g., using exponential notation in SORT). Also, for any given combination of hardware and Business Rules, the system infinity function INF and some testing should be combined to determine whether or not intermediate values used in calculations will be truncated.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;fraction-length&amp;quot; parameter is an integer value that identifies the number of digits contained in the fractional portion of the item to be printed or input. This integer must be preceded by a decimal point.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Wind-num&amp;quot; is the number of a window file that has been opened by an OPEN window statement. It must be a numeric expression or integer value that equals a value between 1 to 127. No other open file or open window may use the same value. Open windows do not count against the operating system limit on open files.&lt;br /&gt;
&lt;br /&gt;
Wildcard characters (? and *) may be used in file names and extensions in place of alphabetic or numeric characters. They may not be used in drive, path, or directory specifications. They have the following meanings:&lt;br /&gt;
{|&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;?&#039;&#039;&#039;||means that any character in that position (including null) is regarded as a match.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|width=&amp;quot;10%&amp;quot;|&#039;&#039;&#039;*&#039;&#039;&#039;||denotes any number of ? characters.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
;Example:&lt;br /&gt;
&lt;br /&gt;
 A:VOL\NAME?.*&lt;br /&gt;
&lt;br /&gt;
The above references all files in subdirectory VOL on drive A with a name consisting of NAME followed by any one character, a period, and any extension.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;var-name&amp;quot; may be either numeric or string. It may be a subscripted or un-subscripted variable, or an array name preceded by MAT. Var-name items are used mainly in various types of input statements to assign values to variables. They typically occur in lists separated by commas.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;string form-spec&amp;quot; parameter should be replaced with a string format specification from the following group: C, CC, CR, CL, CU, G, GL, GU, V, VL, VU. The specifications that are applicable for a given statement are identified in the parameters text for that statement. See the File I/O chapter for information about individual format specifications.&lt;br /&gt;
&lt;br /&gt;
The CL, CU, GL, GU, VL, and VU specifications are valid only in full screen processing statements (PRINT FIELDS, INPUT FIELDS, and RINPUT FIELD); they cannot be used in either type of FORM statement.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;string-expr&amp;quot; parameter represents one of several kinds of string elements, including string system functions, string user-defined functions, string constants, and string variables. See the definitions in this chapter for more information about string constants and string variables. See the Functions chapter for more information about string system functions. See the DEF statement discussion for more information about user-defined functions.&lt;br /&gt;
&lt;br /&gt;
In addition to the four elements listed above, string expressions may utilize substring operators (to specify that only a portion of the string be used) and the concatenation operator (to specify that multiple string expressions be combined together). See the definitions for &amp;quot;Substring operation&amp;quot; and &amp;quot;concatenation operation&amp;quot; in this chapter for more information.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;helpstring&amp;quot; parameter represents an insertable syntax, which is used in the full screen processing statements to specify the user level; window placement and text for field help windows. For additional information and a syntax diagram, see the Screen I/O chapter.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;increment&amp;quot; parameter is used in the AUTO ATT and RENUM commands. It represents an integer value, which indicates how much the system should increase the numbers from one line number to the next.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;INPUT&amp;quot; keyword identifies that the file is to be opened so that its data may only be used as input for the program.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;int&amp;quot; parameter represents an unsigned, positive, non-zero whole number.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;integer&amp;quot; parameter represents a whole number (no decimal points or fractions allowed). NOTE the difference between &amp;quot;integer&amp;quot; and &amp;quot;int&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;internal form-spec&amp;quot; parameter should be replaced with a format specification from the following group: B, BL, BH, PD, ZD. See the File I/O chapter for information about individual format specifications.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;key-length&amp;quot; parameter should be replaced with a number that identifies the number of characters (or columns) in the key.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Key start-pos&amp;quot; indicates the record position of the first key character for the index.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Length&amp;quot; is an integer value that sets the maximum length of all elements in the string variable or array.&lt;br /&gt;
&lt;br /&gt;
A line label is an optional name for a program line that is specified immediately after the line number. It must be unique (no other line can be given the same line label), and it must be followed by a colon when it is defined. This line label can then subsequently be used in place of a line number to reference the line from a secondary expression. Business Rules allows most statement and command keywords to be used as line labels.&lt;br /&gt;
&lt;br /&gt;
In the following example, the line label BIG is defined to represent line 120; it is then used as a line reference for the GOTO statement in line 300:&lt;br /&gt;
&lt;br /&gt;
 00120 BIG: PRINT USING F1: A$,T(5) CONV&lt;br /&gt;
 o&lt;br /&gt;
 o&lt;br /&gt;
 o&lt;br /&gt;
 00300 GOTO BIG&lt;br /&gt;
&lt;br /&gt;
For information about the labels that are used in procedures, See the Procedures chapter.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;line-num&amp;quot; parameter indicates that you must specify a line number rather than a line label. Line numbers can be used only in programs (not in procedure files) and must be integers from 1 to 99999.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;line-ref&amp;quot; parameter indicates that you can specify either a line number or a line label as a parameter.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Num-array&amp;quot; indicates that a numeric array name should be specified.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;num-constant&amp;quot; parameter represents a number consisting mainly of the digits 0-9; other optional elements are a decimal point (.), a minus sign (-) to indicate a negative number, and a plus sign (+) to indicate a positive number (unsigned numbers are assumed to be positive). If a sign is specified, it must precede the digits. Spaces are not allowed in a numeric constant.&lt;br /&gt;
&lt;br /&gt;
Integers, fixed-point numbers and floating point numbers (numbers in exponential notation) are three types of numeric constants. See the following examples:&lt;br /&gt;
&lt;br /&gt;
;Number:&amp;lt;br&amp;gt;&lt;br /&gt;
:44&amp;lt;br&amp;gt;&lt;br /&gt;
:+15.38&amp;lt;br&amp;gt;&lt;br /&gt;
:-86.34&amp;lt;br&amp;gt;&lt;br /&gt;
:10,000&amp;lt;br&amp;gt;&lt;br /&gt;
;Integer:&amp;lt;br&amp;gt;&lt;br /&gt;
:44&amp;lt;br&amp;gt;&lt;br /&gt;
:n/a&amp;lt;br&amp;gt;&lt;br /&gt;
:n/a&amp;lt;br&amp;gt;&lt;br /&gt;
:10000&amp;lt;br&amp;gt;&lt;br /&gt;
;Fixed Point:&amp;lt;br&amp;gt;&lt;br /&gt;
:44&amp;lt;br&amp;gt;&lt;br /&gt;
:+15.38&amp;lt;br&amp;gt;&lt;br /&gt;
:-86.34&amp;lt;br&amp;gt;&lt;br /&gt;
:10000&amp;lt;br&amp;gt;&lt;br /&gt;
;Exponential:&amp;lt;br&amp;gt;&lt;br /&gt;
:4.4E+1&amp;lt;br&amp;gt;&lt;br /&gt;
:1.538E+1&amp;lt;br&amp;gt;&lt;br /&gt;
:-8.634E+1&amp;lt;br&amp;gt;&lt;br /&gt;
:1E+4&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;num-expr&amp;quot; parameter represents one of five kinds of numeric elements: conditional expressions, numeric constants, numeric variables, numeric system functions, and numeric user-defined functions. See the definitions in this chapter for more information about conditional expressions, numeric constants and numeric variables. See the Functions chapter for more information about numeric system functions. See the DEF statement discussion for more information about user-defined functions.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Num-var&amp;quot; is a name that a programmer assigns to a storage location in the computer&#039;s memory; it is used for storing a number. Variables are created by being referenced in expressions or by being specified in the DIM statement. When used in numeric expressions, numeric variables can be either subscripted or un-subscripted. When specified in syntax diagrams in this book, however, num-var must be a simple (i.e., un-subscripted) variable name -except when stated otherwise in the &amp;quot;parameters&amp;quot; section for the specific statement.&lt;br /&gt;
&lt;br /&gt;
A numeric variable name can be 1-30 alphanumeric characters and underscores, the first of which must be a letter. Examples of simple numeric variable names include A5, TOTAL, RATE, and EMPLRATE.&lt;br /&gt;
&lt;br /&gt;
The same character sequence may be used as a name for both a variable (scalar) and an array. By adding a $ on the end, the same character sequence may be used for a string variable and a string array. Thus A, MAT A, A$, and MAT A$ all may co-exist in the same program.&lt;br /&gt;
&lt;br /&gt;
Certain words are reserved by Business Rules, and cannot be used as variable names. Note that all words starting with the letters &amp;quot;FN&amp;quot; are reserved, as they are considered user-defined function names. See also [[Reserved Words]].&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;num form-spec&amp;quot; parameter should be replaced with a numeric format specification from the following group: G, GZ, N, or NZ. The specifications, which are applicable for a given statement, are identified in the parameters text for that statement. See the File I/O chapter for information about individual format specifications.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OUTIN&amp;quot; keyword indicates that the file is to be opened so that information may move in two directions: both into and out of the data file.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;OUTPUT&amp;quot; parameter indicates that the file is to be opened so that information may only be output from the program to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;PARITY=spec&amp;quot; is an OPEN communications parameter. The &amp;quot;PARITY&amp;quot; keyword and equal symbol (=) must be followed by one of three replacements for &amp;quot;spec&amp;quot;: N (no parity checking), E (even parity) or O (odd parity).&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;path&amp;quot; parameter identifies the sequence of directories to be used. Each directory must be separated by a backslash &amp;quot;\\&amp;quot;.  When the path does not begin with a backslash, searching begins at the default directory.&lt;br /&gt;
&lt;br /&gt;
The PIC format specification converts a number into characters according to the picture specified. The &amp;quot;pic-spec&amp;quot; parameter is the picture, and consists of one or more characters, which are either insertion characters to be printed as is, or digit identifiers to be replaced with a digit when printed. See the File I/O chapter for information about PIC and individual insertion characters and digit identifiers.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Row&amp;quot; is an integer value from 1 to the number of rows in the screen or window that indicates a row number&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Rows&amp;quot; (not to be confused with &amp;quot;row&amp;quot;) it is an integer constant which indicates the maximum size for the first dimension of an array.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;String-array&amp;quot; indicates that a string array name should be specified. For rules regarding these names, see &amp;quot;string variable&amp;quot; in this chapter.&lt;br /&gt;
&lt;br /&gt;
A string constant is a series of characters enclosed in quotation marks. Each constant may contain from 0 to 250 characters.&lt;br /&gt;
&lt;br /&gt;
Quotation marks are used as delimiters in string constants. They signal the beginning and end of a string. You may use either single or double quotation marks. If the enclosed string contains one kind of quotation mark, however, you must either use the other kind as a delimiter or express the inner quotation mark as a pair. Examples of string constants are:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;Montana&amp;quot;&lt;br /&gt;
 &#039;Montana&#039;&lt;br /&gt;
 &#039;The &amp;quot;Big Sky&amp;quot; Country&#039;&lt;br /&gt;
 &amp;quot;The &amp;quot;&amp;quot;Treasure&amp;quot;&amp;quot; State&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note that in a &amp;quot;LIST&amp;quot; command single quotes represent case insensitive searching while double quotes represent case sensitive matching.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Quote Processing====&lt;br /&gt;
Quotation marks suppress the recognition of separators in accordance with the following rules.&lt;br /&gt;
Standard BR Quote Processing&lt;br /&gt;
When examining str$ left to right, the first character (and the first character after each separator) is checked to see if is either (&#039;) or (&amp;quot;). If it is ether of those then it activates quotation processing which suppresses the recognition of separators until quotation processing is deactivated. The first character thus becomes the governing quote type until quotation processing is deactivated.&lt;br /&gt;
&lt;br /&gt;
The string is copied until it ends or until an odd number of successive occurrences of the governing quote type is encountered. During this processing, two adjacent occurrences of the governing quote character denote an embedded occurrence of the quote character.&lt;br /&gt;
Examples&lt;br /&gt;
&amp;quot;abc,def&amp;quot; -&amp;gt; abc,def    where the comma is not recognized as a separator and is part of the data&lt;br /&gt;
abc&amp;quot;def -&amp;gt; abc&amp;quot;def    naturally embedded quotes may occur anywhere within a string after the first character&lt;br /&gt;
&amp;quot;abc&amp;quot;def&amp;quot; -&amp;gt; abcdef&amp;quot;   quotation processing is deactivated by the center quote mark&lt;br /&gt;
&amp;quot;abcdef&amp;quot; -&amp;gt; abcdef   normal data&lt;br /&gt;
&amp;quot;abc&#039;def&amp;quot; -&amp;gt; abc&#039;def   the single quote is treated like any other character while double quotes govern&lt;br /&gt;
&#039;abc&amp;quot;def&#039; -&amp;gt; abc&amp;quot;def   double quotes are treated like any other character while single quotes govern&lt;br /&gt;
&amp;quot;abc&amp;quot;&amp;quot;def&amp;quot; -&amp;gt; abc&amp;quot;def   pairs of governing quotes denote a single embedded quote&lt;br /&gt;
&amp;quot;abc&amp;quot;&amp;quot;&amp;quot;def&amp;quot; -&amp;gt; abc&amp;quot;def&amp;quot;   the third successive occurence deactivates quote processing&lt;br /&gt;
&lt;br /&gt;
MAT2STR( MAT zzz$, str$ [, sep$ [, flags$]] )&lt;br /&gt;
Where flag$ is in the format:&lt;br /&gt;
[ quote-type ] [ :LTRM ] | [ :TRIM ] | [ :RTRM ]&lt;br /&gt;
Where quote-type can be Q, QUOTES, (&#039;), or (&amp;quot;), case insensitive. Quote-type denotes that each element should be enclosed in quotation marks. The trim flags denote pre-processing of array elements and the leading colon is only present when quote-type is specified.&lt;br /&gt;
If Q or QUOTES is specified the BR automatically determines which quote type to apply as follows:&lt;br /&gt;
The element is scanned left to right for either type of quote character. If a quote character is encountered, then only the next character is examined. If two occurrences of the same quote character are encountered then that character is used to enclose the element. However, if a single occurrence of a quote character is encountered then the element is enclosed in the alternate quote type. If no quote character is encountered then double quotes are applied.&lt;br /&gt;
Examples&lt;br /&gt;
Quote Type is Q or QUOTES&lt;br /&gt;
abcdef -&amp;gt; &amp;quot;abcdef&amp;quot;&lt;br /&gt;
abc&#039;def -&amp;gt; &amp;quot;abc&#039;def&amp;quot;&lt;br /&gt;
abc&amp;quot;def -&amp;gt; &#039;abc&amp;quot;def&#039;&lt;br /&gt;
abc&amp;quot;&amp;quot;def -&amp;gt; &amp;quot;abc&amp;quot;&amp;quot;def&amp;quot;&lt;br /&gt;
&#039;abcdef -&amp;gt; &amp;quot;&#039;abcdef&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Quote Type is &#039; ( quote type single )&lt;br /&gt;
abcdef -&amp;gt; &#039;abcdef&#039;&lt;br /&gt;
&#039;abcdef -&amp;gt; &#039;&#039;&#039;abcdef&#039;   single quotes get doubled when embedded in singles quotes&lt;br /&gt;
&amp;quot;abcdef -&amp;gt; &#039;&amp;quot;abcdef&#039;   leading double quote is treated normally&lt;br /&gt;
&lt;br /&gt;
Quote type double mirrors quote type single.&lt;br /&gt;
When using MAT2STR on a 2 dimensional array, the first delimiter is used for individual elements and the second delimiter at the end of each row. This principle also applies to three to seven dimensions.&lt;br /&gt;
Example&lt;br /&gt;
Given the following two dimensional array zzz$ containing the values-&lt;br /&gt;
    1            2&lt;br /&gt;
    3            4&lt;br /&gt;
&lt;br /&gt;
The following statements-&lt;br /&gt;
    10 Sep$(1)=&amp;quot;,&amp;quot;&lt;br /&gt;
    20 Sep$(2)=hex$(&amp;quot;0D0A&amp;quot;) ! CRLF&lt;br /&gt;
    30 MAT2STR( MAT zzz$, str$, MAT Sep$ )&lt;br /&gt;
    40 PRINT str$&lt;br /&gt;
&lt;br /&gt;
Will produce-&lt;br /&gt;
    1,2&lt;br /&gt;
    3,4&lt;br /&gt;
&lt;br /&gt;
[[Category:BR Manual]]&lt;br /&gt;
[[Category:Statements]]&lt;br /&gt;
[[Category:Manual Vol 1]]&lt;br /&gt;
[[Category:BR Manual Chapter 1]]&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Open_Window&amp;diff=1712</id>
		<title>Open Window</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Open_Window&amp;diff=1712"/>
		<updated>2013-02-04T19:04:16Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See also: [[Parent=None]] and [[Picture]]&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;OPEN window&#039;&#039;&#039; (OPE) [[statement]] specifies the characteristics for a window and activates the window for input/output. OPEN window can specify the following window characteristics: screen placement and dimensions, border type and attributes, attributes to be used for the text area of the window, and a caption to be displayed within the top border of the window.&lt;br /&gt;
&lt;br /&gt;
:1.) When a file is opened for both SHR and INPUT, Business Rules will no longer change the time and date of the file. As a result of this change, when a file is to be opened both for OUTIN and for INPUT, the OPEN for OUTIN must be executed first. Otherwise an error [[0608]] will result. This will affect current programs.&lt;br /&gt;
:2.) The OPEN window statement now allows for flexibility in the specification of window coordinates. Previously all four coordinates of the window had to be specified in terms of two exact row positions and two exact column positions. With release 3.50, only one exact row position and one exact column position must be specified. Business Rules will automatically calculate the other row and/or column position according to the values of the ROWS= and COLS= parameters, which indicate the desired length or width of the window.&lt;br /&gt;
&lt;br /&gt;
The ROWS= parameter may be used in place of either the SROW= or the EROW= parameter, but not both. Likewise, the COLS= parameter may be used in place of either the SCOL= or the ECOL= parameter, but not both. The following examples show some of the possibilities that are available using this syntax option. Each statement opens a 10 row by 10 column window in the upper left corner of the screen. (NOTE: ROWS= and COLS= parameters are shown in lowercase for emphasis; case makes no difference in actual syntax.)&lt;br /&gt;
&lt;br /&gt;
 00010 OPEN #1:&amp;quot;rows=10,cols=10,EROW=10,ECOL=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00020 OPEN #1:&amp;quot;rows=10,SCOL=1,EROW=10,cols=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00030 OPEN #1:&amp;quot;rows=10,SCOL=1,EROW=10,ECOL=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00040 OPEN #1:&amp;quot;SROW=1,cols=10,rows=10,EROW=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00050 OPEN #1:&amp;quot;SROW=1,cols=10,EROW=10,ECOL=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00060 OPEN #1:&amp;quot;SROW=1,SCOL=1,rows=10,cols=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00070 OPEN #1:&amp;quot;SROW=1,SCOL=1,rows=10,ECOL=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
 00080 OPEN #1:&amp;quot;SROW=1,SCOL=1,EROW=10,cols=10&amp;quot;,DISPLAY,OUTPUT&lt;br /&gt;
&lt;br /&gt;
:3.) The OPEN window statement&#039;s BORDER parameter now accepts S (drop-shadow) as an attribute for the border. See &amp;quot;S Attribute&amp;quot; in the [[BRConfig.sys]] Specification section for more information.&lt;br /&gt;
:4.) The NOCLOSE parameter in any OPEN statement will leave that file open when a program ends or chains to another program. The only way this file is closed is by explicitly closing the file, CLEAR ALL, or by exiting from Business Rules.&lt;br /&gt;
&lt;br /&gt;
 00010 OPEN #1:&amp;quot;NAME=TEST,NOCLOSE&amp;quot;,INTERNAL,RELATIVE,INPUT&lt;br /&gt;
&lt;br /&gt;
===Comments and Examples===&lt;br /&gt;
Business Rules creates two different types of windows: windows that are opened as separate input/output files, and field help windows. The OPEN window statement allows you to create the first type, windows that accept input and output. For information about field help windows, see [[Screen I/O]].&lt;br /&gt;
&lt;br /&gt;
Windows can also be opened separately from the main window. OPEN #0 is reserved for this. Also see [[Parent=Window]] for more information.&lt;br /&gt;
&lt;br /&gt;
Regarding window  size : (as of 4.3) when opening separate windows, &#039;NAME=window-name&#039; indicates that BR is to save the position of the window at the time it is closed and restore it to that position when it is reopened, even across sessions. Replacement or overlaying windows can use the same window names to position themselves wherever and at whatever character size the user has changed it to. So once a window has been opened with a particular name, subsequent opens ignore ROW= and COL= and instead use the user positioned values. &lt;br /&gt;
&lt;br /&gt;
As a result window positioning and size priority is as follows:&lt;br /&gt;
        :1. NAME= window-name&lt;br /&gt;
        :2. (for window zero only) un-named save font size and position.&lt;br /&gt;
        :3. SROW, SCOL, MAXIMIZE, NOMAXIMIZE, ABSOLUTE, RELATIVE, FONTSIZE&lt;br /&gt;
&lt;br /&gt;
Another attribute (that doesn&#039;t get saved) is OVERRIDE, which indicates that the SROW and SCOL (etc) settings in the OPEN statement are to be used even if NAME= is also specified. When OVERRIDE is specified in OPENDFLT, it only applies to the first OPEN of window #0. In all other cases Name= trumps SROW etc settings.&lt;br /&gt;
&lt;br /&gt;
All of the above specifications apply to Window zero except it cannot be &lt;br /&gt;
opened RELATIVE.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NOMAXIMIZE&amp;quot; also removes the maximize button from the window.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;NO_TASK_BAR&amp;quot; suppresses the task bar icon. This feature &lt;br /&gt;
is available on any window.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;MODAL&amp;quot; uses the same task bar icon as it&#039;s parent window. This ignores &lt;br /&gt;
any clicks on its parent window.&lt;br /&gt;
&lt;br /&gt;
===Input Across Multiple Windows===&lt;br /&gt;
As of 4.3, BR allows for input across multiple windows, as in the following example:&lt;br /&gt;
&lt;br /&gt;
 00010  (R)INPUT FIELDS  #121: “10, 10, C 20, UH; 10, 12, PIC(##/##/##), UH;#124,10, 10, C 30, UH”: aaa$, bbb$, ccc$&lt;br /&gt;
&lt;br /&gt;
This will input the first two fields on window #121 and the third field on window #124.  The ‘#window-number,’ prefix may appear in any row or col FIELDS specification and overrides the window number that follows the PRINT/INPUT/RINPUT keyword.&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
[[Image:Openwindow.png|900px]]&lt;br /&gt;
&lt;br /&gt;
===Defaults===&lt;br /&gt;
:1.) No border.&lt;br /&gt;
:2.) N (normal).&lt;br /&gt;
:3.) No caption.&lt;br /&gt;
:4.) Center caption.&lt;br /&gt;
:5.) Interrupt the program if an error occurs and ON is not active.&lt;br /&gt;
:6.) N (normal).&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
&amp;quot;Wind-num&amp;quot; is a file number for the window being opened. It must be a numeric  expression or integer that equals a value from 1 to 999, inclusive. No other open file or open window may use the same value. Open windows do not count against the operating system limit on open files.&lt;br /&gt;
&lt;br /&gt;
From this point, there are two possible paths through the OPEN window syntax. The top path will be described first.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;SROW = row&amp;quot; parameter identifies the starting row for the window. The &amp;quot;row&amp;quot; portion of this parameter can be any integer within the size of the main BR window. If a border is specified for the window, it must be 1 more than the desired starting place, to account for a one row border. The value of &amp;quot;row&amp;quot; cannot exceed the value of the ending row.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;SCOL = column&amp;quot; parameter identifies the starting column for the window. The &amp;quot;column&amp;quot; portion for this parameter can be any integer within the size of the main BR window. If a border is specified for the window, it must be 1 more than the desired starting place, to account for a one colomn border. The value of &amp;quot;column&amp;quot; cannot exceed the value of the ending column.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;EROW = row&amp;quot; parameter identifies the ending row for the window. The &amp;quot;row&amp;quot; portion of this parameter can be any integer (unless a border is specified for the window -then the value must be one less than the desired ending row, to account for a one row border) It cannot precede the starting row value.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;ECOL = column&amp;quot; parameter identifies the ending column for the window. The &amp;quot;column&amp;quot; portion of this parameter can be any integer (unless a border is specified for the window-then the value must be one less than the desired ending column, to account for a one column border) It cannot precede the starting column value.&lt;br /&gt;
&lt;br /&gt;
The optional &amp;quot;ROWS=int&amp;quot; parameter can be used instead of either &amp;quot;SROW=row&amp;quot; or &amp;quot;EROW=row&amp;quot; to specify the number of rows desired (instead of a specific starting or ending row). &lt;br /&gt;
&lt;br /&gt;
The optional &amp;quot;COLS=int&amp;quot; parameter can be used instead of either &amp;quot;SCOL=col&amp;quot; or &amp;quot;ECOL=col&amp;quot; to specify the number of columns desired (instead of a specific starting or ending column).&lt;br /&gt;
&lt;br /&gt;
Note that when opening a #0 window, only &amp;quot;ROWS=int&amp;quot; and &amp;quot;COLS=int&amp;quot; parameters are necessary, the others are not. See [[Parent=None]] for more information.&lt;br /&gt;
&lt;br /&gt;
To specify a border, see the discussion on the supplemental BORDER=Spec syntax and parameters below.&lt;br /&gt;
&lt;br /&gt;
Otherwise, continuing with the main syntax for OPEN window, the next available parameter is &amp;quot;N=attributes&amp;quot;. This parameter identifies the attributes that are to affect the entire inner portion of the window. However, the attribute specified takes effect only after a PRINT NEWPAGE has been sent to the window. The B (blink) attribute is not available for this parameter.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ABSOLUTE&amp;quot; and &amp;quot;RELATIVE&amp;quot; qualify SROW and SCOL to specify the position of a new independent window. RELATIVE (the default) indicates positioning relative to window zero (the main console), and ABSOLUTE indicates positioning relative to the screen. Using negative values    positions an independent window to the left of or above the main console. BR will attempt to honor the request keeping the new window viewable up to the maximum size of the screen. Window zero ositioning is always ABSOLUTE. To position a window on a second monitor, specify a starting position to the right of the last position of the first monitor. &lt;br /&gt;
&lt;br /&gt;
The &amp;quot;CAPTION=&amp;quot; keyword is used to identify text that is to appear in the top border of the window. It may optionally be followed by either a less-than (&amp;lt;) symbol for flush left text or a greater-than (&amp;gt;) symbol for flush right text. When no symbol is specified, the text is centered. The &amp;quot;title&amp;quot; parameter represents the text that is to be displayed.&lt;br /&gt;
&lt;br /&gt;
All of the parameters described above (excluding the wind-num parameter) comprise the file definition string. The alternative to coding these parameters directly in the OPEN window statement is to reference them with the &amp;quot;string expression&amp;quot; parameter found in the bottom path of the syntax diagram.&lt;br /&gt;
&lt;br /&gt;
No matter which path you choose for providing the file definition, two of the remaining parameters in the syntax diagram must be included in your OPEN window statement. &amp;quot;DISPLAY&amp;quot; identifies the window file as a display file, and one of the &amp;quot;INPUT&amp;quot;, &amp;quot;OUTPUT&amp;quot; or &amp;quot;OUTIN&amp;quot; parameters must be used to indicate how the window will be used.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;error-cond line-ref&amp;quot; parameter allows for error processing. See [[Error Conditions]] for more information.&lt;br /&gt;
&lt;br /&gt;
===Supplemental Syntax (&amp;quot;BORDER= spec&amp;quot;)===&lt;br /&gt;
{{:Borderspec}}&lt;br /&gt;
&lt;br /&gt;
===Technical Considerations===&lt;br /&gt;
:1.) Relevant error conditions are: [[ERROR]], [[EXIT]] and [[IOERR]].&lt;br /&gt;
:2.) Open window files do not count against your operating system limit on open files.&lt;br /&gt;
:3.) Using [[CONFIG]] SCREEN N xx to change the normal attribute of a window will only take affect on windows that are opened after the CONFIG SCREEN specification is executed. This applies only to the N (normal) attribute.&lt;br /&gt;
:4.) Unix / Linux terminals - See [[Terminal Consideration]] for special considerations when using windows with Unix / Linux terminals.&lt;br /&gt;
:5.) SROW and SCOL are based on FONTSIZE.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Statements]]&lt;br /&gt;
[[Category:Window File Processing Statements]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Border_Spec&amp;diff=1711</id>
		<title>Border Spec</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Border_Spec&amp;diff=1711"/>
		<updated>2013-02-04T19:00:55Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: Created page with &amp;quot;The &amp;quot;BORDER=spec&amp;quot; parameter represents an inserable syntax that specifies the visual characteristics of the window border, within the Open Window statement. The BORDER= ke...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &amp;quot;BORDER=spec&amp;quot; parameter represents an inserable syntax that specifies the visual characteristics of the window border, within the [[Open Window]] statement. The BORDER= keyword must be followed by one of four border specifications (as of 4.3 these work with CON GUI ON as well). &lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
[[image:Borderspec.png]]&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
*&amp;quot;B&amp;quot; indicates that the border is to be blank; &lt;br /&gt;
*&amp;quot;D&amp;quot; indicates a double-line border; &lt;br /&gt;
*&amp;quot;H&amp;quot; indicates that a shadowed or highlighted border be used; &lt;br /&gt;
*and &amp;quot;S&amp;quot; indicates that a single-lined border be used. &lt;br /&gt;
&amp;quot;Corners&amp;quot; and &amp;quot;8 chars&amp;quot; border specifications may be used for custom-designed window borders. See [[Screen I/O]] for illustrations and more information about border types and border graphics specifications. However, as of 4.3, Border=H and &amp;quot;8 chars&amp;quot; are no longer supported except that a new [[Option (Config)|OPTION]] 62 permits S, D, B, H or an eight character string followed by a colon and then attributes. For example: &lt;br /&gt;
             BORDER=S|D|B|H|8-chars[:attributes]&lt;br /&gt;
While the colon is actually optional, it is recommended for readability when attributes are included.&lt;br /&gt;
&lt;br /&gt;
Also within the BORDER= syntax, the &amp;quot;attributes&amp;quot; parameter may be specified immediately after the border specification (no spaces). The attributes specified here will affect the visual display of the border itself. See [[Definitions]] for the correct syntax to be used with the &amp;quot;attributes&amp;quot; parameter.&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Line_Continuation&amp;diff=1710</id>
		<title>Line Continuation</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Line_Continuation&amp;diff=1710"/>
		<updated>2013-02-04T18:49:25Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An &#039;&#039;&#039;!:&#039;&#039;&#039; in Business Rules! code performs a &#039;&#039;&#039;line continuation&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
More than one clause (or [[statement]]) can reside on a single [[line]] when the statements are separated by a colon (:). When the statements are separated by both an exclamation point and a colon (!:), Business Rules will list them to separate physical lines, even though they continue to belong to the same line number.  Each portion of a line seperated by an !: is referred to as a &#039;&#039;sub-line&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
[[Paragraph labels]] following line continuations are not allowed. However they are allowed following a subline [[comment] out ([[!]]), for example:&lt;br /&gt;
&lt;br /&gt;
 00010 TOP: ! !:&lt;br /&gt;
       Print Newpage&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Statements]]&lt;br /&gt;
[[Category:Terminology]]&lt;br /&gt;
[[Category:Basics]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
	<entry>
		<id>https://brwiki2.brulescorp.com/brwiki2/index.php?title=Return&amp;diff=1697</id>
		<title>Return</title>
		<link rel="alternate" type="text/html" href="https://brwiki2.brulescorp.com/brwiki2/index.php?title=Return&amp;diff=1697"/>
		<updated>2013-02-03T21:03:09Z</updated>

		<summary type="html">&lt;p&gt;66.17.154.248: Created page with &amp;quot;The &amp;#039;&amp;#039;&amp;#039;Return (RETU)&amp;#039;&amp;#039;&amp;#039; statement works in conjunction with the GoSub statement. After execution of a subroutine, RETURN transfers control back to the statement immedi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Return (RETU)&#039;&#039;&#039; [[statement]] works in conjunction with the [[GoSub]] statement. After execution of a subroutine, RETURN transfers control back to the statement immediately following the most recently executed [[GOSUB]].&lt;br /&gt;
&lt;br /&gt;
===Comments and Examples===&lt;br /&gt;
RETURN is required at the end of every subroutine. In the following example, the subroutine in line 5000 is repeated several times throughout the program. Each time the subroutine finishes executing, RETURN transfers control back to the first executable statement after the calling GOSUB.&lt;br /&gt;
&lt;br /&gt;
 00100 GOSUB 5000&lt;br /&gt;
 o&lt;br /&gt;
 o&lt;br /&gt;
 o&lt;br /&gt;
 05000 PRINT &amp;quot;This is my subroutine&amp;quot;&lt;br /&gt;
 05010 RETURN&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
[[file:Return.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Statements]]&lt;br /&gt;
[[Category:Branching Statements]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>66.17.154.248</name></author>
	</entry>
</feed>