Procedures [examples]

Display the currently active procedures and functions
DISPLAY_PROCEDURE
// Display the currently active procedures and functions 

set procedure to yourlib
display procedure
display procedure to print

https://www.lianja.com/doc/index.php/DISPLAY_PROCEDURE


Display the currently active procedures and functions
LIST_PROCEDURE
set procedure to yourlib
list procedure
list procedure to print

https://www.lianja.com/doc/index.php/LIST_PROCEDURE


Declare local formal parameters to a procedure or program
LPARAMETERS
procedure proc2
// proc2 does not have access to the lpara1 and lpara2 parameters declared locally in proc1.
//...
return
 
procedure proc1 
lparameters lpara1, lpara2
proc2()
return
 
do proc1 with 10, 40

https://www.lianja.com/doc/index.php/LPARAMETERS


Declare formal parameters to a procedure or program
PARAMETERS
procedure add
  parameters para1, para2
  result = para1 + para2
return
 
private result
do add with 10, 40
? result
        50

https://www.lianja.com/doc/index.php/PARAMETERS


Declare a procedure
PROCEDURE
// File: finance.prg
procedure payment2
  parameters pmt
return pmt
 
procedure future
  ...
return

https://www.lianja.com/doc/index.php/PROCEDURE


Return from a procedure or program
ENDPROC
procedure example_1
  dialog box [has return statement]
  return
  //already exited function
endproc
 
procedure example_2
  dialog box [has no return statement]
endproc

https://www.lianja.com/doc/index.php/ENDPROC


Return from a procedure, function, or program
RETURN
procedure example_1
  do example_2
  // Returns here <---------------
return
 
procedure example_2
  do example_3
return
 
procedure example_3
  if .T.
      return to master //------------^
  endif
return
 
do example_1

https://www.lianja.com/doc/index.php/RETURN


Execute a Lianja procedure, program or stored procedure
DO
procedure name
  parameters a,b,c
  a = b*c
return
//
name(a,10,20)
// is equivalent to
do name with a,10,20

https://www.lianja.com/doc/index.php/DO


Function to determine whether a function or procedure is active
PEXIST
if not pexist("myproc")
    set procedure to mylib
endif

https://www.lianja.com/doc/index.php/PEXIST()


Close the procedure library file
CLOSE_PROCEDURE
set procedure to yourlib
do yourproc
do yourproc2
close procedure

https://www.lianja.com/doc/index.php/CLOSE_PROCEDURE


Open a procedure library file
SET_PROCEDURE
set procedure to statistics
do std with "patrons", "seats"
set procedure to

https://www.lianja.com/doc/index.php/SET_PROCEDURE


Function to return number of parameters passed
PARAMETERS
function print
parameter m_file,m_filter,m_options
if parameters() <>3
    set message to "3 parameters must be passed."
    return .F.
else
    set filter to &m_filter
    report form &m_file &m_options to print
    set filter to
endif
return .T.

https://www.lianja.com/doc/index.php/PARAMETERS()


Function to return number of parameters passed
PCOUNT

 

function print
parameter m_file,m_filter,m_options
if pcount() <>3
    set message to "3 parameters must be passed."
    return .F.
else
    set filter to &m_filter
    report form &m_file &m_options to print
    set filter to
endif
return .T.

https://www.lianja.com/doc/index.php/PCOUNT()


Operators [examples]

Arithmetic operators

Type Description
+ addition returns the first value added to the second
subtraction returns the second value subtracted from the first
* multiplication returns the first value multiplied by the second
* division returns the first value divided by the second
 % modulus returns the remainder of the first value divided by the second
^ exponential returns the first value to the power of the second
** exponential returns the first value to the power of the second
+= shorthand addition adds the first value to the second
-= shorthand subtraction subtracts the second value from the first
*= shorthand multiplication multiplies the first value by the second
/= shorthand division divides the first value by the second
 %= shorthand modulus divides the first value by the second and returns the remainder

Assignment operator

Type Description
= assigment evaluates the expression on the right hand side and stores in the target variable on the left hand side

String operators

Type Description
+ concatenate concatenates the second value to the first
concatenate trimmed concatenates the second value to the first after trimming spaces from the end of the first
|| concatenate concatenates the second value to the first after converting to character

Comparison operators

Type Description
 = equals returns true if the first value is equal to the second.
 == equals returns true if the first value is exactly equal to the second or matches the pattern specified in the second value.
 != not equals returns true if the first value is not equal to the second
 # not equals returns true if the first value is not equal to the second
 <> not equals returns true if the first value is not equal to the second
 < less than returns true if the first value is less than the second
 > greater than returns true if the first value is greater than the second
 <= less than or equal returns true if the first value is less than or equal to the second
 >= less than returns true if the first value is greater than or equals to the second
 $ contained in returns true if the left hand side is contained in the right hand side
 | contains returns true if the right hand side is contained in the left hand side
 ? sounds like returns true if the second value sounds like the first

Logical operators

Type Description
and logical and returns true if first and second values are both true
or logical or returns true if either first or second values are true
xor logical xor returns true if either first or second values are true but not both
not logical not returns the inverse if the right hand side value
 ! logical not returns the inverse if the right hand side value

Increment and Decrement operators

Type Description
++var pre-increment returns value after incrementing the variable
var++ pre-increment returns current value before incrementing the variable
–var pre-decrement returns value after decrementing the variable
var– post-decrement returns current value before decrementing the variable

https://www.lianja.com/doc/index.php/A_Lianja_Primer


Expressions

Expressions and Statements are the building blocks of Lianja programs.

Expressions consists of combinations of operands which can be constant values such as strings, numbers, and dates and operands which are symbols that act on these operands in some way e.g. add two numbers together, concatenate two strings etc.

hello = "Hello"
world = "world"
hello_world = hello + " " + world
 
result = 100 * 500 / 2 - 6

Operator precedence in expressions

When you have multiple expression terms as in this example:

result = 100 * 500 / 2 - 6

As a general guideline, the operations are performed in the following order.

  • Expressions are evaluated from left to right
  • Multiplication, division and exponents are performed before addition and subtraction
  • Expressions in parentheses are evaluated first
  • Mathematical expressions are evaluated before boolean expressions (AND, OR, NOT, XOR)

If in doubt always use parentheses for readability:

result = ((100 * 500) / 2) - 6

 


Values are assigned to memory variables using the the equals = operator.

cVar1 = 'newer value'

 

nVar1 = 10
nVar1 += 10  // 10 + 10 = 20
cVar1 = "Hello "
cVar1 += "World" // "Hello " + "World" = "Hello World"

 

nVar1 = 20
nVar1 -= 10  // 20 - 10 = 10
nVar1 *= 10  // 10 * 10 = 100
nVar1 /= 10  // 100 / 10 = 10
nVar1 %= 3   // 10 % 3 = 1

 

store 'new value' to cVar1, cVar2

 

? 2*3^2
        18
? 2*25%7
      1.00
? date() + 30 - date()
        30

 

cStr1 = [Welcome to Lianja]
? "Lianja" $ cStr1
.T.
 
cStr2 = [Welcome]
// Compares to the end of cStr2
? cStr1 = cStr2
.T.
 
// Compare contents & size
? cStr1 == cStr2
.F.

 

? .T. and .F. or .T.
.T.

 

i=0
do while i <100
    ++ i
enddo

 

i=100
do while i > 0
    --i
enddo

 

? [Hello] + [ ] + [ World]
Hello World
? [Hello     ] - [ World]
Hello World

 

subscript = 10
i10i = 5
? i&subscript.i
         5

 

set strconvert on
echo "This string can add numerics and dates etc. " + 100.89 + " " + date()
 
set strconvert off
echo "This string can add numerics and dates etc. " + str(100.89,6,2) + " " + etos(date())

 

define class product as custom
	productname = "Lianja App Builder"
	version = "3.4"
	proc init(arg1)
		? etos(arg1)
	endproc
	proc getver
		? this.version
	endproc
enddefine
 
oProduct = new product("Hello World")
oProduct.getver()
? oProduct.productname
 
Hello World
3.4
Lianja App Builder

https://www.lianja.com/doc/index.php/Lianja_Operators

 


 

SELECT account_no, ord_date – rec_date as "Delivery Delay";
FROM accounts;
ORDER BY account_no

https://www.lianja.com/doc/index.php/SQL_Date_operators


 

// AND
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE paid_date < date() AND ord_value > 10000;
ORDER BY name, paid_date
 
// NOT
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE paid_date < date() AND NOT ord_value BETWEEN 0 AND 10000;
ORDER BY name, paid_date
 
// OR
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE paid_date < date() OR ord_value > 10000;
ORDER BY name, paid_date
 
// XOR
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE paid_date < date() OR ord_value > 10000;
ORDER BY name, paid_date

https://www.lianja.com/doc/index.php/SQL_Logical_operators


 

SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE paid_date < date() AND ord_value > 10000;
ORDER BY name, paid_date
 
SELECT account_no, ord_value – paid_value as "Outstanding Balance";
FROM accounts;
ORDER BY account_no

https://www.lianja.com/doc/index.php/SQL_Numeric_operators


 

SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE paid_date = date();
ORDER BY name, paid_date
 
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE paid_date <= date();
ORDER BY name, paid_date
 
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE paid_date <> date();
ORDER BY name, paid_date
 
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE name == "%inc%";
ORDER BY name, paid_date
 
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE name | "inc";
ORDER BY name, paid_date
 
SELECT name, address, balance, cost*1.15;
FROM accounts;
WHERE name $ "BigCo inc, BigCo plc";
ORDER BY name, paid_date

https://www.lianja.com/doc/index.php/SQL_Relational_operators


 

SELECT trim(title) || ’ ’ || last_name as "Full Name";
FROM customers;
ORDER BY last_name

https://www.lianja.com/doc/index.php/SQL_String_operators


 

Expressions

Expressions and Statements are the building blocks of Lianja programs.

Expressions consists of combinations of operands which can be constant values such as strings, numbers, and dates and operands which are symbols that act on these operands in some way e.g. add two numbers together, concatenate two strings etc.

hello = "Hello"
world = "world"
hello_world = hello + " " + world
 
result = 100 * 500 / 2 - 6

Operator precedence in expressions

When you have multiple expression terms as in this example:

result = 100 * 500 / 2 - 6

https://www.lianja.com/doc/index.php/A_Recital_Primer


 

Multi lines [examples]

echo "This is a one line command"
echo "This is a ;
multi line ;
command"

Tabs and spaces have no significance in Lianja. Lianja commands can begin on any column of a line. A newline ends the command. If you have particularly long commands, you can extend them over multiple lines by placing the line continuation character ; (semicolon) at the end of each line that is to be continued.

// indented code if much more readable and easier to maintain
for i=1 to 10
    name = "hello world"
    if name = "hello world"
        // indent like this
    endif
endfor

https://www.lianja.com/doc/index.php/A_Lianja_Primer


The statement is the basic unit of programming in any programming language. Statements in Lianja are delimited by a newline.

echo "Hello world"

You can extend statements over multiple lines by placing a ‘;’ at the end of the line:

echo "Hello ;
world" + ;
" this is a multi-line statement"

https://www.lianja.com/doc/index.php/A_Lianja_Primer


 

Lines and Indentation

Tabs and spaces have no significance in Lianja. Lianja commands can begin on any column of a line. A newline ends the command. If you have particularly long commands, you can extend them over multiple lines by placing the line continuation character ; (semicolon) at the end of each line that is to be continued.

echo "This is a one line command"
echo "This is a ;
multi line ;
command"

For better code readability it is recommended that you indent code blocks such as if statements, for loops etc.

// indented code if much more readable and easier to maintain
for i=1 to 10
    name = "hello world"
    if name = "hello world"
        // indent like this
    endif
endfor

https://www.lianja.com/doc/index.php/A_Recital_Primer


 

IF command [examples]

Conditional command execution
IF
use patrons index events, names
seek "BALLET"
if found()
    edit
else
    dialog message "Record not found."
endif

https://www.lianja.com/doc/index.php/IF


Function to execute an immediate IF
IF
event = "drama"
? if(event = "drama", "It's for Drama", "It's not for Drama")
It's for Drama

https://www.lianja.com/doc/index.php/IF()


Function to execute an immediate IF
IIF

 

event = "drama"
? iif(event = "drama", "It's for Drama", "It's not for Drama")
It's for Drama

https://www.lianja.com/doc/index.php/IIF()


The IF command

The if … endif command is how basic decisions are made in Lianja. The if command has a condition and a code body. If the condition evaluates to true then the code body is executed.

name = "bill"
if name = "bill"
    echo "name is bill"
endif

The if … else … endif command allows for two-way control flow.

name = "bill"
if name = "bill"
    echo "name is bill"
else
    echo "name is not bill"
endif

The if … elseif … endif command allows for multi-way control flow.

name = "bill"
if name = "bill"
    echo "name is bill"
elseif name = "tom"
    echo "name is tom"
elseif name = "mike"
    echo "name is mike"
else
    echo "unknown name"
endif
 https://www.lianja.com/doc/index.php/A_Recital_Primer

The if … endif command is how basic decisions are made in Lianja. The if command has a condition and a code body. If the condition evaluates to true then the code body is executed.

name = "bill"
if name = "bill"
    echo "name is bill"
endif

The if … else … endif command allows for two-way control flow.

name = "bill"
if name = "bill"
    echo "name is bill"
else
    echo "name is not bill"
endif

The if … elseif … endif command allows for multi-way control flow.

name = "bill"
if name = "bill"
    echo "name is bill"
elseif name = "tom"
    echo "name is tom"
elseif name = "mike"
    echo "name is mike"
else
    echo "unknown name"
endif

 https://www.lianja.com/doc/index.php/A_Lianja_Primer


if month(date()) = 1 and day(date()) = 1
    echo "Happy New Year\n"
elseif month(date()) = 7 and day(date()) = 4
    echo "Happy 4th July\n"
else
   echo "Today's date is " + dtoc(date()) + "\n"
endif

https://www.lianja.com/doc/index.php/Lianja_Flow_Control_and_Looping


Functions [examples]

Declare a User Defined Function (UDF)
FUNCTION
// Function to return product of two numbers
function atimesb
  parameters a, b
  result=a*b
return result
 
? atimesb(5,10)
        50
 
//or
function atimesb(a, b)
  result=a*b
return result
 
? atimesb(5,10)
        50

https://www.lianja.com/doc/index.php/FUNCTION


Return from a function
ENDFUNC
function example_1
  dialog box [has return statement]
  return .t.
  //already exited function
endfunc
 
function example_2
  dialog box [has no return statement]
endfunc

https://www.lianja.com/doc/index.php/ENDFUNC


Check whether a function has been declared
FUNCTION_EXISTS
function add18
parameter dob
return gomonth(dob,18*12)
 
if function_exists('add18')
    attainmajority = add18(date())
endif

https://www.lianja.com/doc/index.php/FUNCTION_EXISTS()


 

Functions can be called like built-in functions: postfixing the name of the function with brackets containing any arguments, e.g.

myudf(m_var,"Hello World",123.45,{12/03/2010})

In this case, parameters are passed by value: a copy of the memory variable is passed to the module and the original memory variable is not accessible within the called module.

Alternatively, the function can be called using the do command and specifying the arguments in the with clause, e.g.

do myudf with m_var,"Hello World",123.45,{12/03/2010}

https://www.lianja.com/doc/index.php/A_Recital_Primer


 

myudf(m_var,"Hello World",123.45,{12/03/2010})

In this case, parameters are passed by value: a copy of the memory variable is passed to the module and the original memory variable is not accessible within the called module.

Alternatively, the function can be called using the do command and specifying the arguments in the with clause, e.g.

do myudf with m_var,"Hello World",123.45,{12/03/2010}

With do command, parameters are passed by reference: the called module is given the address of the memory variable so the memory variable itself can be altered.

 https://www.lianja.com/doc/index.php/A_Lianja_Primer


// Passing Parameters by Reference

myudf(@m_var)

https://www.lianja.com/doc/index.php/Lianja_Functions


FOREACH statement [examples]

Iterate over each element of an array or member of an object
FOREACH
// static array
numbers = array(1,2,3,4,5,6,7,8,9,10)
foreach numbers as elem
    ? elem * elem
endfor
 
// associative array
private myarray = array("Name" => "Lianja", "Description" => "database")
foreach myarray as key => value
    echo "key=" + key + " value=" + value + "\n"
endfor

https://www.lianja.com/doc/index.php/Lianja_Flow_Control_and_Looping

https://www.lianja.com/doc/index.php/FOREACH


 

FOREACH statement

The FOREACH command simply gives an easy way to iterate over arrays. FOREACH works on arrays and objects, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable.

There are two syntaxes; the second is a minor but useful extension of the first:

// static array
private myarray = { "hello", "world" }
 
foreach myarray as value
    echo value
endfor
 
// associative array
private myarray = array("Name" => "Lianja", "Description" => "database")
foreach myarray as key => value
    echo "key=" + key + "value=" + value
endfor

https://www.lianja.com/doc/index.php/A_Recital_Primer


 

// static array
private myarray = { "hello", "world" }
 
foreach myarray as value
    echo value
endfor
 
// associative array
private myarray = array("Name" => "Lianja", "Description" => "database")
foreach myarray as key => value
    echo "key=" + key + "value=" + value
endfor

https://www.lianja.com/doc/index.php/A_Lianja_Primer


FOR statement [examples]

Processes a list of commands in a loop for a specified number of times
FOR
for i = 1 to 10 step 2
    ?i*2
next

https://www.lianja.com/doc/index.php/FOR


FOR statement
for var = startvalue to endvalue [step stepvalue]
    // commands
endfor

The FOR … ENDFOR command repeats the commands between the FOR and the ENDFOR statement.

The startvalue specifies the loop start point and endvalue the loop end point. These may be numeric or date values.

The FOR…ENDFOR command is equivalent to a counter based DO WHILE … ENDDO set of commands but FOR … NEXT is faster.

If the optional STEP stepvalue is specified, then the FOR … ENDFOR loop will increment by stepvalue. This value can be a positive or negative number. If stepvalue is not specified then the FOR … ENDFOR loop will increment by 1.

The looping will continue until either endvalue is reached or an EXIT command is encountered.

If a LOOP command is encountered, then control returns to the start of the FOR … ENDFOR loop.

for i = 1 to 10 step 2
    if i % 1 = 1
        loop
    endif
    echo i*2
endfor

https://www.lianja.com/doc/index.php/A_Recital_Primer


The looping will continue until either endvalue is reached or an EXIT command is encountered.

If a LOOP command is encountered, then control returns to the start of the FOR … ENDFOR loop.

for i = 1 to 10 step 2
    if i % 1 = 1
        loop
    endif
    echo i*2
endfor

https://www.lianja.com/doc/index.php/A_Lianja_Primer


for i = 1 to 100 step 10
    ? i * i
next

https://www.lianja.com/doc/index.php/Lianja_Flow_Control_and_Looping


 

DO WHILE command [examples]

Repeat a block of commands while a specified condition is true
DO WHILE
do while condition
    // code body
enddo

If an EXIT statement is encountered then the DO WHILE loop is exited.

If a LOOP statement is encountered, then control returns to the head of the DO WHILE loop.

// scan through a database table displaying information about an event
use events
seek "OPERA"
do while event = "OPERA"
    echo event, seats*price
    skip
enddo

https://www.lianja.com/doc/index.php/A_Lianja_Primer

https://www.lianja.com/doc/index.php/DO_WHILE


Force control to beginning of a looping command
LOOP
use patrons index events, names
do while not eof()
    if deleted()
        loop
    endif
    display event, name, seats, seats * price
    skip
enddo

https://www.lianja.com/doc/index.php/LOOP


 

Force exit from a DO WHILE loop
EXIT
use patrons index events
seek "BALLET"
do while not eof()
    if event<>"BALLET"
        exit
    endif
    display name, event, seats, seats * price off
    skip
enddo

https://www.lianja.com/doc/index.php/EXIT


DO WHILE statement

The DO WHILE command repeats the commands between the DO WHILE and the ENDDO statement, until a specified condition becomes false.

do while condition
    // code body
enddo

If the specified condition is true, then all commands within the DO WHILE loop will be executed. If the specified condition is false, then the first statement following the ENDDO will be executed.

If an EXIT statement is encountered then the DO WHILE loop is exited.

If a LOOP statement is encountered, then control returns to the head of the DO WHILE loop.

Statements within the DO WHILE must be properly nested.

// scan through a database table displaying information about an event
use events
seek "OPERA"
do while event = "OPERA"
    echo event, seats*price
    skip
enddo

https://www.lianja.com/doc/index.php/A_Recital_Primer


open database southwind
use order_details order orderid in 0
use orders in 0
total = 0
do while not eof()
    if shipvia = 1
        skip
        loop
    endif
    select order_details
    seek orders.orderid
    do while order_details.orderid = orders.orderid
        total = total + (order_details.quantity * order_details.unitprice);
          * (1 - order_details.discount)
        skip
    enddo
    select orders
    echo "Order total for order " + orders.orderid + " = " + total + "\n"
    skip
    total = 0
enddo

https://www.lianja.com/doc/index.php/Lianja_Flow_Control_and_Looping


DO CASE command [examples]

Multiple choice selection command
DO CASE
do case
    case mColor = "red"
        // do something
    case mColor = "blue"
        // do something else
    otherwise
        // any other mColor value
endcase

https://www.lianja.com/doc/index.php/DO_CASE


Execute an immediate case statement
ICASE

 

accept "Enter a command: " to command
&(icase(upper(command) = "BROWSE", "browse",;
 upper(command) = "DIR", "dir",;
 "Set message to [Unknown command.]"))

https://www.lianja.com/doc/index.php/ICASE()


The DO CASE command

The DO CASE command selects one course of action out of many alternatives. Lianja evaluates each CASE condition in turn. As soon as one of the conditions evaluates to true the code body for that CASE is executed and any further case statements are ignored. Following execution of the code body, the program continues after the ENDCASE statement.

OTHERWISE If an OTHERWISE statement is present and no CASE condition evaluates to true the OTHERWISE code body is executed.

ENDCASE If no CASE condition is true and there is no OTHERWISE statement specified, then control skips to the next command following the ENDCASE.

CASE statements, as with all of the other Lianja statements can be nested. In other words, a CASE statement can contain further DO CASE commands.

do case
    case upper(command) = "BROWSE"
        echo command
    case upper(command) = "DIR"
        echo command
    otherwise
        echo "Unknown command."
endcase

https://www.lianja.com/doc/index.php/A_Recital_Primer


do case
    case upper(command) = "BROWSE"
        echo command
    case upper(command) = "DIR"
        echo command
    otherwise
        echo "Unknown command."
endcase

https://www.lianja.com/doc/index.php/A_Lianja_Primer


do case
case month(date()) = 1 and day(date()) = 1
    echo "Happy New Year\n"
case month(date()) = 7 and day(date()) = 4
    echo "Happy 4th July\n"
otherwise
   echo "Today's date is " + dtoc(date()) + "\n"
endcase

https://www.lianja.com/doc/index.php/Lianja_Flow_Control_and_Looping


Return from a list the expression at the specified position
CHOOSE
? choose(2,"One","Two","Three")
Two
 
open database southwind
select employeeid, hiredate,CHOOSE(MONTH(HireDate),'Winter','Winter', ;
'Spring','Spring','Spring','Summer','Summer','Summer','Autumn','Autumn',;
'Autumn','Winter') AS Quarter_Hired from employees
 
 EMPLOYEEID HIREDATE   QUARTER_HIRED
 
          1 09/08/2011 Autumn
          2 08/14/1992 Summer
          3 09/08/2011 Autumn
          4 05/03/1993 Spring
          5 10/08/1993 Autumn
          6 10/17/1993 Autumn
          7 01/02/1994 Winter
          8 03/05/1994 Spring
          9 11/15/1994 Autumn