700 likes | 760 Views
Learn basic programming elements, variables, and flow control with examples in Xbasic. Explore data types, variable declaration, assignments, and logical operations. Understand how to create user-defined functions and handle error cases effectively. Dive into event handling and form interactions in programming.
E N D
Extreme Xbasic Dr. Peter Wayne
variables assignment flow control Elements of a programming language
character date logical numeric Variables - Simple Types
Explicit: dim myname as c myname="peter" Variable Declaration and Assignment Implicit: hisname="selwyn"
dim fname as c dim lname as c dim myname as c fname="peter" lname="wayne" myname=fname + " " + lname Character Variables ? myname = "peter wayne"
dim today as d today=date() ? today = {02/15/2002} Date Variables
dim istrue as l istrue="alpha">"microsoft" ? istrue = .F. Logical Variables
dim x as n x=12 y=2*x ' * is the multiplication operator ? y = 24.000000 Variables - numeric
x=12 x=x*2 Assignment is Not Algebra
“any” or variant pointer blob time function collection Variables - Complex
“Any” variable type dim anyvar as A anyvar=12 ? anyvar = 12.000000 anyvar=date() ? anyvar = {02/15/2002} anyvar="today is "+anyvar ? anyvar = "today is 02/15/2002"
tables, indexes, queries fields layout objects (forms, buttons, etc.) chunks of memory Pointer variables
Here all properties are restricted except for changing the record:
Navigation and querying is prevented by the property settings.
if (something) then…(else)...end if for…next while…end while select…case…end while end on error goto…resume *for_each() (advanced) Flow Control
x=1 for i=1 to 5 x=x*2 if x>10 then exit for end if next i ui_msg_box("x is",str(x)) if…end if
x=1 for i=1 to 5 x=x*2 next ? x = 32.000000 For…Next
User Defined Functions FUNCTION reverse AS C (input AS C ) dim i as n dim length as n length=len(input) output="" for i=length to 1 step -1 output=output + substr(input,i,1) next i reverse=output end function
Calculate current checkbook balance Can you follow this script? t=table.open("mycheckbook") balance=0 t.index_primary_put("date") t.fetch_first() while .not. t.fetch_eof() amt=if(t.type$"DIE",t.amount,-t.amount) balance=balance+amt t.fetch_next() end while t.close() ui_msg_box("balance is",str(balance,10,2))
Applying a Query to a Table t=table.open("mycheckbook") credits=0 query.filter="type$'DIE'" query.order="" query.options="" qry=t.query_create() t.fetch_first() while .not. t.fetch_eof() credits=credits+t.amount t.fetch_next() end while qry.drop() t.close() ui_msg_box("total credits is",str(credits,10,2))
Events Form, Browse, and Object events Record and Field Events
Form, Browse, Object Events Simplest Example: OnPush event for button The OnPush event for a button is triggered when the button is pressed. You can attach Xbasic code to any event for any object. Of course, the code may not make sense if you attach it to the wrong event!
Sample OnPush event script This next form starts with multiple restrictions. The "Allow Edits" button removes the restrictions. An if..then..else..end if construct is used to toggle the form in and out of editing mode.
Right-click on the object, then choose Events to see a list of the events defined for the type of object. Different objects have different events. Buttons and hotspots have OnPush events:
OnPush event script for "Allow edits" button. "this" refers to the object containing the script, and "topparent" refers to the form containing the button. if this.text="Allow edits" then topparent.Restrict_change = .f. topparent.Restrict_delete = .f. topparent.Restrict_enter = .f. topparent:Browse1.Browse.Readonly = .f. this.text="Prevent edits" this.fill.forecolor="Red" else topparent.Restrict_change = .t. topparent.Restrict_delete = .t. topparent.Restrict_enter = .t. topparent:Browse1.Browse.Readonly = .t. this.text="Allow edits" this.fill.forecolor="Bright Green" end if
Events With few exceptions, there are 2 basic event types: CanXXX events, whose scripts can be used to deny permission for an event, using cancel() OnXXX events, whose scripts fire after the named event occurs Examples: CanSave and OnSave form level events
Sometimes events behave in ways that are not immediately obvious. Button OnPush code: parent.close() This bypasses the CanExit event, but the OnExit event still fires.
Xbasic can work on tables or objects, with similar results. Example: Program a "mark" button for a set-based form that marks either the active child record or the parent and all its children, depending on what has focus before the delete button is pressed. We can use the form's .active_prev() method to determine what had focus before "mark" is pressed.
First, verify that the user wants to perform the marking operation. name_of_active=parent.active_prev() if name_of_active="Browse1" then do_it=ui_msg_box("Confirm","Mark single detail item?",\ UI_YES_NO+UI_SECOND_BUTTON_DEFAULT) else do_it=ui_msg_box("Confirm","Mark entire transaction and all detail items?",\ UI_YES_NO+UI_SECOND_BUTTON_DEFAULT) end if if do_it=UI_NO_SELECTED then end end if
And then perform the mark, in this case with form-level methods: if name_of_active="Browse1" then browse1.mark_record() else lastrec=0 browse1.fetch_first() rec=table.current(2).recno() ' record number of the first browse record while rec<>lastrec lastrec=rec browse1.mark_record() browse1.fetch_next() rec=table.current(2).recno() end while parent.mark_record() end if
t2=table.current(2) t1=table.current(1) if name_of_active="Browse1" then t2.change_begin() t2.mark() t2.change_end(.t.) else t2.fetch_first() while .not. t2.fetch_eof() t2.change_begin() t2.mark() t2.change_end(.t.) t2.fetch_next() end while t1.change_begin() t1.mark() t1.change_end(.t.) end if Alternatively, one can mark the record at the table level using Table-Level Methods
Form-level vs Table-Level Form-level methods: Imitate a live user Field rules are respected Table-level methods Field rules are overridden
Example of field rule CanChangeRecord event for table:
CanChangeRecord event for mycheckdetail.dbf t=table.get("mycheckbook") status=t.status if status="R" then cancel() ui_msg_box("Error",\ "Changes not allowed to reconciled transactions!") else dim shared old_date as d old_date=t.date end if