shortcall
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 if … elseif 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

- call -- allows a procedure to call a separate procedure within the current database as a subroutine.
- call( -- allows a procedure to be called as a subroutine within a formula and return a result.
- calledby( -- returns true if this function is in code called by the specified database, the specified procedure, or both.
- callingdatabase( -- returns the name of the database that called this procedure as a subroutine, if any.
- callingprocedure( -- returns the name of the procedure that called this procedure as a subroutine, if any.
- callwithin -- allows a procedure to call a mini-procedure within a separate procedure within the current database as a subroutine.
- callwithin( -- allows a "mini-procedure" to be called as a subroutine within a formula and return a result.
- callwithindatabase( -- returns true if the current procedure was called by another procedure in the same database, false if it was called by a procedure in another database.
- execute -- allows a procedure to call a sequence of statements within the current procedure as a "mini-subroutine".
- execute( -- allows a formula to execute a sequence of statements and return a result.
- executeasap -- executes the specified code at the first possible opportunity, non-atomically.
- executecatcherrors -- is the same as the execute statement, except for the fact that if an error occurs while running, it can be trapped by an if error statement immediately following the executecatcherrors statement.
- executelocal -- is the same as the execute statement, but it shares local variables with the procedure that called it.
- farcall -- allows a procedure to call a separate procedure within a different database as a subroutine.
- farcallwithin -- allows a procedure to call a mini-procedure within a separate procedure in a different database as a subroutine.
- getproceduretext( -- gets the contents (source code) of a procedure.
- info("parameters") -- returns the number of parameters passed to a subroutine.
- info("procedurestack") -- returns the contents of Panorama's procedure call stack.
- parameter( -- is used to transfer data between a main procedure and a subroutine.
- parameterentity( -- returns the entity (field or variable) associated with a subroutine parameter, if any.
- return -- ends a subroutine.
- returnerror -- passes an error back to the current subroutines calling procedure.
- setparameter -- is used to transfer data from a subroutine back to the main procedure that called it.

History

Version | Status | Notes
10.0 | Updated | Carried 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.