DBDesk for Clipper users

a brief introduction to DBDesk for old Nantuket and CA Clipper by G.Napolitano - February 2014 Introduction Nowadays is almost impossible to find publications about the old and glorious Clipper Language: this one is probably going to be the last one that will be ever written. Sad as it is, after 25+ years of service, the Clipper language is fading into the oblivion. As you may know the last incarnation of Clipper is MaxScript. MaxScript is largely compatible with Clipper, but it is not a Clipper replacement; there is a specific product for this: Alaska-software Xbase++. You simply can't use MaxScript and the product based on it (i.e. DBFree, DBMAX and derivatives) for Clipper Apps convertions. If you need, for whatever reason, to convert an old Clipper program to something usable today, you should use Xbase++. I did it (I'm a long-time Alaska-software customer) and it works. Anyway the final product (unless timeless rewriting) is obviously a text-based interface and today there is little room left for text-based applications. We live in a world of touch-screens, and even the mouse is something prehistoric. MaxScript is a modern language, precisely intended for building new applications, not to convert old ones, and it is conceived to operate exclusively on the web. Even better, the latest versions are very well suited for building web apps for smartphones. If you want to recycle your Xbase skills and build a new application for the modern world MaxScript is your best bet. Anyway there is still some demand for desktop applications: until now you had several choices (Xbase+ +, Harbour, xHarbour, HMG and the like). These are fully-fledged, complex, professional tools for developing x32 (or x64) applications. They all use Xbase as , but do require real programming skill to be used. What made dBASE (and later, Clipper itself) so great and widely adopted in the 80's was the possibility for anyone to develop an application, capable of running everywhere at anytime, without too big efforts: no installers, no dependencies, only one folder containing everything needed. Just pack and go. Great. Today things are quite different (as we all know). There is nothing ubiquitous, universal and simple to be compared with the old world with only one version of MS-DOS and its executables. Except, of course, HTML. HTML is universal. It is everywhere. And usually accompanied by Javascript. So an application relying on HTML and Javascript is the modern counterpart of old Clipper apps: you can pack it in one single folder. You can distribute it as is. You can expect it to have it working on most computers. And without installation too. What about a similar solution but that incorporates Xbase commands and functions?

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.1/14 So it's time to introduce the DBDesk software family. This publication will introduce you to DBDesk, assuming you're already familiar with Clipper or another Xbase dialect. If you are not an Xbase , this document probably won't help you much, but maybe it's worth while reading because offers a viewpoint not available elsewhere. If you're familiar with MaxScript (and DBFree) here you will find important information about the difference between the two families of products. Overview

DBDesk features Runs as a native desktop application in its standard window: no menus, no buttons, no context menu; Totally portable. No installation required: everything is contained into a single folder, no registry tampering, nothing to setup - can run from any position, including a pen drive; It rely on standard components that are already present on almost any Windows target machine and installed by default along with the Internet Explorer Web Browser (IE); Applications can be written in pure HTML (with or without Javascript), in MaxScript and in a combination of the two. The pure HTML mode is a great way to familiarize yourself with this programming technique: of course this way you won't have connections and the interactivity will be limited to static content. The full mode will add the full armament of the Xbase language implementation offered by MaxScript (plus some new features) to your app, including database access in the same old way of dBASE and Clipper. Building an application with DBDesk thus requires at least a basic understanding of HTML, very basic knowledge of Javascript (just the indispensable sintax for function calls) and a good knowledge of MaxScript (that is a super-set of Xbase).

The roots dBASE II was written to minimize typing for people who had to work interactively at the dot prompt. So its designers avoided making the user type quotes when opening a file with the use command, and did make lot of design choices with their users in mind. MaxScript honors this and other old habits of dBase and Clipper programmers, even if they are nowadays considered superseeded. In effect this is a correct assumption: in a modern language, any single line of code the commands should always be clearly distinguishable from parameters (being strings or numbers or other data types). If the language currently identify strings by double hyphens, it should be doing it all over the code. Xbase does not, making the string identification to depend from the contest, and this is represents a serious language inconsistency. Anyway that's the way dBase (and thus Clipper) was originally conceived, and MaxScript does not complains if you write your programs in this old way. If you want greater precision and language consistency, MaxScript (in its DBFree implementation) offers an alternative sintax, more modern and consistent: the “extended mode” that offers significant advantages on clarity side.

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.2/14 Anyway the “extended mode” is only a secondary aspect of MaxScript, and we're not going to cover this topic here. Just notice that it is there if you need. In this document we want to focus on more significant aspects of MaxScript and its similitude to Clipper.

Different versions of DBDesk This publication concerns DBFreeDesk. Sometime in the text this term will be used interchangeably with DBDesk. In effects the two products rely on same exact runtime, but differs in many other ways. When we cite DBDesk will be because the features on the two versions are the same. DBFreeDesk is the freeware version of the commercial product DBDesk, in the same way as DBFree is the freeware version of DBMAX. DBDesk comes in form of a single executable and a folder with all the ancillaries. (the executable can be named DBFreeDesk.exe, DBDesk.exe or DBDeskLE.exe depending by the version) DBDesk components include into a single package a DBFree runtime engine (the Xbase MaxScript interpreter with its database embedded engine) , an embedded web server and an user interface. It runs into a single window as a standard windows desktop application, where all the actions take place. DBFreeDesk and DBDeskLE run only Windows 7 systems with IE9 or later (IE11 suggested). DBDesk run on any system capable of supporting the Chrome Web Browser. Notice that Chrome does not need to be installed on target system. DBFreeDesk full installation weights as low as 1.3MB and can be easily distributed to final users just sending the packed folder by e-mail. DBDEsk is derived from the Open Source Project PHP Desktop written by Czarek Tomczak. His Project website is: http://code.google.com/p/phpdesktop/ Getting Started with DBDesk

Xbase users MaxScript is very simlar to Clipper. Before you continue you may want to see how a MaxScript page for DBDesk will look like.Here below you see the Hello World page with code differentiated by colors: red for the MaxScript code, blue for HTML code, black for the text and in gray for the DBD header (that is a portion of MaxScipt code you're not supposed to edit but must be only added inaltered on top of every page): 01: 02: 03: <% 04: zz := iif(lower(getenv("server_name"))="my",curdir()+"\main",curdir()) 05: _memory := zz+"\global.mem" 06: restore from &_memory 07: set maxlib to &_library 08: CR_LF := chr(13)+chr(10) 09: cSelf := pageName() 10: %> 11: <%=pheader()%> 12: 13: <%=pnavbar()%> 14: <%=container()%> 15:

16:

Hello World!

17:
18:
19: EXIT

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.3/14 20:


21: Edit 22: <%=container(0)%> 23: <%=pfooter()%> 24: 25: And this is the result

Building Apps for DBFreeDesk In its simplest form, building applications for DBDesk can be as simple as building a standard web site made of HTML pages (plain text files) without anything more than HTML5 code and eventually Javascript. Applications can be modules (to be run from a menu into DBDesk main interface) or full-mode (replacing the stock main interface). DBDesk offers a main interface that is made by two only files: the start page and the main menu. Pure HTML pages are static. This means that its content is predetermined and cannot be changed except than editing the HTML code. They can have dynamic effects through Javascript, but the changes available are still predetermined even if by the Javascript code inserted into the page at the time of its creation. Pages can be made dynamic - thus showing live content - only by adding MaxScript code. MaxScript code can build the HTML code from scratch, interact with existing code, and even create Javascript on the fly. Anyway MaxScript it is mostly used to read and write live data to , leaving to HTML (and CSS) most of the weight of providing the user interface. DBFreeDesk can also be used to run DBFree Web Apps originally built for Internet as portable desktop applications. This involves some modification to the original code (unless the web application has been

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.4/14 conceived for dual-use since the beginning).

DBDesk and network interaction DBDESK is not intended to be multiuser. As the good old Clipper running on MS-DOS, a DBDesk application will have only one user: the one that launched the program from the windows desktop. There is no way to effectively know who this can be because there are no direct connections between DBDesk and the NT Autority System, so you can't rely on Windows for this. Of course if you need to implement multiuser applications (for whatever reason) you can use the stock DBMAX login and user management system, adapting the code (i.e. just replacing the headers). DBDesk is not intended to be used on a network drive Don't place the main executable on a networked drive and then run it from different PCs on the network! This way there will be uncertainity about the user identity, and DBDesk will work only for the first user and the first workstation that will use it, setting itself on that configuration. If you need this kind of usage (on a network) simply use DBMAX (or DBFree), that are native network solutions. In effects you can force a multiuser, network usage by applying some programming trick but this is absolutely deprecated because some library DBDesk functions work in an unpredictable way when used in such environment. The user interface

The standard GUI DBDesk comes with this standard interface, organized on two levels: a Start Page and a Main Menu: the default Start Page: start.msp the Main Menu: main_menu.msp located at :\dbfreedesk\main located at c:\dbfreedesk\main\apps

The start page can be easily modified to fit your need because the only thing that really do is to call the main menu. You may also want to modify the top menu (called the NAVBAR) eliminating or doing some personalization.

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.5/14 Both things are very simple and can be done by directly editing start.msp. For instance, to eliminate the navbar all you have to do is to delete the code that calls the function pnavbar().

Building your GUI DBDesk adopts the famous framework Twitter Bootstrap. Bootstrap makes front-end web development faster and easier. It's made for folks of all skill levels, and can be used easily with DBDesk thanks to its integrated functions and modular structure. For an extensive presentation of Bootstrap please visit: http://getbootstrap.com One of the main advantages of using Bootstrap is the vast set of tools available. Most of these tools are available only online as web applications themselves, so you won't have to install anything. Among the others we suggest these: http://bootsnipp.com/forms (online form builder) and http://www.layoutit.com (Layout builder) You can also buy prefab packages from https://wrapbootstrap.com. Of course you're not forced to use Bootstrap in your pages. You can use plain HTML, pure MaxScript or another framework of your choice among the many around.

Using an editor Of course you will have a favorite editor. DBDdesk (as well as all other MaxScript-based products) does not come with an integrated editor (nor a RAD environment). This means that you must choose one. MaxScript pages can be very confusing (often hosting up to three different languages into the same page) and code highlighting is crucial. At the moment the only text-editor fully supporing MaxScript (and MSP pages) is the freeware PSPad Editor with MaxScript (DBFree) extensions. You can download it from DBFree.org web site. Building your first application Before to start your first project you should get a certain familiarity with MaxScript. DBMAX (and DBFree, starting from version 2.0) offer a convenient way to learn MaxScript: the Command Window. Even if the implementation of MaxScript offered by DBFree sometime differs slightly from DBDesk this is the most convenient place to learn MaxScript. I strongly suggest to use it: anyway this involve you into installing at least DBFree on your development PC, and this may cause some conflict with DBDesk. Fortunately you can easily install the Command Window into DBDesk APPS folder as a separate module: just get the i-App from DBFree web site and copy it into the DBDesk main/apps folder; then replace the original header with the one coming with your DBDesk version and go to main menu.

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.6/14 DBDesk modules

Programming

Variables MaxScript follows the Xbase rules, but with a notable exception: each page must be considered a program itself so PUBLIC and PRIVATE variables in facts are equivalent. For those unfamiliar with web pages this concept may sound obscure. The fact is that HTML pages are known as stateless: in other words each page leaves it own life, with its own variables as it was a single executable of the old Clipper (and in effects it is, because MaxScript is a CGI program). So is enough to say that you will have PUBLIC, PRIVATE and LOCAL variables, but all of them will be released when you change page: this unless you explicitlysave them to memory. You can save all the variable of a page simply by issuing the command save to memory. Similarly you will the variables in the next page by issuing restore from memory. If this seems annoying think at the alternative you should use with pure HTML: you will have to use hidden form fields and create a fields for each variable, load the values into fields and call the next page using the web form submit button instead of using a page link.

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.7/14 This is not difficult as it may seems, but it is a lot of code. And thus a lot of typing. As alternative to saving to memory you could assemble a string (or an array) with all variables names and values to be passed to next page as URL parameter. In fact this is the most common method, but using memory is considerably simpler and type-saving.

User Defined Functions MaxScript follow the same rules of Clipper and supports UDFs. In facts all DBFree, DBDesk and the similar products completely rely on UDFs: the only difference is that they are incorporated into the language through an extensive use of libraries. You will be using libraries all the time, and in all and every page. Anyway you will typically use only one or two libraries for each application. You can write your own UDFs but you can't write yiur own libraries: this is reserved to MaxScript developers. UDFs must be placed at the end of the page, and cannot be shared between different pages. A typical UDFs looks (as you would expect) just like this: <% *------function nextWeek(arg_d) *------return(arg_d+7) %> Most of the old Clipper code can be straightforward reusable: this is expecially true with UDFs not involving user input (like those handling dates, strings and numerics). In general Clipper supports the use of the logical data type placeholder arguments when you want to pass default values on optional parameters. In many cases, this logical value is holding the place for numeric or character types. MaxScript offers strict type checking, so placeholders will generate errors if the data type expected does not match the placeholder’s type. Problem: You're supposed to use empty parameters, instead of placeholders. Solution: Remove Clipper placeholder values and use empty parameters instead.Empty parameters clearly document where you depend upon the default value for a parameter, and the strict type checking enables the compiler to identify data type errors.

Preprocessor MaxScript does not support code preprocessing: there is nothing to compile and link, because the pages are compiled just-in-time before to be passed to web browser, so preprocessor directives would add only further complications in an already complicated situation. Consider that MaxScript is going to work in a web authoring tool and its IDE (Being FrontPage™, Studio MX™ or Expression web™), embedded in a web page, interacting with other two languages: XHTML and Javascript. Believe me: adding preprocessor directive wouldn't help. Life is already hard by its own; don't make it harder.

Filename Extensions Indexes MaxScript can operate with different types of indexes, and even with ODBC connections: DBFree is limited to its own index file type, with extension .MTX. Clipper indexes must be abandoned, and new index rebuilt. The good news are that managing indexes in MaxScript is considerably easier than clipper.

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.8/14 Databases Databases are more appropriately called tables in MaxScript: they uses the classical .DBF and .DBT extensions, and have a specific directory (folder) where they must reside on disk, set by a specific variable in the configuration file. This folder (and the variable representing its path) is called the DATADIR. MaxScript uses the term database to mean the folder containing a group of tables specific to a certain application: databases in fact are subfolders of the main directory DATADIR; it must be noticed that databases can not reside on networked drives but only on the physical drives of the host server.

Program files There are no real program files, and there is only one real Windows application, that is the DBDesk executable. DBDesk structure is simple: you have a folder containing files and subfolders, notably one called runtime and one called main. Main is the main interface that you see when you launch DBDesk executable: you can keep it as it, modify it or simply exchange it with another one. No matter what you do this folder cannot be renamed, otherwise DBDesk executable won't recognize it. If it sounds strange let's think it in this way: with Clipper you were used to organize your application into several .PRG files, and link them into a single executable, possibly with different overlays. Main overlay was containing the common functions and procedures, while the other were implementing different modules calling each other, but not calling modules residing into different overlays than the common one. Then the application needed to be linked,eventually with external libraries. With MaxScript and DBFree the situation is not dissimilar: now instead of .PRG files you'll have web pages (identified by the .MSP extension, if going to contain MaxScript instructions) or by HTM if going to have only static contents, and all of them are just organized into one web site, with links to switch from a page to another (that can be organized in menus as well to other forms) so to build your application logic. Your MSP files are by any aspect standard web pages, except for the fact that their contents are built at runtime and not fixed, and can be linked and link to other web pages as standard HTML pages. Then,you can forget about overlays: with DBFree they have no counterpart nor they would be necessary, because there are no limits to the number of pages you can link together into your application. One last difference is linking: there is no need to link anything, your web pages are compiled transparently at runtime (i.e. when the page is picked from webserver to be sent down the line to a web browser that sent a request for it) so as soon as you save your code in the page the modifications are immediately working. There is not even need to stop the webserver: you can work live (even if this is would eventually result al little impractical). Libraries External libraries are supported (and in fact widely used) by DBFree: they have the .MAX file estension, are loaded at runtime by issuing a specific command and usually contain only functions returning some kind of value: notice that at the moment of this writing you can't build your own library yourself but must rely on those made available by DBFree.org. MAX libraries are precompiled and don't contain source code, but only machine code instructions for the MaxScript command processor.

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.9/14 Data Type for Index Key Expressions Clipper was allowing you to specify an expression of any data type for non-compound indexes. MaxScript supports only character data types for index key expressions. If you need to specify a non- character field as key expression you must include a conversion function. Avoid to use an UDF unless you are shure to use the index always in the same page when you declared .it. Like MaxScript, when an index expression consists of a compound key, Clipper, dBASE and FoxPro also require to convert all elements to character strings, so think like to be operating always that way. For example, assuming that VAT_AMNT is a numeric field type of table INVOICES, you can build an index this way: index on str(VAT_AMNT,10,3) to (cIndexfile)

Creating an index in MaxScript does not require a separate statement: you can open the file and generate the index at the same time in a single statement: use CUSTOMER index CUST_ID key customer->CUST_ID

Data Seeking Seeking against a non-char field With MaxScript SEEK and FIND) will only succeed if you first convert the key to character. If the SEEK command does not have a character expression to work with, the result will always be a seek failure (EOF() = .T.) use CUSTOMERS index CUST_VAT key str(customers->VAT_AMNT,10) cKey := 1000 seek str(cKey,10)

This seems an annoyance, but if it is, it is a small one. Consider that you'll be using the web, and on the web everything is text. Parameters and variables passed from a page to another (using web forms or hyperlinks) are passed always and only as strings. Better to get used to it.

Integrity Protection on UNIQUE indexes Clipper allows indexes to be UNIQUE, but it does not guarantee the uniqueness of keys. MaxScript instead will not insert duplicate index keys for indexes created UNIQUE. If you try to insert a duplicate value the REPLACE will fail, but without raising errors. Is up to you intercept the error using the function UNIQUEVIOL(): use CUSTOMERS index CUST2 key customers->CUST_ID unique append blank repl customers->CUST_ID with 110 if uniqueviol()

? "ERROR: Duplicate customer ID" endif

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.10/14 Writing User Defined Functions MaxScript let you define you functions like Clipper was; the main difference is that if an UDF conflicts with an internal function (i.e .they have the same name) your UDF is ignored, and the internal one takes precedence. This feature, often undervalued, can cause strange behavings and hard times to programmers while debugging a function that accidentally have a conflicting name: the changes made at the code of the function in the page seems not to sort any effect. This is because the function is never executed, being a mere duplicate of an higher priority function already present in a library or in the core of the language. In such cases changing the name in something unique will suffice. Another thing to keep always in mind is that your functions will be available only to the page where you defined them: web pages does not communicate each other, and there is no way to share a common set of functions among them (except by using a library). One last thing about UDFs: they must be placed at the bottom of the page, possibily after the tag and after any javascript code.

Example of file: tester.msp

Hi. This is a test page.
Today is <%=tryMe()%> and are past <%=testMe(140)%> days. Click here to go back to main page

<% function testMe(nnn) return str(nnn*2) function TryMe() return dtoc(date()) %>

Arrays MaxScript offers mono-dimensional arrays (vectors) and multidimensional arrays (square and cubic matrixes). This is a sample of creatying a vector of strings: ainit( "myVector","104","O'BRIAN","WILLIAM","BOSTON","MA",”USD”) Vectors can contain different data types: ainit(“myVector”, 11021, date(), time(), “READY-TO-SHIP”,”KG”,125.50) Handling square matrixes is easy: nRows := 10 nColumns := 2 declare mySquare[nRows,nColumns] for iii=1 to nRows mySquare[iii,1] := “ROW” + str(iii) + “-COL 1” mySquare[iii,2] := “ROW” + str(iii) + “-COL 2” next

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.11/14 Handling cubic matrixes is a little trickier: nRows := 10 nColumns := 2 nLayers := 3 declare myCube[nRows,nColumns] for rrr=1 to nRows for ccc=1 to nColumns for lll=1 to nLayers myCube[rrr,ccc,lll] := “R”+str(rrr)+”-C”+str(ccc)+”-L”+str(lll) next next next Ragged arrays The CA-Clipper 5.x convention of ragged arrays with cells pointing to other cells is not supported. Pseudoclasses Obviously there are no pseudoclasses like: Error , Get , TBrowse , TBColumn

Printing MaxScript accepts all the printing commands (PRINT, ?, ??) but obviously it prints out everything to the currently selected output device, that is not a printer, but the web page containing the code itself. You can always print to file, specifying the full path and name, but the file will go only on your server filesystem, not on user's computer. Familiarize yourself with this concept: user's computer is out of reach. There are a numbers of security features on it (not talking about those built into the browsers) that forbidden you to access it. Even javascript cookies could pose problems nowaday; just forget to access user's file system. So why bothering to print out to file? To offer downloads. You build your file (a report or everything else) and then you save it on your server, in a folder designated for internet access. Then you build a response page for the user with the link to that file. When he or she clicks on it the web server software offers to browser to download it. Simple. Fast.And neat. It's only matter of some SET ALTERNATE TO and SET ALTERNATE ON/OFF. The beauty is that you can build a downloadable version of every pager, while assembling the one to be displayed, so to offer it to user for printing. It is enough to prepare a link with some javascript code like javascript:print()

SAY..GET..READ The familiar @ SAY...GET..READ commands are unsupported. Remeber that you are working on a web page, that has no live connection with the server, so there is no way to support interaction directly. While working on the web it is all matter of sending page up and down the line. Once your page is assembled by MaxScript it is passed back to web browser, than send it down to user's browser. Then it forgets about it forever. Unless the browser sends back the same page with something intresting in it (i.e. submitting the web form you have put into the page). Think it in this way: instead of SAYs you just put plain HTML text (including pictures), in place of GETs you put web form fields and for READ you use a submit button. The page that is going to receive the values typed by users into web form fields is specified in the form declaration. Unfortunately there is no convenient counterpart for PICTURE clause. For example:

PROCEDURE doRegister

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.12/14 @ SAY “Your name” GET cName @ SAY “You surname” GET cSurName @ SAY “Your ZIP code” GET cZip READ

Will translate into:

Your name

Your name

Of course this is a oversimplification: if you decide to turn to the web you won't be satisfied by the poor-looking results of this code. You'll soon find yourself adding pictures, bioxes, coloer, tooltips, fancy buttons and so on. Anyway the concept remains somewhat valid.

MENU TO There is nothing like this in MaxScript. You won't really need it. HTML offers a superb way to link any word to any page. Building a menu is simply a matter of putting several hyperlinks in a row (or a column). Of course there are unnumbered sophisticated versions of interactive menus written in javascript,free and ready to be put on you pages. Togheter with thousand of other utilities. You can use all of them for your pages without any interference with your MaxScript code: MaxScript processes the page before it is sent to user's browser. Javascript runs only there, and it can't ever notice that someone else (MaxScript) handled the page before of it. See www.javascript.com for some of them.

CREATE TABLE... MaxScript and DBFree can read all DBF tables of level 3. Only .MTX proprietary format indexes are supported. To read NTX (Clipper) and MDX (dBase 4,5 or 2K) indexes you'll need DBMax (the commercial version of MaxScript). DBMax can also be used to easily scale up DBFree applications. This is a sample of the code for building a table at runtime: cDb := cDBpath + "TEST.DBF" cMdx := cDBpath + "TEST.MTX" if not file(cDb) ainit( "aField","FLD1","FLD2","FLD3","FLD4","FDL5") ainit( "aType","C","N","D","L","M") ainit( "aSize",10,10,8,1,10) ainit( "aDec",0,0,0,0,0) create (cDb) from aField, aType, aSize, aDec ? "Rebuilt table " + cDb endif

USING TABLES Opening a table for using it is slightly different from what you may be used to in Clipper or other Xbase languages. First of all you may provide a path (in DOS style) for the table to open, then specify some additional parameters in a precise order where the alias comes last.

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.13/14 These examples show well the usage of this command: cPath := setDb('demo') cDb := cPath + 'CUSTOMERS' use (cDb) new use CUSTOMERS in 0 //-- equivalent to previous statement use CUSTOMERS in 0 alias MASTER use CUSTOMERS in 0 index CUST_BY_NAME key CUST_NAME alias MASTER cNdx := 'cust_by_name' use CUSTOMERS in 0 index (cNdx) key CUST_NAME alias MASTER

DBDesk-for-clipper-users.odt 14/02/2014 - Rev. 1.0 Pg.14/14