home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
rbnotes2.zip
/
EDTORIAL.13
< prev
next >
Wrap
Text File
|
1986-05-01
|
67KB
|
1,960 lines
MICRORIM TECHNICAL NOTE
__________________________________________________________________________
DEBUGGING
DATE : 04/86 NUMBER : EX-4-1
PRODUCT : R5K VERSIONS : 1.01
CATEGORY : PROGRAMMING SUBCATEGORY : DEBUG
__________________________________________________________________________
DESCRIPTION: My program will not work! What do I do now?
EXPLANATION: After writing an R:BASE 5000 or XRW program, the next step
is to get your program to work by going through a process programmers call
debugging.
Getting your program to work is like solving a mystery with the debugging
process providing the clues. Several books have been written on debugging.
You might want to do some further research in your library. However, to
get started, this article presents several basic tips you can apply to
debug your R:BASE and XRW programs.
GATHERING INFO
You can learn a great deal about what is currently happening in your
program by creatively using the following R:BASE commands:
SET MESSAGES ON
SET ERROR MESSAGES ON
SHOW VAR; PAUSE
SET ECHO ON
WRITE "message"
MESSAGES ON
Setting messages and error messages on are the most basic debugging
commands. Without these two commands, you are searching in the dark for
clues.
SHOWING VARIABLES
SHOW VAR;PAUSE should be put at several points in your code. This will
display the current values and data types of your global variables and then
pause, giving you a chance to read them. After you read the variable list,
you can press any key to continue processing your program.
SHOW VAR;PAUSE allows you to see if variables are being properly updated.
Also, if you want to see if a certain section of your code is executing,
put SET VAR TESTSEC TO 0 right above the section and then put SET VAR
TESTSEC TO .TESTSEC + 1 inside the section. If your SHOW VAR command shows
TESTSEC has a value of 1, you know that section of your code has executed
once. If it is 2, it has executed twice, and so on.
TRACING EXECUTION
SET ECHO ON allows you to trace the execution of your program. It works
only on the ASCII version of your R:BASE 5000 program, not the compiled
version. So it is best to debug before compiling and before adding your
macro to your EXPRESS application.
SET ECHO ON is one of the most useful debugging tools because it will cause
each command, in your ASCII command file or macro, to display on the screen
before executing. You will then be able to determine exactly which command
lines are causing which messages and error messages.
If everything is scrolling by too fast for you to read, you can interrupt
program operation by holding down the [CTRL] key and pressing [S]. When
you are ready to resume program operation, press [CTRL] [Q] or [ENTER] to
toggle execution back on. If you prefer, you can send the tracing to the
printer or a file with the OUTPUT command or you can put more PAUSE
commands in your code.
Tracing an EXPRESS generated application is a complex process. SET ECHO ON
will not work on compiled files and EXPRESS uses a lot of compiled files.
A future technical note will explain how to trace execution in an EXPRESS
generated application.
WRITING MESSAGES
If it is not convenient to SET ECHO ON because it makes a mess of your
variable form or for whatever reason, put WRITE commands in your code to
trace the execution of certain modules. Liberal use of the WRITE and SHOW
VAR;PAUSE commands will give you a lot of information.
DISABLING SECTIONS OF CODE
You can disable sections of your code that you think may be causing the
problem and then check to make sure everything else works. This is easily
accomplished by commenting out lines of code with *(...) in R:BASE 5000 and
with {....} in XRW.
MULTIPLE BACKUPS
Always back everything up before beginning a debugging session. This way
you can always get back to the way it was. You might even want to have
several backups of different versions until your program is working.
PATIENCE AND FRESHNESS
Be patient with yourself, take frequent breaks, and have someone else take
a look at your code and debugging tracings. A fresh look may bring
valuable new information.
Instead of output going only to the screen, you can send output to a
printer or to a file to peruse at a later, more refreshed time by using
commands such as:
*(Send output to the printer)
OUTPUT PRINTER WITH SCREEN
RUN TESTPROG
or:
*(Send output to a file)
OUTPUT TESTPROG.TST WITH SCREEN
RUN TESTPROG
GOOD PROGRAMMING STANDARDS
If possible, when writing the original code, use programming standards that
facilitate debugging during the programming process itself. Opinions vary
on this, but you can choose from and add to the following list:
o Program in modules (also known as blocks or subroutines). It is
easier to debug each module separately.
o Use structured programming techniques. Many books and articles have
been written on structured programming techniques. Find one that suits
you and learn from it.
o Write the program so that it is clear and easy to understand.
o Use comments liberally throughout your code. You can make an execute
only version later, without the comments, to operate at optimum speed.
o If speed is an issue for your application, read the Technical Note
Speeding Up Execution Microrim Technical Note number EX-4-2 (catagory:
SPEED and subcategory: PROGRAMMING.) Try to incorporate the programming
techniques mentioned as you write your program. For example, you will
want to avoid setting up loops using the GOTO command. Use the WHILE
command instead.
o You have eight characters for variable names, column names, filenames,
table names, report names, and form names. Try to avoid meaningless
names like V1 or COL3 or TBL4. Discipline yourself to set up and follow
a naming convention. For example: Always use a V as the first character
in a variable name. Make column names different from table names.
Always begin a table, variable, column, report, or form name with a
letter. Do not make variable names and column names the same.
o Initialize all variables to a particular value or data type.
o Clear variables by name rather than by using the CLEAR ALL VARIABLE
command.
o Make sure the printout of your code is the most current. It is a good
idea to print a new one often and include the date and time on each one.
o Keep notes on each module of your program, what it does, what it uses
(forms, reports, files, other modules, etc.), and how it fits into the
big picture.
PROBLEM SOLVING
Follow standard problem solving procedure. Answer the following questions
and try to find someone who will listen to your answers. The person you
talk to does not need to know R:BASE. Sometimes just hearing yourself
answer the questions will jog you into realizing the solution or at least a
possible solution.
o What is it that you want to happen?
o What is actually happening?
o When you applied the tips in this article to get a more detailed
picture of what is happening in your program, what did you find out?
o What is another way to get what you want? Try this alternative.
o Make a guess; what might fix the problem? Try it. No matter how
outrageous you think your guess is, you may be right. Try it.
The debugging process is always one of trial and error. As long as you
keep adequate backups, you have nothing to fear from trying. Use your
imagination and let yourself try anything that comes to mind. This is the
way problems get solved. In the process you will learn more about how
R:BASE 5000 and/or XRW work.
SYNTAX, SPELLING, & DOTS
The most common errors are the result of incorrect syntax, misspellings,
spacing errors, or the old question of "to dot or not to dot" your
variables.
Using your Command Summary card as a guide, look for syntax errors. Check
for transposed letters and often confused characters (upper case letter O
vs. the number 0 and lower case letter L vs. the number 1) in your
commands. Even if the error message does not mention syntax, syntax is
often the problem.
Whenever a variable name is in a position of the command line normally held
by a value, make sure the variable has a dot in front of it. If the
variable name is in a spot that normally contains a variable name and NOT a
value, then the variable must NOT be dotted.
Check for other common mistakes like missing spaces or spaces where there
should not be any. Spacing is particularly important in XRW.
Check for comments without a closing parenthesis, misspellings, and missing
or mismatched ENDIF, ENDWHILE, or END commands. Also, check for a missing
closing quotation mark or quotation marks in your data, forms, or reports
that may be causing problems.
Make sure that you are following all the structural rules of the language.
For example, in XRW all "AT START OF attname" blocks must immediately
follow the FOR EACH ROW... line. In R:BASE 5000, you must not GOTO a LABEL
inside a WHILE or IF block if the GOTO is outside the block.
SUMMARY
Remember that debugging is an art just as programming is. Try new things,
be creative, and when you begin to feel frustrated, take a break.
MICRORIM TECHNICAL NOTE
__________________________________________________________________________
SPEEDING UP EXECUTION
DATE : 04/86 NUMBER : EX-4-2
PRODUCT : R5K VERSIONS : 1.01
CATEGORY : SPEED SUBCATEGORY : PROGRAMMING
__________________________________________________________________________
DESCRIPTION: Now that I have my program running, how can I make it run
faster? What rules should I follow when programming in R:BASE 5000 to
ensure that my code will be efficient?
EXPLANATION: To help you to make your applications as efficient as
possible, we are providing you with the following four checklists:
o Programming
o Post Programming
o Operations & Design
o Memory & Hardware
You will find these checklists listed in the SOLUTION section of this
technical note. Using these checklists as a guide, apply as many of the
items as possible. These checklists are general. If you would like us to
expand on any items in particular and explain them in more detail, please
drop a note to the Technical Notes Editor.
Few of you will be able to take advantage of all the items in the list and
no one item is likely to give you any great speed increase. However, if
you are able to implement several of these suggestions, you may well see a
verifiable increase in the speed of your application.
TIMINGS
If you are interested in making actual timings on your application, you do
not have to sit at the computer with a stopwatch. You can use the internal
clock by making use of the #TIME system variable. For example, put:
SET VAR TIMING INTEGER
SET VAR START TO .#TIME
at the start of the section of code you are timing and put the following
code at the bottom of the section:
SET VAR STOP TO .#TIME
SET VAR TIMING TO .STOP - .START
OUTPUT PRINTER
WRITE "FOR TEST DONE ON: "
SHOW VAR #DATE
SHOW VAR #TIME
WRITE "SECONDS FOR THIS RUN: "
SHOW VAR TIMING
OUTPUT SCREEN
PARSING DEFINED
Throughout the checklists you will find us referring to parsing. By
parsing we mean the way R:BASE takes your code, pulls it apart, and
analyzes it to execute your instructions. Just as you decide how to write
your code by choosing from a number of valid alternatives, we have made
choices about how to parse R:BASE code. Knowing how R:BASE parses your
code will help you to write code that executes faster.
SOLUTION:
PROGRAMMING CHECKLIST
[] Group repeating commands
Group repeating commands together. Grouping all the CHANGE commands,
ASSIGN commands, SET VARIABLE commands, etc., together will reduce disk I/O
which is a major time eater. Whenever the command changes, R:BASE may have
to go look for the new command processor in the RBASE.OVL file.
[] Use WHILE loops
Eliminate duplication of code by putting repeating blocks of code into a
WHILE loop.
Use WHILE loops to process your loops instead of IF and GOTO blocks. The
entire WHILE...ENDWHILE block of code is parsed before execution and will
run faster than other looping methods. The block of code that you are
going to with your GOTO, by comparison, will be parsed one line at a time,
and it will be parsed every time the loop is processed. Parsing takes
time.
[] Use forward GOTOs
When using a GOTO make sure that the LABEL you are going to is between the
GOTO and the end of the command file. If the LABEL is located between the
top of the command file and its GOTO, R:BASE will search all the way to the
end of your program and then start over at the beginning to locate the
LABEL.
[] Put most used block first
If you have a series of IF...ENDIF blocks all stacked in a row, put the
most used IF block at the top of the stack with a GOTO around the rest of
the IF blocks. For example, if the variable CHOICE is usually equal to 300
but occassionally will equal 400 or 500, then set up the IF blocks with the
300 choice at the top.
IF CHOICE = 300 THEN
o
o
o
GOTO THEEND
ENDIF
IF CHOICE = 400 THEN
o
o
o
GOTO THEEND
ENDIF
IF CHOICE = 500 THEN
o
o
o
ENDIF
LABEL THEEND
If you are going to a LABEL with the GOTO command, put the most used LABEL
as close to its GOTO as possible and make sure it is between its GOTO and
the end of the file.
[] Replace IFs with LABELs
The speed of menu processing can be enhanced by creative use of a GOTO and
LABEL...GOTO BOTTOM blocks rather than stacked IF blocks. Simply make the
label name the same as the menu pick. For example, if your menu picks are
A, B, or C:
FILLIN CHOICE USING +
"Enter Your Choice: "
GOTO .CHOICE
LABEL A
*( "A" block code goes here )
GOTO BOTTOM
LABEL B
*( "B" block code goes here )
GOTO BOTTOM
LABEL C
*( "C" block code goes here )
GOTO BOTTOM
LABEL .CHOICE
WRITE "Not a valid choice"
QUIT
LABEL BOTTOM
The LABEL .CHOICE command line is necessary as a safety precaution. If an
operator presses a key that is not a valid option, you don't want R:BASE
looking forever for a label that does not exist.
Put the most popular pick at the top. In this example LABEL A would be the
most popular pick.
[] Fast posting
There are many different ways to post new information to existing rows in
existing tables. The fastest we have tested involves using the report
writer to create a file of data that is subsequently loaded to the table.
Assuming that you are posting a transaction table to a master table, you
would need only three steps. This method assumes that the master table has
only one summary row per customer whereas the transaction table may or may
not have many rows per customer.
First, print a report, into a file, that uses the transaction table as the
base table and does lookups on the master table. Have the report create an
ASCII file that recreates the posted rows in the master table, including
the unique identifying column (such as IDNO or CUSTNUM) as well as the
current date in a POSTDATE date column. The POSTDATE column in the master
table will identify the most current information. This way you can use the
power of the report writer to compute any totals or other calculations that
need to be completed prior to posting. Using the report writer makes it
easy to break on CUSTNUM, for example, and end up printing only one summary
row for each customer into the file.
Second, load the file created by the report to the master table with the
command:
.
LOAD tbl FROM filename
At this point you each posted master record will have two records when all
you really want to have is the most current record. Therefore, as a final
step, purge the outdated master records by printing another report into
another file that prints only the most current rows. Load this final file
into a new current master table. Keep the original master table as an
archive.
The report, for this final step, is done by breaking on CUSTNUM, locating
all the columns in the table on a line, and then marking the line as a
break footer. Print the report with a SORTED BY clause, similar to the
following, to make sure that the last row in each break is the most current
row:
PRINT repname SORTED BY CUSTNUM POSTDATE
Because you marked the line as a break footer, only the most current row
for each customer is printed into the file.
This is an advanced programming concept. If it seems confusing to you,
skip it for now. A future Microrim Technical Note will delve more deeply
into the whole subject of posting and provide a much more detailed
explanation.
[] Use table forms
Using table forms is much faster than using variable forms. See Technical
Note number EX-3-7 Fast Multi-Screen Forms (category: FORMS and
subcategory: MULTI-SCREEN) for a way to do multi-screen data entry using
table forms.
[] Use FILLIN, SHOW VAR, and WRITE instead of variable forms
You can create forms similar to variable forms with a series of FILLIN
commands and it may be faster than variable forms. WRITE and SHOW VAR
commands can be used to display informational items on the screen.
[] SET CLEAR OFF
Reduce disk I/O by using the SET CLEAR OFF command before using CHANGE,
ASSIGN, or LOAD commands. Your application will run faster, but will not
be as safe, because your changes will be written to the memory buffer and
not immediately to disk.
The R:BASE 5000 memory buffer will hold up to 1536 characters. If you have
a power failure, you could lose quite a bit of data depending on how full
the buffer is at the time.
[] Use REMOVE to delete all rows
Before doing any deleting or removing make sure you have a current backup.
If you are deleting all the rows in a large table the following code (that
removes the table and then recreates it) is faster than using the DELETE
ROWS command:
OUTPUT TEMP
UNLOAD SCHEMA FOR tblname
OUTPUT SCREEN
REMOVE tblname
SET ERROR MESSAGE OFF
INPUT TEMP
SET ERROR MESSAGE ON
[] CHANGE vs. LOAD
Some people have found that if you are doing multiple changes on a row and
you have all the column values currently stored in global variables, it may
be faster to use the following LOAD command method, rather than using
multiple CHANGE commands:
DEL ROW FROM tblename WHERE...
SET NULL -0-
LOAD tbl
.var1 .var2 .var3 ...etc.
END
Other people have found the LOAD command method to be slower. It all
depends on whether you have SET CLEAR OFF before doing the multiple CHANGE
commands and then SET CLEAR ON after the CHANGE commands. With SET CLEAR
OFF, the mulitple CHANGE commands will probably be faster.
The LOAD process can be significantly speeded up by loading several rows at
once. For example, the following code loads three rows at one time
SET NULL -0-
LOAD tblname
.var1 .var2 .var3
.var4 .var5 .var6
.var7 .var8 .var9
END
This would be much faster than three separate LOAD blocks. See the article
Loading Many Rows From One Form in the March 1986 R:BASE EXCHANGE for a
detailed example.
[] Keep duplicates out
Use RULES to make sure that duplicates do not get into your table in the
first place. DELETE DUPLICATES has to do so much work that it takes a long
time. It should never be used on a regular basis. If you must DELETE
DUPLICATES, be sure at least one column in the table is keyed and that all
columns that are keyed contain values (i.e., are not NULL). Remember that
DELETE DUPLICATES will only delete duplicates that are an exact match in
every column this includes case on TEXT columns. For example, to the
DELETE DUPLICATES command:
This is a COMMENT
is NOT a match with:
This is a comment
because the case is different on the word comment.
[] Use keys
Using keyed columns can speed up execution enormously. However, keys can
slow things down if used to excess and in situations where keys will not
help. For example, keys do not speed up sorting but keys do speed up WHERE
clause searches under certain conditions.
To speed up WHERE clause searches, the keyed column must be the last one
mentioned in your WHERE clause, must be associated with an EQ (or =)
operator, and must be preceded by an AND (if there is more than one
condition in the WHERE clause).
Keys are also used by the relational commands: INTERSECT, UNION, JOIN, or
SUBTRACT. When using relational commands, make sure that the common
columns in the WITH or FROM table are keyed.
The DELETE DUPLICATES command also will use keys. Make sure one of the
columns in the table is keyed.
Keys take time to build and maintain and use up a considerable amount of
disk space. Therefore, if you will not be using them in one of the above
situations, do not build them in the first place. Keys will slow down data
entry operations such as LOAD, ENTER, and APPEND because it takes time to
build them. Unused keys will slow down the DELETE command because it takes
time to delete the key. Keys will also slow down the PACK and RELOAD
processes.
[] Reduce the number of files
Reduce disk I/O by making small command files into a large one or compile
them as blocks in an R:BASE binary procedure file by using RCOMPILE.
[] Set buffers higher
If you have enough spare memory, you can increase the size of your
computer's memory buffer and perhaps improve the speed. Each buffer uses
528 bytes of memory. You need to add the following command line to your
CONFIG.SYS file on your DOS booter disk or on the root directory of your
hard disk:
SET BUFFERS=16
Without the SET BUFFERS command, your computer will use the default of two
buffers.
This does not increase the size of the R:BASE memory buffer used by the SET
CLEAR command, but it will allow larger portions of the overlay file
RBASE.OVL to be read into memory. Hopefully this will reduce the number of
times R:BASE will have to go to the disk to read the overlay file.
[] Use RUN instead of GOTO
If you have several subroutines that make up your program, using the RUN
command to run the various subroutines will probably be faster than going
to a LABEL with a GOTO command. The GOTO will have to look through your
entire program for its LABEL whereas the RUN will be able to quickly find
the appropriate $COMMAND block or file on your disk.
[] Use SET POINTER wisely
When used correctly, the SET POINTER command can increase the speed of your
application. Use SET POINTER when you are going to be doing multiple
commands on a multiple rows in a table and you are not using keyed access.
For example, if you have 30 columns in the table and you want to load each
column into a variable, you will need to process 30 SET VARIABLE commands
for each row of data in your table. Therefore, it is wise to first set up
a pointer to that row and then use the NEXT command in a WHILE loop to step
through your table.
If, however, you are using keyed access, using the SET POINTER command will
not increase your speed. In a test we did where 45 variables were set to
45 columns in a table, we found the SET POINTER command was no faster then
using keyed access. To enable keyed access you simply put a keyed column
into a WHERE clause and use the EQ operator. For example, the following
code uses keyed access to find the desired row.
SET VAR VCOL1 TO COL1 IN tblname WHERE keycolname EQ value
SET VAR VCOL2 TO COL2 IN tblname WHERE keycolname EQ value
SET VAR VCOL3 TO COL3 IN tblname WHERE keycolname EQ value
SET VAR VCOL4 TO COL4 IN tblname WHERE keycolname EQ value
o
o
o
Determine if you can accomplish what you want without having to go row by
row through the data. The ASSIGN command and the relational commands work
on the entire database all at once. They are much faster than going row by
row through the table with the SET POINTER command. The ASSIGN command is
often as much as 20 times faster than doing the same thing by going row by
row through the table. If you are, for example, adding two columns
together to store in a third column, use the ASSIGN command, not the SET
POINTER command.
The INTERSECT command is also quite fast when the common columns (in the
WITH table) are keyed. Some people find the JOIN...WHERE EQ command to be
faster than the INTERSECT command because of the way these commands are
parsed.
Use the SET VAR command instead of the SET POINTER command to check for the
existence of a value and remember to build a key on the column you are
checking in the WHERE clause. For example:
SET VAR ISTHERE TO colname IN tblname WHERE colname = .varname
IF ISTHERE FAILS THEN
*( the value you are checking does not exist)
ENDIF
[] Implicitly type variables
By using implicit data typing, you may be able to reduce the number of
lines of code. By implicit we mean setting the variable to a value and
letting R:BASE assign the datatype, as opposed to explicit data typing
where you issue a command such as:
SET VARIABLE NUM INTEGER
SET VARIABLE LETTER TEXT
Implicit data typing can be done with commands such as the following:
SET VARIABLE NUM TO 12
SET VARIABLE LETTER TO A
In some cases it is necessary to explicitly type variables, especially when
both number and letter values are valid entries for a variable.
[] SET RULES OFF when not needed
Setting rule checking off can provide significant speed improvement if you
have a large number of rules in your database. When using the LOAD,
CHANGE, EDIT, ENTER or ASSIGN commands, and you are certain that rules will
not be violated, SET RULES OFF so that R:BASE will not do automatic rule
checking. This applies even if you are working with a table that has no
associated rules. We suggest that you SET RULES OFF at the top of every
command file and then set them back on only when you need them. With rules
set off, R:BASE does not have to constantly be checking the RULES table.
[] Use relational commands wisely
Use relational commands carefully. If you are doing a UNION on two tables
that have a many-to-many relationship and several common columns, you will
wait a long time. You have given the computer a very big job to do.
Multiply the number of rows in the first table by the number of rows in the
second and you can see that R:BASE has to make a lot of comparisons. You
might want to consider redesigning so that you can use the JOIN...WHERE EQ,
INTERSECT, or SUBTRACT commands instead of the UNION command.
The fastest relational operation is the JOIN...WHERE EQ. This command does
exactly the same thing as the INTERSECT command, but it does it faster.
Make sure the common column (that the WITH table is using) is keyed. When
you use the JOIN...WHERE EQ command, your common column must not have the
same name, so if your common column is spelled the same in both tables, its
best to use the INTERSECT command or rename the common column in one of the
tables with the RENAME command. Note also that the JOIN command uses only
one common column whereas the INTERSECT command can have many common
columns.
POST PROGRAMMING CHECKLIST
[] Abbreviate commands
Wherever possible, abbreviate commands and command words to their shortest
unique representation. This will speed execution because R:BASE must parse
each character in your commands. The fewer the number of characters, the
less work R:BASE has to do.
In most cases commands can be abbreviated to three letters. There are six
exceptions: PROMPT, PROJECT, ENDIF, and ENDWHILE all require a minimum of
four letters; LABEL must be completely spelled out with all five letters;
and VARIABLE may be shortened to the single letter V. Examples:
SET VARIABLE becomes SET V
WHILE...THEN becomes WHI...THE
REMOVE becomes REM
SORTED BY becomes SOR BY
WHERE becomes WHE
PROJECT becomes PROJ
CLEAR becomes CLE
CHANGE COLUMN becomes CHA COL
EDIT USING becomes EDI USI
OUTPUT PRINTER becomes OUT PRI
We do not abbreviate in Microrim Technical Notes for the sake of clarity.
You will want to have a version of your program without abbreviations and
complete with multiple comments to ease any modifications necessary at a
later date.
[] Reduce number of lines
R:BASE parses one physical line of code at a time so in addition to
grouping like commands, put as many as possible on one physical line using
semicolons to separate them.
The only exceptions are WHILE loops (including all the commands between the
WHILE...THEN line and the ENDWHILE line), the RUN and INPUT commands, and
IF blocks (including all the commands between the IF...THEN line and the
ENDIF line). All the command lines in these exceptions need to be on their
own physical line.
In all other cases, put as many commands on one physical line as possible.
For example, if you are initializing a series of 26 variables to the letter
A using the SET VARIABLE command, try to put as many on one 80-column line
as possible. If all 28 variable names were seven characters long, you
could fit four SET V varname TO A commands on one physical line by
separating them with the semicolon (;). You do not need to put a space on
either side of the semicolon. Your seven physical lines containing four
commands each will execute faster than 28 physical lines of code.
You can also reduce the number of lines by removing all the comments in
your programs. Be careful, however, that you keep the original version
with all the comments, no abbreviations, and only one command per line for
documentation and to make revision easier.
OPERATIONS CHECKLIST
[] Set up good operations
Set up your operational system so that long processes can be done
unattended over night. Examples of long processes include: printing a long
report, building keys on large tables, reloading, packing, relational
commands, etc.
[] Use work table
You can speed up data entry by entering the day's work into a separate work
table that has no keyed columns. Then, at the end of the day, have a
command file go through the input table to do any further error checking.
Finally, APPEND the input table to the master table. Because the master
table does have the appropriate columns keyed, the APPEND command will
automatically build the necessary keys. This will prevent your data entry
operator from having to wait for the keys to be built between rows entered.
Overall, you will not save time because the APPEND with keys will use any
time saved. However, it will seem to the operator that the application is
running much faster. This method works especially well when entering short
rows into a large table. If you have long rows, it is not so critical.
MEMORY & HARDWARE CHECKLIST
[] Use a RAM disk
If you have enough memory, install a RAM disk and copy the RBASE.OVL file
to the RAM disk each time you turn on your computer. Include the drive
designator for the RAM disk as the first item in the DOS search path with
the DOS PATH command. Also, it is a good idea to rename your original file
to RBASE.OLD and then copy it to the RAM disk as RBASE.OVL. This way you
will never have to worry about which one is being executed.
Do not use a RAM disk if you have only 640K bytes of memory and you are
sorting in your application. Using a RAM disk in this case will actually
slow down your appliction because the sorts will not be able to use the
extra 64K normally available.
[] Upgrade your hardware
If you can upgrade your hardware, you may see a dramatic increase in speed.
The IBM PC-AT, the COMPAQ 286, and other PC-AT compatible computers are
considered to be among the fastest. Some people have realized as much as a
500 percent increase in speed from their old systems.
Turbo cards can help improve speed. Make sure you test it with R:BASE
before buying it.
However, be careful not to just get a 286 board for your PC. All this will
do is make your memory look like an AT. This may not increase your speed.
The actual PC-AT is faster because of the improved disk I/O and faster
clock speed. It can pass twice as much information to and from the disk
drives in the same amount of time because it has a 16 bit bus whereas your
PC has only an eight bit bus and because the drives on the PC-AT are
faster.
Other hardware improvements are the new one, two, and three-megabyte memory
boards. With these you can set up a huge RAM disk and put your RBASE.OVL
file in it as well as your application programs and your database. With
disk access eliminated, you may see a dramatic increase in speed.
MICRORIM TECHNICAL NOTE
__________________________________________________________________________
PRINTING REPORTS WITH MONTHLY SUBTOTALS BASED ON DATE COLUMN
DATE : 04/86 NUMBER : EX-4-3
PRODUCT : R5K VERSIONS : 1.01
CATEGORY : REPORTS SUBCATEGORY : MONTHLY TOTALS
__________________________________________________________________________
DESCRIPTION: I want a report that gives me subtotals by month, but I do
not have a text column MONTH in my database. Instead, I have a date column
TRANDATE with the actual transaction date in it. How can I get the report
I need?
EXPLANATION: The R:BASE report writer will break on an entire column.
Getting subtotals by day on your date column would be easy. If you had a
text type MONTH column which contained the name or the number of the month,
it would be easy to break on MONTH to get the monthly subtotals you need.
However, to do monthly subtotals based on a date column requires some
further manipulation.
SOLUTION: Follow these steps to modify your report so that it will
subtotal by month based on a date column:
STEP ONE
Using the DEFINE command, set up a special lookup table MNAMES with the two
columns FIRSTDAY and MONTH by using the following series of commands:
DEFINE dbname
COLUMNS
FIRSTDAY DATE
MONTH TEXT 9
TABLES
MNNAMES WITH FIRSTDAY MONTH
END
STEP TWO
You will need a row for every month that is (or will be) in your data.
Therefore, the first step is to determine all the months that will ever be
in your data.
The example presented here assumes a range of dates from November 1985
through December 1986. The next step is to enter the rows one month at a
time starting with the highest (that is the latest) date. For this
example, the latest date is December 1986. You need to enter the first day
of the month into the FIRSTDAY column and the name of the month into the
MONTH column. Be sure to always enter 01 for the day portion of the
FIRSTDAY date column, 12/01/86, 11/01/86, etc.
Using the LOAD WITH PROMPTS command, enter data into the MNAMES lookup
table starting with the latest month and working back to the earliest month
in your range. The order of data entry is very important.
When you get finished, your MNAMES table should look like the listing on
page two.
FIRSTDAY MONTH
-------- ---------
12/01/86 DECEMBER
11/01/86 NOVEMBER
10/01/86 OCTOBER
09/01/86 SEPTEMBER
08/01/86 AUGUST
07/01/86 JULY
06/01/86 JUNE
05/01/86 MAY
04/01/86 APRIL
03/01/86 MARCH
02/01/86 FEBRUARY
01/01/86 JANUARY
12/01/85 DECEMBER
11/01/85 NOVEMBER
Notice the order the rows are in. The highest date 12/01/86 was entered
first followed by the next highest 11/01/86 and so on down the list of
possibilities. The rows in the MNAMES table must always be in this
physical sequence and there must be a row for every possible month.
STEP THREE
Using the REPORTS command, go into the define mode and define a lookup
variable VMONTH. Assuming TRANDATE is the name of the date column in your
original table, your variable definition will look like this:
VMONTH = MONTH IN MNAMES WHERE FIRSTDAY LE TRANDATE
Pay special attention to the WHERE clause; it is the key to why this method
works. VMONTH will only change when the month changes because the lookup
feature in the report writer finds the first row, and only the first row,
that satisfies the WHERE clause.
For example, when the month changes from January to February, the report
writer will find only the first occurrence of a FIRSTDAY date that is less
than or equal to the February TRANDATE. That first occurrence is 02/01/86.
Even though the rows following 02/01/86 have FIRSTDAY values of 01/01/86,
12/01/85, and 11/01/85 (which are also less than a February date) they are
not found because the report writer will only find the first occurrence.
This is why the order of the rows in the special lookup table is so
important.
STEP FOUR
While still in define mode, define the subtotal variable VTOTAMT to be the
accumulator for the column you want to total for each month. If, for
example, the column you want to total is AMOUNT, your subtotal variable
would be defined as follows:
VTOTAMT = VTOTAMT + AMOUNT
STEP FIVE
Go into locate mode of REPORTS and locate VMONTH and VTOTAMT on the line
where you want your subtotals to print. Next, go into mark mode and set up
a break on the lookup variable VMONTH. When prompted to add to the reset
list, add the VTOTAMT variable. Finally, mark the line where VMONTH and
VTOTAMT are located as a break footer.
STEP SIX
As the final step, remember to include a SORTED BY clause on the PRINT
command to sort by the TRANDATE column. When breaking on a variable the
table is not automatically sorted as it is when breaking on a column.
Therefore, use the following command to print the report:
PRINT repname SORTED BY TRANDATE
MICRORIM TECHNICAL NOTE
__________________________________________________________________________
EXPRESS AND MACROS
DATE : 04/86 NUMBER : EX-4-5
PRODUCT : R5K VERSIONS : 1.01
CATEGORY : EXPRESS SUBCATEGORY : ADDING A MACRO
__________________________________________________________________________
DESCRIPTION: My EXPRESS application has been working fine, but now I want
to make a change to it using option 4 in EXPRESS. When I do this I get the
following error message when EXPRESS tries to read it in:
"I/O error - check for full disk"
EXPLANATION: You previously added a macro to your application that had a
$COMMAND (all capital letters) line in it. Macros added to EXPRESS
applications must NOT have $COMMAND already in them because EXPRESS adds
the $COMMAND line itself. When there are two $COMMAND lines in a row and
EXPRESS tries to read the application back in for further changes, the .API
file is damaged beyond repair. You cannot use EXPRESS to edit the
application again.
SOLUTION: You still have the .APP file, so your application is not lost.
To make further changes to it, however, you will need to edit the .APP file
with RBEDIT or another editor and then recompile it using RCOMPILE to make
the new .APX file.
In the future, make sure that any macro you pull into EXPRESS does not
contain the $COMMAND line.
MICRORIM TECHNICAL NOTE
__________________________________________________________________________
WHAT INFO TO COLLECT WHEN TROUBLESHOOTING R5K MULTI-USER
DATE : 04/86 NUMBER : EX-4-6
PRODUCT : R5K VERSIONS : 1.01
CATEGORY : MULTI-USER SUBCATEGORY : TROUBLE SHOOTING
__________________________________________________________________________
DESCRIPTION: I support R:BASE 5000 Multi-user sites. When one of my
users has a problem, what kinds of information should I collect to help me
troubleshoot the problem?
EXPLANATION: Local area networks (LANs) are much more complex for users
to install, maintain, and operate than a single-user microcomputer. Often
the problems being experienced can be traced to the complexity of the
network. All networks need to have a person assigned as the System
Administrator who knows:
o The exact names and version numbers of all network software.
o How to set up the network hardware and the network software.
o How to maintain the network hardware/software.
o Who your network hardware and software manfacturers' contacts and
technical support personnel are.
o How the network works and what all the pieces do.
If you do not have someone like this you may need to get some training from
the network hardware and network software manufacturers or dealers before
attempting to implement R:BASE 5000 Multi-user.
SOLUTION: Use the following questionnaire to help you gather the
information you will need to effectively trouble shoot multi-user problems.
:
Q. What version of R:BASE 5000 Multi-user are you using?
Make sure that it is the correct version for the network hardware and
software that they are using.
Q. What verison of DOS are you using?
It must be version 3.1
Q. What network hardware are you using? What network software are you
using? Are they officially supported by Microrim? If the network
software is supported, is the version of the network software
supported? If your network software/hardware is not officially
supported by Microrim, does it support PC DOS 3.1 and the IBM NETBIOS?
Are all stations using the same version of the network software?
If your hardware/software combination is not officially supported,
R:BASE 5000 Multi-user may still work if your network system supports
PC DOS 3.1 and IBM NETBIOS.
Carefully check to make sure that all stations in the network are
using the same versions of the network software and the same versions
of R:BASE 5000.
Q. How many stations are there on the network? What is the
configuration (memory, autoexec.bat file, type of computer, type of
hard disk, etc.) of each station? How is the path for each station
set? Do any of the machines have a high speed crystal? Are you using
a math coprocessor chip or any other special hardware, boards, etc.?
This is basic background information. Any one of these elements may
be causing the problem; you can experiment and perhaps determine the
culprit station, component, or software product.
Q. Is the file server an IBM PC-AT or 100% compatible? If a compatible,
what machine is it? Does it have a minimum of 640K? What are the file
handles equal to on the server? Are any special (other than default)
parameters issued when the network is started?
Unless you are using the IBM PC Network, the file server must be
dedicated to being only a file server; there is not enough memory to
do anything else. The server must be an IBM PC-AT or 100% compatible
and it must have a minimum of 640K with file handles set between 60
and 100. Check to make sure that the users know how to set up the
file handles by putting FILES=100 (or whatever number) in the
CONFIG.SYS file and rebooting.
Q. What was each station on the network doing at the time of the
failure? Are any DOS, network, or R:BASE error messages displayed?
What is the exact wording of all the error messages you are getting?
Q. Are any locks being manually set in R:BASE 5000?
If the user is setting up locks, they may not understand that default
locking in R:BASE 5000 usually makes this unnecessary.
Q. Is the R:BASE program, command file, or macro (that is being run)
shared or is it being used locally?. Is it being run from the file
server or from a workstation?
This may tell you whether it is a problem related to the entire
network or exclusive to only one machine.
Q. If the failure occurs during execution of an R:BASE 5000 application,
what command is being executed at the time of the failure? Does the
failure occur consistently in the same place? What error messages are
displayed?
Q. How many people typically are on the network? How many people
typically are in the database? Is it normal for more than one person
to be working in the same database and in the same table at the same
time, or is this an unusual occurance?
This basic information about your environment will help you to
recreate a problem by recreating the environment in which the problem
occurred.
Collecting all this information will give you a more complete picture of
the problem and whether you have a debugging or a network fixing job to do.
MICRORIM TECHNICAL NOTE
__________________________________________________________________________
MARKING YOUR REPORT TO GET IT TO PRINT THE WAY YOU WANT IT
DATE : 04/86 NUMBER : EX-4-7
PRODUCT : R5K VERSIONS : 1.01
CATEGORY : REPORTS SUBCATEGORY : MARKING AND PRINTING
__________________________________________________________________________
DESCRIPTION: My report will not print out the way I told it to print out.
I located all the columns and variables that I want to print using the [S]
and [E] keys, but it will not print. What is wrong?
EXPLANATION: A mandatory step in creating a report is to mark the report.
Either you skipped this step or you need to change the way you did it.
MARK MODE FUNCTIONS
You enter mark mode in the report writer by pressing [M] from the main
menu. In mark mode you can do all of the following:
o Set up breaks to print subtotals and/or organize your data into groups
and subgroups.
o Designate which variables are to be reset to zero at break time.
o Mark each line in your report that either contains an S...E location,
is to be printed as a blank line, or is text information (such as the
name of the report and other descriptive informtion). In other words,
mark all the lines that you want to print on your report.
MARKING RULES
There are several rules relating to report markings that you will want to
keep in mind:
o Lines that are not marked will not be printed.
o Note that it is NOT necessary to mark all 66 lines. You need only
mark those lines that are to be printed. If, for example, you have only
used 10 lines of the possible 66 lines for your report, you will only
need to mark 10 lines. The only time you would mark a blank line, is
when you want to print a blank line or you want the detail in your report
to be double or triple spaced. A line marked with a D will print as
many rows of data as will fit into the pagesize you have selected with
the (S)et option on the main menu.
o Reports print marked lines in a certain order only. Report headings
(HR) are always printed first, then the page headings (HP), followed by
the break headings (H1, H2, etc.), next come the detail lines (D), then
the break footings (F2, F1), then the page footings (FP), and finally the
report footings (FR). If any one of the items is not included, the order
of those that remain is still maintained. Here are samples of acceptable
markings:
HP HR HR HR HR HR
D D HP HP HP HP
FP FR D H1 H1 H1
D H1 H2 H2
F1 D D H3
F1 F1 F2 D
HR FP F1 F3
FR FP F1
FR FP
FR
Here are more perfectly acceptable report markings:
D HR HR HR HR HR
FP D HP HR HP HP
FP D F1 H1 H1
FR F1 F3 H2
F2 D
FP
o Unless a report has at least one detail line (D) or break (H1 or F1)
marked, the report will not print correctly. Instead, if you are sending
the report to the screen, you will get the message:
More output follows - press [ESC] to quit, any key to continue
If you are printing the report to the printer, the most likely symptom is
to see page after page being ejected. Working around this is easy. All
you need to do is have at least one break in the report. You can, for
example, break on a constant report variable. You do not need to print
the break variable.
o Reports will not let you skip lines between markings of the same type
nor will it allow you to split a group of like markings.
For example, the following markings are not allowed:
HR HR HR
HP HP HP
D D H1
H1 D
F1 D F1
D FP FP
FP FR F1
FR FR
o Summary reports that do not have detail lines (D) or break headers
(H1, H2, etc.) but that do have break footers (F1, F2, etc.) will not
print the page headers on the first page of the report.
The following sample markings will prevent the page header from being
printed on the first page:
HR HP HR HR HR
HP F2 HP HP HP
F1 F1 F2 F3 F2
FP FP F1 F2 F1
FR FP F1 FR
FR FR FR
FR
If you want the page header to print on the first page there are two
methods you can use. You can repeat the page header text in the report
header as well as also defining the page header. In this way, the report
header is printed only once on the first page of the report and it will
now include the page header. The alternate solution is to include one
blank break header line (H1). This will allow the page header to print
on the first page, and will add only one blank line for each time the
break level breaks.
SOLUTION: Mark every line of your report paying close attention to the
rules presented above.
MICRORIM TECHNICAL NOTE
__________________________________________________________________________
SEQUENTIALLY NUMBERING WITHIN SUBGROUPS
DATE : 04/86 NUMBER : EX-4-8
PRODUCT : R5K VERSIONS : 1.01
CATEGORY : AUTONUM SUBCATEGORY : NUMBERS IN GROUPS
__________________________________________________________________________
DESCRIPTION: I want to sequentially number the rows within each subgroup
in my transaction table. For example, I want to store a number in a SUBNUM
column that starts at 1 for each customer. I want to number each
customer's transactions. I want to then use the SUBNUM column to be able
to:
o SELECT the nth row for each subgroup. For example, if I select all
the rows WHERE SUBNUM = 1, I will get a listing of all the unique
subgroups
o PROJECT using WHERE SUBNUM = 1 to create a new table that has no
duplicate subgroups.
o Do one to many lookups in reports. I know I will only be able to look
up 40 because you can only have 40 variables but without the SUBNUM
column, I cannot lookup into a many table at all.
SOLUTION:
Before building your sequence numbers using SUBNUM.CMD below, use the
EXPAND command to add the SUBNUM integer column to your table.
SUBNUM.CMD is listed below. Build your command file using SUBNUM.CMD as a
guide. Change the column names to match your actual column names.
This procedure will take at least 1 second for each row in your table
(maybe faster on a PC-AT type computer). That's 3600 rows per hour - plan
your time accordingly.
*( SUBNUM.CMD - this procedure will sequentially number each
customer's rows starting with one. Customers are identified by a
CUSTNUM column and each customer's row numbers are put into an
integer column named SUBNUM)
SET POINTER #3 e3 FOR TABLENAME SORTED BY CUSTNUM WHERE CUSTNUM EXISTS
*(CUSTNUM is the subgroup being numbered. The sort is required to put
each customer group together)
WHILE E3 = 0 THEN
SET VARIABLE VCUST TO CUSTNUM IN #3
*(VCUST is an initial variable)
SET VARIABLE VCUSTC TO CUSTNUM IN #3
*(VCUSTC will be used to compare the first row of the subgroup to
the others)
SET VARIABLE VCOUNT TO 0
*(VCOUNT is the counter variable which holds the number which goes
in the subnum column)
WHILE VCUST = .VCUSTC THEN
*(Here each new row is compared with the first row within each
subgroup)
SET VARIABLE VCOUNT TO .VCOUNT + 1
*(this increments the row counter within each subgroup)
CHANGE SUBNUM TO .VCOUNT IN #3
*(This is where the unique subnumber is inserted in the row)
NEXT #3 E3 *(THIS COMMAND MOVES THE POINTER THROUGH THE TABLE)
SET VARIABLE VCUSTC TO CUSTNUM IN #3
*(this sets the comparison variable VCUSTC to the next row)
IF E3 NE 0 THEN
*(This checks for end of data)
BREAK
*(If end of data is found we are done)
ENDIF
ENDWHILE *(while there are rows for this customer: VCUST = .VCUSTC)
ENDWHILE *(While there are rows in the table)
LOOKING UP IN A MANY TABLE
To allow reports to do one to many lookups when your lookup table has a
SUBNUM column, define a variable to find each row in the subgroup.
There must not be more than 40 rows in each subgroup, or this procedure
will not work because you are limited to 40 variable in the R:BASE 5000
report writer.
For example, define three lookup variables ROW1, ROW2, and ROW3, if you
have a maximum of three rows in each customer group.
Row1 = colname in tblname where custnum eq custnum and subnum eq 1
Row2 = colname in tblname where custnum eq custnum and subnum eq 2
Row3 = colname in tblname where custnum eq custnum and subnum eq 3
MICRORIM TECHNICAL NOTE
__________________________________________________________________________
MAXIMUM NUMBER OF LINES IN RBEDIT
DATE : 04/86 NUMBER : EX-4-9
PRODUCT : R5K VERSIONS : 1.01
CATEGORY : RBEDIT SUBCATEGORY : MAX LINES/SIZE
__________________________________________________________________________
DESCRIPTION: What is the maximum file size that RBEDIT can handle?
EXPLANATION: RBEDIT is the screen editor that we provide with R:BASE
5000. There are two ways to use RBEDIT, at the R> prompt inside R:BASE,
and at the DOS prompt, outside of R:BASE.
RBEDIT is designed to be used on small files. If your file is too large
for RBEDIT you will want to use another editor or ASCII word processor to
work on your file.
SOLUTION: There is an absolute maximum number of lines, regardless of the
number of characters per line, that RBEDIT can handle.
805 lines inside R:BASE
802 lines outside of R:BASE
The size of the file in bytes cannot exceed 64.5K bytes (805 80-character
lines.)
When inside R:BASE there is 64K bytes of user addressable memory. If part
of this 64K is used to store global variables, or for other purposes, the
allowable file size may be smaller. In this case you may wish to first
clear all variables before working on a file that is near the limit.