goto
goto
LABEL

The goto statement allows a procedure to arbitrarily jump from one spot to another within the procedure.

Parameters

This statement has one parameter:

label – is the spot the procedure is supposed to jump to. 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..

Description

The goto statement jumps directly to another spot in the current procedure. We recommend that you avoid the goto statement if possible. The goto statement tends to make it difficult to understand the logic of a procedure, code with a lot of goto statements is often called “spaghetti” code. However, sometimes judicious use of the goto statement can simplify your code.

The example below jumps back to the beginning of the procedure if there is an error. This procedure has one label, tryOpen, which is on the first line.

    tryOpen:
    local file,folder,type
    openfiledialog file,folder,type,"ZEPD"
    if file=""
        goto tryOpen
    endif
    opendatabase folder+file

Here is an alternative procedure that does the same thing, but without the goto statement.

    local file,folder,type
    loop
        openfiledialog file,folder,type,"ZEPD"
    while file=""
    opendatabase folder+file

#### Calculated Goto

The goto statement normally jumps to a fixed location, but you can also use a formula as the goto 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 goto can be used to implement a .CustomMenu procedure. Using the calculated goto, 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 calculate goto will be much faster if there are a lot of options.

    goto replace(info("trigger"),"...","")
    if error
        message "Unknown menu item: "+info("trigger")
        rtn
    endif

    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 goto.

    goto myChoice ☞ fixed goto

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

    goto (myChoice) ☞ calculated goto

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

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.
- callerslocalvariablevalue( -- allows a subroutine to access a local variable in the procedure that called it.
- 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.
- case -- allows multiple decisions to be chained together (also see the elseif statement).
- catch -- works with try and endcatch to trap errors in a sequence of statements.
- Custom Database Initialization -- using an .Initialize procedure to automatically run custom code when a database opens.
- debug -- stops the current program, allowing you to examine variables or single step.
- defaultcase -- works together with the case statement to specify statements that will be executed if none of the *case* statements are true.
- disableabort -- prevents loops from being stopped early by pressing SHIFT-COMMAND-ESCAPE or by exceeding the maximum allowed loop time.
- else -- works together with the if statement to specify statements that will be executed for both the *true* and *false* cases.
- elseif -- allows multiple if decisions to be chained together.
- enableabort -- allows the SHIFT-COMMAND-ESCAPE key sequence to stop an endless loop.
- endcase -- marks the end of statements controlled by a previoius case statement.
- endcatch -- works with try and catch to trap errors in a sequence of statements.
- endif -- marks the end of statements controlled by a previoius if statement.
- endloop -- is used at the end of a loop.
- Error Handling -- Techniques for trapping runtime errors instead of letting them abort the program.
- Error Wizard -- Advanced dialog for displaying program errors.
- 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.
- for -- is used at the beginning of a loop that loops a fixed number of times.
- if -- decides what code to execute next.
- info("callerslocalvariables") -- returns a list of local variables defined in the procedure that called the current procedure.
- info("error") -- returns the most recent error message.
- info("labels") -- lists the labels in the current procedure.
- info("procedurestack") -- returns the contents of Panorama's procedure call stack.
- loop -- is used at the beginning of a loop.
- looparray -- is used at the beginning of a loop that loops over the elements of an array.
- loopdataarray -- is used at the beginning of a loop that loops over the elements of a data array.
- loopindex -- allows a procedure to determine how many times a loop has been repeated.
- loopwhile -- is used at the beginning of a loop.
- noimplicitassignment -- does nothing, and is only retained for compatibility with earlier versions.
- nop -- does nothing (**n**o **op**eration).
- onerror -- can be used to catch all errors that are not trapped by if error or try statements.
- onfailedresume -- is used to setup a semi-graceful recovery if a resume statement fails because there was no pause statement.
- parameter( -- is used to transfer data between a main procedure and a subroutine.
- pause -- temporarily pauses a procedure.
- Preventing Endless Loops -- setting up a timeout limit to prevent endless loops.
- quit -- quits Panorama.
- repeatloopif -- decides whether to continue with a loop or to start over again from the top.
- resume -- resumes a procedure that has been temporarily halted with the pause statement.
- resumeaftertask -- resumes after a waitfortask statement.
- return -- ends a subroutine.
- returnerror -- passes an error back to the current subroutines calling procedure.
- setcallerslocal -- allows a subroutine to modify a local variable in the procedure that called it.
- seterror -- changes the error message returned by info("error").
- setparameter -- is used to transfer data from a subroutine back to the main procedure that called it.
- setwaitinglocal -- assigns a value to a local variable in the parent procedure of an asynchronous task, allowing the asynchronouse code to pass a value back to the code that spawned it.
- shortcall -- allows a procedure to call a sequence of statements within the current procedure as a "mini-subroutine".
- stop -- stops all running procedures immediately.
- stoploopif -- decides whether to continue with a loop or to exit the loop immediately.
- throwerror -- causes an immediate error.
- try -- works with catch and endcatch to trap errors in a sequence of statements.
- until -- is used at the end of a loop, and can control how many times the loop is executed.
- usecallerslocalvariables -- temporarily swaps out a subroutine's current local variables with the local variables of the procedure that called this subroutine. The statement can be used only in a subroutine, not in a calling procedure.
- usefunctioncallerslocalvariables -- temporarily swaps out a procedures current local variables with the local variables of the procedure that called this the call(, callwithin( or execute( function.
- usemylocalvariables -- reverses the action of the UseCallersLocalVariables statement, switching back to the current procedure's normal local variables.
- waitfortask -- temporarily pauses a procedure until the specified task is complete.
- while -- is used at the end of a loop, and can control how many times the loop is executed.

History

Version | Status | Notes
10.0 | Updated | Carried over from Panorama 6.0 but now includes the *calculated goto* option that allows the goto label to be calculated on the fly.