




            ______________________________________________________________________________
            ______________________________________________________________________________
             
            Contributions
             
            ______________________________________________________________________________
            ______________________________________________________________________________
             
            Contributions for the  newsletter  can  be  sent  to  either  of the following
            addresses:
             
            Editor, DATATRIEVE Newsletter                  Joe H. Gallagher, Ph. D.
            c/o DECUS U. S. Chapter                        DATATRIEVE Newsletter Editor
            249 Northboro Road, BP02                       Director, Medical and
            Marlboro, MA  01752                             Research Computing
                                                           Cleveland Clinic Foundation
                                                           9500 Euclid Avenue
                                                           Cleveland, Ohio  44106
             
            Letters and articles for publication  are  requested  from members of the SIG.
            They may include  helpful  hints,  inquiries  to  other  users, reports on SIG
            business, summaries of  SPRs  submitted  to  Digital  or other information for
            members of the DATATRIEVE SIG.  Machine readable input is highly desirable and
            machine-to-machine  transfer  of  material  is  preferred,  but  most anything
            legible will be considered.  However,  this  newsletter is not a forum for job
            and/or head hunting, nor is commercialism appropriate.
             
            ______________________________________________________________________________
            ______________________________________________________________________________
             
            Table of Contents
             
            ______________________________________________________________________________
             
                   1   Chairman's Corner
                   3   DATATRIEVE Wish List
                   7   From the Editor's Pen
                   8   Wombat Magic Session
                  54   News Briefs
                  55   DATATRIEVE Masters
             
            ______________________________________________________________________________
            ______________________________________________________________________________
             
            About the Cover
             
            ______________________________________________________________________________
             
            The cover for this issue was drawn  by Bart Lederman of Bankers Trust Company.
            Our Wombat and his girl friend are waiting for us on the beach in California.
             





                                                  i






            ______________________________________________________________________________
             
            Chairman's Corner
             
            Larry Jasmann, U. S. Coast Guard, Burke, VA
             
            ______________________________________________________________________________
             
            First of all, I would like to  welcome  those of you who are new to DATATRIEVE
            SIG (Special Interest Group), and greet those who I haven't spoken to or writ-
            ten to for a long time.  Up until recently, I was attending graduate school at
            Tulane University, and there just didn't seem to be time to write much for the
            Wombat Examiner.  Well, now  I  am  out  of  school and without any excuses, I
            guess I will have to do better in this  area.  I am now stationed in the Wash-
            ington Area, and welcome feedback, questions,  offers to help the SIG, or just
            a chance to talk and get acquainted.    I  am usually at work from 7:00 - 3:30
            Eastern Time.  My work phone is (202) 426-1345.
             
            Things are really changing in  DECUS  and  with  DATATRIEVE SIG, and it may be
            helpful for me to tell you  how  I perceive those changes from my perspective.
            DECUS is in the final  process  of  a  massive restructuring of the leadership
            organization, and although the effects at the membership level may be somewhat
            hard to see at this point, I  feel  that  in the long run, the effects will be
            significant.
             
            Here are some perceptions about DECUS as a whole:
             
             1. The new leadership structure  involves  more volunteers in decision making
                positions, and has a  much  more  "bottom up" orientation than previously.
                The new leadership structure  tries  to  push operational decisions in the
                organization to the lowest  practical  level.    As a result, small groups
                have more ability to do what they want to do.  On the other hand, signifi-
                cant decisions which have to  filter  up through the organization may well
                be more difficult to get resolved.
             
             2. The new system tries hard to  create  paths  for people to move up through
                the organization.  In fact, one element (LDEC) of the organization has the
                primary charter of facilitating this process.
             
             3. Organization of the SIG Chairs into  a  formal body, the SIG Council, is a
                significant step in  increasing  the  effectiveness  and capability of the
                SIGs as a whole.  The  SIG  Council  exists to represent the needs and de-
                sires of the SIGs as a  whole  to  the  rest  of DECUS.  It also exists to
                provide a common body of knowledge  so that SIGs can work together better,
                and learn from each other.  Finally, it provides a place where someone can
                go for resolution of a  problem  that  isn't being treated responsively at
                the SIG level.
             
             4. The DECUS Communications System  (DCS)  has increased the effectiveness of
                the leadership to an extraordinary  degree by enabling rapid and effective
                communication among the leadership.    DECUS  is  a  3 to 5 million dollar
                business run by people who see each other  about 4 times a year for a week
                or less each time.  Think about that,  and think of trying to run your own
                organization that way!!  DCS has  made the process much better and respon-


            1






                sive to the needs of  the  organization.    Sometimes, I wonder how we did
                without it.
             
            Now a few perceptions about our SIG:
             
             1. DATATRIEVE is really changing.  When  I  first started in the SIG, DTR was
                on only PDP-11's, and the  documentation  set was one fairly small manual.
                DATATRIEVE was lots of fun,  and  for  those  of us who couldn't afford an
                army of programmers it was a Godsend, but for the most part, the DEC world
                didn't take it too seriously.  Well, things are really different now.  DTR
                is on ALL systems from DEC-20's to the Professional (I think that the only
                exceptions are the DEC-10 and the Rainbow),  and it is no longer a trivial
                product.   It  is  relational,  it  has  graphics,  a sophisticated report
                writer, and on the VAX, the ability  to be used with other languages or to
                use functions.  It has grown up, and so has the SIG.
             
             2. When I was handed the  SIG  Chair  job  two  years ago by Chuck Watson, we
                could see this process beginning, and  a  primary goal of mine has been to
                increase the organization of  the  SIG  enough  to  handle the increase in
                products and sophistication, but at  the  same  time, keep the same spirit
                and "fun" that has always been the trademark of this SIG.  We now interact
                much more with other SIGs, and  with the DECUS leadership than before, and
                the services that we provide have  increased, both in scope and in number.
                Through all of this though, we  have  tried to keep things spontaneous and
                open.
             
            To continue to do these  things,  we,  the Steering Committee, needs your con-
            tinued help.  We need contributions, both to this newsletter and to the Sympo-
            sia.  We also have a continuous  need for volunteers to help us with projects.
            But even more than all of  that,  I  in particular, need your ideas, your sug-
            gestions, your critical comments and solutions, and sometimes, just some reas-
            surance that we are going in  the  right  direction.  Letters are welcome, and
            should be addressed to DECUS to my attention.  Phone calls to the number given
            above are also welcome.
             
            Well, I think that is enough of  a  sermon for one time.  Have fun DATATRIEVE-
            ing, and we will see you in Anaheim in December.
             


















                                                                                         2






             
            ______________________________________________________________________________
             
            DATATRIEVE Wish List
             
            Bart Z. Lederman, Bankers Trust Company, New York, NY
             
            ______________________________________________________________________________
             
            A wish list is a method by which  the users can get their requests for changes
            or enhancements in a product back directly  to  the persons in DEC who work on
            the product.  The DATATRIEVE  wish  list is somewhat informal, being collected
            during the symposium up until Thursday  night,  when  a copy is given to a DEC
            developer. DEC then responds during the SIG closing session. The answers which
            follow are comments only, and  must  not  be  taken  as a commitment by DEC to
            supply any new feature, but in the  past most of the suggestions from the user
            community which appear useful or which  address a need not presently satisfied
            have ended up in the product. In some cases (though there were not too many of
            them this time), DEC will suggest an alternative solution to the same problem.
            DEC will also often point out that the solution to a problem depends upon some
            other software product, and it sometimes is  necessary to go to that group and
            let them know there is a  problem, though DEC sometimes passes the information
            on internally. Please note that anything labeled "Editor's note" is my opinion
            only, not DEC's.
             
                1. Allow PRO/DATATRIEVE to remotely access domains on a VAX.
             
                   Comment: Being seriously considered now.
             
                   Editor's note: DECNet for the PRO  was announced at this symposium, and
                   is naturally a prerequisite for remote access.
             
                2. Would like DATATRIEVE to  ready  "Batch  Retrieval" to allow reading of
                   records  without  preventing  update  access  (when  running  DTR  with
                   VAX DBMS).
             
                   Comment: Definitely being considered! (Some pieces in place with V3.0).
             
                3. Provide the following: EXTRACT ALL {PROCEDURES, RECORDS} ON file.typ
             
                   Comment: Good suggestion, worth considering.
             
                4. Would like to have a DTR  function to report on report statistics. This
                   would tell, for a report  generated,  the  number of records found, the
                   number of report pages generated, the size of the report, etc.
             
                   Comment: Good suggestion for Report Writer functionality.
             
                5. Provide "user friendly" linkage between  DECalc and DATATRIEVE. Then we
                   would have a Lotus 1-2-3 "emulator".
             
                   Comment: Good suggestion. We are aware  of the problem and want to stay
                   competitive.
             


            3






                6. Thanks for supervisor RMS.  Please  finish  the job and make an I-and-D
                   space DTR-11 for the PDP-11 and J-11.
             
                   Comment: we will pass this along to the DTR-11 developers.
             
                7. Support for scrolling regions in FMS would be nice.
             
                   Comment: not a trivial problem to  solve.  We'll look at it once again.
                   TDMS also difficult to solve.
             
                8. Be able to insert a variable name into the SET REPORT_NAME = variable.
             
                   Comment: Good suggestion for Report Writer functionality.
             
                9. Publish more information on PLOTs once  the plots have reached a stable
                   form.
             
                   Comment: Won't be done.  Plots  are  not  stable,  and we don't want to
                   limit future development by fixing the language.
             
               10. Other than PIE chart, be able to put a title on plots.
             
                   Comment: Good suggestion. Can be done with DECgraph.
             
               11. Even though the  QUADWORD  (DATE)  being  indexed  is  an RMS issue, it
                   effects DATATRIEVE.  It is important that  the QUADWORD be able to be a
                   key field.
             
                   Comment: it REALLY is an RMS issue,  and is expected to be supported in
                   VMS V4.0.
             
               12. Put the space shuttle back in the CDD.
             
                   We'll look at putting something other than the Wombat in the plots. Old
                   plots can be extracted from the 2.0 kit.
             
                   Editor's note: there was some  discussion  about plots having to be re-
                   moved due to copyright restrictions  on  the subjects. A suggestion was
                   made that a plot like the  "Snoopy"  plot that did something other than
                   just plotting (like memos) would be nice, and was noted.
             
               13. Include wildcards for the SHOW command such as SHOW AB*.
             
                   Comment: Good suggestion, worth considering again.
             
               14. Change the defaults for DEFINE FILE  command  so  that the files are at
                   least a little more efficient.
             
                   Comment: Good suggestion.  There  is  documentation describing usage of
                   RMS utilities. It has been given some consideration already.
             
               15. Improve the DELETE command in DATATRIEVE, i.e. DELETE DOMAINS.
             
                   Comment: basically the same idea  as the EXTRACT DOMAINS given earlier.
                   Worth considering.

                                                                                         4






             
               16. When a specific procedure with an  ACL (Access Control List) is edited,
                   that ACL is lost and a  default  one  given. Some way of not losing the
                   ACL after EDITing a procedure [is needed].
             
                   Comment: done in Version 3.
             
               17. Get a better, easier to use editor for PRO/DATATRIEVE.
             
                   Comment: probably won't happen.    Improving  the editor would probably
                   cost pool space.   Suggested  work-around  is to extract the definition
                   and use your favorite editor externally.
             
               18. PRO's are being  sold  as  workstations  in  VAX environments. However,
                   PRO/DTR and VAX DTR are not  fully  compatible.   All efforts should be
                   made towards moving these products closer, so data/models can be easily
                   ported back and forth.
             
                   Comment: technically not feasible.  There  was  some  work done in DTR-
                   11 V3 to close compatibility.  Adding JOIN would eat all pool space.
             
                   Editor's note: some discussion  followed,  where  it was suggested that
                   ADT on the VAX should produce  applications which would run on the PRO.
                   The comment was that this might  degrade the VAX environment, but would
                   be looked at. It was then  suggested  that the VAX have a compatibility
                   switch as is used in  some  other  languages,  so that the VAX could be
                   informed when it is going to target  for an 11 and when it is targeting
                   for a VAX, and this was noted  by  DEC. The response from the users was
                   that they would at least like all  applications which run of the PRO to
                   move to a VAX, but not necessarily vice versa.
             
               19. Variable length record support  would  be  a  great  help in DTR. (This
                   means without  the  OCCURS  clause,  such  as  having  text of variable
                   length).
             
                   Comment: good suggestion, worth  considering  again.  We are looking at
                   this for use with other products as well.
             
                   Editor's note: this is only a  guess,  but  it sounds like they need to
                   handle variable length text to  interface  to other DEC produces, which
                   increases the chances that it will appear, but don't quote me.
             
               20. [Allow] upper and lower  case  in  procedure  definitions. It was there
                   prior to DTR-32 V2.0, it makes for easier-reading code, etc.
             
                   Comment: Not quite  true.  The  first  time  a procedure was installed,
                   everything was converted to  upper  case. Subsequent EDITs could change
                   text to lower case.  The problem is quite difficult to solve.  V2.0 and
                   up requires all code to go  through the parser, which converts to upper
                   case, but also allows editing everything.
             





            5






               21. Allow logical name  for  node  and  access  control  in ready of remote
                   domain:
             
                       $ASSIGN NODE "user password":: DTR_NODE
                       DTR>READY YACHTS AT DTR_NODE 
             
                   Comment: Good suggestion, worth considering.
             
               22. Allow record selection expression on domain table definitions.
             
                   Comment: Neat. Good suggestion, worth considering.
             
               23. Compiled versions of procedures.
             
                   Comment: Probably won't be done. Very, very difficult.
             
               24. Support for RMS segmented keys.
             
                   Comment: Tricky. We'll look at it once again.
             
               25. TDMS validation criteria.
             
                   Comment: Tough to solve. We'll look at it again.
             
               26. Subscripted Variables.
             
                   Comment: Probably won't happen.  Would  require a drastic alteration of
                   DTR syntax. Has been looked  at  several  times  in the past, but other
                   application level solutions were found.
             
               27. I wish DATATRIEVE-11 would  give  more  information when it is inclined
                   now to say "Severe Error - Cannot Continue".
             
                   Comment: Need more information, will pass on to DTR-11.
             
                   Editor's note: some discussion  from  the  floor  indicated that it was
                   most  often  encountered  during  initialization,  and  sometimes  from
                   sorting.
             
               28. Put an index of all the  examples  in the documentation, so they can be
                   easily located.
             
                   Comment: Good idea, we'll pass this along to the documentation group.
             
               29. Need  capability  to  detect  NO MATCH  when  crossing  domains. Should
                   produce error and display "key" (over field).
             
                   Comment: We'll look at the  problem.  We don't think everyone wants it,
                   but will try to come up with  some way of resolving this kind of situa-
                   tion. Maybe we need some additional  levels of DEBUG [other than every-
                   thing on or everything off]?
             




                                                                                         6






               30. Add support for VT100 graphics in VAX DTR
             
                   Comment: probably won't happen.    Had  been  considered, might look at
                   what DTR-20 does and "steal" it from them.
             
            Additional suggestions were made  about  having  multiple forms. It was stated
            that this needs to be done by  the  forms handler, and that the suggestion has
            been passed on. 
             
             
            ______________________________________________________________________________
             
            From the Editor's Pen
             
            Joe H. Gallagher, Cleveland Clinic Foundation, Cleveland, OH
             
            ______________________________________________________________________________
             
            The editor's pen was passed to me at  the DECUS Spring Symposium.  It was with
            some reservations that I accepted this  responsibility.   It is a big job, and
            the community of  DATATRIEVE  users  has  come  to  expect  an informative and
            professional looking newsletter.
             
            We of the DATATRIEVE SIG own a great deal to the retiring editor of the Wombat
            Examiner, Virginia Sventek of  Lawrence  Berkeley  Laboratory, who, along with
            Cynthia (Curry) Mealy, edited the  newsletter  for  over three years from late
            1981  to  early  1984.    During  this  time,  the  Wombat  Examiner underwent
            significant increases in number of pages and quality of production.  On behalf
            of the DATATRIEVE family of users, may  I express our thanks and admiration to
            Virginia for a job well done.
             
            It is my aspiration that  the  Wombat  Examiner  will  again be published on a
            regular basis with four issues per  year.   The issues will roughly correspond
            to the seasons and should  appear  just  before  and soon after the spring and
            fall symposia meetings. 
             
            The activities of the  semi-annual  symposia generates sufficient material for
            two of the four issue per year;  however,  it is from you, the DATATRIEVE user
            community, that the remaining material  must  come.   DATATRIEVE with its wide
            range of machine implementations and  wide  range of applications can not help
            but create interesting, unusual,  and  unique examples, problems, and computer
            solutions.  It is  your  responsibility  and  duty  to share your triumphs and
            troubles with your fellow DATATRIEVE users.
             
             











            7






            ______________________________________________________________________________
             
            Wombat Magic Session
             
            Session Chairman: Bob Lott
            Transcriptionist: M. Iris Compton-Park
            Session Editor:   Joe H. Gallagher
             
            ______________________________________________________________________________
             
            Editor's note: The following  is  a  highly  edited transcription of the audio
            tape of the Wombat Magic Session at  the 1984 Spring DECUS Symposium in Cinci-
            natti, Ohio, which occurred on June 7,  1984.  Material which was presented on
            transparencies has been merged into  the  oral  presentations.  An attempt has
            been made to convey both the technical content of the Magic Session as well as
            the humor, covert  intellectual  swaggering,  and  spirited interchange of the
            presentations.  Material which appears  in  the text within square brackets []
            has been included to  improved,  I  hope,  the  understandability of this very
            accelerating Magic Session.    Special  acknowledgement  is  given to Ms. Iris
            Compton-Park, who works with Dick Azzi,  for her outstanding job in originally
            transcribing the audio tapes.
             
             
            Joe H. Gallagher, Cleveland Clinic Foundation, Cleveland, OH
             
            Here's the problem.  We have a dataset which maps (in both directions) employ-
            ees to projects; it's a  hierarchical  set.    But  that's not the real issue.
            Going with each project there is  an  abstract,  and the abstract can be three
            thousand to four thousand characters  long.    A  field of over three thousand
            characters just can't be managed very well on a screen.  Nothing in DATATRIEVE
            or FMS is very helpful for dealing with  textual data in blocks that big.  The
            magic is really due  to  our  programmer  analyst, Mario Guarracino.  Actually
            this is DCL magic, not so  much  DATATRIEVE.    Our solution goes "We do it in
            DATATRIEVE and if we can't figure out how  to  do it in DATATRIEVE we do it in
            DCL.  If we can't do it in DCL,  we beat someone about the head and ears until
            they do it in BASIC.  If we can't do it that way, we don't do it.  
             
            So here is how we got around the problem.  It's a little DCL command procedure
            [See DCL command file below] that  asks  the  user what project he is going to
            work on.  But first it deletes some things.  Since we did not want the user to
            worry about what that stupid  delete  error  message  was  (when a file is not
            present), we turn off all the messages  by  saying SET MESSAGE /NO...  - don't
            give any error messages.  Delete the  files, if they don't happen to be there,
            there is no message; then turn it back on the [error] messages.  Then ask them
            what is the project number.  If they  enter a blank, a null string, or a zero,
            the command file exits because they  are  done.  Otherwise it starts writing a
            file which happens to be a DATATRIEVE command file.
             
            [This file contains.]  Set abort,  ready the project domain, ready the indexed
            abstract domain for write, and  if  not any projects with project_number equal
            to project_number_entered_by_user then  abort.    If  not  any abstract in the
            index then store a dummy one there.   That  is,  put in the number and a blank
            abstract because they are going to enter one.  That is the end of that command
            - almost.  Then we are going  to  SET  COLUMNS_PAGE  = 60, and we are going to
            print out the abstract which is a  field variable in the domain abstract index

                                                                                         8






            with an EDIT_STRING IS T(60).   It  will  take that great big long abstract of
            over three thousand characters and  wrap  it around into manageable records in
            that sequential file; then we close the  file.  We then type something for the
            user (since some of these  processing  operations  take a while), like "WE ARE
            WORKING FOR YOU," and "BY THE WAY,  REMEMBER TO EDIT THINGS IN UPPER AND LOWER
            CASE." So, we now  have  this  command  file  ready  for doing things.  Before
            starting up the indirect command  file  with  the DATATRIEVE commands, we tell
            them 'WAIT - IT IS GOING  TO  TAKE  A  WHILE.' Then we redirect the startup of
            DATATRIEVE into a garbage file because we  do  not want them to know that they
            are in DATATRIEVE, and execute the file.   It goes in there finds the project,
            finds the abstract, stuffs it out  into  a  file.   In order to make sure that
            there was really a file, we go out  and check that there was one in case there
            wasn't because if it's not, we are going to branch out here to somewhere else.
            If there is a file there,  we  are  going to reassign the input and the output
            of the editor, and pop right  into  the DEC Standard Editor because the editor
            manages large blocks of text very  nicely.    This lets the user edit that ab-
            stract of undetermined  length  (actually  in  this  case about three thousand
            characters).  Then the fun  happens.    They  have  now edited this file which
            consists of records (each one usually less than 80 characters long).  In order
            to get back into DATATRIEVE, we have  to  go  and stick it all back in one big
            record.  Here's the little problem  we  couldn't easily solve [in DCL or DATA-
            TRIEVE] so we had to go to BASIC.
             
            1      ! BASIC program to put text into one record 
                   open "ABSTRACT.SEQ" for input as file #1%,  & 
                           organization sequential variable, recordtype any 
                   open "ABSTRACT.TMP" for output as file #2%,  & 
                           organization sequential variable, recordsize 2995% 
                   on error goto 500 
                   trec$ = "" 
                   while 1 
                           linput #1%,rec$ 
                           rec$ = edit$(rec$,16%+128%) + " " 
                           trec$ = trec$ + rec$ 
                           next 
            500    if err = 11 then resume 520 else 999 
            520    print #2%,trec$ 
                   close #1%,#2% 
            999    end 
             
            This  one  [EDIT$(...,16%)]  removes   all   multiple   spaces  and  this  one
            [EDIT$(...,128%)] removes all trailing spaces  and  then you take the text and
            put it all out on one big line.   Since the record size is very large that you
            are going to write, you  just  write  this  guy  out in one BIG, LONG straight
            line.  We could have probably  done  this  in  some other way but in this case
            neatness did not count,  it  was  fast  program  development time that we were
            after.
             
            Now that we have the thing strung out in a line and edited, we go back and ask
            the user "DO YOU REALLY WANT  TO  PUT  THIS  BACK IN?" because they might have
            made a mistake and want  to  change  their  mind.    If  they do, we go on and
            actually do something - we delete  a temporary command file and create another
            one; we ready [READY WRITE] the data base  we are going to stick it back into;
            we ready a temporary domain  which  is  this  one long record, find that thing
            with that particular project number, and  modify it to stick the abstract back

            9






            in.  And BINGO...  The whole command file is:
             
            $ wo :== write output ! make a shorthand notation for WRITE OUTPUT so the
            $                     ! command file below will fit on the page.
            $begin:
            $ set message/nofacility/noident/nosever/notext
            $ delete ABSTRACT.SEQ;*,SEARCH.COM;*,ABSTRACT.TMP;*
            $ set message/facility/ident/sever/text
            $ inquire PROJ_NO "Enter Project Number(enter 0 to Quit)^G"
            $ if PROJ_NO .eqs.  " " then exit
            $ if PROJ_NO .eqs.  "" then exit
            $ if PROJ_NO .eqs.  "0" then exit
            $ open/write output SEARCH.COM
            $ wo "SET ABORT"
            $ wo "READY PROJ"
            $ wo "READY ABSTIDX WRITE"
            $ wo "IF NOT ANY PROJ WITH PJ_NO =",PROJ_NO," ABORT "
            $ wo "IF NOT ANY ABSTIDX WITH PJ_NO=",PROJ_NO," STORE ABSTIDX USING BEGIN"
            $ wo "PJ_NO = ",PROJ_NO
            $ wo "END"
            $ wo "SET COLUMNS-PAGE = 60"
            $ wo "FOR ABSTIDX WITH PJ_NO=",PROJ_NO," PRINT ABSTRACT(-) ON ABSTRACT.SEQ"
            $ wo "EXIT"
            $ close output
            $ type sys$input
                   Stand by ....I'm Trying to find the ABSTRACT.  If there is one
                   I'll display it and you may proceed to make changes.  If not
                   you may begin to enter the New abstract as soon as I put up a
                   blank screen.
             
                   While we Wait let me remind you to use UPPER + lower case Format
            $ assign/user GARBAGE.FIL sys$output
            $ assign/user GARBAGE.FIL sys$error
            $ dtr
            @SEARCH.COM
            $ open/read/error=noproject abstract ABSTRACT.SEQ
            $ close abstract
            $ assign/user tt: sys$input
            $ assign/user tt: sys$output
            $ edt ABSTRACT.SEQ !editing is a quick way to change the file type
            $ run packrec ! let the BASIC program restructure the data
            $ inquire ANSWER "Shall I Proceed to Update the ABSTRACT?^G^G"
            $ if ANSWER .eqs.  "Y" then goto doit
            $ type sys$input
                   NOTE: Abstract Not updated!!!!!!!
            $ goto begin
            $doit:
            $ delete TUPDATE.COM;*
            $ open/write output TUPDATE.COM
            $ wo "READY ABSTIDX WRITE"
            $ wo "READY ABSTRACT_TEMP READ"
            $ wo "FIND A IN ABSTRACT_TEMP"
            $ wo "SELECT"
            $ wo "FOR ABSTIDX WITH PJ_NO=",PROJ_NO," MODIFY USING ABSTRACT=TABSTRACT"
            $ wo "FINISH"

                                                                                         10






            $ wo "EXIT"
            $ close output
            $ type sys$input
               Stand by ....I'm Updating the ABSTRACT^G
            $ assign/user GARBAGE.FIL sys$output
            $ assign/user GARBAGE.FIL sys$error
            $ dtr
            @TUPDATE.COM
            $ delete GARBAGE.FIL;*
            $ type sys$input 
                   ** Abstract Updated **
            $ goto begin
            $noproject:
            $ type sys$input
               NOTE:   You must Enter the Project Information before
                       you will be allowed to enter an Abstract^G
            $ goto begin
            $end_job:
             
            That is the command file we  have  written  and then we go into DATATRIEVE and
            actually do it and collect garbage, tell the user we have updated the file and
            go back and ask it for the next abstract.
             
            Now, this is not very neat; it is not  very pretty; it is not very fast.  How-
            ever, it works.  Since they only have to do a few hundred [abstract updates] a
            year, it works well enough  and  the  gal  who  enters the data in DATATRIEVE,
            already knows how to use the editor.    Neatness does not count if it gets the
            job done.
             
            The idea is the most important thing,  not  the details.  There are a bunch of
            possible extensions.  One could  have  done  this  all inside of DATATRIEVE by
            writing the appropriate functions and getting  it  done.  That would have been
            nice except we did not want  to  take  the  time  to  do it.  We did this very
            quickly.  One could also do  this  on  multiple  fields, so you are not really
            limited to one field, you can take  a  bunch of fields, write them out, and do
            it this way.  The problem of doing it as a subprocess comes when managing that
            one problem of restringing all the records  back together.  That is the little
            tricky part.
             
             
            Chris Hines, American Board of Family Practice, Lexington, KY
             
            A little bit of anti-magic  first.    Basically,  what happened was I had this
            file that I had to read;  it  was  written  from  FORTRAN.  This is a MORALITY
            TALE; if you look for trouble, you will  find  it.  You could say that this is
            an object lesson in how having  32-bit virtual machines with lots of resources
            - basically there is no limit to  the  amount  of time you can spend doing ex-
            tremely stupid things...  I would like  to point out to you that DATATRIEVE is
            usually extremely willing to help you in this quest.
             
            The problem I had was that someone  presented me with this ASCII file that had
            been formated by FORTRAN.  Right away  all my years - many years of experience
            paid off and the alarm bell started  ringing.   I said "I remember about three
            years ago in a DATATRIEVE session  some  guy  was saying he really had trouble
            reading a FORTRAN format ASCII file."   I  thought about it and said "Yea, you

            11






            are going to have trouble,  because  if  you  got  an I3 format, FORTRAN blank
            fills those, and if you tell DATATRIEVE that  it's a PIC 999, you are going to
            get one of  your  most  favorite,  second  only  I  think  to  -  what is it -
            '"field_name" is undefined or used out of context.'" How many people have ever
            gotten that....  [growns from the audience]   You get our second most favorite
            error message which is 'Illegal ASCII  numeric'."   Has anyone ever seen that?
            [boos from the audience] I spent a lot of time trying to decide whether I like
            the "Illegal ASCII numeric"  better  or  its  COBOL  cousin - "invalid decimal
            data".  It is really kind of a toss up - but COBOL is kind of more spectacular
            when you get it because it is followed by a stack dump.  In DATATRIEVE all you
            get is it zeros your variable - that is not particularity interesting.
             
            Anyway - I said "Yes, that is going to give you problems, same thing with an F
            [FORTRAN format] so that is going to be  out there as -1.23, and I am going to
            tell DATATRIEVE that is some kind  of  field  and  it is not going to like the
            minus, it does not like the  [decimal]  point;  if there are any blanks, it is
            not going to like those."  I  said  "Holy  Moses".  I figured that surely with
            one of the 453,000 functions I had built into DATATRIEVE, I could handle it.
             
            Before I submit my SPR, I will  first  verify  that  I have a problem.  I said
            "Lets just try it straight up" and  the  name of this variable is RVAL - short
            for R VALUE - that is  a  statistical  measure  used for items on a test which
            tells you that - depending on its value  tells you that - all the smart people
            got the item wrong and that all  the  dumb  people got it right.  It makes you
            kind of -- well -- you look at those items a little bit strange.
             
            I said, "It's PIC S9V99" and sure enough, I fed that to DATATRIEVE - and I got
            "Illegal ASCII numeric" and not only  that  but the record comes out the wrong
            length.  The V does not hold  any  space  - that's a virtual period and in the
            FORTRAN format record it does indeed hold a space.  At that point, I said "Ok,
            time to whip out the functions".  I  broke  this thing down - I said "Ok, I'll
            put the sign in one variable and  then  I'll get my one digit another variable
            and I put a filler for the period  and  I will pick up the fraction point in a
            PIC 99."  This looked good.    Then  I  said "Let's put it all together here."
            And there it is.  Isn't that a thing of beauty.
             
               03 RVAL_STR.
                  05 RVAL_S pic x.
                  05 RVAL_1 pic 9.
                  05 filler pic x.
                  05 RVAL_2 pic 99.
               03 RVAL pic s9v99 real computed by ((fn$delta(RVAL_S,'-') * -1) +
                   fn$delta(RVAL_S,' ')) * (RVAL_1 + (RVAL_2/100)).
             
            FN$DELTA is a function I built in.   I was originally a physicist by training,
            it was affectionately named after the Kroniker's Delta function.  Since then I
            have wished about four  million  times  that  I  had named the thing FN$EQUALS
            because this function, you give it two values and it returns a "1" if they are
            equal and a "0" if they are not.   Now there has been a lot of past magic done
            with doing that same type of  thing  through  tables and I thought about doing
            some magic with that, but, of course, that has been obsoleted by the fact that
            you can now do the IF-THEN-ELSE's  in  COMPUTED  BY variables.  Anyway, if the
            two things are equal it gives  you  one,  if  the  two things are not equal it
            gives you zero.  So here we  are  checking  the  sign and then if it is a dash
            [minus sign] we are going to multiply by  minus  one, if it is a space, we are

                                                                                         12






            going to return a 1, so we  are  going  to  multiply by one and then the whole
            part of the number and then the  fracture  part of the number.  I plugged that
            in there and LO AND BEHOLD.   It  worked,    and  I looked upon it, and it was
            GOOOOOD! I was really pleased with this because it did the job but at the same
            time, you know, you look at  that  thing and, you know, that nobody reasonably
            sane is going to figure out what it is doing, you know, in less than about ten
            man year.  I was really pleased  with  it,  but  then I got to looking at it a
            little  bit further and I said "HOLD  ON, WAIT A MINUTE!  I am implicitly let-
            ting DATATRIEVE convert a  string  into  a  number  there,  aren't I?"  Then I
            thought about it a little bit  more  -  I  realize that DATATRIEVE does a real
            nice job  of that, in fact  that  FN$DELTA function does a compare [of 5 char-
            acters] on the strings.   You  tell  DATATRIEVE  that the things coming in are
            strings, it does a compare character  and  you  can pass it almost any kind of
            data and I have never had it not  work, so I think that DATATRIEVE does a real
            good job with its string conversion.
             
            I decided to try something perhaps a little more simpler [sic].  I said "Let's
            declare this string PIC X(5), and let's  take the floating point number - same
            definition - real just computed by a string."
             
               03 RVAL_STR pic x(5).
               03 RVAL pic s9v99 real computed by RVAL_STR.
             
            Guess what?  It works.  Works  just  great.    So if you ever have any problem
            with formated FORTRAN - that is the way you do it.
             
            Now that was not really that great anti-magic, I'd say I only wasted a half an
            hour playing around with  this  stupid  thing,  but  I think that the steering
            committee should seriously consider having  an  award for magic and anti-magic
            also because, I guess that is kinda like your basic horror story isn't it?
             
            Now this is real magic, this is pretty  simple, I do not know if this has been
            discussed before or not - but this has to  do with some of the uses of the "T"
            edit string.  One of the nice things I found out that the "T" edit string does
            is that you can use it to compress white space.
             
               03 name pic x(30).
               03 address_1 pic x(30).
               03 address_2 pic x(30).
               03 city_state_zip pic x(30).
             
            So you have your name, address[es], city/state/zip like you put on labels, and
            you are going to put them in a  report,  and you want to squeeze all the white
            [blank address lines] out of them because some of them are going to be blanks,
            and you do not know which one[s].    Now  you  can do an 'IF THIS ONE IS BLANK
            THEN DONT PRINT" and all of that,  but  what  worked out pretty good is if you
            just do this one thing 
             
               print col 1, name using t(30),
                     col 1, address_1 using t(30),
                     col 1, address_2 using t(30),
                     col 1, city_state_zip using t(30)
             
            and what it will wind up being is that the white space will be compressed out.
            I do not know why it works, but  it  does.    You can also use it - it is real

            13






            nice, if you have your occurs clause because say you have this OCCURS 10 TIMES
            PIC X(n) EDIT_STRING T(n).  When you go  to print that thing out, it will com-
            press the white space out, so any  of  them that are blanks won't print up and
            it saves you a whole lot of paper.    If  you have big occurs but don't have a
            whole lot of elements  in  them.    Now  there's  a  little tiny thing that is
            strange there -- and that is in the case where there is only one value that is
            non-blank, it gives you  a  blank  line  after  it.    If there's two or three
            values, it prints two, three values and  no  blank  line.  But if there is one
            value there it gives you blank line after  that line.  I have never sent in an
            SPR on this because my feelings were  that this was never suppose to work this
            way in the first place anyway, and if I ask them to fix it I know it would all
            go away!!  [laughter for audience]  This is useful on occasion.
             
             
            Bernice Packer, Smith, Cline, and Beckman
             
            I was placed in a difficult  situation  recently.   I was given an application
            for Human Resources Employee Database and one of the major reports that had to
            come out of it had to appear on pre-printed forms, 15 inches across, and I was
            not involved at all in the planning what the report would look like.  In other
            words,  I was given boxes of  paper  where  I had to fill in the actual blanks
            that were there.  I had the actual inches that had to be done on there and was
            told to do it in DATATRIEVE  for  political reasons.  [Laughter from audience]
            All the information was  contained  in  RMS  domains  that were related with a
            common keys so that it could  have  been  done in DATATRIEVE or any other pro-
            gram[ing language] that could read RMS -  say  BASIC.  The theory was that you
            can do things  in  DATATRIEVE  faster,  so  I  used  DATATRIEVE.   Some of the
            anomalies that you will notice on this reporter is that you have some occurs -
            I am trying to note  in  the  boxes  the  fields  that are occurs clauses, for
            instance, for each employee you have several education records, several train-
            ing, previous jobs, salary history, etc,    but there is no guarantee that you
            will have any records or more than  the  number of records allowed per box for
            any of those employees.  [Editor note: The follow is a very, very rough repre-
            sentation of the hand drawn representation of what is obviously a very compli-
            cated form!]
             




















                                                                                         14






               ________________________________________________________________________
              | Name                               | Employee Info                     |
              | ____________________   ___________ | _______|________|_______|______   |
              | First Middle Last        Emp. No   |  Superv Pay-Type Pay-hrs  Dept    |
              | __________________________________ |                                   |
              | address line 1                     | Salary History                    |
              | __________________________________ |  _______________________________  |
              | address line 2                     | | Date  Chg Typ  %incr  New sal | |
              | _____________  _________ ________  | | ____  ________ _____  _______ | |
              |    city          state     zip     | | ____  ________ _____  _______ | |
              |                                    | | ____  ________ _____  _______ | |
              |      [OTHER GENERAL FIELDS]        | | ____  ________ _____  _______ | |
              | Education                          | | ____  ________ _____  _______ | |
              |  ________________________________  | | ____  ________ _____  _______ | |
              | | University     Year   Degree   | | |_______________________________| |
              | | _____________ _____ __________ | | Appraisal History                 |
              | | _____________ _____ __________ | |  _______________________________  |
              | | _____________ _____ __________ | | | Date  Apprtype ApprRdy Promte?| |
              | | _____________ _____ __________ | | | _____ ________ _______ ______ | |
              | |________________________________| | | _____ ________ _______ ______ | |
              | Training                           | | _____ ________ _______ ______ | |
              |  ________________________________  | | _____ ________ _______ ______ | |
              | | Organization    Date  Duration | | | _____ ________ _______ ______ | |
              | | _______________ _____ ________ | | |_______________________________| |
              | | _______________ _____ ________ | | Succession planning history       |
              | | _______________ _____ ________ | |  _______________________________  |
              | | _______________ _____ ________ | | | Date due   RespPer    Action  | |
              | |________________________________| | | _______  __________ _________ | |
              | Previous Jobs                      | |                     _________ | |
              |  ________________________________  | |                     _________ | |
              | | Organization   Pos   Start End | | | _______  __________ _________ | |
              | | ______________ ____  ____ ____ | | |                     _________ | |
              | | ______________ ____  ____ ____ | | |                     _________ | |
              | | ______________ ____  ____ ____ | | |_______________________________| |
              | | ______________ ____  ____ ____ | |                                   |
              | |________________________________| |        [OTHER EMPLOYEE INFO]      |
              |      [OTHER EMPLOYEE INFO]         |                                   |
              |               [ETC]                |                [ETC]              |
              |________________________________________________________________________|
             
            You will also notice that as you go  across the page, there is no real consis-
            tency between where the boxes fall  on  the  page.   For instance, I can't say
            PRINT THE FIRST EDUCATION  RECORD  AND  THEN  THE FIRST SALARY HISTORY RECORD.
            This will take - like 20 minutes to  describe - but it is really magic the way
            it did it, and it has a lot  to  do  with the big view over about about twelve
            different domains.  
             









            15






               DEFINE DOMAIN EMPLOYEES_REPORT OF EMPLOYEES, EDUCATION, TRAIN,
                   PRE_JOB, SALARY_HIST, APPRAISAL, SUCC_PLAN, SICK_DAYS USING
               01  REPORT_ENTRY.
                   03  ENTRY FROM EMPLOYEES.
                   03  EDUCATION_RECORDS OCCURS FOR EDUCATION WITH
                       EMP_NO = EMPLOYEES.EMP_NO SORTED BY DESC YEAR.
                       05  entry FROM EDUCATION.
                   03  TRAIN_RECORDS OCCURS FOR TRAIN WITH
                       EMP_NO = TRAIN.EMP_NO SORTED BY DESC TRAIN_DATE.
                       05  entry FROM TRAIN
             
                    etc ad nausium
             
            I define a domain  called  EMPLOYEES_REPORT  over  employees which is the name
            domain in the system  and  all  the  other domains like EDUCATION, TRAIN[ing],
            PRE_JOB, etc which all are indexed with  the employee number key.  And then in
            this view each subrecord in the view other than the first one, which is actual
            entry from EMPLOYEES domain  contains  an  occurs  clause of the records drawn
            from each of the other domains  that  have the employee number key matching so
            that you  have occurs lists for each one.   Also you will note that there is a
            SORTED BY at the end of each one.   The specification was that it had to be in
            descending date order which  makes  it  even  more interesting.  Another thing
            that was interesting was  that  there  was  a  bug  in  one  of the field test
            versions of DATATRIEVE for a while that  ignored that sorted by syntax when it
            was within a view and  that  was  recently  corrected.   That was THE bug that
            affected this report.  So what ended up happening was that I created two sepa-
            rate report files, one for each half  of the report [left half and right half]
            and then I was faced with  the  problem  of  blank lines.  If there were fewer
            than the proper number of records  to  fill the box, obviously DATATRIEVE, be-
            cause of the problem  the  previous  gentleman  mentioned  [See second part of
            Chris Hines's Magic], does not give you  the  right number of blank lines.  So
            using the wonderful choice clause we  have  recently received, I would have to
            do a count on each occurs clause to  see how many records I had and then print
            the proper number NOT of  blank  lines  but  of  lines filled with dummy char-
            acters.  Then I had another  procedure  in DATATRIEVE that concatenate the two
            reports together, looking for the dummy  character lines to insert blank lines
            instead.
             
            It worked beautifully.  I did  twelve  hundred  employees.  That is the entire
            R&D population of Smith, Cline and Beckman on these pre-printed forms.  Nobody
            believed that it was done in DATATRIEVE.  When I still show it to people, they
            don't believe it was DATATRIEVE.  [Applause!]
             
             
            Stewart French from Wausen[??] Financial
             
            This is really an anti-magic.  I  was  wondering if anybody could help me with
            it.  Before I came here I upgraded  DATATRIEVE from 2.1 to 2.2 and I looked at
            our TDMS forms that pull  up  some  real  numbers and all the numbers appeared
            multiplied by ten (10).    I  called  DEC  Software  Services up and they said
            "Well! it looks like you  found  a  bug."  I  said "Thank You".  [laughter and
            applause]  I've been going around  all  week  trying  to find out what it is -
            TDMS blames it on DATATRIEVE, DATATRIEVE blames  it on TDMS.  [The question is
            put to the audience for them to  think  about  it and advise if they know what
            the problem is.]

                                                                                         16






             
             
            Larry Jasmann, U. S. Coast Guard, New Orleans, LA
             
            Ok, I have a little bit of magic.    Maybe  I have a soap box, but basically I
            feel that some magic should be presented that is not really super fancy and is
            designed to show that some things  can  be  done that aren't really as hard as
            they seem to be.  About a year ago, I became stuck on the call interface and I
            like to play around with it.  The thing that I decided to present tonight is a
            little call interface thing which - you guys are probably going to throw rocks
            at me, but there is even a BASIC program that does it.
             
            The whole point is, is that  if  you  read  the documentation and you read the
            stuff on the call interface and after  you have read about the fifteenth stall
            point, you say "Good grief, how  can  I  even do anything with the call inter-
            face?  It seems to be awfully  complicated."   Well, here's the thing.  What I
            want to show you tonight is  the  fact  that the call interface is not compli-
            cated; it is really easy.  If  you  just  take  a few things out of there, and
            follow them, it works pretty doggone nice.  It can do some nice things.
             
            What I have is a situation where  I  want to have a totally menu driven appli-
            cation.  I want them to NEVER see the  DATATRIEVE prompt.  I want it to be  so
            that if they are inside a procedure  they can't exit outside of the procedure.
            If they do a CONTROL C, I want it  to  all go away or trap it back to the pro-
            gram - whatever you want to  do,  but  I  just  don't want them to ever get to
            DATATRIEVE.  I just want to  lead  them  by  the nose through the whole thing.
            One way of doing that is with the call  interface.  Now, you can do menus - it
            does not make any difference.  You  can  use FMS, TDMS with this; it all works
            the same.  The big problem with just doing menus in DATATRIEVE though is, that
            if you want to do it  without  having  anything to get to DATATRIEVE, you have
            essentially front load the whole thing  and  compile the whole thing right off
            the bat when you call the menu.  That can take a long time and besides -- when
            you are down in the middle of a  BEGIN-END loop and it gets sort of yucky try-
            ing to do things - not that it  can't  be  done, but who likes to start up the
            procedure and then go get a cup of  coffee and come back  fifteen (15) minutes
            later before you start doing things?.   [This is the BASIC program ]... and it
            is really pretty simple. [The  BASIC  program  below is displayed. Growns from
            the audience followed.]
             
             
















            17






            1      ! M E N S H R T . B A S                                               &
                   !                                                                     &
                   !   This program demonstrates a way to do a complete menu             &
                   !   driven application in DTR using the call interface                &
                   !                                                                     &
                   !   By:     L. M. Jasmann                                             &
                   !   Date:   14 May 1984
             
            100    %INCLUDE "DTR$LIBRARY:DAB"  ! include the DAB
            110    MAP(BUFF) STRING OPT = 10   ! buffer for the port
             
            190    ! declare the init and terminal server calls as function              &
                   EXTERNAL INTEGER FUNCTION DTR$INIT, DTR$DTR                           &
                   ! declare the exit and normal status.                                 &
                   EXTERNAL INTEGER CONSTANT DTR$_EXIT, SS$_NORMAL                       &
                   DECLARE INTEGER INIT_OPTIONS, DTR_OPTIONS, RET_STATUS                 &
                   ! assign the initial option                                           &
                   INIT_OPTIONS = DTR$K_SEMI_COLON_OPT                                   &
                    + DTR$K_UNQUOTED_LIT                                                 &
                    + DTR$K_FORMS_ENABLE                                                 &
                   ! initialize the interface
             
            500    RET_STATUS = DTR$INIT(DAB BY REF, 100% BY REF, MSG_BUFF,              &
                           AUX_BUF, INIT_OPTIONS BY REF)                                 &
                   ! check to see if DTR was initialized                                 &
                   IF RET_STATUS <> SS$_NORMAL THEN                                      &
                       PRINT "DATATRIEVE init failed"                                    &
                           GOTO 7000                                                     &
             
                   ! call the terminal server
            2400   ! go to the menu
            2405   ! set dictionary                                                      &
                   CALL DTR$COMMAND(DAB BY REF, "SET DIC MENTST")
            2407   ! clear message for buffer                                            &
                   CALL DTR$DTR BY REF (DAB,DTR$M_OPT_CMD)
            3910   ! call the menu                                                       &
                   CALL DTR$COMMAND(DAB BY REF, ":MENU")
            3920   ! this allows the terminal server to run the procedure                &
                   CALL DTR$DTR BY REF (DAB,DTR$M_OPT_CMD)
            3921   ST$ = "STORE PT USING OPT = QST VIA TRANS_TBL"
            3923   ! This puts the next procedure to be run into the port so             &
                   ! that it can be access by the program (opt)                          &
                   CALL DTR$COMMAND(DAB BY REF,ST$)
            3925   ! This gets the stuff put into the port into the program              &
                   CALL DTR$GET_PORT BY REF (DAB,OPT)
            3926   ! This clears the message from the buffer                             &
                   CALL DTR$DTR BY REF (DAB, DTR$M_OPT_CMD)
            3928   ! If done, exit the subroutine else execute the procedure             &
                   IF OPT = "DONE" THEN GOTO 6000 ELSE                                   &
                   CALL DTR$COMMAND(DAB BY REF, OPT)
            3925   ! Now call dtr$dtr to run the procedure, when done, back to menu      &
                   CALL DTR$DTR BY REF (DAB,DTR$M_OPT_CMD)
            3940   GOTO 3910
            6000   CALL DTR$FINISH BY REF (DAB)
            7000   END

                                                                                         18






             
            This statement [at 100], right  here,  does  an  INCLUDE, and what that is, is
            that it includes something called the  DAB.    And  the DAB is a little buffer
            that tells  all the little goodie  things that have to happen between the pro-
            gram and DATATRIEVE so that they  can  keep  themselves straight.  You go down
            here [at 190] and you declare some  options  for when you are going to open up
            DATATRIEVE.  You come  down  to  here  at  this  point  [at 500] where it says
            'RET[urn_]STATUS = DTR$INIT' - that kicks DATATRIEVE in the tail and says "Get
            moving, it is time to go here" - [and] gets DATATRIEVE running.
             
            [Question from  Bob  Lott]  "Is  that  a  performance improvement?" [Jasmann's
            answer]  Well, that is just a little newdge [nudge] to make it go to work.
             
            At this point in the program  I  call  DTR$COMMAND and set a dictionary into a
            dictionary [at 2405] and that is  just  because  I was using a test dictionary
            and I did not want to muck  up  my regular dictionary.  [Note that] every time
            you do a DTR$COMMAND you have to  do  something afterwards to clear out a buf-
            fer, which DATATRIEVE comes back and tells the program that I [DATATRIEVE] did
            what you wanted to do successfully or else I  did not.  The easy way to do it,
            although probably not the cleanest is  just  to call DTR$DTR [at 3920], and it
            will just flush it right out.   So  you will see this happen several times [at
            3920, 3926, and 3935] where you would  otherwise not think it was necessary to
            do anything.  The next thing  that  it  does is it calls DTR$COMMAND [at 3910]
            and it calls a procedure called MENU and this is the procedure that is actual-
            ly going to paint the menu.  Here is the procedure MENU.
             
                   delete menu;
                   define procedure menu
                   set abort
                   declare qst pic x.
                   ready pt write
                   Print "This is the main menu", skip 2,
                       col 5,"1.       Option 1",
                       col 5,"2.       Option 2",
                       col 5,"3.       Option 3",
                       col 5,"4.       Done", skip 2
                   qst = *."1, 2, 3, or 4"
                   end_procedure
                   
            All it does is declare a variable which has a PIC X.  It readies PT (now PT is
            a port). If you look right here  it  says  "I  have a record PT_REC and a port
            (DEFINE PT USING PT_REC).  So all  that  is  is a little port which just looks
            like a regular ol' domain only it is called a port.  
             
                   delete PT;
                   define port PT using PT_REC;
                   
                   delete PT_REC;
                   define record PT_REC using
                   01  pt_rec.
                       03  opt     pic x(10).
                   ;
            It prints the menu, and it asks "[in the variable] QST [for QueSTion]  - WHICH
            OPTION DO YOU WANT - 1, 2, 3, OR  4" for whichever option you want to do.  And
            then the menu goes away and that is all that it has to do.

            19






             
            After it does that, after you call DTR$COMMAND, and you tell DATATRIEVE to run
            the menu, and you call DTR$DTR  [it]  calls the terminal server and allows the
            menu to [be] display[ed] on the screen,  and  asks  you for a variable - for a
            prompt for the value for QST.  The  next  thing that I do, is do a DTR$COMMAND
            and I use the contents of this  variable  which  says STORE PT USING OPT = QST
            VIA [the] TRANS_TABLE.   TRANS_TABLE  is  a  little  domain table and the only
            thing it does is, it just relates  the  number  that was one of those four (4)
            numbers in the menu to a particular procedure name.
             
                   delete trans;
                   define domain trans using trans_rec on trans.dat;
                   
                   delete trans_rec;
                   define record trans_rec using
                   01  trans_rec.
                       03  num             pic x.
                       03  pro             pic x(10).
                   ;
                   delete trans_table;
                   define table trans_table from trans using
                   num : pro
                   end_table
                   ;
                   
                   ! [The following three procedures would be helpful]
                   ! [in testing the call interface with the BASIC program]
                   !
                   delete test1;
                   define procedure test1
                   declare foo             pic x(10).
                   print "This is TEST1"
                   foo = *."foo"
                   print foo
                   end_procedure
                   
                   delete test2;
                   define procedure test2
                   declare foo             pic x(10).
                   Print "This is TEST2"
                   foo = *."foo"
                   print foo
                   end_procedure
                   
                   delete test3;
                   define procedure test3
                   print "This is TEST3"
                   end_procedure
                   
            After you have done that, you do  a DTR$GET_PORT [at 3925] and a GET_PORT just
            takes that stuff which is the procedure  that was referenced by the number and
            pulls it in the port in DATATRIEVE, actually at the DATATRIEVE end that stuffs
            it in the port, -- NO.  The ST$  stuffs it in the port [at 3923], the GET_PORT
            pulls it out of the program and at that point the variable OPT equals the name
            of the procedure you want to call.    The  next  thing you do is you clear the

                                                                                         20






            message from the buffer again  [at  3926].    If OPT=DONE which was the fourth
            option, then the thing exits,  otherwise  you  do  a DTR$COMMAND, and what you
            tell it to do is  OPT  which  is  the  name  of  the procedure.  Then you call
            DTR$DTR [at 3935] which runs the procedure  or  whatever it is you want to do.
            And when it exits, it goes back and calls the menu again.
             
            Really what you are doing is you  just  have a program, and the menu procedure
            essentially tells the program what  procedure  you  want  to run next, and the
            program turns around and tells DATATRIEVE  to  run the procedure.  The program
            never has to know what procedure is going to be called next so you can use the
            same program without re-compiling essentially in any situation just as long as
            you have a procedure named MENU -  as  you put something back through the port
            it will do whatever you tell it to  do  next.  The whole procedure is about 30
            lines of BASIC.  It is very,  very  simple  BASIC.   If you can do this with a
            call interface, you have done enough  so  that  you can do just about anything
            else that you want to do.  You  can elaborate on this with UDK's [user defined
            keys] and all sorts of things.   The  main  point  is that it is very nice for
            menus and it is very easy to  do  and  the call interface isn't all that hard.
            [Applause] 
             
            [Question from the floor from  an  unidentified  speaker]   "I have a question
            pertaining to DATATRIEVE-11 concerning that.   First of all due to the incred-
            ible speed of DEC Direct I  don't  have any DATATRIEVE[-11] Version 3 documen-
            tation, but I cannot find where I get the DATATRIEVE access block  definition.
            I want to do this out  of  BASIC  PLUS  2 and DATATRIEVE-11 and my question is
            where is the DATATRIEVE access  block  definition,  and  can I do the %INCLUDE
            like you did?"  [Jasmann's Answer]  "I  don't  think you are going to get this
            done in DATATRIEVE-11."  [Questioner from the floor] "Yes, you can do it now."
            [Several  others  from  the  floor]    "Yes,  there  is  a  call  interface in
            DATATRIEVE-11 Version 3. [Other speaker] "You  have  to copy it right out of a
            book" [Bob Lott] For those of you  who might not have heard that answer, Terry
            commented that he did not  know  exactly  where  the  DAB  was but that a call
            interface is on the 11.  [Another unidentified questioner] "Terry, my question
            is can I have two DAB's in my  program?"  [Terry  ] "I am not too sure why you
            want to use two DAB's but the way  I  use two DAB's is to have two independent
            record streams.  You do two  DTR$INIT's  on the DAB's and have two independent
            records streams."  [Questioner] "The reason  why I wanted two DAB's is because
            I need a DAB for each node of DATATRIEVE-11."
             
             
            Phil Naecker
             
            I have a simple and relativity mundane  magic.   How many of you have tried to
            use callable DATATRIEVE?  And have any  of you tried to write function defini-
            tions?  For those of you who haven't tried to write function definitions - the
            reason maybe that you cannot figure  out,  in  every case, how to generate the
            function definition file, that is - how to extend the DATATRIEVE at the bottom
            and add functions into it.  So  I called my magic "Programming in VAX 11 DATA-
            TRIEVE or The DATATRIEVE to MACRO Code  Generator" because that is what we do.
            As everyone well knows, it was  Bell  Labs  that  did a study awhile back that
            said that on the average of the  time, there were two lines of codes generated
            in any language per man-day, or as  I  like to say one before lunch and after.
            Knowing that I have discovered that is  was  much easier to fill in forms.  By
            putting in the forms with the right fields -- answering the fields and putting
            the right data in I could write  MACRO  which I cannot write in any other way.

            21






            I sat down and wrote a record  definition  for the function.  I think the guys
            in [doing] the DATATRIEVE documentation  [group]  have done the same thing, it
            is not very difficult to do.  You make  a record that has all the fields in it
            that are required in the  DTR  function  definition file.  These are basically
            things like the function name that you are going to add, and the external name
            of that function, and the subroutine that you add, and a few other things like
            that like how many arguments, and what kind of arguments the are.  That is not
            terrible difficult, you write a record  definition.   I will go ahead put that
            into the DATATRIEVE SIG library.  You make a domain with functions and actual-
            ly you can even do a make  a  domain functions using functions on FUNC.DAT and
            put a form definition in there if you would like, which is what I like because
            I can type on forms very easily and make mistakes and backup when I am writing
            in MACRO. 
             
                   define domain functions using function on funct.dat;
                   define record function using
                   01  data.
                       03  function_name   pic x(32).
                       03  external_name   pic x(32).
                       03  number_of_args  pic 99.
                       03  . . .
                   ;
             
            So - the next step is trivial - I  did  not put it all on the overhead, I will
            submit it to  the  SIG  again,  but  basically  you  define a procedure called
            BUILD_DTRFND, you ready the  functions  domain,  for those FUNCTIONS SORTED BY
            FUNCTION NAME BEGIN PRINT.  In your  print statement there is a fairly compli-
            cated set of IF-THENs and choices  and  stuff  like  that.  It is not all that
            difficult and what comes out of it is what looks like MACRO.  If you have ever
            read the DATATRIEVE-32 callable manual at the  back there is an example of all
            the MACRO in there that  one  has  to  be  a  MACRO programmer to generate it.
            Since I do not know how to  do  that very well and can't reliably remember all
            the options, I wrote once a DATATRIEVE  definition that did all the rules that
            they gave me and I simply program all of my DATATRIEVE functions by forms now.
            [Applause]
             
             
            Diana Washburn, Hanes Hosiery, Winston-Salem, NC
             
            This is a little bit of magic I don't know if you can read this very well now,
            but I will tell you real quick  what  it  does.   This one is dedicated to SPR
            people.  This is the old problem of  having a number starting with a zero in a
            key field even if it is PICTUREd X.  There are a couple of problems here.
             
                   DTR> FOR CUST WITH OUTLET = 00006,00013,90014,90017,27652
                   [Looking for statement]
                   CON> PRINT OUTLET, REGION
                   
                   OUTLET REGION
                   
                   90014    99
                   90017    99
                   27652    01
                   
            One - and you will notice that  this  first  thing says FOR CUST WITH OUTLET =

                                                                                         22






            and then there are 5 numbers, two  of  them begin with a zero. [It] says PRINT
            OUTLET IN REGION.  We only get the three that do not begin with a zero, and it
            just does not show the other two at all.  
             
                   DTR> FOR CUST WITH OUTLET = '00006','00013',90014,90017,27652
                   [Looking for statement]
                   DTR> PRINT OUTLET, REGION
                   
                   OUTLET REGION
                   
                   00006    99
                   00013    99
                   90014    99
                   90017    99
                   27652    01
                   
            Down below that [just above here], if you  put the quotes around it is just to
            show that you get all five - and it shows you that all of them are there.  Now
            if you want to get real fancy and  you want to put in a prompting variable and
            say 'all right, FOR COST WITH  OUTLET  =  *.OUTLET' and then let them actually
            ask for it.  It comes in and  says  'Enter OUTLET', if you enter more than one
            there, and put commas in  between  them  you  come back with a nice DATATRIEVE
            prompt and no data.  
                   
                   DTR> FOR CUST WITH OUTLET = *.OUTLETS
                   [Looking for statement]
                   CON> PRINT OUTLET, REGION
                   Enter OUTLETS: 00006,00013,90014,90017,27652
                   DTR>              ![Note that there is no output]
                   
            It won't take the multiples, it does  not recognize the comma, it thinks it is
            just one big long string.   This  was  a  problem  for us and we wanted to get
            around that.  If you do the prompt  and  you enter just one outlet, I put that
            in there just to make sure everybody knows  that does work, and you do get the
            one guy back again.  
             
                   DTR> FOR CUST WITH OUTLET = *.OUTLET
                   [Looking for statement]
                   CON> PRINT OUTLET,REGION
                   
                   OUTLET REGION
                   
                   00006    99
                   
            Ok, now to solve this, we wrote  a  procedure.   Now in the procedure I simply
            do, and I call  this  [procedure]  FOR_OUTLETS,  so  that  in the case of this
            rather than saying FOR CUST WITH OUTLET  =, they would just do :FOR_OUTLETS in
            this case it declares a variable, in  this  case  89 long, that is in order to
            hold 15 separate numbers.  The very  first that it does in the procedure after
            it SETS DATA_IN =  a  prompt,  which  says  ENTER  UP  TO 15 FIVE DIGIT OUTLET
            NUMBERS SEPARATE BY COMMAS, it says  FOR  COST  WITH  OUTLET = and it uses the
            function EXTRACT and from data in it  takes  the first five, then it takes the
            next five and then the next five.  
             


            23






                   DEFINE PROCEDURE FOR_OUTLETS
                   DECLARE DATA_IN PIC X(89).
                   DATA_IN = *.'Up to 15 5-digit outlet numbers separated by commas'
                   FOR CUST WITH OUTLET = FN$STR_EXTRACT(DATA_IN, 1,5),
                                          FN$STR_EXTRACT(DATA_IN, 7,5),
                                                      .
                                                      .
                                                      .
                                          FN$STR_EXTRACT(DATA_IN,79,5),
                                          FN$STR_EXTRACT(DATA_IN,85,5)
                   END_PROCEDURE
                   
                   DTR> :FOR_OUTLETS
                   Enter Up to 15 5-digit outlet numbers separated by commas: 00006,
                   00013,90014,90017,27652
                   [Looking for statement]
                   CON> PRINT OUTLET, REGION
                   
                   OUTLET REGION
                   
                   00006    99
                   00013    99
                   90014    99
                   90017    99
                   27652    01
             
            Now there is no problem in here as long as you do not have any spaces in those
            fields.  If you had spaces in  there,  of course, if you only enter three, you
            would end up looking for everything that had  a space in the field.  If you do
            have an index that had spaces you  can  load  NULL  KEY and set it up with the
            space being the NO value so  that  you  would  not have to worry about that as
            long as it was an alternate index, you could do that on your file.  So that is
            one alternative.  Just to show you that  it does work down here, just say :FOR
            OUTLETS, it comes back and  prompts  for  up  to  15 five digit outlet numbers
            separated by commas, you can put  in  however  many  you  want to up to 15, of
            course, that number could  be  incremented  also  if  you  put  in more of the
            functions in that particular procedure,  and  of  course  it comes back and it
            prints all of those for you.  Now  the  neat thing is that you can also add to
            that, you can go ahead and include  into the RSE, you can say :FOR_OUTLETS AND
            REGION = 99, in which case if you will notice here, 
             
                   DTR> FOR_OUTLET AND REGION = 99
                   Enter Up to 15 5-digit outlet numbers separated by commas: 00006,
                   00013,90014,90017,27652
                   [Looking for statement]
                   CON> PRINT OUTLET, REGION
                   
                   OUTLET REGION
                   
                   00006    99
                   00013    99
                   90014    99
                   90017    99
                   
            I put in the same outlet  string  and  it  comes  back with those that were in

                                                                                         24






            region 99, it leaves out the one that is in region 01 that was in the previous
            thing [example].
             
            It is really kind of a nice thing.   If you are doing something in a procedure
            where you have to key them all in  anyway,  it  is no big deal, but if you are
            interactively sitting down doing queries and  you  do not want to key that in,
            especially if you do not  want  to  have  to worry about putting quotes around
            everything that has a zero (0) in the front of it, it keeps you and allows you
            to be able to just leave prompting kinds  of  things.  I did it with FOR.  The
            very same thing works with FIND.  
             
                   DEFINE PROCEDURE FIND_OUTLETS
                   DECLARE DATA_IN PIC X(89).
                   DATA_IN = *.'Up to 15 5-digit outlet numbers separated by commas'
                   FOR CUST WITH OUTLET = FN$STR_EXTRACT(DATA_IN, 1,5),
                                          FN$STR_EXTRACT(DATA_IN, 7,5),
                                                      .
                                                      .
                                                      .
                                          FN$STR_EXTRACT(DATA_IN,79,5),
                                          FN$STR_EXTRACT(DATA_IN,85,5)
                   END_PROCEDURE
                   
                   DTR> :FIND_OUTLETS
                   Enter Up to 15 5-digit outlet numbers separated by commas: 00006,
                   00013,90014,90017,27652
                   [5 records found]
                   DTR> PRINT OUTLET, REGION, ISIS_FLAG
                   
                   OUTLET REGION ISIS
                   
                   00006    99
                   00013    99
                   90014    99
                   90017    99
                   27652    01     1
                   
                   DTR> :FIND_OUTLETS AND ISIS_FLAG='1'
                   Enter Up to 15 5-digit outlet numbers separated by commas: 00006,
                   00013,90014,90017,27652
                   [1 Record found]
                   DTR> PRINT ALL OUTLET,REGION,ISIS_FLAG
                   
                   OUTLET REGION ISIS
                   
                   00006    99     1
                   
            It really does not slow anything down,  it  is a little bit slower than if you
            keyed them in, but for me it is faster because it takes me so long to key them
            in, you know, with the fact that you have to all the little goodies around it,
            so it is really not bad at all.  
             
            Just one little thing, if you  do  not  have  the ability to load something in
            with a NULL KEY, for instance if it  is  not a key and you wanted to this kind
            of thing against it, you can  do  it  another way, and this was something that

            25






            surprised me.  I did not think that it would work until I tried it.  
             
                   DTR> FIND CUST WITH ACCT = PKV,202
                   "PKV" not field, assumed literal.
                   Non-digit in string "PKV", ignoring character(s).
                   Non-digit in string "PKV", ignoring character(s).
                   Non-digit in string "PKV", ignoring character(s).
                   Non-digit in string "PKV", ignoring character(s).
                   [56 records found]
                   
                   DTR> FIND CUST WITH ACCT = 'PKV','202'
                   [56 records found]
                   
                   DEFINE PROCEDURE FIND_ACCTS2
                   DECLARE DATA_IN PIC X(59).
                   DATA_IN = *.'Up to 15 3-digit ACCT codes separated by commas'
                   FIND CUST WITH ACCT =
                       IF  FN$STR_EXTRACT(DATA_IN, 1,3) NE ' ' THEN
                           FN$STR_EXTRACT(DATA_IN, 1,3) ELSE '000'
                       IF  FN$STR_EXTRACT(DATA_IN, 5,3) NE ' ' THEN
                           FN$STR_EXTRACT(DATA_IN, 5,3) ELSE '000'
                                              .
                                              .
                                              .
                       IF  FN$STR_EXTRACT(DATA_IN,57,3) NE ' ' THEN
                           FN$STR_EXTRACT(DATA_IN,57,3) ELSE '000'
                   END_PROCEDURE
                   
                   DTR> :FIND_ACCTS2
                   Enter Up to 15 3-digit ACCT codes separated by commas: PKV,202
                   [56 records found]
                   DTR> PRINT ALL OUTLET, ACCT,SREP
                   
                   OUTLET ACCT SREP
                   
                   00049  PKV   EA
                   01558  PKV   DF
                   00051  202   XE
                   00052  202   XE
                     .
                     .
                     .
                   
                   DTR> :FIND_ACCTS2 AND SREP = 'XE','EA'
                   Enter Up to 15 3-digit ACCT codes separated by commas: PKV,202
                   [55 records found]
                   
            It is the very same procedure, the only thing is that when you get down to the
            FIND or...actually I did this one with a FIND - you can do it with a FOR.  All
            you do is after you say the equal,  in  this case we are looking at an account
            key, this key happens to have spaces in  there, it is not loaded as null value
            space, so it is saying 'FIND CUST WITH ACCT  =  ' and then put an IF.  If then
            you do an EXTRACT, you look at  that particular position, the account field is
            3 rather than 5 [characters long].  If it is not equal to a space then you use
            the value, otherwise, in this case  zero  (0),  zero is not a valid account so

                                                                                         26






            there will never be any.  The  only  purpose for that is because again, like I
            said, if you only entered three, you  would  have  nulls in all of the rest of
            them, and if you had spaces out there the file would try to get them.  In this
            case, by making them zero I do  not  have any valid accounts with zeros in it,
            so it does not do that.  It all works just fine.  Again with this you can also
            add to the RSE, just at the invoke procedure level.  That is for the SPR team.
            [Applause]
             
             
            Jim Starkey, Digital Equipment Corporation
             
            This is one of great historical importance  and significance.  One of the very
            first Wombat Magic presentations was on restructuring a file.  How many of you
            have ever felt the need to restructure a  file?   Isn't it a lot of fun?  NO!!
            Well, I went off and I did a little  bit of coding and now two, no three years
            later I have a way to restructure a file that is a little bit better.  Here is
            a DATATRIEVE procedure and let me just warn  you up front that there are a few
            restrictions, like this only works  with  this Rdb/ELAN. [Laughter]  [Indirect
            pitch to buy a MICRO-VAX, with more  laughter.]   This is a procedure to add a
            field to an existing data  base  without  doing a restructure, without leaving
            DATATRIEVE, and without going nuts.    I  am  going to start by READYing three
            magic domains.  One is called  RDB$RELATIONS, one is called RDB$FIELDS and one
            is called RDB$RELATION_FIELDS.  Very  briefly,  RDB$RELATIONS is a list of all
            of the relations in the database,  RDB$FIELDS  is  a list of all the fields in
            the database, RDB$RELATION_FIELDS says which field is in which relation. 
             
                   define procedure add.field
                   ready   rbd$relations write,
                           rdb$fields write,
                           rdb$relation_fields
                   begin
                       declare relation pic x(31).
                       declare field pic x(31).
                       relation = *.relation
                       if not any rdb$relations with rdb$relation_name eq relation
                           store rdb$relations using rbd$relation_name = relation
                       field = *.field
                       if not any rbd$fields with rdb$field_name eq fields
                           store rdb$fields using begin
                               rdb$field_name = field
                               rdb$field_type = *.type
                               rdb$field_length = *.length
                               end
                       store rdb$relation_fields using 
                           begin
                               rdb$field_name = field
                               rdb$field_source = field
                               rdb$relation_name = relation
                           end
                   end
                   commit
                   end_procedure
                   
            [I've] got a BEGIN_END block there just to be neat.  Declared a temporary just
            for a relation name, 31 name characters  just  like VAX names are, too long or

            27






            too short.  Another field for field, to hold the field name that I am going to
            add to a relation.  Okay, I am going to prompt for the relation name and store
            it in the field.  That is simple.    Just in case that relation did not exist,
            it is going to check to see if  it existed and if that relation did not exist,
            it would store a record in our RDB$RELATIONS.   That has the same effect as to
            finding the field in RMS.  That  will  create  the new relation if it does not
            exist.  Then I get a  prompt  for  a  field name and do approximately the same
            thing to RDB$FIELDS - going to check to  see if that field already exists - as
            you will learn in sessions hence, all fields in the RDB products are global to
            the database - you define them once  in  FIELDS and then you reference them in
            RELATIONS.  If the field does not exist,  it is going to store the field name,
            it is going to store the field  type  which  is an VAX data type, store length
            and that is that -- now you have  a new global field in the database.  Finally
            it is going to  store  a  very  simple  record into RDB$RELATIONS_FIELDS, do a
            commit.  And that is it!    Invoke  the procedure, answer [the prompt for] two
            names, and you add a new field to a database. [Applause]  [Bob Lott] For those
            of you who are new to DECUS  and/or DATATRIEVE, I'd just like to comment, that
            Jim Starkey, was the  guy  that  we  can  blame  for  all those damned yachts.
            [Laughter, followed by boos]  By the  way,  some of the family members in some
            of those domains are  Jim's  family.    He's  also responsible for the wombat.
            [Jim] Also two cats . . .
             
             
            Idris M. Dawud, Technicare Corporation, Solon, OH
             
            The problem I encountered which I had to  use a little bit of WOMBAT MAGIC was
            . . . In order to execute  a  number of different procedures which did similar
            types of things only they  were  different,  and  the differences could be re-
            flected very well in the way the names were made up.  
             
                   Procedure names such as:
             
                       INV_GEN_GAGE
                       REPCAL_GEN_GAGE
                       MSTR_GEN_GAGE
                       INV_SEL_GAGE
                       REPCAL_SEL_GAGE
                       MSTR_SEL_GAGE
             
            I am only giving six examples here and  as  you can see, the first part of the
            name and the second part of the name are different, but in actuality all three
            of the names were different.  It  took  a cumbersome procedure first of all, a
            cumbersome procedure filled with IF statements -- IF such and such do this, IF
            such and such do that.  I had  a little help with a CHOICE statement that came
            out in the last release.  Basically this is what it called for. 
             
                   DEFINE PROCEDURE ----
                           .
                   FORM = *."WHICH FORM TYPE [1, 2, OR 3]?"
                   CARD = CHOICE OF
                           FORM = 1 THEN "INV"
                           FORM = 2 THEN "REPCAL"
                           ELSE "MSTR"
                       END_CHOICE
                   METHOD = *."WHICH METHOD TO USE [GEN,SEL]?"

                                                                                         28






                   TYPE = CHOICE OF
                           METHOD = "GEN" THEN "GEN"
                           METHOD = "SEL" THEN "SEL"
                               .
                               .
                       END_CHOISE
                    . . .
                   DO_THIS = CARD|"_"||TYPE|"_"|"GAGE
                   FN$CREATE_LOG("PROC","DO_THIS")
                    . . .
                   END_PROCEDURE
                   
            The user was  prompted  for  a  method  they  wanted  to  modify a record, for
            example, either a general modification which would keep going on through every
            record in the database until  they  hit  CONTROL  C or whatever or a selective
            modify which is they would prompt for a specific key.  They were also prompted
            for whether they wanted form 1, 2,  OR  3  which turned it out to be either an
            inventory card, a repcal card, or a  master  gauge control card.  So after re-
            ceiving this information in the form of variable 1 and variable 2, you issue a
            choice statement which basically says if  the  form  =  1,2 or 3 then the card
            (card being  another  variable)  would  equal  either  inventory,   repcal, or
            master; and card is a symbol [variable]  and form is a symbol [variable].  You
            have similar choice statements to do the  same thing.  For example if a person
            selected 1, then card would equal inventory  - INV.  Then for the second vari-
            able you would say if method  equal  either general or selective then you give
            the second variable with either equal  general  or selective.  You can do this
            on and on and on for a number  of  variables.   I do not know what limit DATA-
            TRIEVE puts on procedure names, but that  would  be the the limit at which you
            could do this.  Afterwards, you'd make a third symbol [variable] I'd just call
            for simplicity DO_THIS equals CARD  which  is  one variable or symbol concate-
            nated to an underscore,  concatenated  to  TYPE  which is the second variable,
            concatenated to to an underscore,  concatenated  to either a literal like this
            ["GAGE"] or another variable.  Like  I  said  you  can  go on and on.  For the
            purpose of making our  procedure  names  which  are  written in this form once
            again.  So DO_THIS ended up  equalling, in my example, INV_SEL_GAGE, Inventory
            Select gauge, concatenated together to a  DATATRIEVE symbol which you can exe-
            cute as a procedure or domain or  anything  else.  Then you use the DATATRIEVE
            function FN$CREATE_LOG, then you give a  logical name to the symbol name which
            makes it now executable whereas the  symbol  wasn't executable in the past and
            then the end result is you can execute any one of your procedure names by just
            - well, essentially just patched variable  short words together to make a long
            procedure name and this saves you a lot  of time and makes it more readable if
            someone goes through your code.   I  found  it  very  useful.  Also I found it
            useful to - once you have that  logical  inside your procedure you can also do
            FN$TRANS_LOG and you find out where  it  is  and  go on and play with logicals
            back and forth between the create  and  the  translate  back and forth to do a
            number of other things.  Like you  can  READY it as a domain also and anything
            else you can do with DATATRIEVE elements in the dictionary you can do with the
            logical.  [Applause]
             
             
            Jay Vander Wall, Dow Chemical
             
            The problem here is to get some  input from a user and provide data validation
            and HELP without the use of the form because we have to support dumb terminals

            29






            like ADM30's and that type thing.    So  what  I  did is I declared a variable
            HOLD_MANAGER and I made a VALID IF  the  manager  was  in a table OR if it was
            equal to a question mark.  Then I went down where I wanted to get my input and
            put in set  HOLD_MANAGER  =  "?",  went  into  a  WHILE  LOOP  and said 'WHILE
            HOLD_MANAGER = "?", and  inquire  the  managers  name  or ?(question mark) for
            HELP.  Then I went into an IF  statement which said IF HOLD_MANAGER = "?" then
            it printed all the names of the  managers  that were in the table and provided
            them help, went back up and repeated the query.
             
                   declare hold_manager pic x(14)
                       valid if (hold_manager in mgr_tbl) or (hold_manager = "?").
                   
                   hold_manager = "?"
                   while hold_manager = "?"
                       begin
                       hold_manager = *."manager's name (<?> for help)"
                       if hold_manager = "?"
                           then print all name of managers
                       end
                   
             
            Wade Scannell, Ship Analytics
             
            I was up in the DATATRIEVE SIG  earlier  and they said that they wanted to see
            some real simple magic, so my magic is  quite simple.  There is a little story
            behind it, but what I am going to talk about is DATATRIEVE data retrieval.  We
            all know DATATRIEVE does data retrieval but I am going to do it without files,
            without RDB, without tables, without any  of  that crap. The story behind this
            is that somebody came up to me one  day a couple of months ago and they wanted
            to know something about days of the week and they were looking for a perpetual
            calender.  I said, "Hech,  I've  got  a  perpetual calender right on my desk."
            They wanted to know what day  of  the  week  they were born  or something like
            that.  So I said, "Here, I'll find out for you."  I logged into DATATRIEVE and
            typed 
             
                   DTR> PRINT "14-SEP-54" USING W(9) 
             
            and  it  says  "Tuesday".  So  we  have  the  DATATRIEVE  perpetual  calender.
            [Laughter and applause]
             
             
            Bob Lott, E. I. DuPont, Wilmington, DE
             
            This one I've titled AUTOMATIC LOGIN.  It is really sort of VMS and DATATRIEVE
            magic.  It is really VMS, but  because  I manage it with DATATRIEVE it sort of
            comes under DATATRIEVE magic too.   This  is an undocumented feature  but when
            you log in, that procedure or process first looks to see if there is a file on
            your system called SYSUAF.DAT.  If that file exist, it will do the login based
            on entries in that file.  Let me demonstrate what I am talking about.  
             






                                                                                         30






                   define domain alfs using alf_rec on sys$system:sysalf.dat;
                   define record alf_rec using
                   01  alf_rec.
                       05  tt          pic is x(63).
                       05  user        pic is x(65).
                   ;
                   
            First of all the file is an indexed  file with a domain definition for which I
            have shown SYS$SYSTEM:SYSALF.DAT and the  ALF  stands for automatic login file
            or auto login file or whatever.    I  have  also shown a record definition for
            that file, two fields within a record and the first one is the terminal number
            and it is a sixty-three byte record [field].  The second record [field] is the
            - what I have shown as user - I really define these down below.  But TT is the
            terminal I. D. with the  underscores  as  I  have shown - underscore TT1 colon
            (_TT1:) in example.  The user is actually  the account name.  Now I work for a
            chemical  company  and  we  have  operators  that  are  very  unfamiliar  with
            computers, we would like to have  them  log  into what we call a slave account
            which is really captive, and so the account  name that we use is SLAVE so when
            the guy walks up to the terminal and hits a return he is logged into a captive
            command procedure  which  is  specified  in  the  user  authorization file for
            account SLAVE, so he never enters account name, he never enters a password.  I
            manage this file again with DATATRIEVE because it is an indexed file and it is
            a very simple way to manage  an  index  file.    This is not documented but it
            works. [Applause] 
             
            [Editor's Note: An article, How To  Create  "TIED" Terminals Under VMS, by Jay
            Wooten, which appeared in Volume 6,  Number  2,  pages 3 to 11, of the August,
            1984, PAGESWAPPER, very carefully  explains  this undocumented feature of VMS.
            That article uses seven pages to  show  how  to manage this file without DATA-
            TRIEVE.  As we all know, with DATATRIEVE it's a snap.]
             
             
            Pat Scopelliti, Corning Glass Works
             
            This is actually not DATATRIEVE  magic,  this  is actually magic being done on
            DATATRIEVE.  Sort of getting back  at  it.    What  this is, is making a plots
            function on your VT240,  more  or  less.  [Scattered  applause]  This works on
            Version 1.3 and also Version 2.0.  Problems  on  a VT240 are two.  First as it
            draws a plot, it starts scrolling.   Bummer  ...  Second, [laughter]  and even
            worse is that one your very next entry it erases the screen.  It actually does
            not do that, it just turns it off, which is even worse.  The reasons are quite
            simple if you think about it, and  it  is  all due to wonderful DEC and I will
            not call them Digital until  they  quit  selling  DECSlide,  and DECGraph, and
            DECWriters and whatever else they sell.   First of all, the VT240 has both its
            graphics and its text in the same  plane.  So that when you scroll, everything
            scrolls -- problem.  Second, DTR  actually turns off the four mapping graphics
            registers - it just simply turns  off  the  lights, and that is why the screen
            goes blank.  What it actually does is it issues the command at the bottom.  
             
                                <ESC>Pps(m0(l0)1(l0)2(l0)3(l0))<ESC>\
             
            Two things to do.  First  keep  it  from  scrolling  and second keep it on the
            screen.  First one is pretty  easy.   You get in [CDD$TOP.]DTR$LIB.VT125 - you
            EXTRACT every single plot with one little line, you then get in there and edit
            that file whatever it was  and  change  every  single PRINT EXIT_REGIS line to

            31






            PRINT EXIT_REGIS,"<ESC>[H"
             
                   DTR> set dictionary cdd$top.dtr$lib.vt125
                   DTR> extract all on vt240.com
                   DTR> exit
                   $ 
                   EDIT vt240.com
                   * s /print exit_regis/print exit_regis,'<ESC>[H'/ %wh  ! [in concept]
                   * exit
                   $dtr
                   DTR> set dictionary cdd$top.dtr$lib
                   DTR> define dictionary vt240
                   DTR> set dictionary vt240
                   DTR> @vt240.com
                   
            That at the end of every single plot [it] leaves your cursor at the top of the
            screen. Scrolling is solved.  Of course  on the next line, it still blanks out
            the screen.  By the way, you  then  put  this all back in into a separate area
            called VT240 that way you can easily pick  am  I at a VT125 or a VT240 and set
            your plots to the correct spot.    If  you  can't figure that out, the rest of
            this will really bore you. 
             
            The next part is you sort  of  have  to  close  one eye and not think too much
            about what is going to happen.  [Tittering from the audience]  DEC sort of has
            problems with this, but this  works  and  DEC  won't fix it until version 3.0.
            What you have to do is simply get  in....   [Bob Lott] "There not going to fix
            it then." [Pat] They aren't?   Version  3  is  not  fixed?  No answer from the
            crowd!
             
            [Editor's note: The problem  of  VT240  graphics  support from DATATRIEVE is a
            very complex issue.    VAX-DATATRIEVE  can't  properly  support VT240 graphics
            until VMS properly supports the  VT2XX  terminals.   If DATATRIEVE V3.0 is re-
            leased before VMS 4.0, then support for  a VT240 in DATATRIEVE will not appear
            until VAX-DATATRIEVE V3.1.  Thus,  Pat's  unconventional and daring "patch" is
            of considerable practical  interest  to  VAX-DATATRIEVE  users  with VT240 and
            VT2401 terminals.]
             
            No problem, I don't care; I'll  just  fix  it!! [Laughter]  Get into the image
            file, find that little <ESC>Pps(l0 . .   .and so forth, and just eliminate it.
            [Laughter]  And this works!  Keeping in mind that VMS does not know what is in
            the image, thank goodness, and it simply  loads in what is there.  Luckily DEC
            has stored this in ASCII text - it  is  easy to find - methods are you can use
            DUMP and go looking through the ASCII  portion until you find the right code -
            m0(l0)1(l0 and on and on and on.   What  you do is get out your hex calculator
            and you get in there and  you  simply  NAIL THE SUCKERS!  [Amazed laughter and
            applause]
             
            Now that was "Version 1.0"  [Pat's  solutions,  first version] that I came out
            here with.  
             






                                                                                         32






                   $! THIS PATCH IS FOR DTR V1.3 ONLY
                   $! It enables DTR plots to function properly on VT240 terminals
                   $! by replacing the ReGIS command
                   $! <ESC>Pps(m0(l0)1(l0)2(l0)3(l0))<ESC>\
                   $! with nulls.  The above command is sent to the terminal after any
                   $! response to the DTR> prompt after  a plot and causes all four output
                   $! mapping registers to be set to lightness=zero.
                   $!
                   $ PATCH DTRV240.EXE
                   SET MODE DECIMAL,BYTE
                   DELETE 25254 = 27       ! <ESC>
                   DELETE 25255 = 80       ! P
                   DELETE 25256 = 112      ! p
                   DELETE 25257 = 115      ! s
                   DELETE 25258 = 40       ! (
                   DELETE 25259 = 109      ! m
                   DELETE 25260 = 48       ! 0
                   DELETE 25261 = 40       ! (
                   DELETE 25262 = 108      ! l [lower case L, not 1 (one)]
                   DELETE 25263 = 48       ! 0
                   DELETE 25264 = 41       ! )
                   DELETE 25265 = 49       ! 1 [digit one]
                   DELETE 25266 = 40       ! (
                   DELETE 25267 = 108      ! l
                   DELETE 25268 = 48       ! 0
                   DELETE 25269 = 41       ! )
                   DELETE 25270 = 50       ! 2
                   DELETE 25271 = 40       ! (
                   DELETE 25272 = 108      ! 1
                   DELETE 25273 = 48       ! 0
                   DELETE 25274 = 41       ! )
                   DELETE 25275 = 51       ! 3
                   DELETE 25276 = 40       ! (
                   DELETE 25277 = 108      ! l
                   DELETE 25278 = 48       ! 0
                   DELETE 25279 = 41       ! )
                   DELETE 25280 = 41       ! )
                   DELETE 25281 = 27       ! <ESC>
                   DELETE 25282 = 92       ! \
                   UPDATE
                   EXIT
                   $
             
            or
             











            33






                   $! THIS PATCH IS FOR DTR V2.0 ONLY
                   $! It enables DTR plots to function properly on VT240 terminals
                   $! by replacing the ReGIS command
                   $! <ESC>Pps(m0(l0)1(l0)2(l0)3(l0))<ESC>\
                   $! with nulls.  The above command is sent to the terminal after any
                   $! response to the DTR> prompt after  a plot and causes all four output
                   $! mapping registers to be set to lightness=zero.
                   $!
                   $ PATCH DTRV240.EXE
                   SET MODE DECIMAL,BYTE
                   DELETE 99128 = 27       ! <ESC>
                   DELETE 99129 = 80       ! P
                   DELETE 99130 = 112      ! p
                   DELETE 99131 = 115      ! s
                   DELETE 99132 = 40       ! (
                   DELETE 99133 = 109      ! m
                   DELETE 99134 = 48       ! 0
                   DELETE 99135 = 40       ! (
                   DELETE 99136 = 108      ! l [lower case L, not 1 (one)]
                   DELETE 99137 = 48       ! 0
                   DELETE 99138 = 41       ! )
                   DELETE 99139 = 49       ! 1 [digit one]
                   DELETE 99140 = 40       ! (
                   DELETE 99141 = 108      ! l
                   DELETE 99142 = 48       ! 0
                   DELETE 99143 = 41       ! )
                   DELETE 99144 = 50       ! 2
                   DELETE 99145 = 40       ! (
                   DELETE 99146 = 108      ! 1
                   DELETE 99147 = 48       ! 0
                   DELETE 99148 = 41       ! )
                   DELETE 99149 = 51       ! 3
                   DELETE 99150 = 40       ! (
                   DELETE 99151 = 108      ! l
                   DELETE 99152 = 48       ! 0
                   DELETE 99153 = 41       ! )
                   DELETE 99154 = 41       ! )
                   DELETE 99155 = 27       ! <ESC>
                   DELETE 99156 = 92       ! \
                   UPDATE
                   EXIT
                   $
                   
            This afternoon I thought of a much, much better final thing [Pat's Version 2.0
            solution] and that is instead of nulling out every single one, . . .  what you
            really, really do  is  simply  change  the  first  four things [characters] to
            <ESC>[2J and that will clear off  the  screen  in a nice simple matter and you
            simply blank off the rest of the stuff  either with blanks or nulls.  There is
            a nice documented  way  to  do  that,  supported  by  Mr.  DEC and everything.
            [Laughter] I also could have done this in  a  BASIC job.  It worked and it was
            easy.  This is some of the  patch,  I  will  bore  you with it and it uses VMS
            PATCH.  To put the  "<ESC>[2J"  [in]  the  first  four delete lines are simply
            changed to modifies, I think  is  what  the  statement  is, get out the little
            PATCH MANUAL [VAX-11 Patch Utility  Reference Manual, AA-H785B] and instead of
            saying DELETE 25254 = 27 you say  that MODIFY that [25254] equals 27, whatever

                                                                                         34






            you need.  And the four ASCII characters  for <ESC>[2J and that is it.  If you
            rebuild DTR you'll have to go back  in and find where those parentheses L zero
            and on and on or and fix them  again.   It helps to have a hex calculator with
            you.  [Applause]
             
             
            Thomas (Tim) Mahaney, Naval Air Propulsion Center, Trenton, NJ
             
            I am employed by a small naval  establishment  on the east coast.  Being small
            enough, we use DATATRIEVE in a  dispersing  application.  For those of you who
            are not familiar  with  that  it's  make  check  registers,  print checks.  We
            actually print checks to DEC to buy  equipment and software on occasion.  This
            is really a description of what might be loosely termed DEC magic.  We started
            this application in DATATRIEVE-11 on an IAS  system.  It ran very nicely for a
            couple of years and then we got a  VAX and everybody went "Ooooh, a VAX!!"  We
            were a little bit concerned  about  translating our DATATRIEVE applications to
            the VAX, but actually it turned  out  that everything went quite smoothly.  We
            had very few problems.  Most  of  the  backup  procedures that go to the final
            printing in the dispersing application  checked  out  really well -- until the
            first check run.  I must preface this too  with the fact that I am not a DATA-
            TRIEVE guru, I am sort of a  system  manager type and my experience with DATA-
            TRIEVE is mainly a tool to support system manager functions so that when some-
            one calls me in a panic I really  do  not  have all the answers.  In this case
            the dispersing clerk called me  almost  in  tears  and said "Have you seen our
            checks?" I said, "No, I have not  seen  your  checks, you printed them."  As a
            matter of fact our checks are printed on a printer that is slave to a terminal
            off of a terminal port - a small  printer.  I walked over to the building that
            houses the accounting office and took a  look  at the one check that she had a
            sample of and I  said  "looks  ok  with  me".    The  stuff  was there; it had
            name/address/social security number/security classification  and on and on and
            on.  She said, "But look at the  check,  look at the check." I said, "Looks ok
            to me."  It was for $192.92.  [And the amount was to be ] written out in char-
            acters and then it says "AND  NINETY  TWO  CENTS".   Well it did not say ["One
            hundred ninty-two  dollars"]  whatever.    It  was  then  that  we  found that
            DATATRIEVE-11 truncates -- DATATRIEVE-32 rounds.  The procedure that extracted
            the one hundred and ninety two  dollars  to  put over before the dollars field
            used the fact  that  DATATRIEVE-11  truncated  and  rounded.   That was lesson
            number one.  I guess that the  magic  in  this might be that one of the checks
            was actually to DEC.  The further magic in it that in the 115 checks we print-
            ed there, approximately 90 were mailed already and none of them came back with
            any complaints.  [Laughter]  But -  that  is  not the end of the story.  About
            three months later we got DATATRIEVE  Version  2.0.   One thing that I avoided
            describing was the format that our checks were in.  We print checks with stubs
            on top and check on bottom,  it  is  a continuous marginally punched form.  As
            soon as we put Version 2.0 in, the first check run same accounting clerk calls
            and said "Have you seen the  checks?"  "No,  you  printed them."  So she said,
            "Come over here!"  And sure enough, here  are the checks.  "Look at the stub."
            [And I replied,] "That looks great."   And  she said, "Now look at the check."
            It's blank!  So magic number two from DEC is AT BOTTOM for version 2.0 did not
            work very well.  The check  printing procedure was a Report Writer [procedure]
            which had an AT BOTTOM and a long print statement to fill out the stub and the
            check from the information from one record.    In the middle of it, it said AT
            BOTTOM OF whatever PRINT NAME, ADDRESS  and  then  it said AT TOP [PRINT] NEXT
            PAGE [NEW_PAGE] after that - nothing.  So  I  do not know if that is DEC's way
            of trying to reduce the national debit or . . . [Laughter]  That's my story.

            35






             
             
            Don De Palma, Digital Equipment Corporation
             
            I was at a couple of the sessions this afternoon where people complained about
            CDD.  I don't have complaints about CDD performance, but I do have a couple of
            complaints.  One was that Frank Willison  did  not  take up a job offer that I
            made sometime last year so that meant  that  I had to write about 700 pages of
            documentation over the course of the  last  nine  months.  It was a real pain.
            The other thing is I really object to anal retentiveness of certain aspects of
            the CDD language which get carried  over  into  DATATRIEVE in the form of path
            names.  I don't like typing path  names.   And I have thousands of logicals to
            defined,  it  just  gets  me  tired  after  awhile  to  type  the  abbreviated
            [logicals].  I have a large  directory  structure  with a lot of things under-
            neath it, each of which is associated with  a logical name, but even so when I
            log in, I want to be reminded that  I  gotta set my directory or my default or
            my dictionary to wherever I want to  work.    So, in order to remind myself to
            not try to READY things that are not there, I put that 
             
                   print 'SET DICTIONARY '||*.'Dictionary name' on dicto.com
                   @dicto
                   
            in my startup file for DATATRIEVE.    What  it  does  is it prompts me for the
            dictionary that I want and then  writes  out  SET DICTIONARY and then the dic-
            tionary name to a command file called  DICTO.COM and then it executes it.  And
            then I am there.  That is it.  [Applause]
             
             
            R. J. Woodland, Technicare Corporation, Solon, Ohio
             
            This concerns a feature of DATATRIEVE  which  is not exactly documented but it
            is useful anyway.  The domain definition  uses a logical for the file name and
            actually translates logicals rather than working on a physical file name which
            means you can make use of that in all  sorts of good ways.  One of the ways is
            in the case  of  this  type  of  database  where  you  have two hierarchies of
            variable length instead of one -  normally  that would be a problem - normally
            you're are only allowed to have one  at  the end of a record or something like
            that.  What you can actually do 
             
                      ________________________      ________________________
                     |                        |    |                        |
                     |          SITES         |    |          SITES         |
                     |        DATABASE        |    |        DATABASE        |
                     |                        |    |                        |
                     |________________________|    |________________________|
                     |                        |    |                        |
                     ~      Hierarchy #1      ~    |      Filename #1       |
                     ~                        ~    |________________________|
                     |________________________|    |                        |
                     |                        |    |      Filename #2       |
                     ~      Hierarchy #2      ~    |________________________|
                     ~                        ~
                     |________________________|
             


                                                                                         36






                     define domain sites using sites_rec on sites
             
                     fn$create_log("SITES",filename #n)
             
            is to have two fields at the very end of that record which are obviously fixed
            length or whatever, which are file names  and  smash up the two - what you are
            calling the two hierarchies  effectively  into  separate  files.   Now you can
            define the domain - in this case  SITES using the record definition or a logi-
            cal and you can create a logical name with that same name or whatever the file
            name is from the  record  definition  and  then  you can kinda chain databases
            together and have as many as you  like.  The true congratulations should go to
            Digital because they answered the  SPR  and  kind  of  told me how to do this.
            [Applause]
             
             
            Jerome Alterman, U. S. Coast Guard, Juneau, AK
             
            I have this boss who went out  one  day and bought himself one of those little
            machines named after a popular fruit.   He came into the office and said, "Hey
            this is neat, I can do all sorts of  graphics!" I said, "We have a VAX; we got
            DATATRIEVE.  You know DATATRIEVE;  you  can  do  anything you want!"  He said,
            "Prove it!"  So I showed him  the  Wombat.   Of course the Wombat comes in two
            sizes right, your standard plot and  then  your  BIG.  He said, "That does not
            really impress me."  So I  said,  "Well,  being  as  we are in Alaska..." I am
            sorry I do not have a transparency, but  it wouldn't fit the screen.   I [got]
            a plot of Alaska.  What  is  neat  about  it  is  that when it plots it on the
            screen, it will plot the horizontal  and  the  vertical lines and then you can
            watch it draw the outline from the map.   Of course what he did not realize is
            what it took me to do it. [Jerome held up and then dropped out of his hand the
            many, many pages of  ReGIS  graphic  code  to  create  the plot.  Laughter and
            applause followed.]   But  he's  happy  because  when  people  come in he goes
            "LOOK!" and this little thing  draws  all  over  the  screen.   Well it is not
            magic, but I did not understand the  rest of the stuff they were talking about
            tonight! [Laughter and applause]  [Editor's  note:   It is unfortunate, but it
            is not possible to reproduce Jerome's BIG  graph of Alaska.  Perhaps he can be
            persuaded to submit the ReGIS code to the SIG Library tape.]
             
             
            Paul Krug, Weyerhaeuser Company, Federal Way, WA
             
             
            Awhile back I was - this is a  little bit dated because it just occurred to me
            when all the version numbers started with  one  (1).  You will have to pretend
            for a minute that  you  do  not  have  the  advantages  of the choice and sign
            function.  What I wanted to do  is  define  a maximum of a couple of my fields
            and return that as another computed by  field and without even thinking at all
            I used the maximum  statistical  function  which  of  course did not work, but
            having some background in math  I  decided  I  could create a conditional that
            would have the value of one IF A > B and 0 if it wasn't using this equation. 
                   
                                             | B - A | - ( B - A)
                           ( A > B )  <--- --------------------------
                                                   2  | B - A |
                   


            37






                       05  A_B_COMPARISON.
                           10  A USAGE INTEGER.
                           10  B USAGE INTEGER.
                           10  A_GT_B COMPUTED BY 
                                   (FN$ABS(B - A) - (B - A))/2*FN$ABS(B - A).
                           10  B_GT_A COMPUTED BY 
                                   (FN$ABS(A - B) - (A - B))/2*FN$ABS(A - B).
                           10  MAX_A_B COMPUTED BY A*A_GT_B + B*B_GT_A.
                   
            I had a group field which really only  had  data  for A and B in it and then I
            implemented this equation in  this  field  called  A_GT_B  so that thing has a
            value of one (1) if A is  greater  than B and had a corresponding field B_GT_A
            that was one (1) if the opposite was  true  and only one of those was true and
            my last field was MAX_A_B which was A times A_GT_B PLUS B TIMES B_GT_A.  Since
            only one of these two things can be one  it  would return the value A or B.  I
            had to modify that a little bit because  there is a problem when A is equal to
            B, I get division by zero (0) and I did that by adding another field in here -
            A_EQ_B.  I still got an error when  A  is  equal to B but I found that it only
            printed to the screen and caused trouble for  me if I printed that field,  but
            if I printed the field MAX_A_B it never  came to the screen so I got away with
            it and that is a bit of a klugy solution - And that is my magic. [Applause]
             
             
            Mary McKinzie, WABCO, Peoria, IL
             
            We had a little problem setting up  a  menu for several reports for our users.
            Our users do not really like to  read  at 132 columns on their VT100 unless it
            is absolutely necessary.  We wanted  to  print  the  menu at 80 column and the
            report at 132 columns.  So we  thought  that would be easy, we have these won-
            derful functions FN$WIDTH.  So we set up with a WHILE LOOP so that as long  as
            the option is not equal to  zero  (0)  which  is  what they use to get out, it
            prints the menu with report options and all the choices and then do a FN$WIDTH
            132 and print the report.    Then  in  FN$WIDTH  change back to 80 and reprint
            menu. 
             
                   opt = 13
                   while opt ne 0 begin
                       print "Report Options"
                           .
                           .
                           .
                       fn$width(132)
                       if opt = 1  :report1
                           .
                           .
                           .
                       fn$width(80)
                       end
                   
            Well . . ., it did  not  quite  work  that way.  DATATRIEVE has this wonderful
            thing called optimization.  What  that  means  is  it takes the FN$WIDTH out -
            changes the screen to 132 columns at  the beginning and that is it folks, that
            is the way it stays.   I  must  give  credit  for the solution to my colleague
            because he did a lot of the work finally working it out.  
             

                                                                                         38






                   declare c132 default value is "<ESC>. . ." !["<ESC>[?3h"]
                   declare c80 default value is "<ESC>. . ."  !["<ESC>[?3l" lower case L]
                   
                   opt = 13
                   fn$width(132)
                   while opt ne 0 begin
                       print c80,"Report Options"
                           .
                           .
                           .
                       print c132
                       if opt = 1 :report1
                           .
                           .
                           .
                       end
                   
            What we came out with, we declared two  variables.  One of them you put in the
            escape sequences for setting a  VT100  to  132  columns  and the other one for
            setting it to 80 columns and I don't  happen to remember what those are.  Then
            you print that instead of using  your  FN$WIDTH statement so when we print our
            menu we print the escape sequences to  set  it to 80 then print our menu, then
            print the escape sequence to set it to  132 columns and print the report.  You
            still have to do the  FN$WIDTH  132  at  the very beginning so that DATATRIEVE
            knows that you are going to use  132 columns otherwise it gives you tiny char-
            acters but still wraps around. [Applause]
             
             
            Glenn Dimit, Jet Propulsion Lab
             
            At our installation we do about  95%  of  our DATATRIEVE work through the call
            interface.  And for historical reasons we  do  it  all through C.  There are a
            couple of problems that crop  up  -  not terrible major but rather irritating.
            For one, the call  interface  loves  descriptors.    C,  for  those of you who
            [don't] program in C, knows nothing of the descriptors, so every time you want
            to put a value into a  call  to  DATATRIEVE you have to construct a descriptor
            packet which isn't difficult but it's very much a pain.  The other thing is we
            tend a lot to generate record selection  expressions on the fly and built them
            up in a program, and when you are trying to debug a program, if you just go to
            the call interface directly you can't  see  what the command is unless you set
            break points before you go on  [the  call to] DTR$COMMAND and generally it's a
            big pain.  
             
                   {   external integer dtr_trace
                       dtrcommand(cmd,type,p1,p2,p3,...)
                       char *cmd, *type
                           .
                           .       set up description depending on "type"
                           .
                       dtr$command(...cmd...)
                       if(dtr_trace)   {
                   
                               parse cmd, and print substitution directives
                   
                           }
                       }
            39






                   
            So what we did is we  constructed  a  layer  on top of the DTR$COMMAND routine
            that what it does is, you pass in the command here - this is a string variable
            that just indicates the type of  descriptor  that follow in the argument going
            further to the right and these are  all  the address of the argument.  What we
            simply do is, we construct the command,  pass it to DTR$COMMAND like you would
            normally, but then down here you have  an option that if you set this external
            variable which is the same thing  as  a FORTRAN common block variable or some-
            thing,  and inside here we  parse  the  command line that you do searching out
            all the substitution directives,  put  everything  back  in  and print out the
            lines so that as  the  program  executes  you  can  see the actual command you
            submit to DATATRIEVE.  When you are  trying  to debug the program I think that
            is magic.  [Applause]
             
             
            Bert Roseberry, U. S. Coast Guard, New Orleans, LA
             
            Basically one of the uses that I have found for DATATRIEVE is - I use it some-
            what in system tuning.  What I have here is I have two record definitions.
             
                   define domain ws using ws_rec on ws.dat;
                   define record ws_rec using
                   01  ws_rec.
                       02  acct            pic x(13).
                       02  wsize           pic x(2)
                           valid if wsize eq "MG","WO","CD","HD","  ".
                   ;
                   
                   define table ws_tbl from ws using
                   acct : acct
                   end_table
                   
                   define domains wstmp using wstmp_rec on sys$system:sysuaf.lis;
                   define record wstmp_rec using
                   01  wstmp_rec.
                       02  filler          pic x(21).
                       02  acct            pic x(13).
                       02  filler          pic x(98).
                   ;
                   
                   define table wstmp_tbl from wstmp using
                   acct : acct
                   end_table
                   
                   
            The bottom record definition  [and  the]  associate[d] domain is called WSTMP.
            What this is, is this is used with  your output when you run authorize and get
            a listing/brief.  Up at the top I have WS_RECORD [WS_REC].  What I want to end
            up with in WS_RECORD [WS_REC] is  the  name  of  all  the users that are in my
            authorize file plus another PIC two  characters  big called WSIZE.  What WSIZE
            is it has five possible choices  -  we  classify  users as to how they use the
            system - MG would  be for  message,  WO would be for word processing, CD would
            be for casual DATATRIEVE and HD for  heavy DATATRIEVE use.  By going ahead and
            classifying these people this way,  I  can  set  up working set sizes based on
            this and I'll show you how I do that.

                                                                                         40






             
                   define procedure wsout
                   set abort
                   print " "
                   print "     This procedure is used to generate a command file"
                   print "     that can then be invoked while in AUTHORIZE to"
                   print "     modify the working set parameters"
                   print " "
                   print "     Is this what you want to do?"
                   print " "
                   if *."Yes or No" cont "N" then abort "Okay be that way!"
                   print " "
                   print "     It is necessary to create a command file for each"
                   print "     different type of user."
                   print " "
                   print "     Is the user a"
                   print   " "
                   print "     CD      Casual DATATRIEVE User"
                   print "     HD      Heavy DATATRIEVE User"
                   print "     MG      User of Message System"
                   print "     WO      Word Processing User"
                   print " "
                   declare     tyus        pic x(2)
                               valid if tyus = "CD","HD","MG",WO".
                   declare     wsdef       pic 9(4).
                   declare     wsquo       pic 9(4).
                   declare     wsext       pic 9(4).
                   tyus = *."two letter code for type of user "
                   wsdef = *."size of working set default     "
                   wsquo = *."size of working set quota       "
                   wsext = *."size of working set extent      "
                   for ws with wsize = tyus
                   print "MODIFY ","acct(-),"/WSDEF=",wsdef(-),"/WSQUOTA=",
                       wsquo(-),"/WSEXTENT=",wsext(-) on *."name of command file "
                   print " "
                   print "     File is now generated."
                   print "     Exit DATATRIEVE. "
                   print "     SET DEFAULT SYS$SYSTEM"
                   print "     RUN AUTHORIZE"
                   print "     @filename"
                   print " "
                   end_procedure
                   
            Basically what I do here is I generate a command file.  What that command file
            in it says is modify the name of  the  account and then I prompt them for what
            the WSDEFAULT would be, the WSEXTENT and  the WSQUOTA and using that I come up
            with a big command file that would say for instance,
             
                           MODIFY SMITH/WSDEF=500/WSQUOTA=600/WSEXTENT=700
             
            It puts all this information in a  command  file.   After I do that then I get
            out of DATATRIEVE,  I  set  the  default  to  SYS$SYSTEM:,  I run authorize, I
            execute this command file, then it will  go ahead and it will modify the work-
            ing set based on a type of  user  such  as that user uses heavy DATATRIEVE you
            would probably want to set up their  working set sizes pretty big.  Thank you.
            [Applause]
            41






             
             
            Joe H. Gallagher, Cleveland Clinic Foundation, Cleveland, OH
             
            I would like to turn the tables, instead of present some wizardry I would like
            to ask for some wizardry from the  floor.  There is a particular nasty problem
            having to do with timing in  the  way  the  VT125 works.  Since I can't figure
            this out, it must be wizardry.   Now  there  are some wizards out there that I
            would like to know - how to make this work. If you execute an indirect command
            file inside of DATATRIEVE, and that  indirect command file contains a plot and
            a hard copy, there  is  some  timing  problems  while it [the hardcopy printer
            noisily makes the copy].   Then  if  you  try to print something [immediately]
            after that, there is a resynchronization problem.  
             
                   DTR> @FOO
                   
                   where
                   
                   !FOO.COM contains
                   plot wombat
                   plot hardcopy
                   print "That was a Wombat"
                   
            Now obviously, there needs  to  be  a  command  which says PLOT RESYNCHRONIZE.
            Except, that is printer dependant.  Some printers go faster than others and it
            depends on how it is set up  and  you  have  to say PLOT PAUSE THEN PLOT PAUSE
            THEN PLOT PAUSE and you waste  a  lot  of  time  sometimes or you do not waste
            enough time in which case you blow it,  because  there is garbage all over the
            bottom of the plot.  Now,  the  question  is,  what goes there [just after the
            plot  hardcopy  and  before  the  print  "This  is  a  Wombat"]  in  order  to
            resynchronize so that the next  print  [statement]  doesn't get garbled.  [Jim
            Starkey] What kind of printer  do  you  have?    [Answer] LA100.  [Bob Lott] I
            don't think it makes any difference, Jim.   You can do a similar thing outside
            of DATATRIEVE where you are taking  graphic output files from the export files
            from DECGraph, if you don't do the  necessary  amount of delay, and I think it
            is because of the  buffering  that  goes  on  in  the  printer, you can't do a
            formfeed.  [Phil] What goes there  is  the  right  kind of printer cable.  You
            tell your VT125 and your printers  to  X/ON,X/OFF.   [Bob Lott] I have a VT241
            cable for my LA100 and with  DECGRAPH,  that  does not do it.  [Gallagher] The
            problem is not in the printer, the  problem  is in the VT125 - I am absolutely
            convinced.  [Someone else from floor]  On  printer  cable, there is a line for
            DTR (data terminal ready) [which  must  be  used]  [Gallagher] And also if the
            LA100 is set up correctly in that mode.  [Bob Lott] I have a null modem cable.
            [Gallagher] So if you have the correct cabling, there needs to be nothing - is
            that correct?  [Bob Lott]  What cable is it then?  [From the floor] . . .there
            is a switch in the LA100 itself for X/ON,X/OFF.  [Gallagher] The X/ON,X/OFF is
            already set, that is for sure.    [From  the floor]  ....watch your null modem
            cable - there is a lot of different  type  of modem......  you may want a very
            simple null modem cable ....   [Gallagher]  Would  you believe  that it is the
            standard cable that  DEC  supplies  at  great  expense.  [For  Floor] That has
            nothing to do with it ...    [Gallagher]  So,  This should work with the right
            cable if the two devices know about each  other properly.  [Jim Starkey]  I do
            it all the time so it will work.  [Gallagher]  Thank you, that is magic.  [Bob
            Lott] Would you consider proper  cable  number  in  the  Wombat Examiner?   We
            would all love to hear it, give  us  choices  if  it depends on the device.  I

                                                                                         42






            struggle with this myself.    [Gallagher]  I  obviously have a problem because
            every VT125 and LA100 in my  place  has  this  problem.  [Bart Lederman] It is
            refreshing to see that  the  software  developers  coming up with the hardware
            solutions, isn't it? [Laughter]
             
            [Editor's note: I must apologize  to  all  because  I did not properly explain
            this problem during the Magic session; it  might have been due to the lateness
            of the hour or the quantity of refreshments consumed.  The hardware configura-
            tion consists of a VT125 terminal with a LA100 printer attached to the printer
            port of the VT125.  If one  places  the following statements in a command file
            for DATATRIEVE
             
                   plot wombat
                   plot hardcopy
                   print "<ESC>[5i"        ! turn on copy of text to LA100
                   print "That was a Wombat"
                   print "<ESC>[4i"        ! turn off copy of text to LA100
                   
            and then executes them from  within  DATATRIEVE,  the hardcopy on the LA100 is
            besmirched.  What happens is that the "<ESC>" in the "<ESC>[5i" arrives at the
            LA100 before the LA100  has  completed  the  hardcopying.   That is, there are
            still some (few) graphics symbols in the LA100's buffer.  The <ESC> causes 1).
            the LA100 to momentarily leave  graphics  mode,  or 2). the following text, in
            this case "That was a Wombat",  to be interpreted as graphics "symbols" rather
            than text.  Which ever the case,  the hardcopy is spoiled.  After considerable
            experimentation, I found no  combination  of  ESCAPE sequences or "PLOT PAUSE"
            which would always  prevent  the  hardcopy  from  getting  spoiled.  (The only
            partial solution which I found that came  any where close was to place a whole
            series of "PLOT PAUSE", perhaps as many  as  15, after the PLOT HARDCOPY).  My
            question to the audience of the  Wombat  Magic Session at Cincinnati was "What
            should one  placed  between  the  line  "PLOT  HARDCOPY"  and  the line "PRINT
            '<ESC>[5i'" in order to cause the  VT125  and the LA100 to resynchronize their
            activities.  Since I did not  explain  the problem correctly, the audience was
            unable to give a solution.  Later, however, I called Jim Starkey and explained
            the problem; he suggested that I create a dummy plot called RESYNC which would
            delay the execution of the line  containing  the  ESCAPE sequence.  I took his
            suggestion and created a new  plot  in the CDD$TOP.DTR$LIB.VT125 dictionary of
            the form
             
                   delete resync;
                   define plot resync
                   entry 0
                   begin
                       plot housekeep 0
                       plot housekeep 2
                       end
                   end_plot
                   
            This little dummy "plotting" routine  really does no plotting; however, causes
            the VT125 to go into ReGIS mode  (housekeep  0)  and then go out of ReGIS mode
            (housekeep 2).  The important thing is,  that it will not go into graphic mode
            until the previous ReGIS  graphics  command  (PLOT  HARDCOPY) is finished!  It
            thus has the effect of  preventing  the  executions of any subsequent print or
            escape sequences.  Therefore,  the  PLOT  RESYNC  will  not complete until the
            VT125 is  done  with  transferring  is  graphics  screen  dump  to  the LA100.

            43






            However, this command alone does not  solve  the  problem.  One of the reasons
            that this problem is never seen  when  operating interactively is that a print
            to the text screen of the VT125  causes  a  little kick to the LA100 to finish
            printing its buffer.  When  running  as  an  indirect command file, the "DTR>"
            prompt is not displayed on the VT125  text screen, and thus, the LA100 "is not
            told to empty it's buffer".  Therefore,  to encourage the the LA100 to get its
            business done, one needs to print something to the VT125 text screen.  I tried
            printing some spaces and some line  feeds  and  that seemed to work, if I also
            put in another PLOT RESYNC.  Thus my empirical solution to the problem (with a
            grateful acknowledgement to Jim Starkey) is the following
             
                   plot wombat
                   plot hardcopy
                   plot resync
                   print " ", skip 10, " "
                   plot resync
                   print "<ESC>[5i"        ! turn on copy of text to LA100
                   print "That was a Wombat"
                   print "<ESC>[4i"        ! turn off copy of text to LA100
                   
            We have several VT125/LA100 workstations.  This empirical "patch" works on all
            of them.  I am not really sure why  this works or if it will work for everyone
            else.  However, I have yet to see  a spoiled plot with these three extra lines
            added, but I must admit that I haven't tried all possible plots!]
             
             
            Terry Golden, Credit Swiss
             
            Some people can't afford some of  DEC's  software so you sorta do work arounds
            for their products.  I  am  presenting  mine  here, and that is to essentially
            monitor your system with an output  qualifier  inside the batch command job in
            here.  A little bit later on, like  the  next morning, all I do is I come back
            and I READY MONITOR, which is  the  output  file.   I've set up a table called
            MONDEF of all the symbols with  the  various types on the monitor record which
            are listed on the back of the utilities  guide and in essence what I have done
            is trick the CROSS on a double basis, I'm  addressed it here looking at  modes
            so I find all the modes then go  back  and look at the modes that are in front
            of it.  The way that the monitor utility records things is it records it in an
            accumulative basis, so what you  are  interested  in is taking the second from
            the first and on for item [computing  differences].  What I have done there in
            essence in the monitor record I've set up  a set of compute field for the var-
            ious states of the executive.  
             
                   $submit monitor     !start monitor under batch
                   
                   $dtr                ! the next day run dtr
                   DTR> ready monitor
                   DTR> :mondef        ! establish some definitions
                   DTR> find monitor with type = modes
                   DTR> find current cross monitor with rec.type > monitor.rec_type
                   DTR> plot x_y all rec_time, ((kernal+exec+super+user)/
                           (kernal+exec+super+user+idle))("%CPU Used")
                   DTR> plot connect
                   DTR> plot lr
                   

                                                                                         44






            Now very simply what I do is just say  PLOT  X_Y - the reason I do that is be-
            cause [PLOT] DATE[_Y] does not work, it  sort of gives you an access violation
            - all record time, that is the klunk values, in essence just add up everything
            except the idle time, divide that  by  everything including idle time, and you
            have a little plot that comes back  and tells you what your percent CPU utili-
            zation is.  What I usually do after  that is follow that by states for I/O and
            file accessing so in essence  I  can  draw  little  plots and say what sort of
            [things are] going on in the  system.  [Applause]   [Request from the floor to
            put this in the Wombat Examiner and/or VMS  Date Book.]  [Golden]  I will give
            you the record [definition] but it has like,  it goes out to about 6 pages and
            we'll be here till 11  o'clock.  [Larry  Jasmann]  We  need to put this in the
            library.  [Bob Lott] There was  an undocumented utility that came somewhere in
            VMS called Meeter which gave you  some pretty nice statistics for plotting CPU
            performance, disk usage, that sort of thing.  In fact, I use that in my shop.
             
             
            Bob Lott, E. I. DuPont, Wilmington, DE
             
            This particular magic I call "DATATRIEVE Eliminates an IBM Cardpunch".  A year
            ago this past January, we  were  faced  with  really having converting all our
            applications to the point that we did  not  need the key punch except for one.
            In this particular instance, we  were  sending  some  -  in  the DuPont Co.  -
            something that we refer to FIXED  ASSET  VOUCHER DATA to some business systems
            in Delaware over a remote job entry link and in keypunching this data, the way
            they showed negative values, or  credits  if  you  will,  they did it by over-
            punching the last digit.  Some of  you  are  familiar with it, I see some nods
            and hear some yeps.  Well we  wanted  to eliminate the key punch, and this was
            the last straw, so here is what I did.  
             



























            45






                   01  FAV_REC.
                       05  CARD                  PIC IS 9.
                       05  DEPT                  PIC IS 99.
                       05  PLANT                 PIC IS 99.
                       05  VOUCHER               PIC IS 9(4).
                       05  ACCOUNT               PIC IS 9(4).
                       05  ACNT_MODIFIER.
                           07  UNIT              PIC IS X(4).
                           07  ITEM              PIC IS 99.
                           07  ZERO              PIC IS 9         DEFAULT IS "0".
                           07  SPACE             PIC IS X         DEFAULT IS " ".
                       05  DECSRIPTION           PIC IS X(40).
                       05  SUMMARY                                REDEFINES DESCRIPTION.
                           07  TRANS_SUSPENS     PIC IS X(4).
                           07  UNIT_DEPRECIATED  PIC IS X(12).
                           07  BLANK             PIC IS X(24).
                       05  COST                  PIC IS S9(8)     USAGE IS COPM_5.
                       05 COST_PIECES.
                           07  FIRST_SEVEN       PIC IS X(7).
                           07  LAST_ONE          PIC IS X.
                       05  YEAR_ACQ              PIC IS XX.
                       05  CLASS                 PIC IS XX.
                       05  TYPE_ENTRY            PIC IS X.
                       05  FILLER                PIC IS XX.
                       05  POLL_CODE             PIC IS XX.
                       05  SEQUENCE              USAGE IS DATE.
                       05  SIGN_BYTE             PIC IS X        COMPUTED BY
                                                 CHOICE
                                                    LAST_ONE = "p" THEN "}"
                                                    LAST_ONE = "q" THEN "J"
                                                    LAST_ONE = "r" THEN "K"
                                                    LAST_ONE = "s" THEN "L"
                                                    LAST_ONE = "t" THEN "M"
                                                    LAST_ONE = "u" THEN "N"
                                                    LAST_ONE = "v" THEN "O"
                                                    LAST_ONE = "w" THEN "P"
                                                    LAST_ONE = "x" THEN "Q"
                                                    LAST_ONE = "y" THEN "R"
                                                    ELSE LAST_ONE
                                                 END_CHOICE.
                   05  FIRST_SEVEN_DIGITS        PIC IS X(7) COMPUTED BY FIRST_SEVEN.
                   ;
            You know you can ignore most  of  the  record definition but you will see I've
            defined something shown in  the  top  in  green  called COSTS USAGE IS COMP_5.
            What happens with COMP_5 is that the sign shares the last byte, it shares some
            of the value with  that  last  digit.    I  redefine  COST  in what I call the
            FIRST_SEVEN here in the LAST_ONE, and some  of you went to the records defini-
            tion presentation that Diana did today and she talked about all the things you
            can do in a record definition.  Here is  a case where I use a COMPUTED BY with
            a CHOICE.  Now if you'll look  at  what  the DEC code generates with the USAGE
            COMP_5, if you have a zero  with  a  minus  sign  in the last digit, you get a
            lower case p.  A one (1) with a minus  sign  is a lower case q, and so on to a
            nine with a minus sign is a lower  case  y.  But this did not quite match what
            the IBM system was expecting, and you  can  see  the  }, J, K, and L and so on
            down through R.  That is really what the IBM system expected.  One other thing

                                                                                         46






            that I've shown in this  record  definition  is  sequence.  In this particular
            instance, I wanted to keep the cards or the records that the clerk  was enter-
            ing in the same order.  
             
                   01  NEW_FAV_REC.
                       05  CARD            PIC IS 9.
                       05  DEPT            PIC IS 99.
                       05  PLANT           PIC IS 99.
                       05  VOUCHER         PIC IS 9(4).
                       05  ACCOUNT         PIC IS 9(4).
                       05  ACNT_MODIFIER.
                           07  UNIT        PIC IS X(4).
                           07  ITEM        PIC IS 99.
                           07  ZERO        PIC IS 9         DEFAULT IS "0".
                           07  SPACE       PIC IS X         DEFAULT IS " ".
                       05  DECSRIPTION     PIC IS X(40).
                       05  SUMMARY                          REDEFINES DESCRIPTION.
                           07  TRANS_SUSPENS     PIC IS X(4).
                           07  UNIT_DEPRECIATED  PIC IS X(12).
                           07  BLANK       PIC IS X(24).
                       05 NEW_COST_PIECES.
                           07  FIRST_SEVEN PIC IS X(7).
                           07  LAST_ONE    PIC IS X.
                       05  YEAR_ACQ        PIC IS XX.
                       05  CLASS           PIC IS XX.
                       05  TYPE_ENTRY      PIC IS X.
                       05  FILLER          PIC IS XX.
                       05  POLL_CODE       PIC IS XX.
                   ;
                   
            In this particular definition which I call the new record definition, you will
            notice I've defined something called NEW_COST_PIECES which was the first seven
            digits  plus  that  SIGN_BYTE  which  was  COMPUTED  BY  the  previous  record
            definition.
             
                   DELETE POPULATE_NEW_FAV_FILE;
                   DEFINE PROCEDURE POPULATE_NEW_FAV_FILE
                   READY FAVS SHARED READ
                   READY NEW_FAVS WRITE
                   FIND FAVS SORTED BY SEQUENCE
                   NEW_FAVS = CURRENT
                   FINISH
                   END_PROCEDURE
                   
            Here is the procedure to  populate  the  new  domain from the original domain.
            FIND THE ORIGINAL DOMAIN SORTED  BY  THIS SEQUENCE NUMBER which represents the
            order in which the records were entered into the domain, and I equate those to
            the new domain.  So I have taken  the  values that I got from the USAGE COMP_5
            and translated them into what was  expected  in the IBM systems in never-never
            land and now have something I can  send  up over my RJE network that is under-
            stood by the IBM and I have indeed eliminated by card punch. [Applause]
             
             



            47






            Wade Scannell, Ship Analytics
             
            We have often had this problem where we get this message saying "FIXED IN NEXT
            RELEASE."   [Part of presentation lost in changing sides of the tape.] ... and
            you search for an EMT instruction and  you  look  before it and see what is on
            the stack.  Well, DEC does not  give  a  cross reference of the words that are
            what EMT code is what directive  so  I  just defined a DATATRIEVE record which
            has a code and the type of the EMT 
             
                   01  EMT_REC.
                       05  CODE        PIC 999.
                       05  TYPE        PIC X(10).
                   ;
                   
                   PRINT EMT WITH CODE = 123
                   
                       OR
                   
                   PRINT EMT WITH TYPE = "CRRG"
                   
            and I sat there with two terminals  and  I wanted to figure out which EMT this
            was, I just say PRINT EMT WHERE  CODE  =  123  or whatever the code was, or it
            works the other way around too.  I just  used  this to fix a bug in P/OS and I
            sent the patch to  DEC  and  they  included  the patch in the overlay run-time
            system for me.  [Applause] It is  a good start for building a disassemble with
            DATATRIEVE.   [Applause]  [Larry  Jasmann]  I  one  time  considered  doing an
            assembler in DATATRIEVE, but whoa, I never considered a disassembler.
             
             
            Richard Copeland, Corning Glassworks
             
            Recently we went to a dual VAX 780 configuration, of course that meant distri-
            buted DATATRIEVE, and it has worked 99.44%  well, we have only had a couple of
            problems with it.  This one really  buffaloed  me for a while so you will pro-
            bably find it entertaining.  We had  a user who had rolling average report and
            they were finding a domain with date field greater than or equal to today (-7)
            to get a seven day  rolling  average.    Find  that collection, write a report
            based on it, print the averages and everyday at midnight this thing kicked off
            and it was good.  Then it  was  distributed  and the today minus seven did not
            work across the network.  It could not pass that expression across the network
            to be processed by the remote node.  So we had to find some way around that.  
             
                       05  seven_days_age computed by (fn$julian("TODAY") - 7).
                       05  date_julian computed by (fn$julian(date_field) - 7).
                   
            So the following was defined  on  the  remote  node, define two fields in that
            record  seven_days_ago  computed  by  FN$JULIAN   of  today  minus  seven  and
            date_julian computed by FN$JULIAN of  date  field minus seven which enabled us
            to say FIND DOMAIN WITH  DATE_JULIAN  GE  SEVEN_DAYS_AGO on the original node.
            That worked pretty well,  but  at  least  it  was syntactically correct and it
            worked most of the time.  But we  ran  into a problem with it.  The next thing
            they wanted to do is after they  got  the  entire week they wanted to break it
            down by days within that week so they said 
             


                                                                                         48






                         FIND A IN DOMAIN WITH DATE_JULIAN GE SEVEN_DAYS_AGO
             
            to get the collection of the last week.  Immediately thereafter 
             
                           FIND B IN A WITH DATE_JULIAN EQ SEVEN_DAYS_AGE
             
            to avoid searching the long domain  again.    When this was run at midnight, B
            was always empty, but when I  said  -  well  resubmit  it and run it again, it
            always worked.  That took a little  head  scratching to figure out.  The solu-
            tion was that the remote node system  clock was three minutes earlier than the
            local  systems  clock  [Laughter]  so  today  rolled  after  the  first  FIND.
            [Applause] Now we run  that  batch  job  at  1:00  AM  and it works just fine.
            [Laughter]  [From the floor] What  do  you  want  to bet that it show up again
            with daylight saving time?  [Pat  Scopelliti]   Maybe DEC has a cluster clock.
            [Laughter]
             
             
            Bob Lott, E. I. DuPont, Wilmington, DE
             
            This one I call "ACCESS CONTROL".   There  is  a lot of work going on in DATA-
            TRIEVE version 3.0 in terms of the access control.  I commented earlier on the
            slave - the auto login that we use  in our shop and we have users running pro-
            cedures that generate reports and in  that  particular  case - we do not care,
            anybody can get a report.   But  those procedures that modify data, whether it
            be deletes, erases, or modifying  specific  fields  in records - we don't want
            those users to have access to all  procedures.   On the other hand when you do
            edits of your procedures, as you all know,  the access control is lost.  So we
            defined a little dummy procedure, which I have shown at the top
             
                   define procedure program
                   end_procedure
                   
                   define procedure foo
                   :program (*)
                   ready yachts
                   for yachts with . . .
                       begin
                           . . .
                       end
                   end_procedure
                   
                   DTR> :foo
                   Enter Password for PROGRAM
                   
            called PROGRAM and as you can see,  it  does nothing but it has lots of access
            control on it.  And I've shown another procedure which I've named appropriate-
            ly as FOO in this case and  the  first  thing  I do in FOO is invoke Procedure
            PROGRAM and request that you get a password prompt.  And then you READY YACHTS
            - do whatever you want to do,  in  our particular case again, these are proce-
            dures that do modify the data so  you would do whatever modifications that you
            wanted to.  Down at the bottom, you  invoke  FOO and I've shown in green FOO -
            because of the access control on it  -  it says Enter PASSWORD for PROGRAM and
            we have choice the name program because  of all these people out there who are
            not computer users - they just  think  that  it  is a program running and that
            they have been requested to enter  the  password  for  it.   So that is how we

            49






            handle the access control - we can  modify  a procedure all we want to and the
            access  control  is  never  lost  because  we  never  edit  PROCEDURE PROGRAM.
            [Applause]
             
             
            Chris Wool, E. I. DuPont, Wilmington, DE
             
            We had a little thing I was trying to  work up the other day.  I was trying to
            establish a report or a print -  I've  shown the example with a FIND here, but
            the problems with  any  records  selection  expression  -  when  you want to a
            STARTING WITH and it is fine if you want to get the values that you are start-
            ing with once so you can put it at a prompt.  So you say 
             
                   FIND domain WITH field STARTING WITH *."prompt"
             
            Well, what if you want to keep the value that they are asking for - the start-
            ing value.  It might be a  telephone  directory  and they can enter B or BR or
            what ever they want for the first  starting characters and you want to be able
            to use that in the title or something? So I tried this 
             
                   declare tmp pic x(20).
                   tmp = *."prompt"
                   find domain with field starting with tmp
             
            I declared a variable of - in this case it was twenty characters, prompted for
            it and then I said FIND DOMAIN  WITH FIELDS STARTING WITH the variable.  Well,
            that does not work because the blanks in  the variable - it is looking for the
            full twenty characters no matter how many are in it.  So I said well, lets try
            something crazy and it turned out that it worked.  I said
             
                   find domain with field starting with tmp||""
             
            (concatenated with a  null  string).    You  use  the double bar concatenation
            [because] it takes the trailing blanks off and it works fine.   [Applause]  By
            the way - this works only on VAX  DATATRIEVE - I tried it in DATATRIEVE-11 and
            complained about the null string.  [Larry  Jasmann] I think you should explain
            about the single bar Chuck Watson concatenation, Jim.  [Jim Starkey] Original-
            ly DATATRIEVE-11 had just a dumb concatenate.   It just stuck two things back-
            to-back.  Then people wanted to  send  out  junk mail with DATATRIEVE and they
            complained so I changed it and then Watson sent  in an SPR.  All we need to do
            is create a second concatenate which beget  a third concatenate.  Seems he had
            some incredibly crock application where he  was building keys - gibberish keys
            out of the random strings  of  digits  and  he  wanted to stick them together.
            [From the audience] It was for  another a database application. [Jim] Yeah, it
            was probably a database application.  It  is  not a whole lot of the story but
            what is what it is.  I think there  is  a comment in there that labels it as a
            Chuck Watson concatenate.
             
             
            Diana Washburn, Hanes Hosiery, Winston-Salem, NC
             
            This is in answer to something that  came  up in the Pre-symposium seminar - I
            mentioned there that it would be answered here and I tried to get someone else
            to do it but failed, so I am  doing  it.   This was part of a REPORT statement
            using the CHOICE within the  PRINT  of  your  report.   It was used to produce

                                                                                         50






            actually two fields.  There was one choice that produced based on the value of
            BEAM sale price and then the second  in  a second field gave kind of a commen-
            tary documentation on how much  percent  off  that  particular thing was.  The
            question was - could it be done in  one  choice  rather than in two.  And - it
            can be.  
             
                   report yachts with builder = "CHALLENGER"
                   print model, beam, price using $$$$,$$$,
                       choice
                           beam le 10 then (price * 0.9)
                           beam bt 11 and 20 then (price * 0.85)
                           else (price * 0.80)
                       end_choice ("Sale"/"Price") using $$$$,$$$,
                       choice
                           beam le 10 then "10% off Retail"
                           beam bt 11 and 20 then "15% off Retail"
                           else "20% off Retail"
                       end_choice
                                         Sale
                   Model Beam  Price    Price
                   
                    35    12  $58,823  $49,999    15% off Retail
                   
                       choice
                           beam le 10 then
                               format(price * 0.9) using $$$$,$$$|" 10% off Retail"
                           beam be 11 and 20 then
                               format(price 0.85) using $$$$,$$$|" 15% off Retail"
                           else
                               format(price * 0.80) using $$$$,$$$|" 20% off Retail"
                       end_choice
                   
                                               Sale
                   Model Beam  Price          Price
                   
                    35    12  $58,823  $49,999 15% off Retail
                   
            If put it in one choice, then you can use the format on the first part and use
            a concatenated expression then to put  in  the  other half.  The difference in
            your print line is that in the  first  one  sale price is the heading over the
            top of the sale price column  - the second one is just kinda pushed over there
            a ways without a heading and in the second one the sale price is centered over
            the two columns together.  [Applause]
             
             
            Meryem Kazanfer, LSI Avionics
             
            I have something  very  simple  and  sometimes  the  simplest  things can help
            you.... What I did is when  I  started  working  with this company, one of the
            tasks that came up was that they had this menu driven system and what they had
            was two jobs and it is the same database - one was used for retrieval purposes
            and the other one for updates.   However  in the morning, a DATATRIEVE job ran
            at 7:30 in the morning and took almost half a day and what it would do is copy
            every single record from UIC to  another  UIC  and  change a little bit on the
            format of the menu retrieval.  It was  holding  up the system.  I made a batch

            51






            and let it run -  submitted  it  at  night  so  I'd  have the operators to run
            "@command" to submit the batch job and it runs the DATATRIEVE.  
             
                   $JOB (1:00)
                   $@A
                   $EOJ
                   
                   ! file A.CMD contains
                   MCR DTR @B
                   
                   ! file B.CMD contains
                   SET DICTIONARY SAMPLE
                   :PROCEDUREA
                   EXIT
                   
            This is basically - from  what  I  remember  of  the  format - I think that is
            simple - probably all of you know it.  [Applause]  One more thing that I found
            out - this is RSX-11M at the time and  in  the notes - they did not have it in
            the manual - but in the update  notes  it  said  a little paragraph -  Oh, the
            QXDR is used to extract the whole  dictionary.   I said that great - just what
            we need - if I extract  the  whole  dictionary  -  and it is a great utility -
            really - since under  [PDP-]11/44]  at  the  time  we  did not have EXTRACT or
            EXTRACT ALL.  So at that time it was great - it was magic.. [Applause]
             
             
            [Unidentified questioner from the audience]
             
            I would like  to  know  if  anyone  else  knows  this  -  we  have a person in
            Louisville at the Federal Land Bank  ... who re-taskbuilt DATATRIEVE under RSX
            in supervisor mode, [with] RMS  resident  libraries,  and it seems to increase
            the pool quite a bit on DATATRIEVE and increase the performance as well. I was
            wondering if anyone has done that.  Is DEC planning on doing that as an option
            or ...  [Bart Lederman]  I  don't really know, there have been unofficial com-
            ments on it.  I do know  that  you  can  get  the instructions to do it out of
            telephone support which means that certainly  somebody  in DEC knows how to do
            it.  It's a little complicated - now  to  do it right you need RMS version 2.0
            and it has to be up to the patch  level its at.  On a lightly loaded system it
            won't make your procedures run  any  faster  but  it will greatly cut down the
            amount of system overhead that is  invoked  by the DATATRIEVE task image so if
            you have a lot of  copies  running.....    [Questioner] All of the RMS overlay
            crap is gone?  [Lederman] Yeah - that is basically the reduction of overhead -
            you have far fewer overlays and far fewer directives and especially if you are
            running on a single disk system if you have  a lot of users it will make a big
            difference. [Questioner]  Why wouldn't DEC do  that as a standard or an option
            in the installation?  [Lederman] You are going  to have to DEC that, but all I
            know is right now you can get  it  from  telephone support but they have had a
            policy about not having anything  that's  specific to one operating system and
            you can't do it on all operating  systems.  Other than that, you're just going
            to have to go to DEC.  But  if  someone wants to do it, I got the instructions
            through telephone support and I understand they will supply.
             
             




                                                                                         52






            Bob Lott, E. I. DuPont, Wilmington, DE
             
            This one I call "DATATRIEVE UPDATING  DECGRAPH".    We have a lot of things we
            are  running from batch.  Run odd hours in the middle of the night - that kind
            of thing.  . . . we have things that we like to update for batch in the middle
            of the night and so I use DATATRIEVE to extract data from some of my databases
            and generate DECGRAPH load files the procedure for which I've shown here. 
             
                   delete create_plot_load_files;
                   define procedure create_plot_load_files
                   ! procedure to create DECGraph "load" files for plant performance data
                   ready performs shared read
                   declare begdate usage is date.
                   declare cost_month pic is xxx.
                   declare month pic is xxx.
                   declare year pic is xxxx.
                   begdate = "TODAY"
                   begdate = begdate + (-14 * 40)
                   cost_month = max prod_date of performs
                   month = fn$str_extract(cost_month,4,3)
                   year = fn$str_extract(cost_month,8,4)
                   find performs with prod_date ge begdate sorted by prod_date
                   ! cost of manufacture
                   on plot:com.grl
                       begin
                           print "TITLE COST OF MANUFACTURE"
                           print "SUBTITLE ", month(-)," ",year(-)
                           print "X_DATA_TYPE TEXT"
                           print "VERTICAL_LABEL $/CWT DMT"
                           print "HORIZONTAL_LABEL COST MONTH"
                           print "Y_LEGEND CAPE FEAR"
                           print "Y_LEGEND OLD HICKORY"
                           for current print col 1,"""",col 2, prod_month(-),col 5,"""",
                               " ",cf_com(-)," ",actual_com(-)
                       end
                   !       .
                   end_procedure
                   
                   $GRAPH/NOINT/LOAD/OUTPUT=COM COM COM
                   
            You can ignore some of the earlier  things,  all I'm really doing is trying to
            decide the date span over which I  want to use in the record selection expres-
            sion.  You will notice that I have  used a FIND and you've heard, I'm sure, in
            the past that you really don't want  to  use  FIND,  that a FOR is better.  In
            this particular instance, the  FIND  is  better  and  I  will explain why in a
            moment.  But at any rate, I'm establishing a collection based on the date span
            that I have shown for my data.    I  am  moving the ON statement to PRINT to a
            file called COM.GRL and the  .GRL  extension is something that DECGRAPH under-
            stands as a load file and  you'll  see  that  I am printing something called a
            TITLE ..... SUBTITLE and in  this  particular instance, I'm printing the month
            and the year of my most  recent  data  and  I'm  printing the X data type, the
            vertical label, the horizontal label, the X  -  the two Y legends and then I'm
            printing data from my collection.    In  this particular case from the current
            collection.   I'm printing a  month  - something I call CF_COM and ACTUAL_COM.
            Without the heading, of course, these  go  to  a file and I really should have

            53






            brought a copy of that file with me  -  I  didn't but at any rate, it's a load
            file which  DECGraph understands.   Then, interactively or from batch, in this
            particular instance, the command I've shown is from batch, you can do -- some-
            where in there its GRAPH/NOINTERACTIVE/LOAD -  I am telling DECGraph that I am
            using a load file then put - I want to create an output file - something call-
            ed COM and is used  for  my  descriptor  in  my  data  file.  With Version 1.2
            DECGRAPH you  can generate the  graphic  output  file - something they call an
            EXPORT file from batch without a terminal being connected and then you can put
            these files on  a  screen  by  simply  doing  a  DCL command: $type file_spec.
            [Applause]  One other thing I  would comment, this procedure has been abbrevi-
            ated - I've do some twenty or  thirty of these with subsequent ON FILE_NAME so
            I do a whole series of plots within this procedure.
             
             
            Awards for Magic Presentations
             
            Runner up awards went to:  Chris  Hines  for  his anti-magic - TV magic cards;
            Wade Scannell for his perpetual  data calender and another excellent presenta-
            tion - a boomerang of sorts; Tim Alterman for his map of Alaska - a boomerang;
            Bob Lott for volume of presentation - a boomerang.
             
            Grand prize went to Pat Scopelliti for his VT240 magic.
             
             
            ______________________________________________________________________________
             
            News Briefs
             
            ______________________________________________________________________________
             
              * Version 3.0  of  VAX-DATATRIEVE  was  in  the  SDC  (software distribution
                center) in the first week  in  September.   Shipment of Version 3.0 should
                have begun on about September 28, 1984.
             
              * This year is the 20th  Anniversary  of  DEC's  36 bit systems - the PDP-6,
                PDP-10, and PDP-20.  The  Large  System Special Interest Group is planning
                special activities at the  Fall  Symposium  to commemorate this auspicious
                event.  You are invited to join them in their celebration in Anaheim.
             
              * Jim Starkey has left Digital to  form  his own software company which will
                supply relational database software  for  UNIX-based systems.  The members
                of the DATATRIEVE community owe Jim  a great debt for creating our produc-
                tive and enjoyable computing environment.  We wish for him all the best in
                his new endeavor.  Wonder if the UNIX world is prepared to "READY YACHTS"?
             











                                                                                         54






            ______________________________________________________________________________
             
            DATATRIEVE Masters
             
            ______________________________________________________________________________
             
            The following list  of  names  identifies  people  who  have agreed to provide
            assistance to other DATATRIEVE users.
             
            Operating System      Phone                      Name and Address
             
            ______________________________________________________________________________
             
               RSX & P/OS    (212) 775-3567          Bart Z. Lederman
                                                     Bankers Trust Co., 28th Floor
                                                     One Bankers Trust Plaza
                                                     New York, NY  10006
             
               RSX & VMS     (617) 839-4411 X5480    Joe Kelly
                                                     Waymon Gordon
                                                     Worchester Road
                                                     North Grafton, MA  01536
             
               IAS & VMS     (509) 376-2227          Chuck Watson
                                                     Battelle Northwest
                                                     Richland, WA  99352
             
               VMS           (202) 426-1345          Larry Jasmann
                                                     10067 Marshall Pond Rd.
                                                     Burke, VA  20015
             
               VMS           (312) 982-7430          James Swanger
                                                     G. D. Searle & Co.
                                                     4901 Searle Parkway
                                                     Skokie, IL  60077
             
               VMS           (206) 396-2501          Darrell Eade
                                                     Naval Undersea Water E. S.
                                                     Hayport, WA  98345
             
               VMS           (302) 366-4610          Chris Wool
                                                     E. I. DuPont
                                                     Engineering Dept., Louviers Bldg.
                                                     Wilmington, DE  19898
             
               VMS           (602) 24404316          Dick Azzi
                                                     Motorola SPS
                                                     Box 2953 MS: P116
                                                     Phoenix, AZ  85062
             
            _____________________________________________________________________________
             
             



            55

