shortcall
LABEL
,
PARAMETERS

The shortcall statement allows a procedure to call a sequence of statements within the current procedure as a “mini-subroutine”.


Parameters

This statement has two parameters:

label – identifies the beginning of the mini-subroutine. (The end of the mini-subroutine is defined by a return statement or the end of the procedure.) A label is a unique series of letters and numbers that identifies a location within the procedure. The label must begin with a letter, may not contain any spaces or punctuation except for ., _ and %, and must always end with a colon. The colon is not actually part of the label, it simply identifies the series of letters and numbers as a label instead of a field or variable.

parameters – is a list of parameters to be passed to the subroutine. This list is optional, you don’t have to pass any parameters if you don’t need to. See parameter( and setparameter for more information on accessing parameters within a subroutine.


Description

The shortcall statement allows a procedure programmer to call a mini-procedure within the current procedure as a subroutine. Subroutines make it easy to use the same sequence of statements at different times within the same procedure. This allows you to write the statements once and use them again and again rather than duplicating the same statements over and over again. (Note: If you want to call an entire procedure as a subroutine, use the call statement.)

Subroutines normally finish when the end of the procedure is reached. To stop the subroutine before the end of the procedure, use the return statement. The return statement makes Panorama return control to the statement just after the shortcall statement.

The example below groups and totals two fields in the database. Instead of repeating the statements that group and total, they have been placed in a mini-subroutine. They can be called as many times as needed with the shortcall statement.

field "GL Category"
shortcall GroupTotal
field "Pay To"
shortcall GroupTotal
stop
// mini-subroutine
GroupTotal:
    groupup
    field "Debit"
    total
    return

This example has only one mini-subroutine, but a procedure may contain as many mini-subroutines as you wish. Each one must begin with a label and end with a return statement (the last subroutine can end at the end of the procedure, without a return statement.

Parameters

When you call a subroutine you can supply one or more parameters to be passed to the subroutine (each parameter must be separated by a comma). This example performs the same task as the previous example, but passes the field name in a parameter. As you can see, this cuts the number of statements in the main program in half.

shortcall GroupTotal, "GL Category"
shortcall GroupTotal,"Pay To"
stop
// mini-subroutine
GroupTotal:
    field parameter(1)
    groupup
    field "Debit"
    total
    return

You can also use the setparameter statement to modify the value of a parameter passed to the subroutine.

Local Variables

If no parameters are passed to the mini-subroutine, the mini-subroutine will share all of its local variables with the main procedure. The mini-subroutine can access and modify any local variable defined in the main portion of the procedure (or in other no-parameter mini-subroutines within the procedure), and can even create new local variables that will be accessible from the main procedure.

If one or more parameters are passed to the mini-subroutine, the rules change. When parameters are passed, the mini-subroutine will have its own, unique local variables. It cannot access or modify local variables in the main section of the program (unless they are passed to the mini-subroutine as parameters). The mini-subroutine must use the local statement to define its own local variables. In fact, you can even create a local variable in the mini-subroutine that has the same name as a local variable in the main section of the program. The two local variables are kept completely separate and will not interfere with each other.

Calculated Label

The shortcall statement normally jumps to a fixed location, but you can also use a formula as the label parameter. In that case, Panorama will calculate the value of the formula (it should be a text value) and then jump to the corresponding label. (If there is no corresponding label, an error will occur. You can trap this error with the if error statement.)

The example below shows how a calculated shortcall can be used to implement a .CustomMenu procedure. Using the calculated shortcall the procedure can quickly jump to the right spot for each menu item. You could also do this with a series of ifelseif statements, but the calculated shortcall will be much faster if there are a lot of options.

shortcall replace(info("trigger"),"...","")
if error
    message "Unknown menu item: "+info("trigger")
    rtn
endif
... do something after menu item
rtn

Menu.File.Open:
    ...
    ...
    rtn

Menu.File.Close:
    ...
    ...
    rtn

Menu.File.Save:
    ...
    ...
    rtn

Menu.Edit.Cut:
    ...
    ...
    rtn

Menu.Edit.Copy:
    ...
    ...
    rtn

Menu.Edit.Paste:
    ...
    ...
    rtn

If your formula consists entirely of a single field or variable name, Panorama will think that you are trying to do a fixed shortcall.

shortcall myChoice ☞ fixed label

You can force Panorama to use a calculated label by putting parentheses around the field or variable name:

shortcall (myChoice) ☞ calculated label

Note: You can use the info(“labels”) function if you need a list of the available labels in the current procedure.

ShortCall and Goto

You should never, ever use the goto statement to jump into or out of a mini-subroutine. Seriously, we really mean this. Doing this will cause Panorama to lose track of what subroutine it is in, and will almost certainly cause unexpected program behaviour.


See Also


History

VersionStatusNotes
10.0UpdatedCarried over from Panorama 6.0 but now includes the calculated label option that allows the shortcall label to be calculated on the fly. Also now allows parameters to be passed to and from the subroutine using the parameter( function and setparameter statement.