11
USING THE COMMON SPACE: FREE YOUR SITE FROM CUSTOM I-DESCRIPTORS IMPROVE READABILITY OF CODE presented by MIKO Programmer/Analyst III Dept Technology Solutions of ASD University of California, Berkeley (510) 643-5015 [email protected] Datatel Users Group Conference March 1999 Session TT849 of the Tools and Technology Track

Using-The-Common-Space-DUG-Datatel-Miko

  • Upload
    miko-

  • View
    13

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Using-The-Common-Space-DUG-Datatel-Miko

USING THE COMMON SPACE:

• FREE YOUR SITE FROM CUSTOM I-DESCRIPTORS• IMPROVE READABILITY OF CODE

presented by

MIKOProgrammer/Analyst III

Dept Technology Solutions of ASDUniversity of California, Berkeley

(510) [email protected]

Datatel Users Group ConferenceMarch 1999

Session TT849 of the Tools and Technology Track

Page 2: Using-The-Common-Space-DUG-Datatel-Miko

INTRO: Problems Associated With I-Descriptor Clutter

Selecting data using a Unidata UNIQUERY statement requires reference to fields that must be defined in datadictionaries, called DICT files. UNIQUERY requires that selection is based upon the content of data fields orvirtual fields. Virtual fields, or I-descriptors, as they are often called, can be used to pass arguments tosubroutines. Arguments represent the means by which data can be sent from one program to another. Thisfunctionality allows the programmer to take advantage of the UNIBASIC language to analyze, “crunch” ortranslate data through the Uniquery selection process, making use of code that cannot be incorporated intoUniquery statements.

Traditionally, a person working with Uniquery has had to suffer through the creation of new I-descriptors inorder to call subroutines using the data that he would specifically like to pass as arguments. This is because I-descriptors don't have a built-in interface to anything outside of the Uniquery statement within which they'recalled. To change arguments being sent by an I-descriptor to a specific subroutine, a programmer must edit theI-descriptor or create a new version. The problematic nature of this process is compounded by the simple factthat I-descriptors do not delete themselves.

After going LIVE, many sites quickly see a dramatic growth in the number of I-descriptor type fields in the datadictionaries of their files. These virtual fields pose several problems:

1. They make it harder to read or list out the items in our larger data dictionaries.

2. There is often no adequate process in place for documenting the purpose or use of these many I-descriptors.This is hard to implement even when it becomes a site goal. Therefore, there often end up many "dead" butvery "specific" I-descriptors that no one dares destroy for fear of messing up someone else's work.

3. Creating new I-descriptors requires editing a database's DICT and then compiling the DICT item, taskswhich are separate from the process of writing a paragraph and therefore more time-consuming thanworking completely within a paragraph.

4. Consequently, because I-descriptor arguments live inside of I-descriptors and not Uniquery paragraphs,traditional I-descriptors inherently “hide” data from phantom files and paragraphs, where you would ideallywant to see the values that are being used as part of your selection criteria.

5. I-descriptors make it more difficult to make repetitive use of Envisionized processes with front end screens,such as DMP (mail merge), which may require a change of text in only one field- such as correspondencecode- for each savedlist used.

6. Some users of Uniquery cannot create their own I-descriptors because they do not have access to an editorsuch as AE. These same users may nonetheless desire to make use of I-descriptors that call subroutineswithout being limited to passing arguments that were passed by other programmers. Custom I-descriptorswith situation-specific arguments are useless to these users.

The good news is this: Use of the shell process-based “COMMON” space can solve all of these problems foryour users and help you to work toward data dictionaries with few items that are customizable from thecommand line. In fact, the common space can be used to circumvent a broad range of the limitations imposedby the "data field" nature of I-descriptors and the often "closed" nature of other UNIBASIC programming.

Page 3: Using-The-Common-Space-DUG-Datatel-Miko

Making Use Of The COMMON Space

There is a way to create I-descriptors to which you can pass arguments from within a Uniquery paragraph orfrom the command line!! Moreover, by doing the methods described in this document, you can avoidhaving to customize I-descriptors, or create new custom I-descriptors, for selection and reporting.

You do this by populating a "pocket" of computer memory called a COMMON space. These areas exist forstoring data in active memory so that it can be used by different queries and subroutines within a single login (or“process”). There exist two types of COMMON spaces in the Unidata environment- named or unnamed.. A“named COMMON” will retain values stored within it during a full Unidata session- that is, the entire time youremain logged into a specific Unidata account in a particular screen, or will retain values though the entire lifeof a phantom process. An “unnamed COMMON”, on the other hand, is set within a process and cleared uponreturn to the ECL “:” (colon) prompt. In this document you will find a clear bias toward the "named"COMMON spaces since they more fully realize the primary advantage of these areas- to keep data available toyour processes.

Note: For the "official information" of COMMON spaces, you can refer to APPENDIX A, which includes theUnibasic HELP entry for COMMON.

It is important to remember, as you begin thinking about how to use COMMON areas, that the data in theseareas is never shared among different user logins or between your colon prompt environment and your phantomprocesses. Every single login and each phantom process for each user starts with a clean slate and makes use ofits own unique, separate COMMON space. The word “COMMON” does not mean that the information storedin this space is shared - or “COMMON” - between users and login processes. Rather, it means that the data isshared by or is COMMON to selection, reporting and other process events that take place within a specificsingle login or phantom process. To understand the COMMON space it will be crucial to keep this in mind.

U.C. Berkeley Subroutines That Make Use of COMMON Space

The truth is, you don’t have to understand much about the COMMON space, nor worry about its limits, to beable to begin to use it right away. This is because, in APPENDIX C you will find the code for one UC Berkeleyprogram (XMIK.COM) and one UC Berkeley subroutine (XMIK.GETCOM), which will allow you to gainaccess to a named COMMON space in a very simple manner. You can use the UC subroutines as templates foryour own, once you feel you understand them better. Following is a description of how these programs areused.

• XMIK.COM - SUBROUTINE THAT POPULATES A "NAMED COMMON" AREA

XMIK.COM was inspired by the Rotman and Sjoquist SELINP subroutine available at the Cedarvilledownload site (Appendix B). SELINP is an excellent tool, but it hardwires the number of COMMON spacevariables that will be allowed. XMIK.COM was written to overcome this limitation but also has a slightlydifferent logical structure to it. Other differences are:

a) that XMIK.COM is not bound to in-line prompts

Page 4: Using-The-Common-Space-DUG-Datatel-Miko

4b) it uses a dynamic array instead of a MAT-type arrayc) allows entry of multi-values with the use of a “left brace” (“{“) delimiter. This delimiter, which

will be discussed further on, doesn't have to be a left curly brace, by the way. If you modify thecode for your site you can change this delimiter to some other esoteric character (one that will beunlikely to be part of most arguments that you pass.

XMIK.COM is used to create a space for a certain type of information and then to fill that space with data thatyou would like to retrieve later from within a select statement in a paragraph or perhaps a report program. AtUC Berkeley, XMIK.COM is used to populate a named COMMON space called /XMIKCOM/.

XMIK.COM is currently written is always at the colon prompt. To use it to create a COMMON space for data,think of a unique name for the data group (technically it will be a “dynamic array”), and then type:

:XMIK.COM uniquename value{value{value{value…

For example, if I want to create a COMMON area for mail rules and fill it with a set of mail rules to be used forcomparison in a subroutine, I would perhaps type:

:XMIK.COM MAILRULE UCNADR{UCBADR{UCNCON{UCNS

If the TRIM option is kept in XMIK.COM (see the code), these values can also be assign like this:

:XMIK.COM MAILRULE UCNADR\:{UCBADR\:{UCNCON\:{UCNS

The second way of doing it makes it easier to modify previously stored lists to add and remove values that youwant to store.

In both examples above, I have created a data group (“array”) called MAILRULE. The left brace character“{“ is the data value delimiter and will be converted into a “value mark” (also known as an @VM orCHAR(253)) before the data is stored in memory. This character was chosen because it’s rarely used in actualdata and is also easier to type than “:@VM:”. Any site choosing to adopt an XMIK.COM type of subroutinewill of course have the option to re-code the subroutine so that their version uses a different delimiter.

The data will be stored as if you had a free-floating multi-valued field in memory, called “MAILRULE”,containing the values “UCNADR”, “UCBADR”, “UCNCON”, “UCNS”.1

Data can be cleared from a COMMON space variable by typing:

:XMIK.COM variablename CLEAR

For example, to clear the MAILRULE variable so that it still exists but contains no values, type:

1 Geek note: It will be stored with all of your other assigned COMMON area “data groups” in one large array that is itself separated by attributemakers (@AMs)

Page 5: Using-The-Common-Space-DUG-Datatel-Miko

5:XMIK.COM MAILRULE CLEAR

One special note, or “trick”: you can store blank (null) values by starting or ending with a “{“ or by putting 2“{{“ together to create a “data pocket”. In other words, @VMs end up wherever brackets are, and so you getthe same dynamic array outcome that you get with @VMs in programs, data fields and I-descriptors.

An even more special note: This document discusses only a command line "program" version of XMIK.COM.It would be fairly easy, though, to create "subroutine" version of XMIK.COM that could be called from withinan I-descriptor or another program that doesn't have access to the colon prompt. All you'd need to do is take the2 arguments that are parsed from the command line sentence - the COMMON area variable name it associatedvalue(s) - and pass these instead as two arguments in your first line of code in your program, as follows:

SUBROUTINE XMIK.COM(X.RESULT,X.VAR.NAME,X.VAR.VALUES)

Such a version of an XMIK.COM-type of program offers some interesting benefits. Since it can be called in I-descriptor, it allows something truly astounding to happen- it allows you to pass information from one I-descriptor to another as you pass though a savedlist. This is a great ability to have if you want to create a"toggle" flag on data being uploaded into a data file.

For instance, if I have a file sorted by ZIP and I want to send two different test letters in exactly equal numbersto two near-identical geographic groups, I could toggle the letter flag through the zip sort.

You could also use an XMIK.COM type of I-descriptor to do COMMON area "math" - so that, perhaps, youcould count the number of items in various categories without sorting on that data and using TOTAL.

Wow- great features. But how does one get this data out of the name COMMON area when it's needed?

There are two ways (*examples of both are in APPENDIX C):

1. you can retrieve these stored values from within a UNIBASIC program or subroutine2. you can use a subroutine like XMIK.GETCOM in an I-DESC.

• XMIK.GETCOM - "GETS" DATA OUT OF /XMIK.COM/ FROM WITHIN AN I-DESC

XMIK.GETCOM is used from inside an I-descriptor or is called using the UNIBASIC CALL statement, toretrieve the value or values you stored in the COMMON space using XMIK.COM. XMIK.COM only retrievesdata, so it cannot be used when the COMMON space is empty. This will cause an error.

IMPORTANT: You can’t make use of XMIK.GETCOM in an I-DESCunless you ALWAYS store the data being called by XMIK.GETCOM first.

To use this great subroutine, simply insert SUBR(“XMIK.GETCOM”,”uniquename”) where you want thevalues to be inserted into the I-DESC in field 2, the LOC entry. For example, to insert the mail rules stored viaXMIK.COM in the above example above into an I-Descriptor, you would create an I-DESC that has a LOC(field 2) that looks like this:

SUBR(“XC10.SPECIAL.MAIL”,SUBR(“XMIK.GETCOM”,”MAILRULE”))

Page 6: Using-The-Common-Space-DUG-Datatel-Miko

6Note: XMIK.GETCOM can replace each argument in your I-Descriptor if necessary and is especially useful forstoring often-changed strings of “:@VM””-separated data, such as mail rules, departments, funds, city names,country names, zip codes, etc. HOWEVER, you cannot “cross commas” or “cross arguments” inside ONEGETCOM statement. If you need to supply mail rules and then, after a comma, also need to supply city names,you will need a separate XMIK.GETCOM section (and XMIK.COM statement) for these two differentarguments in your I-descriptor. This is actually a standard rule for string variables, and that’s all thatXMIK.GETCOM returns, in the end- a string variable.

Thus, note also that outside of the exception of its use in subroutine arguments, you CAN play with theXMIK.GETCOM result as if it were an ordinary string. You can create an I-DESC that does this:

FIELD(SUBR("XMIK.GETCOM","TESTING"),@VM,2):" plus text":@VM:"Second value"

This results in the printed multi-valued field looking something like:

xmik.getcom value with this appendedSecond value

To take advantage of retrieving data from within a program, you will always include the following statement inyour program, before you try to retrieve any of the variables you have stored:

COMMON /XMIKCOM/ VAR.NAMES,VAR.VALUES

This statement announces the existence of a named common space called /XMIKCOM/, which is the namegiven to the common space created using XMIK.COM. It also heralds the existence and arrangement (relativeposition) of two arrays within the /XMIKCOM/ space.

After this statement, you need to determine the position of the string of data that you desire to retrieve fromcommon space in order to determine its value. You do this by looking for the position of the name that yougave to the array, as a sort of "variable name", in the larger array in the named common area called/XMIKCOM/. One technique for doing this would be to use the UNIBASIC LOCATE command, as follows:

LOCATE 'value' IN VAR.NAMES<1> SETTING VAR.POS ELSE…

Note: often when using the LOCATE command in UNIBASIC, you would search an array at the multi-value levelby typing <1,1> instead of searching the level that includes multi-valued information- the attribute level, indicatedabove by the <1> next to VAR.NAMES. Since XMIK.COM was designed to allow storing multi-values andpotentially even sub-values, the delimiter BETWEEN the values stored in the common space was chosen to be theattribute mark.

After finding the value in the COMMON space, you can set a dynamic array variable to equal to the data storedat the LOCATE-returned position, VAR.POS, in VAR.VALUES:

newvariable = FIELD(VAR.VALUES,@AM,VAR.POS)

Look to APPENDIX C for an example of this implemented in a subroutine.

SPECIAL ADVICE: KNOWING WHEN TO CLEAR COMMON SPACE

Page 7: Using-The-Common-Space-DUG-Datatel-Miko

7Sometimes you will want to use a subroutine that populates COMMON space over and over within the sameparagraph or other single process or linked set of processes. When you do this, it is good to remain aware that,within the same phantom, login, or program, the COMMON space does not clear itself out. If you have asubroutine that expects a named or unnamed COMMON to be clear when it starts, you will have to make surethat you do this manually.

For this purpose, there is a command called CLEARCOMMON available to UNIBASIC. Regrettably, I don'tthink there's an ECL (Uniquery verb) form of CLEARCOMMON, so you will normally have to write a minimalUNIBASIC program and catalog it in order to do this.

For example, if you've created a program that fills a named COMMON space for certain savedlists called/XCLSTS/, you'd create a UNIBASIC program to clear that space, let's call it X.CLEARLISTS, which wouldhave only one line in it:

001: CLEARCOMMON /XCLSTS/

See APPENDIX D for a complete code example involving the specific circumstance mentioned above.

CONCLUSION

Hopefully you’ll quickly develop an understanding of how to use the COMMON space to your advantage.You’ll surely learn that using this space will allow you to work more efficiently from within your ad-hocparagraph or program, where you can better keep track of and audit how tasks are completed and how items areselected, without cluttering DICT files with gazillions of new single-use I-descriptors that we’re forever afraidto delete…

Good luck!

Page 8: Using-The-Common-Space-DUG-Datatel-Miko

8

APPENDIX A: UNIBASIC HELP FILE FOR “COMMON”

COMMON

Syntax:

COMMON [/COMMON.name/] var1 [,var2][MAT1]... COM [/COMMON.name/] var1 [,var2][MAT1]...

The UNIBASIC COMMON command makes named variables available to external subroutines and programs. COMMON.name mayhave any valid variable name no longer than 7 characters.

The COMMON statement must appear before you use any of the variables (i.e., var1, var2, MAT1) it declares. You may enter aCOMMON statement on several lines by using a comma after each line.

Variables may have one name in the main program and a different name in each subroutine where the COMMON statement appears.The statement refers to the position of the variables in the statement to identify matching variables.

• Passing Matrices

You may declare matrices with a COMMON statement. You may not declare matrices by both a COMMON and a DIMENSIONstatement. Matrices you declare in a COMMON statement may not be dynamically re-dimensioned. All variables and matrices youcreate by a COMMON statement are initialized to zero.

• Passing Variables

Variables you declare by a COMMON statement without a COMMON.name lose their values when the Unidata Environment ControlLanguage (ECL) prompt redisplays. You may access the values by any program you call or chain to. The values of variables youdeclare by a COMMON statement without a COMMON.label are stored in a single area called: unnamed COMMON.

Variables you declare by a COMMON statement with a COMMON.name retain their value until the end of the Unidata session. Thesystem clears the when you terminate your Unidata session.

The number of variables that a COMMON statement may contain depends on the virtual memory of your system. For information onvirtual memory, refer to the System Administrator's Guide.

• Examples

In the following example, the program statement uses an unnamed COMMON statement to declare the matrices, NAME and DATES,as well as the variable DCHANGE.

COMMON NAME(100),DATES(100,2),DCHANGE

In the next example, the program segment creates two named COMMON areas. The second COMMON statement continues on asecond line with the comma ( , ) continuation character.

COMMON /MENU/ X,Y,X DIM,Y DIM,S.CHAR COMMON /CALC/ RATE(10),AMOUNT(10),DATE1, DATE2,LATE

In the following example, the program segment in invalid since the COMMON statement must appear first. You cannot redefine avariable in the COMMON statement after it has been assigned. Unidata requires one-to-one correspondence between main line andsubprograms.

VALUE = 253 COMMON VALUE,SUBVALUE,ATTRIBUTE

Page 9: Using-The-Common-Space-DUG-Datatel-Miko

9

APPENDIX B: CEDARVILLE “SELINP” SUBROUTINE

SUBROUTINE SELINP(RETURN.VALUE,VARIABLE,PROMPT.TEXT,CONV.CODE)** INFO/BASIC PROGRAM** TITLE ----- SELINP** PURPOSE: SUBROUTINE TO ASK FOR INPUT WHEN A SELECT IS FIRST RUN** Last updated by LIVE (ROTMAN) at 10:06:07 on 08/11/1989.* Echo input value to screen so that paragraphs using in-line* prompts do not confuse the user (thinking he/she has to enter a value* more than once).* Last updated by LIVE (SJOQUIST) at 11:29:42 on 05/12/1988.* Use FIRST.RECORD & labeled COMMON* Last updated by LIVE (SJOQUIST) at 08:28:58 on 10/07/1987.************************************************************************************* This program is provided 'as is' for your use by ROTMAN & SJOQUIST.* You are encouraged to verify the accuracy of program functions prior* to use with actual data files.** If you have questions about this program, or if you wish to obtain* a list of programs available for purchase from ROTMAN & SJOQUIST,* contact Dave Rotman or Doug Sjoquist:** Rotman and Sjoquist* c/o Cedarville College* PO Box 601* Cedarville, OH 45314* (513) 766-2211************************************************************************************ MAX.VAR = 25 COMMON /SELINP/ NUM.VAR, VAR.NAME(MAX.VAR), VAR.VALUE(MAX.VAR) THIS.IS.THE.FIRST = '' CALL FIRST.RECORD(THIS.IS.THE.FIRST,'SELINP') IF THIS.IS.THE.FIRST THEN NUM.VAR = 0 MAT VAR.NAME = '' MAT VAR.VALUE = '' END PROMPT '' VAR.NUM = 0 LOOP VAR.NUM += 1 UNTIL VAR.NUM > NUM.VAR OR VARIABLE = VAR.NAME(VAR.NUM) REPEAT* NEW VARIABLE IF VAR.NUM > NUM.VAR THEN NUM.VAR += 1 VAR.NUM = NUM.VAR VAR.NAME(VAR.NUM) = VARIABLE IF PROMPT.TEXT THEN TEXT = PROMPT.TEXT:': ' END ELSE TEXT = VARIABLE:': ' END* IF CONV CODE USED, FORCE CORRECT VALUE LOOP CRT TEXT: INPUT VALUE IF CONV.CODE THEN NEW.VALUE = ICONV(VALUE,CONV.CODE) ISTAT = STATUS() END ELSE NEW.VALUE = VALUE ISTAT = 0 END IF ISTAT = 0 THEN CRT NEW.VALUE END UNTIL ISTAT = 0 CRT '"':VALUE:'" DOES NOT MATCH THE CONV CODE "':CONV.CODE:'"' REPEAT VAR.VALUE(VAR.NUM) = NEW.VALUE END RETURN.VALUE = VAR.VALUE(VAR.NUM) RETURNEND

Page 10: Using-The-Common-Space-DUG-Datatel-Miko

10

APPENDIX C: XMIK.COM, XMIK.GETCOM, XMIK.MEM.ONLYXMIK.COM: this subroutine can be used to populate a named COMMON called /XMIKCOM/

SENTENCE = @SENTENCEVAR.NAME = FIELD(SENTENCE,' ',2)VAR.VAL.LEN = LEN(SENTENCE) - (10 + LEN(VAR.NAME))VAR.VAL.START = 11 + LEN(VAR.NAME)VAR.VAL = SENTENCE[VAR.VAL.START,VAR.VAL.LEN]VAR.VAL.TEMP = ''COMMON /XMIKCOM/ VAR.NAMES,VAR.VALUESIF UPCASE(VAR.VAL) = 'CLEAR' THEN LOCATE VAR.NAME IN VAR.NAMES<1> SETTING POS THEN VAR.NAMES = DELETE(VAR.NAMES,POS,0,0) VAR.VALUES = DELETE(VAR.VALUES,POS,0,0) MESSAGE = VAR.NAME:" is cleared" PRINT MESSAGE STOP ENDEND ELSE BRACE.CT = DCOUNT(VAR.VAL,"{") IF BRACE.CT GT 1 THEN FOR BRACE.MARK = 1 TO BRACE.CT THIS.VALUE = FIELD(VAR.VAL,"{",BRACE.MARK) VAR.VAL.TEMP<1,-1> = TRIM(THIS.VALUE)

** place a TRIM statement above if you want to allow data to be spread across ** paragraph lines with “\” and you don’t mind ignoring leading or trailing ** spaces - otherwise, don’t use trim above NEXT BRACE.MARK VAR.VAL = VAR.VAL.TEMP END LOCATE VAR.NAME IN VAR.NAMES<1> SETTING POS THEN MESSAGE = "Old value of ":VAR.NAME:" was ":FIELD(VAR.VALUES,@AM,POS) PRINT MESSAGE VAR.VALUES = REPLACE(VAR.VALUES,POS,0,0,VAR.VAL) MESSAGE = "New Value of ":VAR.NAME:" is ":FIELD(VAR.VALUES,@AM,POS) PRINT MESSAGE END ELSE VAR.NAMES = INSERT(VAR.NAMES,-1,0,0,VAR.NAME) VAR.VALUES = INSERT(VAR.VALUES,-1,0,0,VAR.VAL) MESSAGE = VAR.NAME:" set to ":VAR.VAL:" in XMIKCOM VAR.VALUES at position":DCOUNT(VAR.VALUES,@AM) PRINT MESSAGE ENDEND

XMIK.GETCOM: this subroutine is used to recall values stored in /XMIKCOM/ with XMIK.COM

SUBROUTINE XMIK.GETCOM(RESULT,VAR.NAME)RESULT = ''COMMON /XMIKCOM/ VAR.NAMES,VAR.VALUESLOCATE VAR.NAME IN VAR.NAMES<1> SETTING POS THEN RESULT = FIELD(VAR.VALUES,@AM,POS)ENDRETURN

XMIK.MEM.ONLY: A UNIBASIC code that gets the value of “MEMRL” from /XMIKCOM/

SUBROUTINE XMIK.MEM.ONLY(RESULT,PERSON.ID)COMMON /XMIKCOM/ VAR.NAMES,VAR.VALUESLOCATE 'MEMRL'* IN VAR.NAMES<1> SETTING VAR.POS ELSE PRINT "Submit MEMRL to XMIK.COM!!!!" RETURNENDMEMRL = FIELD(VAR.VALUES,@AM,VAR.POS)CONVERT ',' TO @AM IN MEMRL

* MEMRL is set up in the paragraph, before the subr is called, with: “XMIK.COM MEMRL values”

Page 11: Using-The-Common-Space-DUG-Datatel-Miko

11

APPENDIX D: XMPE.CHECK.SAVEDLISTS & X.CLEARLISTS

XMPE.CHECK.SAVEDLISTS stores savedlist ids in an array in COMMON so that IDs in an active savedlistcan be sought within that array.

* UNIBASIC SUBROUTINE: XMPE.CHECK.SAVEDLISTS* BY: MICHAEL ERNST* DATE: 11/20/96* DESCRIPTION: CHECKS EACH OF A PASSED LIST OF SAVEDLISTS FOR THE* EXISTENCE OF A PASSED RECORD KEY. RETURNS THE LIST* OF SAVEDLISTS IN WHICH THE RECORD KEY IS FOUND.* USES ACTIVE LIST 9.*********** Last updated by bendev (ur0mpe) at 15:38:10 on 11/20/1996.**********SUBROUTINE XMPE.CHECK.SAVEDLISTS(RESULT,KEY,LISTS,OUTPUT,TYPE)X.PRESERVE.RECORD = @RECORDCOMMON /XCLSTS/ LIST.ARRAY, NUM.LISTS, ARRAY.BUILTIF ARRAY.BUILT # 1 THEN EXECUTE "HUSH ON" LIST.ARRAY = '' NUM.LISTS = DCOUNT(LISTS,@VM) FOR EACH.LIST = 1 TO NUM.LISTS LIST.NAME = LISTS<1,EACH.LIST> GETLIST LIST.NAME TO 9 THEN READLIST R.LIST FROM 9 ELSE R.LIST = '' END END CONVERT @AM TO @VM IN R.LIST LIST.ARRAY<-1> = R.LIST NEXT EACH.LIST ARRAY.BUILT = 1 EXECUTE "HUSH OFF"ENDRESULT = ''FOUND = ''FOR EACH.LIST = 1 TO NUM.LISTS IF TYPE # "S" OR FOUND # "1" THEN LOCATE KEY IN LIST.ARRAY<EACH.LIST,1> SETTING POS THEN IF LEN(OUTPUT) THEN RESULT<1,-1> = OUTPUT<1,EACH.LIST> END ELSE RESULT<1,-1> = LISTS<1,EACH.LIST> END FOUND = 1 END ENDNEXT EACH.LIST@RECORD = X.PRESERVE.RECORDRETURNEND

The I-DESC that is used at UCB to determine whether certain IDs are in certain lists is the following, calledXMIK.CHK.LISTS:

SUBR("XMPE.CHECK.SAVEDLISTS",@ID,SUBR("XMIK.GETCOM","LISTS"),SUBR("XMIK.GETCOM","RESULTS"),'S')…

The savedlist array can be cleared, between reports within a single paragraph, with the command:

X.CLEARLISTS

This subroutine has a single line of code in it, which is all that is needed. The code is:

CLEARCOMMON /XCLSTS/