DBPlus V261 User Guide
DBPlus V261 User Guide
VERSION 7.5
iii
Printer Support . . . . . . . . . . . . . . . . . . . . . . 18 The Project Explorer . . . . . . . . . . . . . . . . . . . . . . .34
Project Explorer . . . . . . . . . . . . . . . . . . . . . 18 Starting a New Project . . . . . . . . . . . . . . . . . . . .34
Query Class . . . . . . . . . . . . . . . . . . . . . . . . 18 Adding an existing file: . . . . . . . . . . . . . . . . . .36
QUIT Command . . . . . . . . . . . . . . . . . . . . . 18 Creating a new file to add to the Project: . . . . . . . . .36
Report Designer . . . . . . . . . . . . . . . . . . . . . 18 A few things to consider . . . . . . . . . . . . . . . . . .36
Rowset Class . . . . . . . . . . . . . . . . . . . . . . . 19 Translating the Project File line . . . . . . . . . . . . . .37
Runtime Application . . . . . . . . . . . . . . . . . . . 19 Converting the pathnames . . . . . . . . . . . . . . . . .37
SAVE … LIKE / LIKE( ) / LIKEC( ) . . . . . . . . . . 19 Converting relative pathnames: . . . . . . . . . . . . . .37
Source Editor . . . . . . . . . . . . . . . . . . . . . . . 19 Opening a .PRJ file in the dBASE Plus Source Editor: . .37
SpinBox Class . . . . . . . . . . . . . . . . . . . . . . 19 Opening a Project . . . . . . . . . . . . . . . . . . . . . . .38
StreamSource Class. . . . . . . . . . . . . . . . . . . . 19 The Details tab. . . . . . . . . . . . . . . . . . . . . . .38
Subform Class . . . . . . . . . . . . . . . . . . . . . . 20 The Source tab . . . . . . . . . . . . . . . . . . . . . . .38
Table View - Context Menu . . . . . . . . . . . . . . . 20 The Viewer tab. . . . . . . . . . . . . . . . . . . . . . .38
TreeView . . . . . . . . . . . . . . . . . . . . . . . . . 20 Creating an Application . . . . . . . . . . . . . . . . . . . .38
XP Theme Support . . . . . . . . . . . . . . . . . . . . 20 Creating a DEO Application . . . . . . . . . . . . . . . . .39
Create Table. . . . . . . . . . . . . . . . . . . . . . . . 20 DEO Folders . . . . . . . . . . . . . . . . . . . . . . . .39
Database Connection Wizard . . . . . . . . . . . . . . . 20 Selecting the DEO Folder For Each File . . . . . . . . .39
Datamodule Code Generation . . . . . . . . . . . . . . 20 Selecting the DEO folder for each file . . . . . . . . . .39
Export Wizard . . . . . . . . . . . . . . . . . . . . . . 21 Building the Executable . . . . . . . . . . . . . . . . . . . .40
Import Wizard . . . . . . . . . . . . . . . . . . . . . . 21 .INI files . . . . . . . . . . . . . . . . . . . . . . . . . . . .40
Miscellaneous. . . . . . . . . . . . . . . . . . . . . . . 21 Encrypted Tables . . . . . . . . . . . . . . . . . . . . . . .41
Multi-Table View . . . . . . . . . . . . . . . . . . . . . 22 OCX and DLL controls . . . . . . . . . . . . . . . . . . . .41
One-Click Windows Application . . . . . . . . . . . . . 22 Using Inno. . . . . . . . . . . . . . . . . . . . . . . . . . .41
Parent/Child Wizard . . . . . . . . . . . . . . . . . . . 22 The Defaults tab . . . . . . . . . . . . . . . . . . . . . .42
Reports . . . . . . . . . . . . . . . . . . . . . . . . . . 22 The Files tab . . . . . . . . . . . . . . . . . . . . . . . .42
Set Order Dialog . . . . . . . . . . . . . . . . . . . . . 22 Flags Parameter (Files tab) . . . . . . . . . . . . . . . .43
SQL Expression Generation . . . . . . . . . . . . . . . 22 The Menu Group tab. . . . . . . . . . . . . . . . . . . .46
Star Filter . . . . . . . . . . . . . . . . . . . . . . . . . 23 The Runtime tab . . . . . . . . . . . . . . . . . . . . . .47
Web Wizards . . . . . . . . . . . . . . . . . . . . . . . 23 The License tab . . . . . . . . . . . . . . . . . . . . . .47
XP Theme Support . . . . . . . . . . . . . . . . . . . . 23 The BDE Settings tab . . . . . . . . . . . . . . . . . . .48
dBASE Plus documentation . . . . . . . . . . . . . . . . . . . 23 The INI tab. . . . . . . . . . . . . . . . . . . . . . . . .48
Typographical conventions. . . . . . . . . . . . . . . . . . 23 The Script tab . . . . . . . . . . . . . . . . . . . . . . .49
Documentation updates and additional information resources23 Building the user interface . . . . . . . . . . . . . . . . . . . .49
Software registration . . . . . . . . . . . . . . . . . . . . . 24 Form design guidelines . . . . . . . . . . . . . . . . . . . . . .50
Goal of form design . . . . . . . . . . . . . . . . . . . . . .50
Chapter 2 Purpose of a form . . . . . . . . . . . . . . . . . . . . . . .50
Installing dBASE Plus and connecting Some guidelines for data entry forms . . . . . . . . . . . . .50
Designing the form layout . . . . . . . . . . . . . . . . .51
to an SQL database server 25 Guidelines for using the z-order. . . . . . . . . . . . . . . .51
What you need to run dBASE Plus . . . . . . . . . . . . . . . 25
Creating a form . . . . . . . . . . . . . . . . . . . . . . . . . .52
HARDWARE . . . . . . . . . . . . . . . . . . . . . . . 25
Using the Form wizard . . . . . . . . . . . . . . . . . . . . . .52
OPERATING SYSTEM . . . . . . . . . . . . . . . . . 25
Using the Form designer . . . . . . . . . . . . . . . . . . . . .52
NETWORKS . . . . . . . . . . . . . . . . . . . . . . . 25
.WFM file structure . . . . . . . . . . . . . . . . . . . . . . . .53
Products and programs in your dBASE Plus package . . . . . . 26
Form class definition . . . . . . . . . . . . . . . . . . . . .54
Installing dBASE Plus . . . . . . . . . . . . . . . . . . . . . . 26
How the contents are generated . . . . . . . . . . . . . . . .54
What happens during installation . . . . . . . . . . . . . . . . 26
Editing a .WFM file. . . . . . . . . . . . . . . . . . . . . . . .54
Un-installing dBASE Plus . . . . . . . . . . . . . . . . . . . . 27
Editing the header and bootstrap . . . . . . . . . . . . . . .55
How to connect to an SQL database server . . . . . . . . . . . 27
Editing properties in the .WFM file . . . . . . . . . . . . . .55
Install and configure the server software. . . . . . . . . . . 27
Types of form windows . . . . . . . . . . . . . . . . . . . . . .55
Configure the Borland Database Engine (BDE) . . . . . . . 28
MDI and SDI applications . . . . . . . . . . . . . . . . . .56
Listing SQL tables in the Navigator . . . . . . . . . . . . . 28
Modal and modeless windows . . . . . . . . . . . . . . . .56
Chapter 3 Customizing the MDI form window . . . . . . . . . . . . .56
Standard features of MDI windows:. . . . . . . . . . . .56
Introduction to programming in dBL 29 Using multi-page forms. . . . . . . . . . . . . . . . . . . . . .57
"Hard coding" vs. visual programming . . . . . . . . . . . . . 29 Global page (forms) . . . . . . . . . . . . . . . . . . . . . .57
Advantages of event-driven programs . . . . . . . . . . . . . . 29 Navigation buttons (form pages) . . . . . . . . . . . . . . .57
How event-driven programs work . . . . . . . . . . . . . . . . 30 Creating a custom form, report, or data module class . . . . . .58
Developing event-driven programs . . . . . . . . . . . . . . . 32 Using a custom class . . . . . . . . . . . . . . . . . . . . . . .58
Creating custom components . . . . . . . . . . . . . . . . . . .59
Chapter 4 Creating custom components . . . . . . . . . . . . . . . . .59
Creating an application 33 Adding custom components to the Component palette . . . .60
Creating an application (basic steps) . . . . . . . . . . . . . . 33 Removing custom components from the Component palette .60
iv
Chapter 5 Selecting components . . . . . . . . . . . . . . . . . . . . .84
Moving components. . . . . . . . . . . . . . . . . . . . . .85
Accessing and linking tables 62 Cutting, copying, pasting, deleting components . . . . . . .85
The dBASE data model . . . . . . . . . . . . . . . . . . . . . 62
Undoing and redoing in the designers. . . . . . . . . . . . .85
Query objects. . . . . . . . . . . . . . . . . . . . . . . . . 62
Aligning components . . . . . . . . . . . . . . . . . . . . .85
SQL property . . . . . . . . . . . . . . . . . . . . . . . 63
Resizing components . . . . . . . . . . . . . . . . . . . . .85
rowset property . . . . . . . . . . . . . . . . . . . . . . 63
Spacing components . . . . . . . . . . . . . . . . . . . . .87
Rowset objects . . . . . . . . . . . . . . . . . . . . . . . . 63
Setting a scheme (Form designer) . . . . . . . . . . . . . . . .87
The row cursor and navigation . . . . . . . . . . . . . . 63
Editing a Text object . . . . . . . . . . . . . . . . . . . . . . .88
Rowset modes . . . . . . . . . . . . . . . . . . . . . . 64
Saving, running, and printing forms and reports . . . . . . . . .88
Rowset events. . . . . . . . . . . . . . . . . . . . . . . 64
Opening a form or report in Run mode . . . . . . . . . . . .88
Row buffer . . . . . . . . . . . . . . . . . . . . . . . . 64
Printing a form or report . . . . . . . . . . . . . . . . . . .88
Field objects . . . . . . . . . . . . . . . . . . . . . . . . . 64
value property. . . . . . . . . . . . . . . . . . . . . . . 64
Using dataLinks . . . . . . . . . . . . . . . . . . . . . 65
Chapter 7
Database objects . . . . . . . . . . . . . . . . . . . . . . . 65 Creating menus and toolbars 90
Accessing a database . . . . . . . . . . . . . . . . . . . 65 Attaching pulldown menus to forms . . . . . . . . . . . . . . .90
Database-level security . . . . . . . . . . . . . . . . . . 65 Attaching popup menus to forms . . . . . . . . . . . . . . . . .90
Database-level methods . . . . . . . . . . . . . . . . . 65 Creating toolbars and attaching them to forms . . . . . . . . . .91
Default Database object . . . . . . . . . . . . . . . . . 65 Creating a reusable toolbar . . . . . . . . . . . . . . . . . .91
Session objects . . . . . . . . . . . . . . . . . . . . . . . . 65 Attaching a reusable toolbar . . . . . . . . . . . . . . . . .91
StoredProc objects . . . . . . . . . . . . . . . . . . . . . . 66 Creating a custom toolbar . . . . . . . . . . . . . . . . . . .92
DataModRef objects . . . . . . . . . . . . . . . . . . . . . 66 Creating menus with the designers . . . . . . . . . . . . . . . .93
Linking a form or report to tables . . . . . . . . . . . . . . . . 66 The designer menu . . . . . . . . . . . . . . . . . . . . . .93
Linking to a table automatically . . . . . . . . . . . . . . . 67 Building blocks . . . . . . . . . . . . . . . . . . . . . . . .93
Linking to a table manually . . . . . . . . . . . . . . . . . 67 Adding, editing and navigating . . . . . . . . . . . . . . . .94
Procedure for using a Session object. . . . . . . . . . . . . 68 Features demonstration . . . . . . . . . . . . . . . . . . . .94
Calling a stored procedure . . . . . . . . . . . . . . . . . . 68 Examining menu file code . . . . . . . . . . . . . . . . . . . .95
Using local and remote tables together . . . . . . . . . . . . . 68 Changing menu properties on the fly . . . . . . . . . . . . .97
Creating master-detail relationships (overview) . . . . . . . . . 68 Menu and menu item properties, events and methods . . . . . .97
Using an SQL JOIN statement . . . . . . . . . . . . . . 69 Toolbar and toolbutton properties, events and methods . . . . .99
Linking master-detail in local tables . . . . . . . . . . . 70
Using the masterSource property . . . . . . . . . . . . . 70 Chapter 8
What is a DataModule? . . . . . . . . . . . . . . . . . . . . . 70 Using the Source editor and other
Creating a DataModule. . . . . . . . . . . . . . . . . . . . 71 code tools 101
Creating business rules in a DataModule. . . . . . . . . 72 Using the Source editor . . . . . . . . . . . . . . . . . . . . . 101
Using a DataModule . . . . . . . . . . . . . . . . . . . . . 72 Two-pane window with tree view . . . . . . . . . . . . . . 102
Notes on the Source editor . . . . . . . . . . . . . . . . . 102
Chapter 6 Creating a new method . . . . . . . . . . . . . . . . . . . . . 103
Using the Form and Report The Code Block Builder for editing code blocks . . . . . . . . 103
designers 73 To create or edit a codeblock . . . . . . . . . . . . . . . . 103
The designer windows . . . . . . . . . . . . . . . . . . . . . . 73 Editing an existing code block. . . . . . . . . . . . . . 104
Design and Run modes . . . . . . . . . . . . . . . . . . . . . 74 The Command window . . . . . . . . . . . . . . . . . . . . . 104
The Form Design Window . . . . . . . . . . . . . . . . . . 74 Typing and executing commands . . . . . . . . . . . . . . 105
The Report Design window . . . . . . . . . . . . . . . . . 75 Executing a block of commands. . . . . . . . . . . . . 105
The visual design is reflected in your code . . . . . . . . . 75 Reusing commands . . . . . . . . . . . . . . . . . . . 105
Component palette . . . . . . . . . . . . . . . . . . . . . . . . 75 Editing in the Command window . . . . . . . . . . . . . . 105
Standard page . . . . . . . . . . . . . . . . . . . . . . . . 76 Saving commands into programs . . . . . . . . . . . . 106
Data Access page. . . . . . . . . . . . . . . . . . . . . . . 78
Data Buttons page (forms) . . . . . . . . . . . . . . . . . . 78 Chapter 9
Report page. . . . . . . . . . . . . . . . . . . . . . . . . . 79 Debugging applications 107
Custom page . . . . . . . . . . . . . . . . . . . . . . . . . 79 Types of bugs . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Using ActiveX (*.OCX) controls . . . . . . . . . . . . . . 79 Using the Debugger to monitor execution . . . . . . . . . . . 107
The Field palette . . . . . . . . . . . . . . . . . . . . . . . . . 80 General debugging procedure . . . . . . . . . . . . . . . . . 108
The Inspector . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Debugging runtime applications . . . . . . . . . . . . . . . . 109
Properties page of the Inspector . . . . . . . . . . . . . . . 81 The Source window. . . . . . . . . . . . . . . . . . . . . . . 109
Events page of the Inspector . . . . . . . . . . . . . . . . . 82 To locate and move to a line number in the Source
Methods page of the Inspector . . . . . . . . . . . . . . . . 83 window . . . . . . . . . . . . . . . . . . . . . . . . . 110
The Method menu . . . . . . . . . . . . . . . . . . . . . . 83 To find a text string in the current program file . . . . . 110
Manipulating components . . . . . . . . . . . . . . . . . . . . 83 The Debugger tool windows . . . . . . . . . . . . . . . . 110
Placing components on a form or report . . . . . . . . . . . 84 Variables . . . . . . . . . . . . . . . . . . . . . . . . . 110
Special case: container components . . . . . . . . . . . . . 84 Watches . . . . . . . . . . . . . . . . . . . . . . . . . 110
v
Call Stack . . . . . . . . . . . . . . . . . . . . . . . . 110 Simple Having Summary Expression . . . . . . . . . . 126
Trace . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Two Summary Expression . . . . . . . . . . . . . . . . 126
Docking the Debugger tool windows. . . . . . . . . . 110 Combining group criteria . . . . . . . . . . . . . . . . . . 127
Excluding variable types . . . . . . . . . . . . . . . . 110 Deleting a row. . . . . . . . . . . . . . . . . . . . . . . . 127
Controlling program execution . . . . . . . . . . . . . . . . .111 Sorting page of the SQL designer . . . . . . . . . . . . . . . 127
Stepping in the Debugger . . . . . . . . . . . . . . . . . 112 Joins page of the SQL designer. . . . . . . . . . . . . . . . . 127
Using breakpoints . . . . . . . . . . . . . . . . . . . . . 112 Including Unmatched Rows. . . . . . . . . . . . . . . . . 128
Setting and removing breakpoints . . . . . . . . . . . 112 Join list box . . . . . . . . . . . . . . . . . . . . . . . . . 128
Working with breakpoints . . . . . . . . . . . . . . . 113 Joins grid . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Running a program at full speed from the Debugger . . . 114 Deleting a join . . . . . . . . . . . . . . . . . . . . . . 128
Running to cursor position . . . . . . . . . . . . . . . 114 Deleting a row . . . . . . . . . . . . . . . . . . . . . . 128
Stopping program execution . . . . . . . . . . . . . . . . 114 Creating joins in the SQL designer . . . . . . . . . . . . . . . 128
Debugging event handlers . . . . . . . . . . . . . . . . . 114
Viewing and using the Call Stack . . . . . . . . . . . . . . . 114 Chapter 11
Watching expressions . . . . . . . . . . . . . . . . . . . . . 115 Designing reports 129
Adding watchpoints . . . . . . . . . . . . . . . . . . . . 115 Report wizard . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Editing watchpoints. . . . . . . . . . . . . . . . . . . 115 To use the Report wizard . . . . . . . . . . . . . . . . . . 130
Changing watchpoint values . . . . . . . . . . . . . . 115 Example of a report created with the Report wizard . . . . . . 130
Wizard-generated Summary Report. . . . . . . . . . . . . 131
Chapter 10 Report designer elements . . . . . . . . . . . . . . . . . . . . 132
SQL designer 117 The Report and Group panes . . . . . . . . . . . . . . . . 132
Opening the SQL designer. . . . . . . . . . . . . . . . . . . 117 Modifying report in the Report designer . . . . . . . . . . . . 133
For new queries . . . . . . . . . . . . . . . . . . . . . . 117 Deleting columns (fields) from a report. . . . . . . . . . . 133
SQL designer elements . . . . . . . . . . . . . . . . . . . . 117 Adding columns (fields) to a report . . . . . . . . . . . . . 133
Interacting with the Source editor . . . . . . . . . . . . . . . 118 Suppressing duplicate field values . . . . . . . . . . . . . 134
Entering data in the SQL designer . . . . . . . . . . . . . . . 118 Displaying default values in a blank report field . . . . . . 134
Running a query from the SQL designer . . . . . . . . . . . 119 Adding a floating dollar sign to field values in reports . . . 134
Putting your queries to work. . . . . . . . . . . . . . . . . . 119 Adding page numbers . . . . . . . . . . . . . . . . . . . . 134
Using your .SQL files with the SQL Property Builder . . 119 Creating a page number from scratch . . . . . . . . . . 135
Looking at the table pane . . . . . . . . . . . . . . . . . . . 119 Drill-down reports. . . . . . . . . . . . . . . . . . . . . . 135
About the table boxes . . . . . . . . . . . . . . . . . . . 119 Controlling drill-down reports in the Report designer . 135
Adding tables in the SQL designer . . . . . . . . . . . . . . 120 The drillDown property . . . . . . . . . . . . . . . . . 136
Renaming a table . . . . . . . . . . . . . . . . . . . . . . 120 Adding standard components to a report . . . . . . . . . . 136
Removing a table . . . . . . . . . . . . . . . . . . . . . . 120 Changing the report’s appearance . . . . . . . . . . . . . . 136
Selecting fields in the SQL designer. . . . . . . . . . . . . . 120 Creating report borders . . . . . . . . . . . . . . . . . 136
Selecting all fields in a table . . . . . . . . . . . . . . . . 120 Setting background color in reports . . . . . . . . . . . 137
Selecting individual fields in a table . . . . . . . . . . . . 120 Setting background image in reports . . . . . . . . . . 137
Reordering selected fields . . . . . . . . . . . . . . . . . 121 Performing aggregate (summary) calculations . . . . . . . . . 137
Criteria page (SQL designer) . . . . . . . . . . . . . . . . . 121 Designing a report with multiple streamFrames . . . . . . . . 138
Deleting a row . . . . . . . . . . . . . . . . . . . . . . . 121 Creating printed labels . . . . . . . . . . . . . . . . . . . . . 138
Adding selection criteria in the SQL designer. . . . . . . . . 121
Specifying selection criteria . . . . . . . . . . . . . . . . 122 Chapter 12
Simple Equation . . . . . . . . . . . . . . . . . . . . . . 122 Introduction to designing tables in
SQL Expression . . . . . . . . . . . . . . . . . . . . . . 122
EXISTS Clause. . . . . . . . . . . . . . . . . . . . . . . 122
dBASE Plus 139
Terms and concepts . . . . . . . . . . . . . . . . . . . . . . . 139
Combining selection criteria . . . . . . . . . . . . . . . . . . 123
Table design guidelines . . . . . . . . . . . . . . . . . . . . . 140
Row info . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Identifying the information to store . . . . . . . . . . . . . 140
Criteria combo box . . . . . . . . . . . . . . . . . . . . . 123
Classifying information . . . . . . . . . . . . . . . . . . . 140
Grouping selection criteria in the SQL designer . . . . . . . 123
Determining relationships among tables . . . . . . . . . . 141
Drill-down column . . . . . . . . . . . . . . . . . . . . . 124
Single versus multiple tables . . . . . . . . . . . . . . 141
Query operators . . . . . . . . . . . . . . . . . . . . . . . . 124
One-to-one and one-to-many relationships . . . . . . . 141
Selection page of the SQL designer . . . . . . . . . . . . . . 125
Parent and child tables . . . . . . . . . . . . . . . . . . 142
Selecting a field . . . . . . . . . . . . . . . . . . . . . . 125
Minimizing redundancy . . . . . . . . . . . . . . . . . . . 142
Specifying an output name . . . . . . . . . . . . . . . . . 125
Choosing index fields . . . . . . . . . . . . . . . . . . . . 142
Producing summary data . . . . . . . . . . . . . . . . . . 125
Defining individual fields . . . . . . . . . . . . . . . . . . 142
Removing duplicate rows . . . . . . . . . . . . . . . . . 125
Table structure concepts . . . . . . . . . . . . . . . . . . . . 143
Deleting a row . . . . . . . . . . . . . . . . . . . . . . . 125
Table names . . . . . . . . . . . . . . . . . . . . . . . . . 143
Grouping page of the SQL designer . . . . . . . . . . . . . . 125
Table types . . . . . . . . . . . . . . . . . . . . . . . . . 143
Creating a grouped query . . . . . . . . . . . . . . . . . 125
Field types . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Group criteria page of the SQL designer . . . . . . . . . . . 126
Adding group selection criteria . . . . . . . . . . . . . . 126
SQL Expression . . . . . . . . . . . . . . . . . . . . 126
vi
Chapter 13 Viewing only selected table data . . . . . . . . . . . . 164
Table navigation . . . . . . . . . . . . . . . . . . . . . . . . 164
Creating tables 145 Data entry considerations . . . . . . . . . . . . . . . . . . . . 165
Supported table types . . . . . . . . . . . . . . . . . . . . . 145
Finding and replacing data . . . . . . . . . . . . . . . . . . . 166
Using the Table wizard . . . . . . . . . . . . . . . . . . . . 146
Searching tables . . . . . . . . . . . . . . . . . . . . . . . 166
Using the Table designer. . . . . . . . . . . . . . . . . . . . 146
Replacing data in rows . . . . . . . . . . . . . . . . . . . 167
Table designer tips . . . . . . . . . . . . . . . . . . . 147
Adding rows to a table . . . . . . . . . . . . . . . . . . . . . 168
User- interface elements in the Table designer . . . . . . . . 147
Deleting rows . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Resizing columns. . . . . . . . . . . . . . . . . . . . . . 148
Saving or abandoning changes . . . . . . . . . . . . . . . . . 168
Getting around in the Table designer. . . . . . . . . . . . 148
Performing operations on a subset of rows . . . . . . . . . . . 169
Adding and inserting fields . . . . . . . . . . . . . . . . 148
Selecting rows by setting criteria . . . . . . . . . . . . . . 169
Moving fields. . . . . . . . . . . . . . . . . . . . . . . . 148
Setting For conditions . . . . . . . . . . . . . . . . . . 169
Deleting fields . . . . . . . . . . . . . . . . . . . . . . . 148
Setting While conditions. . . . . . . . . . . . . . . . . 169
Saving the table structure . . . . . . . . . . . . . . . . . 149
Counting rows . . . . . . . . . . . . . . . . . . . . . . . . 169
Abandoning changes . . . . . . . . . . . . . . . . . . . . 149
Performing calculations on a selection of rows . . . . . . . 170
Restructuring tables (overview) . . . . . . . . . . . . . . . . 149
Viewing and editing special field types. . . . . . . . . . . . . 171
Important guidelines for restructuring . . . . . . . . . . . 149
Viewing the contents of special field types . . . . . . . . . 171
Changing the structure . . . . . . . . . . . . . . . . . . . 150
Memo fields . . . . . . . . . . . . . . . . . . . . . . . . . 171
Printing the table structure . . . . . . . . . . . . . . . . . 150
Binary fields. . . . . . . . . . . . . . . . . . . . . . . . . 171
Table access passwords . . . . . . . . . . . . . . . . . . . . 150
Importing an image or sound into a binary field . . . . 172
Creating custom field attributes . . . . . . . . . . . . . . . . 150
OLE fields . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Specifying data-entry constraints . . . . . . . . . . . . . . . 151
Adding an OLE object to an OLE field . . . . . . . . . 172
Creating and maintaining indexes . . . . . . . . . . . . . . . 151
Removing an OLE object from an OLE field . . . . . . 173
Indexing versus sorting. . . . . . . . . . . . . . . . . . . 152
Sorting or exporting rows . . . . . . . . . . . . . . . . . 152
dBASE index concepts . . . . . . . . . . . . . . . . . . . 153
Chapter 15
Planning indexes . . . . . . . . . . . . . . . . . . . . . . 154 Setting up security 174
Using indexes in data entry . . . . . . . . . . . . . . . 154 Setting up security strategies . . . . . . . . . . . . . . . . . . 174
Using indexes in queries . . . . . . . . . . . . . . . . 154 Individual login via automatic password dialogs . . . . . . 175
Using indexes in reports . . . . . . . . . . . . . . . . 154 Preset access via Database and Session objects. . . . . . . 175
Using indexes to link multiple tables . . . . . . . . . . 155 Preset access for Standard table types. . . . . . . . . . . . 175
Creating a simple index . . . . . . . . . . . . . . . . . . 155 Preset access for SQL and other table types . . . . . . . . 176
Using the Table designer to create a simple index . . . 155 Table-level security for DBF tables. . . . . . . . . . . . . . . 176
Using the Manage Indexes dialog box to create a simple About groups and user access . . . . . . . . . . . . . . . . . 177
index . . . . . . . . . . . . . . . . . . . . . . . . . 155 Table access . . . . . . . . . . . . . . . . . . . . . . . . . 177
Selecting an index for a rowset . . . . . . . . . . . . . . 156 User profiles and user access levels. . . . . . . . . . . . . 177
Index tasks . . . . . . . . . . . . . . . . . . . . . . . . . 156 About privilege schemes . . . . . . . . . . . . . . . . . . . . 177
Modifying indexes . . . . . . . . . . . . . . . . . . . 156 Table privileges . . . . . . . . . . . . . . . . . . . . . . . 178
Deleting indexes . . . . . . . . . . . . . . . . . . . . 156 Field privileges . . . . . . . . . . . . . . . . . . . . . . . 178
Indexing on a subset of rows for dBASE tables . . . . 157 About data encryption . . . . . . . . . . . . . . . . . . . . . 178
Hiding duplicate values. . . . . . . . . . . . . . . . . 157 Planning your security system . . . . . . . . . . . . . . . . . 178
Creating complex indexes for dBASE tables . . . . . . . 157 Planning user groups . . . . . . . . . . . . . . . . . . . . 179
Rules for dBASE complex indexes. . . . . . . . . . . 157 Planning user access levels . . . . . . . . . . . . . . . . . 179
Creating the dBASE complex index . . . . . . . . . . 158 Planning DBF table privileges . . . . . . . . . . . . . . . 179
Key expressions . . . . . . . . . . . . . . . . . . . . 158 Planning field privileges . . . . . . . . . . . . . . . . . . 180
Primary and secondary indexes . . . . . . . . . . . . . . 158 Setting up your DBF table security system . . . . . . . . . . . 180
Unique keys. . . . . . . . . . . . . . . . . . . . . . . 159 Defining the database administrator password . . . . . . . 180
Secondary indexes, maintained and non-maintained . . 159 Creating user profiles . . . . . . . . . . . . . . . . . . . . 181
Creating primary indexes . . . . . . . . . . . . . . . . 159 Changing user profiles . . . . . . . . . . . . . . . . . . . 181
Creating secondary indexes. . . . . . . . . . . . . . . 159 Deleting user profiles . . . . . . . . . . . . . . . . . . . . 181
Referential integrity . . . . . . . . . . . . . . . . . . . . . . 159 Establishing DBF table privileges . . . . . . . . . . . . . . . 181
Defining referential integrity . . . . . . . . . . . . . . . . 160 Selecting a table . . . . . . . . . . . . . . . . . . . . . . . 182
Update and delete behavior . . . . . . . . . . . . . . . . 160 Assigning the table to a group. . . . . . . . . . . . . . . . 182
Changing or deleting referential integrity . . . . . . . . . 161 Setting DBF table privileges . . . . . . . . . . . . . . . . 182
Setting field privileges . . . . . . . . . . . . . . . . . . . 182
Chapter 14 Setting the security enforcement scheme . . . . . . . . . . . . 183
Table-level security for DB tables . . . . . . . . . . . . . . . 183
Editing table data 162 Removing passwords from DB tables . . . . . . . . . . . . . 184
A few words of caution . . . . . . . . . . . . . . . . . . . . 162
Running a table . . . . . . . . . . . . . . . . . . . . . . . . 162
Protected tables. . . . . . . . . . . . . . . . . . . . . . . 163
Chapter 16
Table tools and views . . . . . . . . . . . . . . . . . . . . . 163 Character sets and Language
Table and query views . . . . . . . . . . . . . . . . . . . 163 drivers 185
Adjusting the view . . . . . . . . . . . . . . . . . . . 163 Determining the language displayed by the User Interface . . 185
vii
About character sets . . . . . . . . . . . . . . . . . . . . . . 186 dataModule Menu Bar . . . . . . . . . . . . . . . . . . 212
About language drivers . . . . . . . . . . . . . . . . . . . . 187 Database Menu Bar . . . . . . . . . . . . . . . . . . . 213
Performing exact and inexact matches . . . . . . . . . . . . 187 Query Menu Bar . . . . . . . . . . . . . . . . . . . . . 213
Using global language drivers . . . . . . . . . . . . . . . . . 188 Query Options . . . . . . . . . . . . . . . . . . . . . . 214
To set the ldriver option in PLUS.ini: . . . . . . . . . . . 188 Custom View . . . . . . . . . . . . . . . . . . . . . . 215
Using table language drivers. . . . . . . . . . . . . . . . . . 189 Run Data-Entry Application . . . . . . . . . . . . . . . . 216
Identifying a table language driver and code page . . . . . . 190 Run Report . . . . . . . . . . . . . . . . . . . . . . . . . 216
Non-English Character Display Issues . . . . . . . . . . . . 190 Administration . . . . . . . . . . . . . . . . . . . . . . . 216
Selecting Specialized Product Fonts. . . . . . . . . . . . . . 190 Customizing the dQuery/Web Server Side Components . . . . 217
Table language drivers versus global language drivers . . . . 191
Handling character incompatibilities in field names . . . . . 191
Converting between OEM and ANSI Text . . . . . . . . . . 192
Converting from OEM to ANSI . . . . . . . . . . . . . . 192
Converting from ANSI to OEM . . . . . . . . . . . . . . 192
How to convert and view your source code . . . . . . . . 192
Chapter 17
Converting prior version dBASE
Applications to dBASE Plus 194
Converting a dBASE III+/IV Application to Visual dBASE 5.7194
Installing Visual dBASE 5.7 . . . . . . . . . . . . . . . . 194
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Suggested Steps . . . . . . . . . . . . . . . . . . . . . . 195
Sample . . . . . . . . . . . . . . . . . . . . . . . . . 195
Recreating Menus . . . . . . . . . . . . . . . . . . . . . 196
Create a sample menu in Visual dBASE 5.7 . . . . . . 196
Converting .VUE Files . . . . . . . . . . . . . . . . . . . 196
Converting Forms . . . . . . . . . . . . . . . . . . . . . 197
Using The Component Builder to Convert a Form from
a .PRG . . . . . . . . . . . . . . . . . . . . . . . . . 198
Fine-Tuning The Form . . . . . . . . . . . . . . . . . . . 199
Notes about Memo and Logical fields . . . . . . . . . 199
Running the Form . . . . . . . . . . . . . . . . . . . . . 200
Using ACCEPT or INPUT? . . . . . . . . . . . . . . . . 201
Reports and Labels . . . . . . . . . . . . . . . . . . . . . 203
Converting dBASE 5.0 for DOS Screens/Menus to
dBASE Plus . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Setting up for Conversion . . . . . . . . . . . . . . . . . 204
Converting screens or menus to dBASE Plus . . . . . . . 204
Conversion considerations . . . . . . . . . . . . . . . . . 205
An Option. . . . . . . . . . . . . . . . . . . . . . . . 206
Converting dBASE 5.0 for DOS Reports and Labels . . . 206
Converting Visual dBASE 5.7 Applications to dBASE Plus . 206
Converting Forms . . . . . . . . . . . . . . . . . . . . . 207
Converting Reports and Labels . . . . . . . . . . . . . . 207
Converting QBE Files to Datamodules . . . . . . . . . . 208
Updating Forms to Use Datamodules . . . . . . . . . . . 209
Chapter 18
dQuery/Web Server Side
Components 210
Installation and Configuration . . . . . . . . . . . . . . . . . 210
Requirements. . . . . . . . . . . . . . . . . . . . . . . . 210
Installing the dBASE Plus Runtime . . . . . . . . . . . . 210
Installing the dQuery/Web Server Side Components . . . 211
Web Server Configuration . . . . . . . . . . . . . . . . . 211
Apache . . . . . . . . . . . . . . . . . . . . . . . . . 211
Security . . . . . . . . . . . . . . . . . . . . . . . . . 211
Configuring the dQuery/Web Server Side Components . . 212
Using the dQuery/Web Server Side Components . . . . . . . 212
dQuery/Web Query(dataModule) . . . . . . . . . . . . . 212
viii
ix
Tables
6.1 Standard controls . . . . . . . . . . . . . . . . . . . . . 76 15.1 Setting user groups . . . . . . . . . . . . . . . . . . . . 179
6.2 Data Access . . . . . . . . . . . . . . . . . . . . . . . . 78 15.2 Setting user access levels . . . . . . . . . . . . . . . . . 179
6.3 Shading Properties in the Table Designer . . . . . . . . . 78 15.3 Setting table privileges . . . . . . . . . . . . . . . . . . 180
6.4 Components specific to reports . . . . . . . . . . . . . . 79 15.4 Setting field privileges . . . . . . . . . . . . . . . . . . 180
6.5 Method menu commands . . . . . . . . . . . . . . . . . 83 15.5 Setting DBF table privileges . . . . . . . . . . . . . . . 182
7.1 Menubar and popup root properties, events 15.6 Setting field privileges . . . . . . . . . . . . . . . . . . 183
and methods . . . . . . . . . . . . . . . . . . . . . . . . 97 16.1 European language drivers available in dBASE Plus. . . 187
7.2 Item properties, events and methods . . . . . . . . . . . 98 16.2 Automatic assignment of language drivers by
7.3 Toolbar properties, events and methods . . . . . . . . . . 99 dBASE Plus . . . . . . . . . . . . . . . . . . . . . . . . 189
7.4 Toolbutton properties, events and methods . . . . . . . 100 16.3 Language drivers: Table versus Global. . . . . . . . . . 191
9.1 Methods of controlling execution in the Debugger . . . .111
10.1 Query operators . . . . . . . . . . . . . . . . . . . . . 124
11.1 Values for the drilldown property . . . . . . . . . . . . 136
12.1 dBASE field types for level 7 tables . . . . . . . . . . 143
13.1 Data-entry constraints . . . . . . . . . . . . . . . . . . 151
13.2 Sample dBASE key expressions . . . . . . . . . . . . 158
14.1 Navigating rows using the menu, mouse or keyboard . 164
14.2 Types of calculations . . . . . . . . . . . . . . . . . . 170
14.3 Field selection keyboard shortcuts . . . . . . . . . . . 171
x
Figures
3.1 Sample event handler for a "Hello world" form. . . . . . 31 17.4 Component Builder window with displayed source
4.1 Project Explorer: The Project Page . . . . . . . . . . . . 35 code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
4.2 Project Explorer: Adding files. . . . . . . . . . . . . . . 36 17.5 A Running Form . . . . . . . . . . . . . . . . . . . . . 200
4.3 Sample MDI window . . . . . . . . . . . . . . . . . . . 56 17.6 Form with PushButton . . . . . . . . . . . . . . . . . . 202
4.4 Saving a custom class . . . . . . . . . . . . . . . . . . . 58 17.7 The dBASE IV for DOS Report designer . . . . . . . . 203
4.5 Set Custom form Class Dialog Box . . . . . . . . . . . . 59 17.8 Crystal Reports for dBASE. . . . . . . . . . . . . . . . 204
4.6 Save as Custom dialog box; saving Custom Components 60
5.1 dQuery Design Surface with default Session object . . . 71
5.2 Design surface after Drag&Drop of Query object . . . . 72
6.1 Form Designer with a wizard-created form . . . . . . . . 74
6.2 Report Designer with a wizard-created report. . . . . . . 75
6.3 Field Palette . . . . . . . . . . . . . . . . . . . . . . . . 80
6.4 Using the Inspector . . . . . . . . . . . . . . . . . . . . 81
6.5 Events page of The Inspector . . . . . . . . . . . . . . . 82
6.6 Methods page of The Inspector . . . . . . . . . . . . . . 83
6.7 Layout | Align commands . . . . . . . . . . . . . . . . . 86
6.8 Layout | Size commands. . . . . . . . . . . . . . . . . . 86
6.9 Layout | Spacing commands. . . . . . . . . . . . . . . . 87
6.10 Set Scheme dialog box . . . . . . . . . . . . . . . . . . 87
6.11 Format toolbar . . . . . . . . . . . . . . . . . . . . . . . 88
8.1 Code Block Builder . . . . . . . . . . . . . . . . . . . 103
8.2 The Command window . . . . . . . . . . . . . . . . . 104
9.1 Source Window . . . . . . . . . . . . . . . . . . . . . 109
9.2 Debugger tool windows, docked . . . . . . . . . . . . .111
9.3 Breakpoint window . . . . . . . . . . . . . . . . . . . 113
9.4 Breakpoint Condition dialog box . . . . . . . . . . . . 113
9.5 Call Stack window. . . . . . . . . . . . . . . . . . . . 115
9.6 Watch window . . . . . . . . . . . . . . . . . . . . . . 115
10.1 SQL Designer: Table pane. . . . . . . . . . . . . . . . 118
10.2 SQL Designer: Query notebook . . . . . . . . . . . . . 118
10.3 SQL Designer Criteria Page . . . . . . . . . . . . . . . 121
10.4 SQL Designer: Adding criteria . . . . . . . . . . . . . 121
10.5 SQL Designer: Group selection . . . . . . . . . . . . . 123
10.6 SQL Designer: Grouped . . . . . . . . . . . . . . . . . 124
11.1 Wizard-generated report on a GOODS table . . . . . . 130
11.2 Wizard-generated Summary Report . . . . . . . . . . . 131
11.3 Adding grand total in the Report wizard . . . . . . . . 132
11.4 Report in Design mode with Group view displayed . . 132
11.5 Field Palette containing active fields . . . . . . . . . . 134
11.6 Aggregate calculation on a Report . . . . . . . . . . . 137
12.1 Components of a Table . . . . . . . . . . . . . . . . . 140
12.2 One-to-many relationships . . . . . . . . . . . . . . . 141
14.1 Table-editing toolbar. . . . . . . . . . . . . . . . . . . 163
14.2 Columnar view . . . . . . . . . . . . . . . . . . . . . 164
14.3 Navigating rows using the toolbar. . . . . . . . . . . . 165
14.4 Find Rows dialog box . . . . . . . . . . . . . . . . . . 166
14.5 Replace Rows dialog box . . . . . . . . . . . . . . . . 167
14.6 Delete Rows dialog box . . . . . . . . . . . . . . . . . 168
14.7 Count Rows dialog box . . . . . . . . . . . . . . . . . 170
14.8 Calculate Aggregates dialog box . . . . . . . . . . . . 170
14.9 Calculation Results dialog box . . . . . . . . . . . . . 171
16.1 Setting LDRIVER in the PLUS.ini . . . . . . . . . . . 189
17.1 Sample Menu . . . . . . . . . . . . . . . . . . . . . . 196
17.2 Sample Form . . . . . . . . . . . . . . . . . . . . . . 197
17.3 The Component Builder . . . . . . . . . . . . . . . . . 197
xi
xii
Chapter
dBASE Plus is also a great second tool for developers working in other languages, environments and databases.
From its ad-hoc data-query tools to its built-in Report Classes, dBASE Plus provides the functionality missing
from other, popular, single-purpose tools. Writing an application in Delphi or Visual Basic? Need to see the
results immediately? Just fire up dBASE Plus and browse the data in real-time. Need to kick out a report in
minutes? dQuery/Web’s No-Click reports require virtually no work at all. Need to model your data, view
relationships, check out the results of a SQL Query? Just a few mouse clicks and you’ve got a real-time result.
Need to get your data out on the Web right now? You’re just seconds away from a dBASE Plus One-Click Web
application, or a live, direct-connect Web report.
This section introduces you to the dBASE Plus development environment and provides examples and tips that
will help you get started quickly. It also describes features introduced in versions of dBASE prior to dBASE
Plus as well as those new to the latest releases.
dBASE Newsgroups
The dBI Newsgroups, located at news://news.dBase.com, are a place where dBASE users and developers can
obtain peer support and exchange information, tips and techniques. We encourage members of the dBASE
community to assist each other with technical questions. Please read the Newsgroup Guidelines before
participating.
For more information about Newsgroup Guidelines and configuring your newsreader, visit the dBASE website
at www.dbase.com.
• Data objects
• ActiveX integration
• Visual designers
• The Inspector
• Full-featured Source editor
• SQL designer
• BDE utility and database support
• DBF7 file format
Project Explorer
A few of the features The Project Explorer provides include:
• Automatic file viewers
• Instant switching between visual preview and source code views
• Project-based compiler directives
• The ability to compile, build, and deploy entire projects
Note that the Project Explorer replaces the Catalog functionality available in earlier versions. A conversion
utility, CAT2PRJ.PRG, is available in your dBASE Plus/bin directory to let you easily convert Catalogs to
Projects.
Data objects
Data access classes merge the SQL and object-oriented paradigms. You can use queries within databases within
sessions. Sessions provide independent connections to tables. Each database can then connect to a different data
source. The queries connect to one or more tables and provide table navigation capability. The objects let you
• Use Query, Rowset, Field, Database, Session, StoredProc, and other classes to access tables and stored
procedures. (Data objects use only SQL to gather data.)
• Use DataModule and DataModRef objects to represent multiple data objects and their relationships. These
objects take the place of form.view and old QBE files.
• Create custom data objects to access specialized, third party, and future data formats.
Visual designers
The visual designers feature numerous usability and productivity enhancements, including
• Win32 controls
• Grid and Browse controls, which are faster and offer more functionality than the table browsing functionality
in earlier versions
• Complete ActiveX control integration
• Live Two-Way-Toolª editing: changes made in visual designers are immediately reflected in the source code
and vice versa; to switch between the two, press F12
• File drag-and-drop capability lets you easily link tables and pull files onto a form or report from the
Navigator, Project Explorer, Windows Explorer, or even the Windows Find results window
• Dockable toolbars
• A text-formatting palette, featuring industry-standard HTML tags
• In-place editing for Text components
• Automatic labeling for fields dragged from the Field palette
• Versatile form/report metrics (chars, twips, pixels, millimeters and more)
• Expanded image format support. The list now includes support for BMP, GIF (including animated GIF),
ICO, JPEG, PNG, XBM, WMF, EMF, TIFF, PCX, and EPS formats
ActiveX integration
You may add ActiveX (OCX) controls directly into your forms and reports. You can either inspect ActiveX
controls directly, or right-click a control to access its internal configuration dialog.
The Inspector
A few of the features offered by The Inspector include:
• Single-click list expansion
• Advancement or toggling of a selection with Ctrl-Enter (an alternative to double-clicking)
• A tool button on the Methods page to let you write method overrides
• Bold highlighting on changed and non-default values
• A property type chooser and history list
• Access to a codeblock builder and long string editor tool
SQL designer
The SQL designer lets you create, edit, and execute SQL queries. You can use the tool to test and apply the
simplest SELECT statements to the most advanced queries on data in any supported data source. You can then
view the results and save your query for inclusion in your programs.
• Referential integrity
• Table constraints: an array of strings containing logical dBASE Plus expressions that act as row-level
constraints when attempting to save a row
• Custom field attributes that comprise an active data dictionary that works at runtime as well as design time.
These attributes are named properties with string values and are created in the Table designer.
• New dBASE Plus Web and "Powered by" bitmaps are included on the dBASE Plus install CD.
• A new multi-language single-CD install.
• The Designer class
• Source Aliasing
• Dynamic External Objects - DEO
• TableDef class
• DBFIndex class
• DBASE_SUPPRESS_STARTUP_DIALOGS
• baseClassName property
• Starting dBASE Plus or application .exe without using the BDE (see below).
• Startup optimizations for Web applications (see below).
• Change to command line for PLUSRun.exe (see below).
• onDrop event added to Editor class (see below).
Date Functions
• DATETIME( ) function
• DTTOD( ) function
• DTTOT( ) function
• DTODT( ) function
Note Source Aliasing works only in the dBASE Plus design environment or when running programs from within the
dBASE Plus shell. It is not a runtime feature. To access files indirectly in deployed applications, use Dynamic
External Objects (DEO) instead of Source Aliasing.
New _app object property used to override Rowset SET SKIP behavior
• detailNavigationOverride
New Class
• class SubForm
bgColor property
• Previously, the bgColor property set the background color for data displayed in grid cells. The bgColor
property can also now be used to set the background color for the empty area within a grid (the area to the
right of the last column and below the last grid row).
speedTip property
• The speedTip property has been added to the following classes: Image, TreeView, Text, TextLabel,
ListBox,Rectangle,Container,Browse, PaintBox, TabBox, OLE, ActiveX.
New Class
• class ColumnEditor
onNotify event
• In addition to firing when a Table or SQL Designer closes, the onNotify event can now fire upon the closing
of a Source Editor or Report Designer.
editorType property
• Includes a value, 5, that enables the selection of the "ColumnEditor" control.
Grid behavior
• Clicking on a Grid Row Indicator changes the currently selected row.
• Clicking on a Grid Column Header gives focus to the field in the selected column.
• Clicking on a method in the object pane moves the cursor to the first line of the method in the source code
pane, even if the cursor is already somewhere within the selected method.
Optimized ReportViewer
• Speedier rendering of report pages.
Grid Class
• New grid column control events: beforeCellPaint( ) and onCellPaint( )
These events allow a grid cell's color, font, and other attributes to be modified on a cell by cell basis. The
value to be displayed is accessible within these events and can be used to modify the cell conditionally.
These events are available for each of the GridColumn editor and heading controls:
• columnEntryField
• columnSpinBox
• columnComboBox
• columnCheckBox
• columnEditor
• columnHeadingControl
• New grid property: grid.colorRowHeader to set the color of the row header.
The foreground color specifies the color of the indicator arrow or plus sign.
The background color specifies the row header background color.
The default setting is: WindowText/BtnFace
• Grid can now be scrolled at design time.
This speeds grid design by making it possible to scroll a grid horizontally to bring a particular column into
view. Once in view, if columns have been defined, you can click on the column to select it into the Inspector
and directly modify the columns properties, methods, and events.
Project Explorer
• dBASE Plus Project Explorer now supports creating deployers for dBASE applications using Inno Setup and
ScriptMaker.
• An "Inno" tab is now surfaced in the Project Explorer for non-web projects that can be used to create Inno
Setup installers using ScriptMaker.
TreeView
• Modified TreeView so that expanding or collapsing a tree node (clicking on + or -) does not change the
currently selected item (unless the currently selected item is among those being collapsed).
• Modified canExpand and onExpand events
• treeview.canExpand and treeview.onExpand events now receive a parameter, oItem, providing an object
reference for the treeitem whose + or - has been clicked.
• Expanding or collapsing a TreeItem
• Expanding or collapsing a TreeItem by clicking on its + or - no longer selects the item that is expanded or
collapsed. THIS MAY REQUIRE CHANGES TO EXISTING CODE.
• TreeView control can now display images using more than 16 colors.
Images using anywhere from 4 bit color up to 32 bit color are now supported.
Array Class
• Array.dir( ) and array.dirext( ) can now return a file count greater than 32K
Report
• The default value of the report autoSort property has been changed to 'false'. Previously, it was 'true'. THIS
MAY REQUIRE CHANGES TO EXISTING REPORTS
Inspector
• Inspector defaults changed to increase size and expand categories
_app Object
• New _app method:.ExecuteMessages( )
Allows a dBASE Plus program to respond to mouse, keyboard, and other events while running a lengthy
process instead of having to wait until the process completes
_app.frameWin
• New methods: hasHScrollBar( ) and hasVScrollBar( ).
These methods allow a form to more accurately determine how much room is available within the frame
window.
The hasHScrollBar( ) method returns True if the frame window has a horizontal scrollbar.
The hasVScrollBar( ) method returns True if the frame window had a vertical scrollbar.
Procedure files
• SET PROCEDURE TO <procedurefile> has been changed to assume ADDITIVE was specified.
Report Designer
• The detailBand, headerBand, and footerBand are now visible in the Report Designer when they are empty (if
their height is not zero).
• The margins are now painted accurately to show the page edge.
• In the left outline view the rectangle that used to be labeled as pageTemplate1 is now correctly labeled as:
Available Page (report.pageTemplate1 margins)
• The stream frame is no longer allowed to be resized larger that the margins of the pageTemplate.
• A page-template margins rubber band is now available when clicking on the page-template area to allow
setting the margins by resizing the rubber band rectangle.
• Re-sizing the pageTemplate margins with the mouse now correctly sets the pageTemplate's margin
properties rather than its height and width properties.
Error Handling
• dBASE Plus now prevents inappropriate "Insufficient Disk Space" errors from occurring due to the BDE
using truncated disk free space data.
• Error handling in the dBASE Plus byte code interpreter has been enhanced to catch Memory Access
Violation errors and provide file name, procedure, and line number information. Previously, these kinds of
exceptions were triggering critical errors which displayed a message that dBASE or Windows had
encountered an internal error. The additional information is helpful when diagnosing the source of the error.
dBASE IDE
• Updated to use Windows XP Visual Styles in built-in tools and dialogs when running on Windows XP.
Form Controls
• Form controls have been upgraded to auto-detect if Windows XP Visual Styles are being used and to adjust
accordingly.
• Ability to automatically match the background of form components to the XP Style background of Notebook
controls when their colorNormal property settings match.
PushButton
• Ability to override automatic behavior of PushButton to use Classic or XP style via the new systemTheme
property.
• Ability to specify how to align an image and text on a PushButton via the new bitmapAlignment property
• Ability to place both text and an image on an XP style PushButton.
Grid
• Ability to differentiate between selected and unselected rows in the beforeCellPaint( ) and onCellPaint( )
events via the new bSelectedRow parameter
• Ability to set color of lines between rows and columns via the new colorRowLines and colorColumnLines
properties
• Ability to determine and set the current leftmost grid column via the new firstColumn property
• Ability to set the color of the checkmark in a columnCheckbox control
• Grid’s columnCheckbox control now displays the checkbox in all rows of the grid, not just the current row
Rectangle
• Added the transparent property to Rectangle
MousePointer
• Added additional built-in mousepointer settings to include the vertical and horizontal splitter mousepointers.
• Updated mousePointer option 5 - Size to use the standard Windows crossed arrows (IDC_SIZEALL) mouse
cursor.
GETFONT( )
• Ability to send default values to GETFONT( ) function. This allows you to initialize the GETFONT dialog
with current settings.
ReportViewer
• Ability to detect when a report has reached its last page in the ReportViewer class via the new onLastPage( )
event.
Error Dialog
• Enhanced error dialog to support long error messages.
Exception Handling
• Enabled ability to catch Memory Access Violations in dBL code using try...catch blocks.
• Added ability to turn off enhanced Memory Access Violation trapping for applications where this caused
compatibility problems.
Reports
• Improved setting of default band height and of autoSort to improve backward compatibility.
ListBox
• Added the vScrollBar property to turn on, or off, the vertical scrollbar
Project Explorer
• Added ability to create and deploy a Windows XP manifest file with an application.
• Added ability to choose which runtime engine installer files to include with a deployed application.
New Features
New Bundled ODBC Drivers
• dBASE Plus now ships with a bundle of branded Data-Direct ODBC drivers to make it simpler to connect to:
Oracle
SQL Server
Sybase ASE
DB2
Informix
FoxPro
Visual FoxPro
Clipper
Pervasive SQL (formerly Btrieve)
Database Class
• Added new property loginDBAlias, which allows a second database connection to be made to a database
using the login credentials from an existing database connection.
Exception Handling/Security
• Enhanced execution time validity checks to prevent execution of invalid or corrupted instructions by the
dBASE virtual machine interpreter.
Grid Class
• Added new method firstRow( ) - returns bookmark for first visible row in the grid.
• Added new method lastRow( ) - returns bookmark for last visible row in the grid.
Project Explorer
• Added new "Ini" tab to the Inno section of the Project Explorer that allows a user to indicate whether or not a
default ini file should be generated for a deployed application. If the user chooses to create the ini file, they
can include a settings to use the BDE or not and to enable/disable the _app.ErrorTrapFilter flag.
Query Class
• Added new property usePassThrough. The usePassThrough property is checked during query activation.
If true, the query's sql statement is passed through directly to the database server for execution. When
opening very large tables this allows for very fast retrieval of the initial query result rows.
If false and a query's sql statement is a simple "select * from table" statement, dBASE Plus attempts to open
the table using "table style" semantics. For tables up to a few million rows, this usually works well. For larger
tables, this can result in a very time-consuming query operation.
Rowset Class
• Added new property autoLockChildRows
When true (the default), child rows are automatically locked when a parent row is locked. This corresponds
to previous behavior.
When false, child rows are not locked when a parent row is locked
Source Editor
• When commenting (or uncommenting) multiple lines of code, the Source Editor will no longer comment (or
uncomment) the last line if the cursor is in the first column
Variant Support
• Upgraded built-in COM and ActiveX support for variants so that most data types allowed in variants can be
converted into dBASE variable or property values or into dBASE arrays (for COM SafeArrays).
ArgVector()
• Fixed Memory Access Violation that occurred when ARGVECTOR( ) was called within a procedure to
retrieve an argument whose name was declared PRIVATE prior to calling ARGVECTOR( ). This condition
now triggers the following new error (Error code 403):
Error: Argument out of scope or hidden by a PRIVATE command: <varName>
Editor Class
• Fixed firing of a field object's onChange( ) event when an Editor is datalinked to a memo field and a change
is made via the Editor object and a rowset navigation is triggered.
EntryField Class
• Modified Entryfield component to check if the framewindow is visible before opening a viewer for a
datalinked blob field. If the framewindow is visible, then the viewer form will be opened as an mdi form (i.e.
inside the framewindow). If the framewindow is not visible, the viewer form will now be opened as a non-
mdi window (i.e. without any framewindow).
• Fixed a problem when using the 'R' formatting code in the function property and a picture property template
of '99999', in which a 1 in the leftmost position of the field would be lost when tabbing to next field. The
resulting value would display as '00000'.
• Fixed two problems that occurred when using the 'R' formatting code in the function property:
1 Fixed problem where digits entered in a numeric entryfield were lost because the actual characters
displayed during data entry were not a valid numeric value. The entryfield was changed so that if the 'R'
formatting code is specified and the picture property contains a valid template for a numeric value, then
numeric data entry rules are enforced.
For example, with 'R' in the function property, and '999.99' in the picture property, entering the four
characters, '9.12', from the left end of the entryfield would display as '9.1.2', which becomes 9.10 when it
is converted to a numeric value (after pressing the enter key or tabbing to the next field). This happened
because the entered decimal point did not automatically align with the placeholder decimal point from the
picture property, so the second decimal point and all characters to the right of it were ignored when the
string was converted to a numeric value.
2 Fixed the processing of numeric picture characters '9', '#', '*', '$' to only allow '-' or '+' to be entered at the
left end of an entryfield or spinbox value.
Form Class
• Fixed the form's nextObj property so it only returns objects in the tab order.
Form Designer
• Fixed Source Alias substitution, which is used when code is streamed from the Form Designer (and other
places), so the longest matching Source Alias path is used instead of a Source Alias to a higher level sub-
path.
• Fixed painting of line objects so that the ends of the lines do not bleed-through to a new page when changing
the current page for a form or notebook.
mousePointer Property
• Fixed a problem that occurred when a non-default mouse pointer (also called the mouse cursor) was chosen
for a form. Clicking any mouse button on the form surface (not on a component on the form) caused the
mouse pointer to change to an arrow until the mouse was moved. This problem could also be seen when any
of the mouse buttons was released (mouse up) after holding a button down, moving the mouse slightly to
restore the selected pointer, and then releasing the button.
Printer Support
• Fixed GPF that occurred when changing the PrinterName property of a printer, or after selecting a specific
printer with a print dialog
• Fixed lockup that occurred if printer.choosePrinter( ) was called more than once after changing
printer.printerName.
Project Explorer
• Fixed CURSOR::BEGINWAIT error that sometimes occurred when opening the Project Explorer.
• Explorer.dll, which contains graphic files for the Project Explorer, has been renamed to ProjExp.dll to
prevent it from being improperly labeled as spyware or a virus by some anti-spyware and anti-virus utilities.
Query Class
• Corrected the query activation code so that if the query's canOpen( ) event returns False, query.active will be
set to False instead of being left True.
QUIT Command
• Fixed QUIT WITH <expN> so that <expN> (a return code) is correctly passed back to the operating system.
When calling a dBASE Plus application .exe from another program or batch file, the return code can now be
tested to determine if an error occurred or if some other action is required.
Report Designer
• Corrected Group Pane of Report Designer so that clicking on an object in the Group Pane correctly selects
the object in the Report Pane.
• Corrected indentation of the group bands in the Group Pane of the Report Designer, so that when multiple
group bands are present the outermost group has the smallest indent, the next group has a bigger indent and
so on. Also, moved the text that labels the pageTemplate so it displays vertically along the left side instead
of along the top.
• Objects in the Group Pane of the Report Designer are now drawn with the same width as their corresponding
object in the Report Pane.
Runtime Application
• Fixed GPF that occurred when invoking a deployed application .exe using a UNC path.
Source Editor
• Fixed "dQuery.wfo does not exist" error that occurred when using the Fix option from a previous error
dialog. With dQuery loaded, when certain errors occurred the following would trigger a secondary error:
• Pressing Fix to open the Source Editor
• Correcting the error
• Closing the Source Editor
• Fixed GPF that would occur when setting rowset.masterFields to a memo field when the child table's current
index is based on a character field. This will now generate a Type Mismatch error.
SpinBox Class
• Fixed regression that caused the the spinbox to initially increment a value when its down arrow is clicked.
• Fixed a problem when using the 'R' formatting code in the function property and a picture property template
of '99999', in which a 1 in the leftmost position of the field would be lost when tabbing to next field. The
resulting value would display as '00000'.
• Fixed two problems that occurred when using the 'R' formatting code in the function property:
1 Fixed problem where digits entered in a numeric entryfield were lost because the actual characters
displayed during data entry were not a valid numeric value. The entryfield was changed so that if the 'R'
formatting code is specified and the picture property contains a valid template for a numeric value, then
numeric data entry rules are enforced.
For example, with 'R' in the function property, and '999.99' in the picture property, entering the four
characters, '9.12', from the left end of the entryfield would display as '9.1.2', which becomes 9.10 when it
is converted to a numeric value (after pressing the enter key or tabbing to the next field). This happened
because the entered decimal point did not automatically align with the placeholder decimal point from the
picture property, so the second decimal point and all characters to the right of it were ignored when the
string was converted to a numeric value.
2 Fixed the processing of numeric picture characters '9', '#', '*', '$' to only allow '-' or '+' to be entered at the
left end of an entryfield or spinbox value.
StreamSource Class
• Fixed problem with streamSource's rowset property. Setting it to a different rowset now, correctly, turns off
notifications from the previous rowset to the streamsource object.
TreeView
1 Fixed regression to treeview's borderStyle property so that changing it from its default value no longer causes
flickering. Also fixed lockup that occurred when changing it via the Inspector in the Form Designer. This
problem was caused by the fix for QAID: 5287.
2 Fixed Memory Access Violation that sometimes occurred when a treeView's releaseAllChildren ( ) method
was called, and a tree item was selected.
XP Theme Support
• Fixed copy( ), cut( ), and paste( ) methods when called from an XP themed pushButton. Previously, these
methods failed to work when using an XP theme.
• Fixed the following XP theme issues:
1 EntryField, SpinBox, Editor, ListBox and Rectangle now support XP styles, when XP theme is active and
with default properties.
2 Fixed position of text for a rectangle object when XP themes are used.
• When the mouse enters an XP style push button (turning it orange), XP sends a paint message to the form
text component. The painting of non-transparent text was done directly to the screen and caused flickering.
The text painting code is now changed to do most painting operations off screen.
• Disabled combobox (simple or dropDown styles) with XP style had black background behind the list items.
The background brush and text background of a disabled combobox are now white.
• Fixed systemTheme speedBar pushButton so that clicking it with the mouse does not take focus from control
that currently has focus. This occurred with editor and entryField components among others..
• Fixed problem in the Form Designer, when pasting a shape or line component onto an XP themed notebook,
the pasted shape or line were invisible.
• Corrected text and group box background colors to match containing window for various core product
dialogs when XP Themes are enabled.
• Fixed a regression in the Form Designer Properties dialog that caused the OK, Cancel, Help and Apply
buttons to be positioned incorrectly when XP Themes were not enabled.
• Fixed regression that caused rectangle components to ignore mouse events and not fire their mouse event
handlers that was due to changes to support XP Themes.
• Corrected overlapping of some controls in Project Explorer when using XP Themes.
dQuery
Create Table
• Added new form for selecting database and table name for "create table".
Import Wizard
• Fixed "Database Not Opened" error that occurred in the Import Wizard when canceling out of the database
login dialog when choosing a table to import.
Miscellaneous
• Fixed a "variable undefined" error when deleting a session object from the design surface that the user had
added.
• Fixed table or view not found error that occurred when opening a SQL Server table with spaces in the name.
• Fixed Memory Access Violation that occurred after attempting to use the Rows | Replace Field Values menu
option when the currently selected query is a table that cannot be edited due to it being opened via ODBC
and not having any indexes.
• Removed the extra back-slash in the default dQuerySamples alias path created by dQuery when the alias
doesn't already exist.
• Fixed "Index Does Not Exist" error when clearing index for a Non-Indexed Parent/Child Link when using a
MySQL database.
• Removed "Include all rows" option from Standard Filter and Non-Indexed Search dialogs.
• Fixed "Database Engine Error: Index does not exist" that occurred when closing the Table Designer after
opening some DBMS tables that have no indexes.
• Added code to prevent user from closing dQuery form while dQuery is in the middle of running processes
that require controlled exits. Processes modified are: Load current report, Calculate sum, Calculate count,
Calculate minimum, Calculate maximum, Calculate average, Open fly-out tables list.
• Fixed "Value out of Range" error and other potential errors that could occur when dragging splitter bar past
bottom of dQuery form window and when maximizing dQuery form within its frame window. Added code to
prevent dQuery from using splitter position values that are too large or too small from .ini file.
• Removed access to right-click popup menus for editor controls in the following dQuery Business User
dialogs: Filter Properties, Field Detail, Table and Query Properties, Rowset Properties.
• Fixed "Variable Undefined: QLANG" error when canceling a search run via the Search | Non-Indexed
Search menu option.
• Fixed the Set Order dialog, which has the wrong name for the second tab when there is no current index or no
index is selected.
• Fixed "Database Engine Error: Table does not exist: t" when using Filter | SQL Select Filter dialog.
Corrected use of table alias "t" in the generated SQL Select statement when reserved words are used for
fieldnames in a field list.
• Fixed incorrect font size problem that sometimes occurred in the Multi-Table View grid's rightmost column
where the font size of this column would become larger than in the other columns.
• Disabled the Filter | SQL Select menu option for inactive queries.
• Prevent error that occurred when right-clicking on dQuery design surface, choosing "Add Table" and then
canceling out of the database login dialog.
• Modified the dQuery Tables menu to enable the "Encrypt table" option only for dBASE or Paradox tables.
• Corrected the Fly-out Table list window's resize routine so that it correctly positions and sizes all of the
window's components.
• Disabled menu and toolbar options to Add Row and Goto Last Row for large DBMS tables.
Multi-Table View
• Mouse pointer now changes to an hour glass when dropping a field onto the Multi-Table view and changes
back once the view has been updated.
• Fixed a problem where Multi-Table View column width changes are lost the first time a datamodule is saved.
Parent/Child Wizard
• Fixed "Index does not exist" error after using Parent/Child Wizard to setup a non-indexed link, choosing to
enforce one-to-one relationship, and then clicking on each query object on design surface.
Reports
• Upgraded report totals so that they will not include a decimal point and additional digits to the right of the
decimal point unless absolutely necessary.
Star Filter
• Fixed Server Error with the Star Filter's "Apply to Datamodule" option when the query's requestLive
property is set to false. Also fixed problems with recovery of the datamodule rowset state after this error
occurred. Fixed the right-click Requery option to handle the case where query.requestLive=false and there is
a "T" alias in the SQL statement from a Star Filter generated WHERE clause.
Web Wizards
• Fixed "In use by another: ...\dBLCore\temp\Wiztemp1" error dialog that could occur when choosing
Applications | Web Wizards a second time in dQuery standalone.
• Fixed "Unknown database name: dQueryTemp" error that occurred when selecting Applications | Web
Wizards a second time.
XP Theme Support
• The current Windows XP Theme is now used by form components in dQuery dialogs and One-Click
Window applications including: EntryFields, SpinBoxes, Editors, ListBoxes and Rectangles.
Typographical conventions
The following typographical conventions used in this Help system will help you distinguish among various
language and syntax elements.
Software registration
To register your product with dataBased Intelligence, Inc. and qualify for support, use the registration card
included in your dBASE Plus package or register at our Web site at http://www.dbase.com dBASE technical
support services
dataBased Intelligence, Inc. offers developers high-quality support options. These include free services on the
Internet, where you can search our extensive information base and connect with other users of dBASE products.
In addition to this basic level of support, you can choose from several categories of telephone support, ranging
from support on installation of your dBASE product to fee-based consultant-level support and detailed
assistance. To obtain pricing information for dBASE technical support services, please visit our Web site at
http://www.dbase.com.
To request assistance, call:
dataBased Intelligence, Inc. Call Center Toll free (USA and Canada only)
607-729-0960 888-dBASE-32
(888-322-7332)
The call center is open from 9:00 AM to 5:00 PM eastern time USA.
HARDWARE
All of the following are required
• Intel 486DX2 or higher
• CD-ROM drive
• 16MB RAM
• 35 MB hard disk space
• VGA or higher resolution (SVGA recommended)
• Microsoft mouse or compatible pointing device
OPERATING SYSTEM
• Microsoft Windows® 95/98/2000
• Microsoft Windows® NT 4.0
• Microsoft Windows® ME
• Microsoft Windows® XP
NETWORKS
• It runs on all Windows-compatible networks, including NT networks, Novell networks and peer-to-peer
networks, such as Lantastic and Netbeui.
• In addition to the usual subdirectories, like BIN, a subdirectory named My Projects is created off the dBASE
Plus home directory, by default C:\Program Files\dBASE\Plus\My Projects.
• The Language of the installer will attempt to match the Windows system language setting. This can be set via
the Control Panel | Regional Setting. During the install process, you are given the option of selecting
additional languages. For example, if you select English and German, the User Interface resources and
documentation (as available) will be installed for both languages
• The User Interface language resources installed for the BDE Administrator, the BDE Online Help, and the
User Interface resources for the Project Explorer, will match the language of the Installer itself. Multi-
language installs are not supported for these components.
dBL is an object-oriented, event-driven programming language that allows developers to create sophisticated,
scalable applications using objects and classes.
Objects are a means of encapsulating collections of variables, some containing data, others referencing code.
Classes are a mechanism for creating reusable groups of objects. With dBL, you can
• Create objects from standard classes or custom classes you declare
• Add custom properties to an object with a simple assignment statement
• Declare custom classes
• Declare classes that are based on other classes and inherit their properties and methods
• Write highly reusable code by building hierarchies of classes
• Event-driven, where the user interacts with visible objects, such as forms containing pushbuttons and list
boxes, in any sequence. The user interface is event-driven, and you can create event-driven applications
using dBL.
Using traditional programming techniques, you can build menu-driven user interfaces. In these applications, the
program dictates the sequence of events. If the user selects Order Entry from a menu, the program typically
walks through a series of screens asking the user for information: enter the customer name, enter the date and
purchase order number, enter the line items, enter the shipping charge.
These menu-driven techniques are not well-suited for programming in event-driven environments such as
Windows. In an event-driven application, the user controls program flow. A user can click a button, activate a
window, or select a menu choice at any time, and the program must respond to these events in whatever
sequence they occur.
In a well-designed event-driven application,
• The user can focus on the task, not on the application. The user doesn’t have to learn a complex hierarchy of
menu choices. Rather, when choosing to enter an order, the user sees an order form similar to a familiar paper
form.
• The user doesn’t need to re-learn how to perform tasks. Because you create an application’s interface using
familiar objects such as pushbuttons and list boxes, common operations—opening a file, navigating a form,
and exiting the application—are more consistent across applications.
Most important, event-driven interfaces reflect the way people work in the real world. When clerks write up
orders, they pick up forms and fill them out. When they receive checks for orders, they pick up the invoices and
mark them as paid. This natural flow of work follows an object-action pattern. That is, a clerk selects an object
(an order form, an invoice) and performs some action with it (fills out the order, posts the check).
Likewise, in an event-driven application, the user selects objects (forms, entry fields, pushbuttons) and performs
actions with them.
The following code, a .WFM file generated by the Form designer, creates the form just described. This code
follows the general structure of all forms generated by the Form designer. For now, don’t try to understand
every line. Just look at the general structure to get a sense of how forms are created, properties are set, and event
handlers are assigned to events.
parameter bModal
local f
f = new Hello( )
if (bModal)
f.mdi = .F. && ensure not MDI
f.ReadModal( )
else
f.Open( )
endif
CLASS Hello OF FORM
with (this)
Height = 16
Left = 30
Top = 0
Width = 40
Text = "My first Plus form"
EndWith
this.TEXT1 = new TEXT(this)
With (this.TEXT1)
Height = 3
Left = 11
Top = 3
Width = 33
Metric = 0
ColorNormal = "N/W"
FontSize = 23
Text = "Hello world!"
EndWith
this.BUTTON1 = new PUSHBUTTON(this)
With (this.BUTTON1)
onClick = class::BUTTON1_ONCLICK
Height = 2
Left = 19
Top = 9
Width = 13
Text = "Goodbye"
Metric = 0
StatusMessage = "Click button to exit"
Group = True
EndWith
// {Linked Method} Form.button1.onClick
Function Button1_OnClick
DO WHILE (Form.Height > 0) .AND. (Form.Width > 0)
Form.Text1.Text = "Goodbye"
Form.Height = Form.Height - 1
Form.Width = Form.Width - 1
Form.Top = Form.Top + .5
Form.Left = Form.Left + .5
ENDDO
Form.Close( )
return
ENDCLASS
Creating an application
Chapter 4
Using dBASE Plus design tools, you can create the visual elements of an application quickly, in a manner that
promotes reuse of design elements rather than repeated reinvention. Using the Component palette, you simply
drag and drop both the visible user-interface components (also known as controls or objects) and the invisible
data objects onto forms. The Inspector gives you an easy way to set an object’s attributes, or properties, and
access its event handlers and methods directly, without hunting.
As you work with the design tools, dBASE Plus writes the corresponding dBL code for you. If you prefer to do
most of your developing in the Source editor, the code you write is reflected in the designer, and you can see
immediately what your form looks like and how it runs. In either case, the entire source code for your form is
available to you in the Source editor at all times. Press F12 to toggle between the source code and the visual
designer.
This section discusses the basic steps of creating an application in dBASE Plus. It includes information on
• Creating projects and using the Project Explorer to manage them
• Using the Project Explorer
• Planning and creating forms
• Code generated by the Form designer
• Types of form windows (MDI, SDI, modal, modeless)
• Using ActiveX controls, container components, and multi-page forms
• Creating custom classes, custom components, and data modules and using them in a form or report.
Menus are created separately with the Menu designer. You program a form to display a pull-down menu by
referencing it in the form’s menuFile property; a popup menu you reference manually in the Source editor.
Creating an application 33
The Project Explorer
5 If several forms (or reports) will be using the same data-source setup (table relationships, SQL statements,
methods, and so on) create a data module so you only need to create the data-source setup once. The "Plus
data model" and how to access tables using Data Access components is described in Chapter 5, "Creating
DataModuleDataModules" is described on page 71.
6 Create custom form and report classes to give your application a unified look (see page 58).
7 Create the forms (data entry forms, dialog boxes, and so on) that make up the user interface of your
application.
8 Create any reports that your forms will link to or run, using the dBASE Plus Report wizard and integrated
Report designer (see Chapter 6, “Using the Form and Report designers”, and Chapter 11, “Designing
reports”).
9 Compile and build your project (choose Build | Compile from the Project Explorer).
10 Test and debug, using the dBASE Plus debugger (see Chapter 9, “Debugging applications”).
DEO Application Check this box if you want your entire application to be a Dynamic External Object
based application. Leave this box unchecked if you only want part, or none, of an application to be DEO. More
will be said on DEO later in this section.
Web Application This tells the Project Explorer to use the WEB option during the BUILD process. It
restricts a web application from containing code to create, or use, visual components such as forms, buttons,
toolbars, status bars, and other form components, which allows the dBASE Runtime to load faster.
Main Program File The file that starts your application. This option cannot be set until the project
contains at least one program (.prg or .wfm) file.
Main Program Parameters Used only when you are requiring parameters for startup of the application.
Parameters assign data passed from a calling routine to private variables.
Target EXE Filename The name of the executable resulting from the build process.
Figure 4.1 Project Explorer: The Project Page
Splash Bitmap The name of the bitmap to be used as the splash screen of your application. This option
cannot be set until the project contains a bitmap (.bmp) file.
Program Icon The name of the icon file to be used as the titlebar of your application. This option cannot
be set until the project contains an icon (.ico) file.
Log Filename A text (.txt) file that lists errors or warnings generated during the BUILD process.
Status Shows the most recent Date and Time the file was created or modified.
Author The Project developer.
Description A name or phrase that serves as the Project identifier.
Creating an application 35
The Project Explorer
Creating an application 37
The Project Explorer
Opening a Project
To open a project in the Project Explorer, do one of the following:
• Open the Navigator (View | Navigator), select the Project tab, and double click on the project file.
• Select File | Open Project from the Main menu, and navigate to the file in the Open Project dialog.
Creating an Application
Once all the necessary files have been included in a project, creating a dBASE application is quite simple using
the Project Explorer.
• Complete the Project page
• Add your files
• Designate a Main Start program by checking the, “File is Main Startup Program?”, box in the Build Options
section of the file’s Detail tab.
• Compile and Build the Application
DEO Folders
1 Select the DEO tab
2 If you have existing folders you wish to use for your DEO deployment, you can select them by clicking on
the 'folder' icon. This will open the Choose Directory dialog, allowing you to browse to a folder. Once you
have located the desired folder, click OK and the file will be added to the DEO folder list.
3 If you wish to create new folders, type the full path into the entryfield and press the ENTER key. The Project
Explorer will create the folder.
4 Repeat this for each folder you wish to create by selecting the next numbered line in the listbox, and
designating a path and name in the entryfield.
5 To remove a folder from the list you must first remove any files assigned to it. Once it is empty, select it from
the list and click the “Clear a Target Folder” icon on the right.Selecting the DEO Folder For Each File
Creating an application 39
The Project Explorer
.INI files
To insure your deployed application performs as intended, you MUST deploy an .INI file of the same name as
the .EXE.
Some settings you should consider (see online help in dBASE for details for SET EPOCH, SET CENTURY,
SET LDCHECK, etc.) adding as an example below:
[CommandSettings]
EPOCH=1950
LDRIVER=WINDOWS
[OnOffCommandSettings]
CENTURY=ON
LDCHECK=OFF
BELL=OFF
TALK=OFF
[CommandWindow]
Open=1
Maximized=0
Minimized=1
[ComponentTypes]
ComponentTypeNumeric=1
ComponentTypeDate=1
ComponentTypeLogical=0
ComponentTypeMemo=0
ComponentTypeBinary=0
ComponentTypeOLE=0
ComponentTypeNumericForTables=1
ComponentTypeDateForTables=1
ComponentTypeLogicalForTables=0
ComponentTypeMemoForTables=0
ComponentTypeBinaryForTables=0
ComponentTypeOLEForTables=0
[Grid]
DefaultMemoEditor=0
[Toolbars]
Format=0
[ObjectPath]
objPath0=c:\path
objPath9=c:\anotherpath
[IDAPI]
CONFIGFILE01=mycustom.cfg
The LDRIVER=WINDOWS setting ensures that no matter what your application's BDE Driver, your source
code will be saved as ANSI.
Setting TALK=ON will cause dBASE Plus to constantly echo commands to the command window, and may
cause performance degradation. In dBASE Plus, the Runtime Engine automatically assumes talk is OFF
The ComponentTypes settings reduce the likelyhood of datatype mismatches, particularly if you are using the
grid component on your forms. You should copy the section shown above from your own DB2K or PLUS.INI,
as you may have different settings than those shown above.
Grid was new to dBASE Plus in version 2.21, and is used to set the default columnEditor type for memo fields
in a grid. If DefaultMemoEditor is set to zero, the default (columnEditor) is used, if set to one (1), the
columnEntryfield is used.
Toolbars: When the Format option is set to "1", the Format Palette is displayed when a form with an editor
control is opened. The Format Palette does not display when this is set to “0”.
ObjectPath: This is how DEO is handled. Briefly, when you run an executable built with dBASE, it checks:
1 It looks in the "home" folder from which the application was launched.
2 It looks in the .ini file to see if there's a series of search paths specified. It checks all the paths in the list
looking for the object file requested by the application.
3 It looks inside the application's .exe file, the way Visual dBASE did in the past.
IDAPI is only really necessary if you are using a custom configuration file for the BDE. This may cause a
problem if multiple programs on the same computer try to use the BDE with different configuration files. It is
recommended that other methods of modifying the BDE's setup are used, such as running code in the dBASE
Users' Function Library (dUFLP) that will modify the BDE’s registry settings.
Encrypted Tables
If you are working with tables encrypted using the dBASE PROTECT command, you will need to:
• Deploy the DBSYSTEM.DB file
• Have an entry in your .INI that looks like:
[CommandSettings]
DBSYSTEM=D:\PATH
Where, D:\PATH, is the path to the directory where you are deploying this file.
If you already have a "[CommandSettings]" section, just add the "DBSYSTEM" entry.
If you are deploying the DBSYSTEM file to the same as your application, set this to "."
DBSYSTEM= "." //the "." stands for "current directory"
Using Inno
To make an installer for a project, use the Inno tab on the Project Explorer to create an installation script. Using
Inno Setup and ScriptMaker, the generated script can then be used to create the installer. This section discusses
the basic steps of creating an installer using the Project Explorer. It includes information on:
• Setting defaults
Creating an application 41
The Project Explorer
• Including files
• Windows Start Menu settings
• Including the Runtime
• Setup a License agreement
• Including the BDE and required aliases
• Naming the Script
Needed empty subfolder Specify the name of any empty folders that will be needed within the
destination folder when the program is installed. Click the plus sign to add a subfolder, and click the minus sign
to remove one.
Creating an application 43
The Project Explorer
Setup is trying to install. When this option is left unchecked, Setup would not try to overwrite the existing file.
This flag has no effect if the copy mode isn't either normal or AlwaysSkipIfSameOrOlder.
This flag is left in for backward compatibility only, and we recommend that you not use it.
• NT users may encounter false "existing file is newer" messages when they change their system's time zone,
or when daylight savings time goes into effect.
• A similar problem can occur if an installation was compiled on an NTFS partition and the files are installed
to a FAT partition, because times only have a 2-second resolution.on FAT partitions
ConfirmOverWrite Instructs Setup to ask for user confirmation before overwriting an existing file.
CreateAllSubDirs Instructs Setup to create subdirectories, associated with a file, when they don't
currently exist. Has an effect only when used in combination with RecurseSubDirs.
DeleteAfterInstall Instructs Setup to copy the file as usual, but delete it once the installation is completed
or aborted. This can be useful for extracting temporary data needed by a program executed in the script's [Run]
section.
This flag will have no affect on existing files that weren't replaced during installation.
This flag cannot be combined with the IsReadMe, RegServer, RegTypeLlib, RestartReplace, SharedFile, or
UninsNeverUninstall flags.
DontCopy Setup will not copy the file to the user's system. This flag is useful if the file is handled by the
[Code] section exclusively.
DontVerifyChecksum Prevents Setup from attempting to verify the checksum of the file. This flag must
be used in combination with the NoCompression flag to have an effect.
External Instructs Setup to copy the file, specified by the Source parameter, from an existing file on the
distribution media, or the user's system. If left unchecked, Setup will, instead, statically compile the file into the
installation files.
FontIsntTrueType Specify this flag if the entry is installing a non-TrueType font with the FontInstall
parameter.
IgnoreVersion Setup will not compare any version info, and existing files will be overwritten regardless of
their version number. This flag should only be used on files private to your application - never on shared system
files.
IsReadMe Instructs Setup that this is the "README" file. Only one file in an installation can have this flag.
When a file is designated a README, users will be given the option to view the README file after installation
has been completed. If so desired, Setup will open the file with the default program the user has designated for
that file type. For this reason, the README file should always end with an extension like .txt, .wri, or .doc.
Note: The user will not be given an option to view the README file.when Setup has been instructed to restart the
computer (as a result of installing a file with the flag RestartReplace, or if the AlwaysRestart [Setup] section
directive is yes).
NoCompression Prevents the compiler from attempting to compress the file.
NoEncryption Prevents the file from being stored encrypted.
NoRegError When used in combination with either the RegServer or RegTypeLib flags, instructs Setup
not to display an error message if the registration fails.
OnlyIfDestFileExists Instructs Setup to copy a file only when a file of the same name exists on the user's
system. This flag may be useful if your installation is a patch to an existing installation, and you only want to
replace files currently residing on the user's system.
OnlyIfDoesntExist Instructs Setup to install a file only when it does not currently reside on the user's
system.
OverWriteReadOnly Instructs Setup to always overwrite a read-only file. Without this flag, Setup will
give the user the option to overwrite existing read-only files.
PromptIfOlder When a file being installed has an older version number (or older time stamp, when the
CompareTimeStamp flag is used) than an existing file, instructs Setup to give the user the option to replace the
existing file. See the Remarks section at the bottom of this topic for more details.
RecurseSubDirs Instructs the compiler to search for the Source <filename><wildcard> in the
subdirectories as well as the Source directory.
RegServer Instructs Setup to register the OLE server (a.k.a. ActiveX control), by locating and executing
the DLL/OCX's DllRegisterServer export. The uninstaller calls DllUnregisterServer. When used in combination
with SharedFile, the DLL/OCX will be unregistered only when the reference count reaches zero.
See the Remarks at the bottom of this topic for more information.
RegTypeLib Instructs Setup to register the type library (.tlb). The uninstaller will unregister the type
library (unless the flag UninsNeverUninstall is specified). When used in combination with SharedFile, the file
will be unregistered by the uninstaller only when the reference count reaches zero.
See the Remarks at the bottom of this topic for more information.
ReplaceSameVersion Instructs Setup to replace current files even when they appear to be the same
version as the newer files. The default behavior is to retain the current files.
RestartReplace Instructs Setup to register locked files, designated for replacement, in either
WININIT.INI or MOveFileEx for Windows and Windows NT respectively. These files will be replaced during
the next system startup. When such files are encountered, the user will be prompted to restart the computer at
the end of installation.
This flag is generally useful when replacing core system files.
To maintain compatibility with Windows 95/98 and Me, long filenames should not be used on an entry with this
flag. Only "8.3" filenames are supported. (Windows NT platforms do not have this limitation.)
Important: The RestartReplace flag will only successfully replace an "in-use" file on Windows NT platforms when the user
has administrative privileges. If the user does not have administrative privileges, the following message will be
displayed;
"RestartReplace failed: MoveFileEx failed; code 5."
Therefore, when using RestartReplace it is highly recommended that your installation require administrative
privileges, by setting "PrivilegesRequired=admin" in the [Setup] section.
SharedFile (Windows 95/NT 4+ only) This flag uses Windows' shared file counting feature, located
in the registry at:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs)
It enables a file to be shared between applications, without worrying about it being inadvertently removed. Each
time the file is installed, the reference count for the file is incremented. When an application using the file is
uninstalled, the reference count is decremented. If the count reaches zero, the file is deleted (with the user's
confirmation, unless the UnInsNoSharedFilePrompt flag is also specified).
Most files installed to the Windows System directory should use this flag, including .OCX, BPL, and .DPL
(Delphi 3 package) files. One of the few exceptions is MFC DLLs, which should use the OnlyIfDoesntExist
copy mode, in conjunction with the UninsNeverUninstall flag.
SkipIfSourceDoesntExist Instructs the installer, or Setup, if the external flag is also used, to silently
skip over an entry, and not display an error message, when the source file does not exist. Has effect only when
used in combination with the External flag.
SortFilesByExtension Instructs the compiler to compress the found files, sorted by extension before
being sorted by path name. This potentially decreases the size of Setup if SolidCompression is also used.
Touch Instructs Setup to set the time/date stamp of the installed file(s) to that which is specified by the
TouchDate and TouchTime [Setup] section directives.
This flag has no effect if combined with the external flag.
UnInsNeverUninstall Instructs the uninstaller to never uninstall this file. Never remove the file. This flag
can be useful when installing very common shared files that shouldn't be deleted under any circumstances, such
as MFC DLLs.
Note: If this flag is combined with the SharedFile flag, the file will never be deleted at uninstall time but the reference
count will still be properly decremented.
Creating an application 45
The Project Explorer
Language Select a language for the text files. Files can be set for more than one language.
License file Choose a text file that contains the License Agreement.
Text before installation begins Choose a text file that contains any text or messages that should
display in the installation window before the installation begins.
Creating an application 47
The Project Explorer
Text after installation completes Choose a text file that contains any text or messages that should
display in the installation window after the installation completes.
Selected license files Lists the files that are currently set for the license and messages during the
installation
Delete before create If checked, an existing alias with the specified name will be removed before setting
up the new database alias.
Database aliases to create at install time The list of aliases that will be created during the
installation. To add an alias, click the plus sign; to remove an alias, click the minus sign.
To specify the name of the script, click on the folder icon. The script should have an .iss extension.
To generate and save the script, click on the disk icon. The script can then be seen in the large box below the
icons. The text line above the script will indicate if the script is current with the latest settings or not.
Once the script and project exe are generated, the installer can be created by launching ScriptMaker with the
lightning bolt icon. Once ScriptMaker is open, create the installer by clicking on the Inno button under compile.
By default, the installer will be in a folder called Output, located in the source directory
Creating an application 49
Form design guidelines
components you place on a form are the controls that let a user operate the application. Other components are
data objects that are invisible when the application runs but that link the application with data in tables.
Components contain three kinds of information:
• State information. Information about the present condition of a component is called a property of the
component. Properties are named attributes of a component that a user or an application can read or set.
Examples of properties are Height and Color.
• Action information. Components generally have certain actions they can perform on demand. These actions
are defined by methods, which are procedures and functions you call in code to tell the component what to
do. Examples of component methods are Move and Refresh.
• Feedback information. Components provide opportunities for application developers to attach code to
certain occurrences, or events, making components fully interactive. By responding to events, you bring your
application to life. Examples of component events are OnClick and OnChange.
Purpose of a form
Each form in your application should serve a clear, specific purpose. Forms are commonly used for the
following purposes:
• Data entry forms provide access to data in one or more tables. Users can retrieve, display, and change
information stored in tables.
• Dialog boxes display status information or ask users to supply information or make a decision before
continuing with a task. A typical feature of a dialog box is the OK button, which the user clicks to process the
selected choices.
• Application windows contain an entire application that users can launch from an icon off the Windows Start
menu.
You should be able to explain the purpose of a form in a single sentence. If a form serves multiple purposes,
consider creating a separate form for each.
• Identify tasks users will perform when working with data on the form, and provide menus, pushbuttons, and
toolbar buttons that users can choose to initiate tasks.
When designing a form, you can provide validation criteria on a field-by-field basis. Use the following
questions to help decide which criteria you need.
• Do you require an entry for the field, or can users leave it blank?
• Are duplicate entries allowed?
• Must the data fall within a valid range?
• Must the data appear in a specific, fixed format, such as a phone number?
• Are valid entries limited to a list of values? If valid entries are not limited to a list of values, you can speed
up data entry by compiling and displaying a list of frequently entered values, which also allows users to
enter companies not on the list?
You can also provide form-level validation in a canClose event. This event returns True or False based on a
condition you specify. If the condition is not met, the form will not close. For example, you could use canClose
if a user has not saved the last row entered. In the method you write for this event, you would ask if the user
wants to save the data and, if yes, allow the user to do so.
You can associate some field types with particular controls. By default, each dBASE field type is associated
with a specific control type. For example, a Numeric field type uses a spin box control by default. You can
change these associations to make data entry easier and more efficient in your particular application. Right-click
the Field palette, and choose Associate Component Types.
If your form needs to contain many fields or controls, consider using the Notebook component. Divide controls
into related groups and list each group on a separate page of the notebook. Or use a multi-page form with
buttons for page navigation. Or, instead of buttons, add a TabBox component and set various TabBox properties
to create page tabs and name each page.
Creating an application 51
Creating a form
Another need for z-ordering is when you use a rectangle control, for example, to group a series of RadioButtons.
The RadioButtons must appear on top of the rectangle, so you need to place the rectangle behind them in the z-
order.
Creating a form
You can create a form in two ways:
1 Use the Form wizard. The Form wizard creates a data-entry form. It presents you with a series of options,
and based on your selections, creates a form It saves time, and you can modify and further develop the form
in the Form designer (see ”Using the Form wizard’ on page 52).
2 Use the Form designer. Here you can create a form from scratch, by dragging components onto the form
and specifying their properties. Since components have built-in functionality, you can actually create very
simple applications with little or no coding. However, to create more complex and highly customized
applications, you need to write your own event handlers and methods for various components.
During form creation, press F12 to open the Source editor, where you can see and edit the dBL code generated
by dBASE Plus as you design your form. Pressing F12 toggles you between the visual design view and the
integrated Source editor.
4 Create menus, as necessary, using the Menu designer (see Chapter 7, “Creating menus and toolbars”).
5 Create toolbars and tool buttons, as necessary (see Chapter 7, “Creating menus and toolbars”).
The Form designer creates a .WFM file.
The components available in dBASE Plus and the mechanics of using the Form designer, including the
Inspector, are discussed in Chapter 6, “Using the Form and Report designers”. Also see the samples that come
with dBASE Plus, installed by default in the Plus\Plus\Samples directory.
The following sections give you an orientation to the code generated by the Form designer.
Creating an application 53
Editing a .WFM file
When editing the .WFM file directly, you want to preserve the two-way nature of the Form designer so that any
changes you make manually will not be lost the next time you save the form from the Form designer.
Creating an application 55
Types of form windows
If the MDI property is set to true, those features are automatically applied to the form. Accordingly, the
following form properties are automatically set to true: Minimize, Maximize, Sizeable, Moveable, and SysMenu.
Changing the MDI-required properties will have no effect until you change the MDI property itself to false. For
more information about any of these properties, press F1 when the property in the Inspector is highlighted.
Creating an application 57
6 For each button, on its Events page, select onClick and click the tool button to display the Source editor.
You’ll see a comment for an onClick method. Write the code that will send the user to the appropriate page.
Return to page 1 before running the form.
Your custom class now applies to the current file in the designer. In addition, subsequent new files of that type
will use the current setting in the Set Custom Class dialog box. To change this, choose File | Set Custom Class,
and either enter a new form or report custom class, or choose the Clear Custom Class button to restore the
default class as the setting.
Creating an application 59
to the palette individually in this dialog box (by checking the appropriate check box), you can remove
them from the palette only as a group. So, if you want to be able to add and remove custom components
from the palette separately, put each in its own file.
• Check the Place In Component Palette check box, if you want this component to appear on the
Component palette. If you are putting the component in an existing .CC file whose components are
already on the palette, and you don’t check this box, then later, if you want to add the component to the
palette, you’ll have to remove the .CC file from the Set Up Custom Components dialog box, and then add
it anew.
Figure 4.6 Save as Custom dialog box; saving Custom Components
5 Click OK.
The custom component is now stored in the .CC file you specified. You can open the file in the Source editor.
Creating an application 61
Chapter
To link your forms and reports to the data in tables, dBASE Plus provides a set of data objects. In the designers,
these objects are available on the Data Access page of the Component palette. These components make
specialized database access functionality available to your dBASE Plus applications.
This section discusses the following topics:
• The dBASE Plus data model
• Linking a form or report to tables
• Creating master-detail relationships
• Creating and using a DataModule
Before you use the data objects, you should understand the dBASE Plus data model, described in the next
section.
Note Although the old dBASE Data Manipulation Language (DML) still exists for backward compatibility, those
methods are no longer recommended. The new data object model is recommended because it utilizes the full
power of object-oriented programming.
Query objects
Query objects are the center of the data model. In most cases, if you want to access a table, you must use a
Query object.
Note Alternatively, you could use a StoredProc object that returns a rowset from an SQL database, or a DataModRef
object that points to a data module containing the appropriate data access code, including at least a Query or
StoredProc object.
The Query object’s main job is to house two important properties: SQL and rowset.
SQL property
The SQL property’s value is an SQL statement that describes the data to be obtained from the table. For
example,
select * from BIOLIFE
The * means all the fields and BIOLIFE is the name of the table, so that statement would get all the fields from
the BIOLIFE table.
The SQL statement specifies which tables to access, any tables to join, which fields to return, the sort order, and
so on. This information is what many people think of when they hear the word query, but in dBASE Plus, SQL
statements are only one of many properties of the Query object.
SQL is a standard, portable language designed to be used in other language products to access databases. When
you use the Form and Report wizards or drag a table from the dBASE Plus Navigator, dBASE Plus builds the
SQL statement for you. Once a table has been accessed by the SQL statement, you can do almost anything you
want with dBASE Plus’s data objects, including navigating, searching, editing, adding, and deleting.
Although knowing SQL is useful for initially configuring data objects for your databases, once these are
complete and saved as custom components or in data modules, they can be reused without modification. Then
others can create complete Windows database applications without knowing a word of SQL.
rowset property
A Query object is activated when its active property is set to true. When this happens, the SQL statement in the
sql property is executed. The SQL statement generates a result: a set of rows, or rowset.
A rowset represents some or all the rows of a table or group of related tables.
Each Query object generates only one rowset, but you can add multiple Query objects to a form to use multiple
rowsets from the same table, or from different tables. Using multiple Query objects also allows you to take
advantage of dBASE Plus’s built-in master-detail linking. See “Creating master-detail relationships (overview)”
on page 68
The Query object’s rowset property refers to the Rowset object that represents the query’s results.
Rowset objects
While you must use a Query object to get access to data, you must use the Query object’s resulting rowset to do
anything with the data. All navigation methods for getting around in tables depend on the query’s rowset.
• goto( ) uses the value returned by bookmark( ) to move back to that specific row.
Because each rowset maintains its own row cursor, you can open multiple queries—each of which has its own
rowset—to access the same table and point to different rows simultaneously.
Master-detail rowset synchronization can be overridden by using the _app object’s detailNavigationOverride
property. For more information on these properties, see Help.
Rowset modes
Once a Query object has been activated, its rowset is always in one of the following five modes (indicated by
the rowset’s state property):
• Browse mode, which allows navigation only.
• Edit mode, the default, which allows changes to the row.
• Append mode, in which the user can type values for a new row, and if the row is saved, a new row is created
on disk.
• Filter mode, used to implement Filter-By-Form, in which the user types values into the form and dBASE
Plus filters out all the rows that do not match.
• Locate mode, similar to Filter mode, except that it searches only for the first match, instead of setting a filter.
Rowset events
A rowset has many events used to control and augment its methods. These events fall into two categories:
• can- events, so named because they all start with the word can—which are fired before the desired action to
see whether an action is allowed to occur; and
• on- events, which fire after the action has successfully occurred.
Row buffer
The rowset maintains a buffer for the current row. It contains all the values for all the fields in that row.
You access the buffer by using the rowset’s fields property, which refers to an array of Field objects.
Field objects
The rowset’s fields array contains a Field object for each field in the row. In addition to static information, such
as the field’s name and size, the most important property of a Field object is its value.
value property
A Field object’s value property reflects the value of that field for the current row. It is automatically updated as
the rowset’s row cursor is moved from row to row.
To change the value in the row buffer, assign a value to the value property and set the rowset’s modified
property to "true". This signals the rowset that values have been changed. If the row is saved, those changes are
written to disk.
Important When referring to the contents of a field, don’t forget to use the value property. For example,
this.form.rowset.fields[ "Species" ].value
If you leave out value,
this.form.rowset.fields[ "Species" ]
you are referring to the Field object itself, which is rarely intentional—except for dataLinks, explained next. Get
in the habit of including value when referring to a field; if you don’t, the code doesn’t work.
Using dataLinks
Just as a Field object’s value property is linked to the actual value in a table, a visual object on the form (such as
an EntryField or RadioButton) can be linked to a field object through the visual object’s dataLink property. This
property is assigned a reference to the linked Field object. When connected in this way, the two objects are
referred to as dataLinked.
As the rowset navigates from row to row, the Field object’s value is updated, which in turn updates the
component on the form. If a value is changed in the form component, it is reflected in the dataLinked Field
object. From there, the change is saved to the table.
Database objects
Database objects are one level up from Query objects in the object hierarchy. Database objects have three main
functions:
• To access a database
• Database-level security
• Database-level methods
Accessing a database
A Database object is needed to access SQL databases, ODBC databases, and any other tables you are accessing
through a BDE alias.
Before you can use a Database object, you must set up BDE to access the database by using the BDE
Administrator (available from the dBASE Plus program group). See “How to connect to an SQL database
server” on page 27.
To connect a Database object to a database, set the Database object’s databaseName property to the BDE alias
for the database.
Database-level security
Many SQL and ODBC databases require the user to log in to the database. You can preset the Database object’s
loginString property with a valid user name and password to log in to the database automatically.
Because each Database object represents access to a database, you can have multiple Database objects that are
logged in as different users to the same database.
Database-level methods
The Database object contains methods to perform database-level operations such as transaction logging and
rollback, table copying, and re-indexing. Different database formats support each method to varying degrees.
Before accessing the methods of a Database object, the Database object itself must be active. The methods of a
Database object will not function properly when it's active property is set to "false".
Session objects
At the top of the object hierarchy is the Session object. Each session represents a separate user.
Each session contains one or more Database objects. A session always contains at least the default Database
object, which supports direct access of dBASE and Paradox tables.
Session objects are important for dBASE and Paradox table security. Multiple users each have their own
session, so that different users can be logged in with different levels of access, or they may share a single
session, so that all users have the same level of access. For the Session object's security features to work, the
session property of an active database object must be set to the session object.
A default Session object always exists whenever you run dBASE Plus (either the environment or an application,
sometimes referred to as a dBASE Plus executable). In most cases, the default Session is all you need. There is
usually no need to add a Session component to your forms or reports. dBASE Plus’s App object has a property
that points to the default session object and the default database object. Thus, when you create a Query object, it
is automatically assigned to both the default Session object and the default Database object.
The Session object has an event called onProgress that you can use to display progress information on database
operations.
StoredProc objects
The StoredProc object is used for calling a stored procedure in SQL databases. When you’re calling a stored
procedure, the StoredProc object takes the place of the Query object in the class hierarchy; it is attached to a
Database object that gives access to the SQL database, and it can result in a Rowset object that contains Field
objects.
The stored procedure can:
• Return values, which are read from the params array
• Return a rowset, which is accessed through the rowset property, if the server supports this capability
DataModRef objects
The DataModRef object points to preprogrammed data access components stored in a DataModule. If you
maintain data access code in a DataModule, then you can use a DataModRef object to return rowsets in place of
a Query or StoredProc component.
Data modules offer convenient reusability and easy maintenance of data access code. By storing custom or
preset data access components in a data Module, it is easy to maintain them (change links to changing databases,
for example). Then, you can use just the DataModRef component (or custom class) to instantly implement the
full set of current data access components.
To set a DataModRef object to point to a DataModule, set its filename property to the path name of the data
module.
Note The DataModRef object is maintained for backward compatibility. Enhancements to the DataModule class
make it a more desirable method of storing data objects.
By creating a master-detail relationship and adding SQL statements to the Rowset or Query object properties,
you can create forms and reports that group detail rows from detail tables with a selection of rows from the
master table. For example, a report could include a filter on the ORDERS rowset to display a customer’s orders
only for the month of March. You can create complex filtered joins and perform virtually any programmatic
operation on a database.
This section includes three different procedures to link master and detail tables:
1 Use an SQL JOIN statement to generate a rowset from two or more tables. This procedure is often the fastest
and easiest. It is illustrated in the AIRCRAFT.REP report in the SAMPLES directory.
2 For local BDE-standard tables, use the Rowset object’s masterRowset and masterFields properties.
3 For client/server databases, use the Query object’s masterSource property. (You can also use this in local
tables.)
In general, for any procedure, you begin with these steps:
1 Make sure each pair of tables is indexed on a common field.
2 Drag the tables from the Navigator to the visual design surface of the designer you’re working in. This
creates a Query object for each table.
What is a DataModule?
A DataModule is a dBASE Plus class for centralized handling of data access objects (Query, Database,
StoredProc, and Session). A DataModule enables you to:
• Place all your data access objects in a single container instead of duplicating them on each application form.
• Design queries once for use with many forms and reports instead of recreating them separately for each one.
• Create business rules—using object events, and additional methods you add to the source code for a
DataModule—that can be shared across an entire application.
• Separate business logic and data access from user interface code for easier maintenance.
After you’ve set up data access objects in a DataModule, it’s easy to maintain them (change links to changing
databases, for example).
Creating a DataModule
To create a DataModule,
1 Open the dQuery DataModule Designer by choosing File | New | Data Module.
Figure 5.1 dQuery Design Surface with default Session object
2 From the Drag & Drop area, drag the components you need onto the design surface, set their properties (SQL
and so on), and write their event handlers
Press F12 to toggle between the Source editor and the visual designer.
3 When everything is set up as you want it, save the DataModule (File | Save). It is saved with a .DMD
extension.
.
Figure 5.2 Design surface after Drag&Drop of Query object
Using a DataModule
To use a DataModule in a form or report, do one of the following:
• Add a DataModRef object from the Component palette and link it to the desired DataModule file by setting
the DataModRef’s filename property to the path and filename of the DataModule.
• Drag the DataModule file from the Navigator or Project Explorer to a form or report design surface. This
adds a DataModule object to the form.
The properties, event handlers, and methods you set for components in a DataModule apply consistently to all
forms and reports that use the module.
designers
This section shows you the common elements you have to work with in the Form and Report designers. Other
designers—for DataModules, labels, and custom classes—are variations on the Form and Report designers.
Their menus and tools vary, and they might look a little different, but otherwise they all work basically the
same. This section refers to the Form and Report designers, but the information applies to the other designers, as
well. The section includes the following:
• A description of the Form and Report designer windows
• What’s available on the Component palette for use in your forms and reports (this is an overview in table
form; see Help for more detailed information on how to use specific components)
• A discussion of the Field palette and how to populate it with components linked to fields in a table
• How to change component properties and create event handlers and other methods by using the Inspector
• How to manipulate components (change alignment, spacing, formatting, and so on)
You can open any of the designers from the File menu (File | New) or from the Navigator or Project Manager.
Note The yellow untitled icon on several pages of the Navigator is for creating a custom class that you can use as a
template.
The report design surface has several objects the form design window does not, for example, pagetemplate and
streamframe. These objects are necessary for formatting report pages. See Chapter 11, “Designing reports”, for
information on working in the report design window.
Component palette
The Component palette displays the components and data objects you can add to the form or report you’re
designing.
To open the Component palette, do one of the following:
• Choose View | Component Palette.
• Right-click anywhere on the form or report window and choose Tool Windows | Component Palette from the
context menu.
Depending on which designer has focus, or whether you have installed the dBASE Plus samples (which include
a number of custom components that appear automatically on the Component palette), you’ll see a selection of
the following pages on the Component palette:
Standard page
This table briefly describes the standard user-interface controls appearing on the Standard page of the
Component palette. For more details, select the component and click the Question Mark button on the toolbar.
PushButton Let a user perform a task with a single A control that a user can click to execute code that you attach.
mouse-click. (Sometimes called a command button.)
CheckBox Let a user toggle between two choices of a Check boxes often are arranged in groups to present choices or
logical value. Or choose a number of options a user can turn on or off. Any number of check boxes in
options that are not mutually exclusive. a group can be checked at a time
RadioButton Let a user select one choice among a group Example: A group of buttons labeled Credit, Cash, Check,
of mutually-exclusive possible values. Visa, and MC to choose among for entering only one of those
values in a PAY_METHOD field of a table.
Line Organize elements visually The line is a divider that may be extended vertically,
horizontally, or diagonally to visually divide a form into
sections. Users cannot edit or manipulate it.
Editor Display the contents of a text file or memo Text exceeding the size of the box causes a scrollbar to appear.
field. You can choose to allow users to edit this text.
ListBox Display values in a fixed-size, scrollable list The values in a list can be file names, records, array elements,
box, from which a user can select one or table names, or field names.
more items.
ComboBox Combine an entry field and a drop-down list A combo box accepts a value typed into the entry field or
box. A user clicks the down-arrow button to selected from the drop-down list box.
display the list.
Image Display an image. Display area for a bitmap image stored in a binary field,
resource file, or graphic file.
Shape Visually divide a form into sections, for A visual appearance element. By setting the component’s
example, to place related RadioButtons shapeStyle property you can create rounded rectangles,
within a box. rectangles, ellipses, circles, rounded squares, and squares. You
can also set the line style, weight, and interior color.
Container Create moveable panels that can contain Example: Moveable toolbars and palettes.
other components on a form.
Browse Display multiple records in row-and-column The Browse component is maintained for compatibility and is
format. suitable for viewing and editing tables open in work areas. For
forms that use Data Access use a Grid object instead.
Horizontal Allow users to horizontally scroll a Example: A custom dialog box containing an area filled with
scroll Bar grouping of controls, or a large control that many file icons.
has no integrated scroll bars
TabBox Group related data items on overlapping Use a TabBox to display multiple pages the full size of the
pages with labeled tabs form. A user selects a tab to display the items on the TabBox.
Similar to Notebook, except for the full form size.
SpinBox Provide up and down arrows to assist You can type a number into the numeric entry field or can
changing a numeric value. increment or decrement the number by clicking the up and
down arrows.
OLE Create an object linking and embedding Using an OLE control, a document from another application,
(OLE) client area in a form, in which you for example, a sound file from a sound recorder application, can
can embed, or link to, a document from be opened from your dBASE Plus application
another application
ReportViewer Displays a report in a sizeable frame The report is executed when the form is opened.
Report page
This page of the Component palette contains the data formatting components required for reports.
Custom page
The Custom page of the Component palette contains custom-built components. If you didn’t install the dBASE
Plus samples, you won’t see the Custom page until you create your first custom component and assign it to the
palette. If you did install the samples, you’ll see that the Custom page already contains custom components that
are used in the sample applications.
You can build new components from scratch, and you can alter existing components and save them as custom
components. See “Creating custom components” on page 59 for instructions.
The dialog box that appears shows all available controls registered on your system.
2 Select the desired controls.
Selected controls appear on the ActiveX page of the Component palette, ready for use. After placing a
component on a form, the Inspector shows the properties of the ActiveX control. To use the control’s own
property dialog box, right-click the control and choose ActiveX Properties from the context menu.
Dragging a field from the Field palette onto a form or report saves you the work of having to set its dataLink or
text property manually for each component you want to link to a field in a table, although you can do it
manually, if you want to.
If no active Query object exists on the form or report, the Field palette is empty, showing only the Pointer
button. When you begin to design a data-aware form or a report, first add a Query object and set its sql property
to the appropriate SQL statement and its active property to true. If you drag a table from the Navigator to the
design surface, this automatically creates a Query object that selects all the records in that table and links the
table to the form or report. See Chapter 5, “Accessing and linking tables”, for more details.
Once an active Query object exists on the form or report with its active property set to true, its fields appear on
the Field palette as linked components. The type of the component depends on the data type of the field. For
example, a Boolean field appears on the Field palette as a CheckBox control. To change the control type of a
field, right-click the Field palette, and choose Associate Component Types from its context menu, or choose
File | Associate Component Types.
If more than one Query object exists on the form or report, each table’s fields are displayed on a separate page
of the Field palette.
The Inspector
You can change a component’s properties in the Inspector. When you select a component in a form or report,
the Inspector displays the component’s properties. If the Inspector is not open, do one of the following:
• Press F11.
The Inspector has three tabbed pages that show the properties, events, and methods of the selected object. The
name of the currently selected object appears in the drop-down list box at the top of the Inspector. Click the
Down arrow of this box to select a different object, or select the object on the form or report, itself.
Properties, methods and events set by you, or that have no default value, are shown in bold. (Bold properties are
ones that will be streamed out.)
• Click the wrench tool button that appears to the right of the property value. Tools are not available for every
property.
The tool button may produce
• A property builder in which you can build or select a value. For example, you can display the Color
property builder to set the color for an object.
• The String Builder dialog box, which makes it more convenient to type a long string.
To specify what you want to happen when an event occurs, you can do one of the following:
1 Type a code block into the text box for the event. Or, if you want to use the Code Block Builder,
• Click the Type drop-down list beside the text box, and select CodeBlock.
• Click the wrench tool beside the text box.
This opens the Code Block Builder. Type parameters, if any, in the Parameters text box, and type the code
block in the Commands Or Expression box. It’s okay to put only one statement on each line, and end it
with a semicolon, where appropriate. When you click OK, the code block becomes a one-line code block
in the event’s value text box and in your code. See "The Code Block Builder" on page 103 for more
information.
2 Write a method to link to the event. Click the tool button to display the Source editor with the cursor inside
the skeleton of a new method, ready for you to type.
For information about code block syntax and writing a method, see Help.
You can also link and unlink events by using the Method menu from within the Source editor. See "The Method
menu", on page 83.
Manipulating components
This section describes how to work with components: placing them, resizing, aligning, and so on.
Selecting components
To work with a component once you’ve placed it on the form, first select it. Once you select a component, you
can resize it, move it, or delete it. You can also change its properties.
To select a component, do one of the following:
• Click the component.
• Press Tab or Shift+Tab until it’s selected.
• Select it from the drop-down list at the top of the Inspector.
When a component has focus, its handles—small, black squares around the periphery—are visible.
Note If it is a component that is part of a custom form or report class, the handles are white to remind you that you
have selected such a component, because you may not want to change it.
Moving components
To move a component, select it, and then do one of the following:
• Drag the component to the position you want. As soon as you move the mouse, the pointer becomes a hand.
This indicates you’re moving the component.
• Press any of the arrow keys to move the component in the direction of the arrow. If Snap To Grid is turned
on, the object moves one gridline at a time.
• Change the object’s position properties in the Inspector.
To move a multiple selection of components, put the mouse cursor within the borders of one of the components,
and then either drag or press the appropriate arrow key to move your selection in the direction you want.
If Snap To Grid is checked in the Properties dialog box of the designer you’re working in, then components
align to the grid.
Aligning components
You can align components by using the Layout | Align menu commands or the corresponding toolbar buttons
(to display the Alignment toolbar, choose View | Tool Windows, and check Alignment Toolbar.) These
commands adjust the position of objects in relation to each other or in relation to the form or report. To find out
what each option does, highlight it and read the explanation in the status barer press F1. See Figure 6.7 for a
summary.
Resizing components
To resize a component, select it and do one of the following:
• Place the mouse pointer on one of its handles. When the pointer turns into a double-headed arrow, drag the
handle to size the component the way you want.
• Press Shift+any arrow key to resize it in the direction of the arrow.
You cannot resize a multiple selection of components with the mouse; however, you can press Shift+an arrow
key to resize a multiple selection in the direction of the arrow.
To change the sizes of multiple objects to conform to one size, choose an option from the Layout | Size menu or
the corresponding button in the Alignment toolbar. (To display the Alignment toolbar, choose View | Tool
Windows, and check Alignment Toolbar.) To find out what each option does, highlight it and read the
explanation in the status bar
:
Figure6.7L
.
Figure 6.8 Layout | Size commands
Spacing components
To change the spacing of components in the Form designer, select the components, and choose an option from
the Layout | Spacing menu.
Note The Spacing menu is not available in the Report designer.
To find out what each command does, highlight it and read the explanation in the status bar.
Figure 6.9 Layout | Spacing commands
Note Once you have used the Format toolbar or menu to change parts of a Text object, you cannot use the Inspector to
override what you have done. Use the Format toolbar or menu, instead. However, the Inspector will make
changes you specify to anything you haven’t already changed by using the Format toolbar or Format menu.
Most Windows applications offer menus of some kind—standard pulldown menus, popup menus, or both. Most
also feature static or detachable toolbars.
This section describes how to create these objects and integrate them into your dBASE Plus applications.
Like all other objects in an object-oriented environment, menus and toolbars can be designed to be completely
reusable by any number of forms. For that reason, we’ll start with the task you’ll face most often—attaching
objects to forms.
catch ( Exception e )
// Ignore already attached error
? "Already attached"
endtry
ENDCLASS
class myTBar of toolbar
this.imagewidth = 16
this.flat = true
this.floating = false
this.b1 = new toolbutton(this)
this.b1.bitmap = 'filename ..\artwork\button\dooropen.bmp'
this.b1.onClick = {;msgbox("door is open")}
this.b1.speedtip = 'button1'
this.b2 = new toolbutton(this)
this.b2.bitmap = 'filename ..\artwork\button\doorshut.bmp'
this.b2.onClick = {;msgbox("door is shut")}
this.b2.speedtip = 'button2'
endclass
Note that the only change to the contents of the earlier program is the removal of the FormObj parameter
definition (and related change to the referenced form object, the form, in the new method called show_bar) and
the removal of the unneeded pcount(_) parameter check at the top of the file.
Otherwise, the code was simply partitioned and placed in the appropriate areas of the form source, and the new
method, show_bar, was created to hold the instance-checking and toolbar creation/attachment code.
Building blocks
Building basic menus through the designers is a simple two-step process of adding items, then adding code to
make the items do what you want them to do.
Like any other object, each menu item has its own set of properties available through the Inspector (F11 to
view). The "action" code is applied through an item’s onClick event.
Not all items need to perform an action, however. Some, like top-level items, normally only serve as entry
points to additional menu choices. Lower-level items, and any item in a popup menu, can also serve as entry
points to additional menus. These types of menus are called submenus (also known as "cascading" or "flyout"
menus). File | New on the main dBASE Plus menu is an example of this type of menu. And any submenu item
can be specified as an entry point to another submenu.
Another type of "non-action" item is the separator bar, a horizontal line that lets you group items within menus.
You specify a separator anywhere except in a top-level item. To make a separator, set an item’s Separator
property to True.
To provide further visual cues and functionality, you can add graphics, mnemonics, check marks, shortcut keys,
and conditionally enable or disable any item in any menu.
Features demonstration
The following exercise demonstrates a number of menu creation principles and features, including preset
menus.
1 Open a new pulldown Menu designer window.
2 Type &File (including the ampersand) at the cursor, then press Enter. Type &Form into the new item entry
box, then press Tab. A new item entry box appears to the right of the current entry. Type &Close into this
box.
3 If it isn’t already open, press F11 to open the Inspector. Choose the Events tab, then type form.close( ) into
your Close item’s onClick event.
4 Back at the Menu designer, select the top-level "&File" item.
5 Press Tab. A new top-level item entry box appears. Press Alt+NE to insert a complete menu of basic editing
commands. Now press the Tab key again for one more top-level item entry box.
6 Press Alt+NW. This time, a new top-level "&Window" item is created. This item has no subentries yet, but it
will later.
7 Save the menu as MTEST.MNU, then close the Menu designer.
8 Open a new form in the Form designer. Add an entryfield control to the form.
9 Click on the form background. If it’s not already in view, press F11 to view the Inspector. Click the tool
button on the form’s menuFile property (Menu category), choose your MTEST.MNU file, and click OK.
Keep other form properties at their default settings.
10 Press F2 to save (MTEST.FRM, for example) and run the form.
Because this is an MDI form (the default setting), the menu appears on the application frame, replacing the
dBASE Plus menu while the form has focus.
Click the Windows menu item; you should see a selectable list of other active dBASE Plus windows. Now try
the Edit menu commands. You should be able to use all of these standard Windows text editing commands on
the text in your form’s entryfield control.
The reason these two menus provide full functionality without any coding on your part is that the items use
built-in menubar objects. You’ll see how these objects work in the next topic when we examine the code behind
the menu.
Note Since the properties used to create these preset menus belong only to the menubar class and are not available to
the popup class, you can’t use the properties in a popup menu.
Finally, try your File | Form | Close item to test your first piece of menu action code by closing the form.
Now let’s go to the Source editor to examine the code structure of this menu.
onClick = {;form.close( )}
text = "&Close"
endwith
this.MENU12 = new MENU(this)
with (this.MENU12)
text = "&Edit"
endwith
this.MENU12.UNDO = new MENU(this.MENU12)
with (this.MENU12.UNDO)
text = "&Undo"
shortCut = "Ctrl+Z"
endwith
this.MENU12.CUT = new MENU(this.MENU12)
with (this.MENU12.CUT)
text = "Cu&t"
shortCut = "Ctrl+X"
endwith
this.MENU12.COPY = new MENU(this.MENU12)
with (this.MENU12.COPY)
text = "&Copy"
shortCut = "Ctrl+C"
endwith
this.MENU12.PASTE = new MENU(this.MENU12)
with (this.MENU12.PASTE)
text = "&Paste"
shortCut = "Ctrl+V"
endwith
this.MENU17 = new MENU(this)
with (this.MENU17)
text = "&Window"
endwith
this.MENU11 = new MENU(this)
with (this.MENU11)
text = ""
endwith
this.windowMenu = this.menu17
this.editCutMenu = this.menu12.cut
this.editCopyMenu = this.menu12.copy
this.editPasteMenu = this.menu12.paste
this.editUndoMenu = this.menu12.undo
endclass
In the code above, after the menus are defined, certain key menus are assigned to menubar properties which
automatically give the menus their required functionality. For example, when this.menu12.copy is assigned to
the menubar’s editCopyMenu property, the copy menu takes on the following characteristics:
• The Copy item remains dimmed unless there is highlighted text in an appropriate object on the form, such as
an Entryfield or Editor object.
• When text is highlighted, the Copy item is enabled.
• When the Copy item is selected, the highlighted text is copied to the Windows clipboard.
The remaining Editmenu properties function in a similar fashion.
You can modify the preset Edit menu by adding, inserting, or changing item characteristics from the pulldown
Menu designer properties sheet.
The windowMenu property is useful only with top-level menus on MDI forms. The menu assigned to
windowMenu will automatically have a menu added to it for each open child window (such as all other active
dBASE Plus windows). This feature provides a means for the user to easily switch windows.
Another important menubar feature is the onInitMenu event, which is fired when the menu system is opened.
You can use this event to check for certain conditions and then modify your menus accordingly.
If, for example, you offer a Clear All item on your Edit menu, you can set an onInitMenu(_) event to disable the
item if no tables are open when your form opens. To do that, you could add a pointer to the top of your menu
file:
NEW MTESTMENU(FormObj,"Root")
CLASS MTESTMENU(FormObj,Name) OF MENUBAR(FormObj,Name)
this.onInitMenu = class::chkClearAll
And then create a method to handle the event:
function chkClearAll
if alias( ) == ""
this.edit.clear_all.enabled = false
endif
return
Table 7.1 Menubar and popup root properties, events and methods
Property Description
alignment (popup only) Lets you align items on your popup menus and submenus. Options are left-aligned, centered, and
right-aligned. Default is left-aligned.
baseClassName Identifies the object as an instance of the Menu, MenuBar or Popup class.
className Identifies the object as an instance of a custom class. When no custom class exists, defaults to
baseClassName
editCopyMenu, These four built-in objects are available for assignment to items on a preset Edit menu on a pulldown
editCutMenu, menu (menubar class). To access properties for these objects, click the object’s Tool button.
editPasteMenu,
editUndoMenu (menubar
only)
left (popup only) Sets the position of the left border of the popup. Default is 0.00.
name String used to reference the root menu object. Except for Edit and Window menu names (which use
the defaults EDIT and WINDOW), default for custom menus is ROOT. A reference to a default item
would thus be this.root.menuNN, where NN is a system-assigned item number.
top (popup only) Sets the position of the top border of the popup. Default is 0.00.
trackRight (popup only) Logical value (default true). Determines whether popup menu items can be selected with a right
mouse click. If set to false, the popup menu is still opened with a right-click, but items must be
selected with a left-click.
Table 7.1 Menubar and popup root properties, events and methods
windowMenu (menubar This built-in object is available for assignment to items on a preset Window menu on a pulldown
only) menu (menubar class). To access properties for the WindowMenu object, click the object’s Tool
button.
Event Description
onInitMenu Codeblock or reference to code that executes when the menu is initialized (when its parent form is
opened).
Method Description
open( ) (popup only) Opens the popup menu.
release( ) Removes the menu object definition from memory.
Each toolbar and toolbutton has its own set of properties, events and methods, only a few of which were applied
in the samples above. The tables on the next few pages describe the primary elements you’ll use to define your
toolbars.
You can find additional toolBar examples in the samples that come with dBASE Plus and more detailed
coverage of ToolBar class elements, with examples, in Help (search for "class ToolBar" or "class ToolButton").
Tip To inspect all toolbar and toolbutton properties, methods and events, as well as the defaults for each, type four
lines like this into the Command window:
t1 = new toolbar( )
t2 = new toolbutton( t1 )
inspect( t1 ) // opens the Inspector with toolbar properties visible
inspect( t2 ) // opens the Inspector with toolbutton properties visible
code tools
This chapter introduces three tools for working with code in dBASE Plus:
• The Source editor
A full-featured, customable ASCII text editor, the main window for editing dBL code (both .PRG files and
other project-related files, such as form, report, menu, query, and data module files). The Source editor
displays all the code in a file. To view or edit code in the Source editor, press F12 when a design window has
focus, or right-click a file in the Navigator, and choose Open In Source Editor. (Not all files have this
command available).
You can have several files open in the editor; each opens on a separate page of the editor, with its name on
the page tab. Menus and the toolbar change, as appropriate, depending on the type of file you are editing.
• The Code Builder
A dialog box available from the Inspector, that lets you conveniently edit code blocks (either commands or
expressions). Since code blocks must be on one line, they can be cumbersomely long when you’re editing in
the Source editor. The Code Block Builder displays the line of code set up in a dialog box, command by
command, for easy editing without horizontal scrolling.
• The Command window
A two-paned command-line interface that lets you experiment with dBASE Plus commands and expressions,
instantly viewing results. You can use the Command window freely at any time. To open it, choose View |
Command Window. Your work in the Command window is not saved.
• Press F12 when you have a designer open (except the Table designer).
Thereafter, use F12 to toggle between design view and the code page for any given designer file. Changes made
in either the Source editor or visual designer are reflected by the other when you move focus between them.
Code is automatically compiled when you shift focus to the designer. If an error occurs during compilation,
dBASE Plus displays an error message and points to the offending line in the file.
If an error occurs during runtime, dBASE Plus displays a dialog box, giving you the opportunity to fix the error.
If you cancel the Fix dialog box, then the only copy of the work is in a temporary disk file which is placed on
another page (or another instance) of the editor. You can do with this as you wish.
Choosing Edit | Open File At Cursor when a block of selected text includes more than just the file name, or
no file name at all, opens the Open File dialog box.
Files with .WFM, .CFM, .REP, .CRP, .PRG, .CC, and .H extensions are opened in another instance of the
editor. Other files are opened in their specific visual designer (for example, .DBF files are opened in the
Table designer).
File names with extensions unknown to dBASE Plus and not registered with Windows produce an error.
Edit what you need to, and choose OK. The code block appears in your code as one line again.
You don’t have to open the Code Block Builder if you don’t want to. You can edit directly in the Inspector or
the Source editor.
2 Click the wrench tool beside the event to open the Code Block Builder.
To create a new codeblock for a Text control,
1 Select its text property in the Inspector.
2 Select CodeBlock from the text property’s drop-down Type list.
3 Click the wrench tool beside the property to open the Code Block Builder.
Reusing commands
To reuse commands you’ve already entered in the input pane,
1 Scroll the window, if necessary, to display the commands you want.
2 Click the command line you want, or select a block of commands.
3 Execute the command (or commands) by pressing Enter, clicking the Run button, or choosing Edit | Execute
Selection.
Debugging applications
Chapter 9
Debugging is the process of locating and eliminating errors—bugs—from an application. Use the dBASE Plus
Debugger to repair broken code and resolve problems in your forms, reports and programs.
With the Debugger you can
• Load and debug multiple files.
• Control program execution by stepping through an entire program line by line or skipping to defined
breakpoints.
• Monitor the values of variables, fields, and objects. You can even make temporary changes for testing
purposes, and then update your code using the dBASE Plus Source editor.
• View subroutines (methods, procedures, and functions) that the main program calls, and track the points at
which each is called.
• Stop program execution at any point, or run full-speed to the cursor position.
• Run the Debugger as a standalone application to debug compiled programs.
Types of bugs
The two most common types of bugs are syntactical and runtime errors.
Errors in syntax include such oversights as misplaced braces or endif statements, and are generally caught by the
compiler before you even get to the debug stage. If you run uncompiled code through the Debugger, however, it
will easily catch any syntactical errors.
Runtime errors, such as calls to non-existent tables, are also quickly exposed by the Debugger, which
automatically halts at the offending reference.
When you are stopped by any error, you can either cancel or suspend further execution of the program, ignore
the error and continue running the code through the Debugger, or note the problem, open your dBASE Plus
Source editor, fix the code, and then return to the Debugger to check for additional errors.
The third, and least obvious type of bug is an error in program logic, and these are not detected so easily. If, for
example, your program includes a method that is supposed to execute after a certain event, but the event is
bypassed, you may need to use all the debugging power described in this chapter to track down and correct the
problem.
• Compile your application, then debug it by typing debug <programname.exe> into the Command window.
This method provides a "real world" test, showing how your program accesses tables, for example. After
running your tests, you can use the dBASE Plus Source editor to make any needed adjustments.
• Run the Debugger as a standalone application, set breakpoints, then run your program from dBASE Plus.
When the program reaches a breakpoint, control is handed over to the Debugger.
As your program runs, source code scrolls to the line about to receive program control. You can scroll the
source code without affecting program execution; the next command to be executed remains highlighted
regardless of where the cursor is in the Source window.
Your program runs in the background while the Debugger retains focus. You can interact with your program by
moving focus to it (use Alt+Tab to switch to it, or minimize the Debugger and click your program window).
While you interact with your program, its code continues to scroll in the Source window. If you close the
application, your program’s code remains open in the Source window.
You also use the Source window to locate and set breakpoints. If an error occurs, the Source window
automatically scrolls to the offending line, highlighting (in blue) the line immediately following the offending
line.
To correct any detected errors, return to the dBASE Plus Source editor, load your file, locate the offending line
(using the dBASE Plus Source editor’s line-numbering feature) and fix the error.
Variables
Lists variables found in the currently selected program. You can limit the extent of the variable search by
deselecting options in the Debugger Options dialog box (File | Options).
Watches
The Watch tool window lets you specify particular variables, fields, and expressions that you would like to
watch as the program code executes. The window shows the changing values for the watched items as you test
the program (by clicking buttons, sending queries, and so on).
Call Stack
This tool window displays a list of subroutines called by the current program. Each call to a separate program
file (or module) is displayed as it occurs, showing its line number, function name, and path name.
Trace
Displays the output that appears in the Output panel of the Command window.
The Options dialog box also permits you to hide exceptions during a debugging session.
Figure 9.2 Debugger tool windows, docked
Using breakpoints
A breakpoint stops program execution so you can evaluate variables, fields, arrays, objects, and expressions;
change the value of variables, arrays, and objects; and check what subroutine the program is in. Using
breakpoints lets you run the program at full speed until it comes to a problem area; breakpoints give you an
alternative to stepping through the entire program.
When you step or trace through a program, you’re essentially breaking at each line. However, once you are
certain that no bugs exist in certain parts of your program, there is no need to repeatedly step through each line;
instead, set breakpoints at crucial places where the code is less certain, then run the program at full speed and
evaluate program values at the breakpoints.
If, for example, you suspect a bug in occurs at one particular place, such as when a subroutine is called, you
could set a breakpoint at the line that calls the suspect subroutine. You could then step into the called method or
function.
You can use the Breakpoints list to keep track of existing breakpoints in all open modules. The line number of
each breakpoint is listed next to the path name of the program in which it appears.
To delete a breakpoint, select it and click the Delete button.
To delete all breakpoints, click the Delete All button.
To go to any breakpoint, simply double-click the line number of the desired breakpoint (or select it and click Go
To). The Breakpoint window closes and the Source window opens to the selected breakpoint.
To conditionally set breakpoints, click Condition to open the Breakpoint Condition dialog box, and type in an
expression—such as the value of a variable, a global condition, or any conditional expression that defines a
condition in which the current breakpoints should be active. If the condition is not met, breakpoints are ignored.
Figure 9.4 Breakpoint Condition dialog box
• Line Click the Line radio button to specify a condition for the line currently selected in the Breakpoint
window. The conditional expression you enter applies only to the selected breakpoint line.
• Global Click the Global radio button to enter a conditional expression for the entire program. For example,
you might have noticed that when a global variable reaches a certain value, say 10, the program becomes
unstable, but until then everything works fine. To test your observation, you could set the condition x=10 to
force all breakpoints to activate when the global variable x reaches 10.
calling line, the current execution point remains where it was, and will continue from that point if you resume
program execution.
Figure 9.5 Call Stack window
Watching expressions
The Debugger’s Watch window lets you monitor expression execution and results. You can even use it to
temporarily change and retest variables. It can help you detect such problems as the assignment of incorrect
values to variables, or assignment of values at the wrong points.
Watchpoints are evaluated and their current values displayed in the Watch window whenever program
execution is paused.
Adding watchpoints
To add a watchpoint, do one of the following:
• Choose Debug | Add Watch from the Debugger menu.
• Right-click the Watch window and choose either Add Watch or Watch Variable At Cursor from the popup
menu.
• Press Ctrl+W.
The selected expression appears in the Watch window.
Figure 9.6 Watch window
Note If you haven’t already run the program past a point where variables, fields, arrays, or objects in the selected
expression are initialized, "unknown" is displayed to the right of the expression.
Editing watchpoints
To edit an existing watchpoint,
1 Select the watchpoint in the Watch window.
2 Choose Debug | Edit Watch Value or Debug | Edit Watch Name from the Debugger menu. Alternatively,
right-click the Watch window and select one of the editing commands in the popup menu.
• Pause program execution by setting up a breakpoint at the line where the correct value is supposed to be
assigned to the variable.
• Use the Watch window to directly assign the correct value to the variable.
It’s important to remember that this sort of testing does not result in a permanent code change. It is only
intended to let you examine how your program behaves when the correct variable value is assigned. If the test is
successful, you can open the dBASE Plus Source editor to permanently correct the part of the program that was
responsible for returning the wrong value.
SQL designer
Chapter 10
The dBASE Plus SQL designer lets you create, edit, and execute SQL queries on any supported data source.
You needn’t be an SQL expert to use the SQL designer. In fact, you can use the tool to learn SQL by examining
the results and structure of the queries you create. You can start with simple SELECT statements and progress
to the most complex table joins and grouped queries—all of which can be easily constructed in the designer’s
table pane and notebook pages.
When your statements are structured to produce the results you want, you can save them to disk, edit them with
the Source editor, or use them as templates in the SQL Property Builder.
You can also add your saved queries to a dBASE Plus program directly by assigning an .SQL file to the SQL
property of a Query object, or by copying statements from your query files directly into your code.
1 The table pane, the upper portion of the designer, where tables and fields are depicted. This area lets you
select and deselect data for your queries. You can also use these table listings to quickly create joins.
Figure 10.1SQL Designer: Table pane
2 The query notebook is the tabbed lower portion of the designer. Each page of the notebook offers a grid
layout for specifying query parameters and options.
Figure 10.2SQL Designer: Query notebook
Dragging the mouse over a table window shows you the full name of the table. For example, the full name for a
customer table might be ":mydb:Customer.dbf".
To view tables in a collapsed mode where only the table name appears, click on the minimize button next to the
table name.
Tables can be joined by dragging a field from one table window to a field in another table window. When two
tables are joined, a join line appears that links the joined tables. For more information on joins, see "Creating
joins in the SQL designer" on page 128.
Renaming a table
1 Right-click on the table window and select Edit Table Alias.
2 Type an alias for the table name in the edit box.
Removing a table
1 Right-click on the table window and select Remove Table.
2 A table may also be removed by pressing the Delete button when the table window has focus.
Deleting a row
After selecting the row to delete, right-click and choose Delete Row from the context menu.
Simple Equation
A simple equation compares the values of two values for each row of data. For example,
CustNo >= 1000
The values can be either a field name, constant value or any valid SQL expression. String and date constant
values must be surrounded by single quotes.
When defining a simple equation the grid has three columns: Field or Value, Compare, and Field or Value.
To enter a simple equation:
1 Enter the first field or value you wish to compare into the first Field or Value column. This can be done by
either dragging a field from a table window in the table pane and dropping it onto the Field or Value column,
selecting a field from the drop-down list box, or entering a constant value or valid SQL expression into the
Field or Values column.
2 Select the appropriate comparison operator from the Compare column drop-down list box. You can choose
from =, >, <, >=, <=, <>, LIKE, IN, BETWEEN, NOT BETWEEN, IS NULL, or IS NOT NULL.
3 Enter the field or value you wish to compare to the first into the second Field or Value column. This can be
done by either dragging a field from a table window in the table pane and dropping it onto the Field or Value
column, selecting a field from the drop-down list box, or entering a constant value or valid SQL expression
into the Field or Values column.
Remember to press Enter after entering the last element of your equation.
SQL Expression
Enter an SQL expression directly into the SQL Expression column. For example,
((CustNo < 2000) OR (CustNo > 3000))
String and date constant values must be surrounded by single quotes.
EXISTS Clause
Adding an EXISTS clause returns True when the subquery produces at least one row of query results.
When a row has this type of selection criteria, the row in the grid has two columns: Operator and SQL
Expression. Select EXISTS from the Operator column. You can now enter an SQL expression to see if any rows
are produced.
The following example returns all the companies who have placed orders:
SELECT Company FROM Customer.db WHERE EXISTS (SELECT * FROM Orders WHERE Orders.CustNo =
Customer.CustNo)
In the preceding example, you would enter the statement following the ‘EXISTS’ into the SQL Expression
column.
String and date constant values must be surrounded by single quotes.
Drill-down column
The drill-down column is the leftmost column of the grid and doesn’t have a header description. If the query
contains a nested selection criteria, a drill-down arrow appears next to the nested row. Clicking this arrow "drills
down" into the expression. If a grouped expression has already been drilled down, a drill-out arrow appears in
upper left cell of the grid. Clicking this arrow "drills out" the expression.
Ctrl+U and Ctrl+D also allow you to drill up and drill down respectively.
To ungroup selection criteria,
Change the operator in the grouped expression to its opposite. For example, if you have the previous grouped
expression:
(City = ‘Freeport’) OR (Company = ‘Unisco’)
Change the OR to an AND:
(City = ‘Freeport’) AND (Company = ‘Unisco’)
Query operators
The following are the operators available in the SQL designer’s Criteria and Group Criteria pages. The Joins
page uses only the standard boolean operators.
Selecting a field
Select a field from the Field drop-down list box. Fields will be available for each table that appears in the table
pane. A Field may also be dragged from a table window in the table pane and dropped onto the Field column.
Deleting a row
After selecting the row to delete, right-click and choose Delete Row from the context menu.
2 Click the Add button to move the field to the Grouped On list box. The query will be grouped based on fields
that appear in the Grouped On list box.
To have a field appear in the Output Fields list box, select the field in the Table Pane.
To remove a field from the Grouped On list box, select the field and click the Remove button.
SQL Expression
Enter an SQL expression directly. For example,
SUM (Qty * Price) > 1000
4 Select the appropriate summary value from the Summary column for the second summary to compare.
5 Enter the second field you wish to summarize for the comparison as described in step 2.
Deleting a row
After selecting the row to delete, right-click and choose Delete Row from the context menu.
Joins grid
The Joins grid contains three columns: Field, Operator, and Field.
To have a field appear as a choice in the Fields column drop-down list boxes, select the field in the Table Pane.
The operator column allows you to specify a comparison operator for the join. You may choose from =, <, >,
<=, >=, and <>.
Deleting a join
To delete a join, in the table pane, right-click on the join line between the two joined tables, and choose Delete
Join from the context menu.
Deleting a row
After selecting the row to delete, right-click and choose Delete Row from the context menu.
Designing reports
Chapter 11
Reports provide non-editable views of data for formatted print or screen output. You can create reports to
answer questions that may involve elaborate queries across a range of databases. A report can focus and
manipulate data in many useful ways.
Tip In addition to the Designers outlined in this chapter, dQuery/Web offers "No-Click Reports", a quick and easy
way to generate reports.
This group of topics shows you how to
• Use the Report wizard to automatically generate reports (using the wizard is the recommended way to begin
creating a report)
• Understand the Report designer structure and objects
• Modify a report, changing its appearance and functionality
• Perform aggregate calculations
• Use multiple streamFrames that point to the same or different rowsets
• Create a variety of specialty labels by using the Label wizard
For information on linking a report to tables see, “Linking a form or report to tables” on page 66. For
information on creating master-detail relationships, see, “Creating master-detail relationships (overview)” on
page 68.
Before you can link a report to a client/server database, the database must be assigned an alias in the BDE. For
details on linking dBASE Plus to a client/server database, see, “How to connect to an SQL database server” on
page 27.
Note After you have created a report with the look and functionality you want, you can save that report as a custom
report (.CRP) and use it as a template for subsequent reports. For instructions on how to create a custom report,
see, “Creating a custom form, report, or data module class” on page 58.
Report wizard
You can quickly create useful reports by using the Report wizard. You specify which table or query contains the
data you want to display in the report, and the wizard links to it automatically. The rest of the wizard’s options
let you do the following:
• Display detail rows or just summary information.
• Specify fields to be included in the report.
• Group the report by specific fields. You can nest subgroups within groups.
• Choose aggregate operations that can be applied both to a group and to the entire report.
• Specify layout style, including a drill-down option, which displays summary information at the top of the
page and details farther down.
The report displays a heading for each furniture type, listing the individual styles below each heading. Grouping
by furniture type lets you do subtotals, and several other calculations, for each type.
Aggregate operations analyze the values of a selected summary field within a group or over the entire report.
You can use any field in a table, even if it is not included in the report. Also, you do not have to specify a field
for grouping to use it as a summary field.
The Qty Onhand field was selected from step 5 of the wizard, and Sum was selected as the Aggregate
Operation. This totaled the values in the Qty Onhand field for each grouping of rows, so that a total of the Qty
Onhand column appears in each Part Name group.
Because the report is grouped by Part Name, the Part Name column is redundant. To delete a column, see
“Deleting columns (fields) from a report” on page 133.
In the wizard, the Qty Onhand field was specified as the summary field for the Part Name group. Sum was
chosen as the aggregate operation for this field.
To create the grand total, <Grand Summary> was chosen from the Group drop-down list in step 5. Qty Onhand
was selected in the Available Fields box, Sum was chosen from the Available Aggregates list, and the right
arrow (>) button was clicked to add the Qty Onhand field to the Summary box, as shown below. The Qty
Onhand field’s associated aggregate operation then appears in the Selected Summary Aggregate box
.
Figure 11.3Adding grand total in the Report wizard
• The dotted-line frame labeled Pagetemplate1 is the report object that determines the appearance of the page,
such as the background color. Here is where you would place a report title. A report may include more than
one pageTemplate object, so that different pages can have different layouts.
When creating a report, you place data access components on the pageTemplate object.
• The inner dotted-line frame with the vertical label Streamframe1 is a streamFrame object. This object
displays rowset data that is streamed from linked tables (specified in its streamSource property). One or more
streamFrame objects may be contained within the pageTemplate object. Whatever is placed in the
streamFrame area of a report will be displayed when the report is printed.
If you’re using standard user interface components, place them on the streamFrame.
• The Group1-Headerband displays the label of the grouped field. Groups are contained in a streamSource
object and rendered in a streamFrame object.
• The detailBands are the streamFrame objects that contain the rowsets streamed from the linked table. Each
detailBand contains data from an individual row in the table.
The Report pane shows the report appearance with the corresponding structures shown in the Group pane
marked.
• The outer dotted area represents the margins of the actual report page (the pageTemplate object).
• The inner dotted line represents the data rows of the report (the streamFrame object).
• The individual fields of the row are columns in the report (the detailBand objects).
.
Figure 11.5Field Palette containing active fields
If you need to move the added column, remember to reposition its heading, as well.
Drill-down reports
Drill-down reports display summary information for a report at the beginning of the report. The details of the
report appear toward the bottom. Hence the name drill-down—users can drill down from the summary at the top
to the details at the bottom.
The Report wizard offers you the option to create a drill-down report. You can also create a drill-down report in
the Report designer.
4 From the Group drop-down list, select the group on which you want to perform an aggregate operation.
(Grand Summary is always available.)
5 From the Available Fields list, select the field on which you want to perform the operation.
6 From the Available Aggregates drop-down list, select an operation.
7 Click the arrow button to move the field and its operation to the Summary list.
8 Repeat for as many fields as you want.
If you want to change the aggregate summary operation for a field already in the Summary box, select that field
in the Summary box and use the drop-down list below it to select a new operation.
If you need very sophisticated calculations beyond the operations offered in the Available Aggregates box, you
could also create summary calculations in fields by writing methods for their events. Select the object linked to
the field, and type your code into one of its report-specific events, such as
• onDesignOpen, activated on opening a report
• preRender, activated before a report runs
• canRender, activated before a component is rendered, to determine whether the component will be displayed.
dBASE Plus
The foundation of any application is the system of tables that store the data. dBASE Plus gives you powerful
tools for creating and managing databases, whether your application needs a simple table or complete access to
an enterprise client/server database system.
This section is a conceptual introduction to designing and creating tables:
• Table terms and concepts
• Table design guidelines
• Table structure concepts
.
Figure 12.1Components of a Table
Classifying information
After you identify the information you need, review the list and begin to classify the information into distinct
groups. Identify the separate entities (such as persons, places, and things) and activities (such as events,
transactions, and other occurrences). In general, each table should contain only one kind of entity or activity.
The fields in each table identify the attributes of that entity or activity.
Reviewing the list in the previous topic reveals two separate entities (customers and products) and one separate
activity (orders). Each of these components has unique attributes. When you reorganize the list according to
these categories, you might come up with a new list similar to the following one:
• Customers, including customer name, address, city, state, postal code, phone number, credit standing,
signature, notes, and so on
• Orders, including order date, order number, sales date, amount paid, and so on
• Products ordered, including product name, sales price, quantity ordered, and so on
For example, a customer can place several orders, and an order can contain one or more items. These are one-to-
many relationships. Each order is associated with one customer, a one-to-one relationship.
The query might then relate three tables:
• From the Customer table comes the customer name, NAME
• From the Orders table comes the order number ORDER_NO
• From the Lineitem table comes the stock number STOCK_NO and selling price, SELL_PRICE.
The query results show each customer name followed by many orders, and under the orders, a list of the items
and prices in the order (Figure 12.2).
Minimizing redundancy
Using multiple tables reduces redundant information. In addition, don’t store information you can easily
calculate, unless the calculation requires excessive processing effort or you need an audit trail. For example, if
you were creating tables for our hypothetical dive shop, you might want to store the total invoice amount, but
not the total sales tax, which dBASE Plus can easily calculate.
In general, indexed fields that are used for linking should be the only fields that contain redundant information
in related tables. Identical data in index fields is necessary for linking tables. In this example, it is the way to
identify the same customer in both tables.
• For indexed fields, use abbreviated codes instead of long character fields wherever possible. For example,
instead of duplicating the entire customer name in every order, use a short customer code to simplify data
entry, indexing, and linking. This results in more efficient indexes and makes it easier to update information.
• Define fields in a logical order in the table. The order you define is the default way in which users will see
the table. In general, put indexed fields toward the beginning of the table, and put similar information
together in a sensible sequence.
• Use descriptive, unique field names. Be consistent when naming fields that contain similar data. Standardize
field names shared across tables if possible (this is not permitted with some SQL databases).
Table names
See your database software documentation to determine valid file names for its tables. For example, an Access
table has no extension requirement because it is stored within an Access database with an .MDB extension. On
the other hand,.DB is the required extension for Paradox tables and .DBF for dBASE tables.
The table name should indicate its purpose and be easy to remember. For example, if a table contains employee
information, you might call it EMPLOYEE.DBF.
Table types
The table type determines the file format of a table. See “Supported table types” on page 145.
The table type you define depends on the way you plan to use the table. If you expect to use the table only with
dBASE Plus applications, the dBASE Level 7 format is recommended for its flexibility and rich feature set. If
the table is to be shared with other applications, consider the most useful format for all applications involved.
The dBASE Level 7 format offers all the features of the previous dBASE file formats, including expression
indexes and extensive table-, row-, and field-level security.
The dBASE Plus interface adjusts automatically to accommodate the type of table you are using. For example, if
the table with which you are working supports it, you can specify data-entry constraints in the Inspector while
working in the Table designer. Otherwise, data-entry constraints are unavailable in the Table designer.
Field types
Each field has a defined field type, which determines the kind of information it can store. For example, a
character field accepts all printable characters including spaces. You can define up to 1,024 fields in a table.
A dBASE (.DBF) table can contain the following field types.
The field type determines what you can do with the information in the field. For example, you can perform
mathematical calculations on values in a numeric field, but not on values in a logical field.
The field type also determines how the data appears in the field. For example, a date field, by default, displays
dates in the MM/DD/YY format (such as 02/14/96). The display of field data is also affected by the settings of
the Windows control panel and the settings defined by using the BDE Administrator.
Other table types, such as SQL tables, may have different field types. Refer to your server documentation for
specific details.
Creating tables
Chapter 13
This chapter describes the dBASE Plus Table wizard, designer, and other tools for designing table structures.
Here you will find procedures for creating structures, indexes, and performing other database design tasks. It
assumes you are familiar with the basics of table design presented in Chapter 12, “Introduction to designing
tables in dBASE Plus”, and covers the following topics:
• Supported table types
• Using the Table wizard
• Using the Table designer
• User-interface in the Table designer
• Restructuring tables (overview)
• Creating custom field attributes
• Specifying data constraints
• Creating and maintaining indexes
• Referential integrity
4 Set the table type in the Inspector. You can select a BDE-standard table type or the table types of those
databases for which you have created BDE aliases.
5 In the Table designer, type a name (no spaces for dBASE files) in the Name field. (You have to name a field
before you can specify any of its other attributes.)
6 Specify values for the remaining attributes (Type, Width, Decimal, Index) by typing what you want, or by
selecting a value from the drop-down list, or by clicking the spinbox arrows. You can tab through these to
select the default values.
To create additional fields, press Return when you have finished specifying a field. Or press the Down arrow
key. Or right-click and choose Add Field from the context menu.
You can generate new fields in rapid succession by naming each, then pressing the Down arrow key. After
naming all the fields in your table design, you can go back and set or reset the attributes for each field.
Warning! Later on in your work, do not use functions such as CHR(_), LTRIM(_), RTRIM(_), TRIM(_), or IIF(_) that
vary the field width in the key expression.
If you select Ascend or Descend for a dBASE table, the Table designer creates an index for the field in the
multiple index file (.MDX) associated with the table.
To set a primary key on a dBASE 7 or Paradox table, choose Structure | Define Primary Key. Some SQL
types also support this.
You can also set other field attributes or create custom field attributes by selecting the field and opening the
Inspector. See Help.
Resizing columns
You can resize or move columns and move rows in the Table designer.
• To resize a column, point to the column border. When the pointer changes to a double-headed arrow, the
column is outlined and you can drag the border until the column is the size you want.
• To move columns, point to the title of the column you want to move. When the pointer changes to a hand, the
column is outlined and you can drag it to its new location.
• To set multiuser locks or default table type and other properties, choose Properties | Desktop Properties |
Table tab.
Note If you want to see rows that have been marked for deletion when the table is in Run mode, the Deleted option
must be unchecked in the Desktop Properties dialog box. The rows will appear and the work deleted will appear
in the status bar for those records marked for deletion. There is not a "delete flag" for each record.
Moving fields
To move a field, changing its order in a table, point to the field number in the leftmost column. When the pointer
changes to a hand, drag the row up or down to its new location.
Deleting fields
To delete fields from a table,
1 Click anywhere in the property row of the field you want to delete.
2 Choose Structure | Delete Current Field (or right-click and choose Delete Current Field from the context
menu).
The Table designer deletes the field definition. If the table contains rows, the data in this field is deleted as soon
as you save the table structure.
Note Short-cut keystrokes can also be used to add (Ctrl+A), insert (Ctrl+N) and delete (Ctrl+U) fields.
Abandoning changes
Abandon changes to a table design if you want to cancel creating a new table or discard the changes you have
made to an existing table.
To abandon changes,
1 Choose File | Close to close the Table designer.
2 Choose No when asked to save changes.
To prevent losing data that you want to keep, save the table structure frequently as you make changes and
confirm that they are completed successfully.
If you change the type of a field, the Table designer does its best to convert data to the new type. Some
conversions are relatively straightforward, such as converting date, logical or numeric fields to character.
However, radical conversions (such as a memo field to a date field) might produce results you don’t want. In
addition, the Table designer does not copy data that is invalid in the new field type. For example, attempting to
copy the value "123ABC" from a character field to a numeric field fails because letters aren’t valid entries in
numeric fields.
In addition to these guidelines, remember that if you delete a field in a table that contains rows, you lose the
information in that field permanently. You can recover the information only if you have made a backup of the
table.
Properties assigned to fields by creating custom field attributes are not streamed. Therefore, you can change the
attribute in the table without having to change your code. If you later change the field’s attributes, the changes
are automatically applied to the control dataLinked to the field. No change to a report or form is necessary.
By using custom field attributes, you can cause a table’s field to have its own special font, color, or format that
will be reproduced on any form or report whose controls are datalinked to it. For example, you can assign a
picture attribute to a PHONE field. When you dataLink an entryfield control to the PHONE field, that entryfield
control will automatically take on the picture property that was assigned as the field’s picture attribute.
To create custom field attributes in the Table designer,
1 Select the field for which you want to create a custom attribute. Open in the Inspector.
2 Right-click and from the context menu, choose New Custom Field Property...
3 In the dialog box, enter a name for the new field attribute. For example, if your table contains a phone
number field whose data you want to appear in forms in a particular phone number format, you would type
picture to add the picture property (which provides data format templates, not images).
4 Now enter a value for the new field attribute. If you used the picture property, you might add a template
value for the property, such as 999-999-9999 for a USA phone number template.
5 The new field attribute appears in the Inspector, listed under the Custom category.
To edit or delete custom field attributes,
1 In the Inspector, select the custom field attribute.
2 Right-click to display the context menu.
3 Choose Modify or Delete Custom Field Property from the context menu.
No checks are performed on the attribute name; be sure not to create attributes, such as "Name," that will cause
undesired property name conflicts. Attributes with names not used by the component simply become custom
properties of the component.
When you sort a table, all fields in the source table appear in the target table. You select the fields on which to
sort rows.
dBASE Plus sorts data in case-sensitive alphabetic order, using the sort order specified by the language driver in
the BDE Administrator. Sorting starts with the first character in the key and proceeds from left to right.
Punctuation comes before numbers, numbers before letters, and uppercase letters before lowercase letters.
Note Make sure you have enough available disk space to store the table on the target drive.
To create a sorted table or export table data to another table type,
1 Open the table you want to sort in Run mode.
2 Choose Table | Sort Rows to Table. The Sort Rows dialog box appears.
3 Specify a target table. This is the path name of the new-sorted file. Click the Target Table name tool button to
display a Save dialog box. If you want to export the table data to another table type, choose the new table
type in the box at the bottom of the Save As dialog box.
4 Select the field(s) on which to sort rows, and click the > button to move them to the Order By list.
The order in which the selected fields appear in the Order By list determines the order of the sort. The target
table contains all fields from the source table.
5 Select each Order By field, then specify the sort order.
6 When you have finished, click OK. dBASE Plus creates a new table. If the target file exists, dBASE Plus asks
whether to overwrite it. The rows you selected are copied to the target table and sorted as you specified,
starting with the first Order By field.
Planning indexes
When you design indexes for a table, consider how you will use and process data. Indexes affect and support
features that an application provides: data entry, queries, and reports. Asking the right questions at the
beginning can save you redesign efforts later.
• Using indexes in data entry
• Using indexes in queries
• Using indexes in reports
• Using indexes to link multiple tables
customer number. Using an index makes it easier to calculate running totals. If a report includes subtotals
within totals, consider using a complex index.
• If the index is solely for occasional or ad hoc reports, consider generating an index at report time instead of
maintaining an index on an ongoing basis. When the report is finished, you can delete the index to recover
disk space.
Note You might have to wait while the indexes are created, particularly if the table has many rows or if key
expressions are long and complex.
Index tasks
In addition to creating and selecting indexes, there are several other index maintenance tasks.
Modifying indexes
You can modify an existing index to make it more useful or efficient. For example, if you create a simple index
for a dBASE table in the Table designer, you might want to make it a complex index by adding fields or
expressions. Or, you might learn after using the index for a while that a different key is more suitable.
To modify an index,
1 Open the table in the Table designer.
2 Choose Structure | Manage Indexes. The Manage Indexes dialog box appears.
3 Select the index you want to modify, and click the Modify button. The Define Index dialog box appears.
4 Make your changes, then choose OK.
Deleting indexes
You can delete an index you no longer need to save space and improve performance. Deleting an index does not
delete any rows in the table—it deletes only the separate index that arranges rows in a particular order.
To delete a simple index, open the table in the Table designer, and choose None as the index type for the field.
To delete any other index,
1 Open the table in the Table designer.
2 Choose Structure | Manage Indexes. The Manage Indexes dialog box appears.
3 Select the index you want to delete, and click the Delete button.
4 Choose OK.
5 Save the table.
The index you deleted is removed from the production index file. If you delete the only index in the file,
the.MDX file is deleted as well.
CUSTOMER_N + DTOS(ORDER_DATE)
• For converting number fields, use the STR( ) function. Include the width and number of decimal places of the
numeric field(s), to ensure accuracy of the index. For example, suppose you are creating an index that
includes a character field LNAME, and a numeric field called AMOUNT that is 10 places wide with 2
decimal places. Use the following syntax:
LNAME+STR(AMOUNT,10,2)
Key expressions
The following table shows several examples of key expressions and the fields used.
The first example uses a single field as the key expression. Complex indexes, on the other hand, can use a
combination of one or more fields, plus functions and operators.
• CUSTOMER_N + ORDER_NO is a complex key expression using multiple fields and the concatenation
operator (+).
• CUSTOMER_N + DTOS(SALE_DATE) is a complex key expression consisting of multiple field names and
a function.
• UPPER(LAST_NAME)+UPPER(FIRST_NAME) converts characters to all caps before concatenating them.
The UPPER function prevents sorting problems when capitalized entries are mixed in with lowercase ones.
Unique keys
Primary indexes require unique values—they do not permit duplicate key values. For example, if a dBASE table
has a primary index on ORDER_NO, you cannot add two orders with the same order number—only one can
exist in the table. In a composite index, individual field values can be duplicates, but the combined value of all
key fields must be unique. (Secondary indexes do permit duplicate values.)
When you create the primary index, use a field that will contain a unique value for each row, such as a customer
number field.
A table can have only one blank (empty) value in the keyed field, because subsequent blank values are
considered duplicates. Therefore, key fields usually require entries.
Note Some field types, such as memo, OLE, binary, and logical, are unavailable as key fields.
Referential integrity
Referential integrity validates and updates the data in the linked key fields of a relational database. In a
relational database, a field or group of fields in one table (the child table) refers to the key of another table (the
parent table). Referential integrity rules ensure that only values that exist in the parent table’s key are valid
values for the specified fields of the child table.
You can establish referential integrity only between like fields that contain matching values. For example, you
can establish referential integrity between two tables that both have a field that holds the customer number. The
field names do not matter as long as the field types and sizes are identical.
dBASE Plus lets you establish referential integrity for any file type that supports it, such as dBASE and Paradox
table types. Some SQL-server tables also offer referential integrity. See your SQL-server database
documentation to determine if your table type supports referential integrity.
The way referential integrity is used depends on the way you have set up indexing for the tables in a relational
database. This section assumes you are familiar with the concepts of index creation and management.
• Restrict: You cannot change or delete a value in the parent’s key if there are rows that match the value in the
child table.
For example, if the value 1356 exists in the Customer No field of Orders, you cannot change that value in the
Customer No field of Customer. (You can change it in Customer only if you first delete or change all rows in
Orders that contain it). If, however, the value doesn’t exist in any rows of the child table, you can change the
parent table.
• Cascade: Any change you make to the value in the key of the parent table is automatically made in the child
table. If you delete a value in the key of the parent table, dependent rows in the child table are also deleted.
The availability of cascading updates and deletes varies according to the table type:
• dBASE Level 7: Cascading updates or deletes permitted
• Paradox: Cascading updates only
• Oracle: Cascading deletes only
• Sybase: No cascading updates or deletes permitted
• InterBase: No cascading updates or deletes permitted
• Microsoft SQL Server: No cascading updates or deletes permitted
To browse, change, or add to data in a table, open the table in Run mode. You can use any of three different
layouts: grid, form, and columnar.
Though the various data sources supported by dBASE Plus (see “Supported table types” on page 145) have
different capabilities, limitations and structures, the same basic procedures for running tables from within
dBASE Plus apply to all.
This section describes how to use dBASE Plus’s built-in data-editing capabilities to
• Scan information
• Find or replace information
• Perform data entry (add information)
• Delete and undelete information
• Save or abandon changes
• Operate on a subset of information
• View and edit special field types
Running a table
To view or edit a table, open a table in Run mode using any of the following methods.
• Menu: Choose File | Open (Alt+FO). The Open File dialog box appears. If it’s not already selected, choose
the Tables (*.dbf, *.db) item from the Files Of Type list and locate a table on your local drives, or select an
alias from the Database list. Then choose the View Table Rows option at the bottom of the dialog box. Select
your table, then click Open.
• Project Explorer: Select a table, right-click, and choose "Run" from the context menu.
• Navigator: Choose the Tables tab, then use the Look In drop-down list to choose a local folder or alias (or
use the Browse button to choose an unlisted folder). Then double-click a table icon. You can also open a
selected table by clicking the Run button on the toolbar or by pressing F2.
• Command window: type
use <tablename>
where <tablename> is a local table file name or aliased :database:table reference, for
example,:MSSQL1:mytable. You may include the full path to the file name. Then type
edit
The table appears in a grid of rows and columns. Each column is a field. You can browse or edit all the data in
the table.
Protected tables
When you open a protected table, complete the Group, User, and Password fields in the Login dialog box, and
choose OK. The database administrator assigns groups, users, and passwords for table protection.
Also note that some tables may have read-only protection or other access and editing restrictions.
Search the Help index for "security" for more information about protected tables, access rights, and encryption.
• You can resize columns and rows by pointing to a column or row border, then dragging when the pointer
changes to a double-headed arrow.
• You can move columns by dragging field titles to new positions.
Figure 14.2Columnar view
Table navigation
dBASE Plus uses a row pointer to identify the current row. Use the following methods to move the row pointer
in a table:
Note Your Desktop Properties settings might cause the exclusion of certain rows in a table. For example, if Deleted is
selected on the Table page in the Desktop Properties dialog box, the row pointer skips deleted rows. Similarly, if
you’ve specified a scope in the Table Rows Properties dialog box, the row pointer ignores rows outside the
scope. If you’ve specified a filter for the table, rows not meeting the filter condition are ignored. For details on
these and other Table Property settings, see Help (search for "table properties").
Selecting a view for entering data. When you run a table, three views are available: grid (default), form and
columnar. Choose the one that best suits your data entry task.
Repeated values. If you are entering the same value repeatedly, consider using the Replace option to update a
number of rows with the same value quickly.
Note The Data Entry page of the Desktop Properties dialog box offers a number of data entry configuration options,
including Bell, Confirm, Delimiters, and Type-ahead. For details on these options, click the Help button on the
Data Entry page.
Searching tables
In addition to scrolling through rows, you can quickly find the row you want by searching for a value in a field
you select. For example, you could quickly find a specific customer order by selecting the ORDER_NO field
and typing the number of the order you want to find. You can search character, numeric, float, date, and memo
fields.
To begin a search, click the Find Rows button, or choose Table | Find Rows.
The Find Rows dialog box provides options you can use to focus and speed up your search. The options you use
depend on the search value you specify, the way information is organized in the table, how specific the search
needs to be, and how much of the table you want to search.
Figure 14.4Find Rows dialog box
• Find What In your search text, you can specify any printable character, including spaces. The search string
can be as long as the width of the search field. In general, the longer the search string, the greater the
precision required. If you can’t find a match with the current search string, shorten it to increase your chances
of finding a match.
• Located in Field You can search for text in any field, whether or not it has been indexed. Searching is fastest
when you search on an indexed field. Before you start your search, select the index you want to use as the
master index.
• You can also search non-indexed fields, such as memo fields. Doing so might be slower than an indexed
search, particularly in tables with many rows.
• Partial Length There is no requirement that the length of the search string be identical to the field value.
This rule is checked by default.
• Exact Length To be a match, the search string must appear in the field just as you type it.
• Match Case Match Case requires that the field value match the search string exactly, including uppercase
and lowercase letters.
Once you have selected the options you want, click Find Next. If a match is found, the row pointer moves to the
matching row and the row appears highlighted. If no match is found, a message appears.
If you don’t find the match on the first try, shorten the search string or adjust other search options as needed and
try again.
To replace rows,
1 Select the table, then choose Table | Replace Rows. The Replace Rows dialog box appears.
2 Complete the dialog box.
• The replacement value you specify must match the data type of the selected replace field. Make sure that
the value fits in the field.
• In character fields, if the text is too long for the field, it is truncated.
• In number fields, if the value exceeds the field size, the fields fill with asterisks.
• In memo fields, the existing memo text is overwritten with the replacement text. The replacement text
must be in character format.
3 Once you’ve specified the replacement text, do one of the following:
• Choose Find to find the next occurrence of the search text. Then choose Replace to replace it, or choose
Find to leave it alone and go to the next occurrence.
• Choose Replace All to replace all occurrences of the search text.
Deleting rows
To delete a row in grid view, select the row by clicking the button at the left of the row, then press Ctrl+U. In
columnar view, navigate to the row and press Ctrl+U.
1 You can also delete rows through the Delete Rows dialog box:
2 Find the row in the columnar view or select the row in the grid view.Choose Table | Delete Rows, or click the
Delete button on the toolbar. The Delete Rows dialog box appears
3 Click OK to delete the currently selected row, or specify a particular row number, or choose all to delete all
rows. Click OK.
Figure 14.6Delete Rows dialog box
Counting rows
You can count rows to determine how many rows meet a given set of criteria. For example, you might want to
know how many customers fall within a certain zip code range, or how many orders were taken on Tuesday.
To count rows:
1 Choose Table | Count Rows. The Count Rows dialog box appears.
Figure 14.7Count Rows dialog box
Most calculations work on numeric and float fields only, but Maximum and Minimum can also be used with
date and character fields.
To calculate values:
1 Select the table, then choose Table | Calculate Aggregates. The Calculate Aggregates dialog box appears.
Figure 14.8Calculate Aggregates dialog box
2 Choose the type of calculation you want to perform, then select one or more of the listed fields. (Use
Shift+click to select several contiguous fields, or Ctrl+click to select several noncontiguous fields.)
Optionally, you can type an expression in the Where box to select a group of rows on which to perform the
calculation
3 Click OK.
dBASE Plus performs the calculation and displays the results in the Calculation Results message box.
Figure 14.9Calculation Results dialog box
Memo fields
Memo fields open in a text editor. When the text editor is open, the Format toolbar becomes available, and you
can format text in the memo field.
Binary fields
Your tables can contain any supported sound and image data, and the data can be stored, viewed (or played, in
the case of sound files), added, or replaced any time you run a table.
.DBF and .DBF 7 tables support most popular image formats (for a complete list, see the Image page in the
Navigator). The supported sound format is .WAV.
OLE fields
Object linking and embedding (OLE) lets you use objects from other Windows applications in your tables.
You can either link objects to or embed objects into OLE fields. Linking inserts a reference to the file from
which the object originated, which means that in order to keep the object updated, both the source file and
source application must remain available. If the linked object is updated, your OLE field is updated as well.
Embedding places an entire object into the OLE field. Embedding is a more portable solution, but still requires
that the application that created the source be available. It can also cause significant enlargement of your table
file sizes, which grow by the size of each object you embed plus some OLE reference code for each. And unlike
links, embedded objects are not updated when the source object changes. Instead, they become separately
editable (in the source application) objects of their own.
An OLE object can be a graphic image, a sound, a document created by a word processor, or any other object or
document that can be created by an OLE-compliant server application. For example, Microsoft Word is an OLE
server, and any document created in Word can be linked or embedded into an OLE field.
In any OLE exchange, dBASE Plus then becomes the client application.
Whether you choose to link or embed an object into your OLE field, you can launch the server application and
load the object for editing by simply double-clicking the OLE field in your running table.
file, change the link (useful if the source file is moved) or even break the link—by right-clicking the OLE
viewer and choosing Links from the popup menu.
To edit an embedded object, double-click the OLE viewer containing the object. The server application opens
with the object loaded for editing. When you’re finished with your edits, update the OLE field by choosing
Update from the server application’s Edit menu.
You can also link or embed OLE objects by right-clicking an OLE viewer window and choosing Insert Object
from the popup menu. The Insert Object dialog box lets you choose from among the OLE object types
registered on your system. You can then either create a new object in the server application (for embedding) or
create an object from an existing file (for embedding or linking).
Setting up security
Chapter 15
dBASE Plus provides built-in levels of security against unauthorized access to encrypted databases and tables.
This table-level security depends on data encryption.
Sensitive tables should always be encrypted by using the database vendor’s administration software. dBASE
Plus’s password dialog is presented whenever a user tries to access a form linked to an encrypted table or
database. The user’s response to the password dialog is passed to the encrypted table or database for verification
before dBASE Plus will display the form. See your database vendor’s documentation about security
administration for SQL, ODBC, or non-Standard systems.
The DBF and DB tables you create within dBASE Plus have built-in encryption. dBASE Plus provides direct
database administration security access to set passwords for BDE-Standard DB and DBF tables, as well as the
extensive user-access and privilege-level security features of DBF tables.
you intend to create tables within dBASE Plus, DBF tables offer the most extensive and versatile security
features.
• Table-level security for DB tables
dBASE Plus provides direct access to master password security for each DB table. However, you must use
Borland’s Paradox or Database Desktop to set auxiliary passwords.
can share the default session. You would need only call the session’s methods once through an administrative
program or form.
All the forms would thus require a Query object to access the DBF or DB tables, but no Database object or
Session object, because everyone uses the default database in the default session.
On the other hand, if any two applications use different user names or passwords, then every form must have its
own Session object, so that each form runs in its own session and the security is localized.
No Database object is needed because the form uses the default database of its own session. Then users must log
into each session before the query is activated.
Use the Query object’s canOpen event to call the session’s security methods.
Table access
First, you’ll need to define user groups and determine which group has access to which table. Try to organize
users and tables into groups that reflect application use (for example, by department or sales area).
• A table can be assigned to only one group. If the user group and table group don’t match, the user can’t
access the table.
• Typically, each group is associated with a set of tables. By associating each application with its own group,
you can use the group to control data access.
• A user can belong to more than one group. However, each group that a user belongs to must be logged-in
separately.
• If a user needs to access tables from two different groups in the same session, the user must log out of one
group, then log in to the second. A user may have separate logins into different groups in separate sessions to
access files in different groups.
• Which user access levels can read, update, extend and/or delete the table (table privileges).
• Which user access levels can modify and/or view each field within the table (field privileges).
After a user logs in, dBASE Plus determines what access the user has to that DBF table and its fields by
matching the user’s access level with the rights you specified in the table’s privilege scheme.
For example, if you assigned a user an access level of 2, that user’s access to the table, and to various fields
within the table, are determined by the privileges you assigned to Level 2 in the table privilege scheme.
In building a table privilege scheme, note the following:
• A user’s ability to access a table is a function of both the access level of the group and the user’s individual
access level. However, only the user’s access level determines what the user can do with a table once it is
opened.
• If you do not create a privilege scheme for a table, all users of the group can read and write to all fields in the
table.
• Access rights cannot override a read-only attribute established for the table at the operating system level.
Table privileges
At the table level, you can control which operations each user access level (1–8) can do:
• View records in a table (read privilege)
• Change table record contents (update privilege)
• Append new records to a table (extend privilege)
• Delete records from a table (delete privilege)
When you create a table privilege scheme, all four table privileges are granted initially. That is, all table access
levels are 1 by default (1 being the least restrictive level).
Field privileges
At the field level, you can control which operations each user access level (1–8) can do:
• Read and write to the field in the table (FULL privilege). This is the initial default.
• Read but not write to the field (READ ONLY privilege).
• Neither read nor write the field (NONE privilege). NONE blocks a user from writing to fields and from
seeing fields you do not want to display.
Selecting a table
To select a table,
1 Open the Tables tab of the Security dialog box. You use the Tables tab of the Security dialog box to create
and modify DBF table privilege schemes. The DBF table privilege schemes are saved in the table structure.
2 In the Table field, type the name of the desired table. (Or click the Tools button and select the table.)
3 Click the Modify Table button. The Edit Table Privileges dialog box opens.
To set table privileges, select a value (1–8) for each operation (Read, Update, Extend and Delete) in the dialog
box. Remember that lower access numbers indicate the greatest access; higher numbers indicate the greatest
restriction.
Note You cannot specify access levels that are logically incompatible. For example, you cannot prohibit Level 6 from
having read access, and also permit Level 6 to have update access. To have update access, Level 6 also needs
read access.
Note Table privileges take precedence over field privileges. For example, if a table privilege is set for Read but not
Update, the only meaningful field privileges are Read-Only or None. You must restrict table privileges to
protect your data against table-oriented commands like DELETE and ZAP. Restricting field privileges to Read-
Only or None without restricting table privileges doesn’t protect data against these commands.
The Fields list in the dialog box lists all of the fields in the current table. The Rights buttons display the field
privileges for the selected field for access levels 1 through 8. Initially, all field privileges are set to Full.
Follow this procedure to change a field privilege:
1 Select the field.
2 Click the Rights buttons that correspond to the privileges you want to grant for the field for each access level.
3 Repeat the process for each of the other fields in the table.
4 Click OK to save the field access privileges.
Warning! Never change the access rights of the _DBASELOCK field of any table. The rights to this field must remain
Full for all access levels.
only a specific set of DB tables or allow read/write access to only certain fields within those tables. However, to
set auxiliary passwords for field rights to a DB table you must use Paradox.
The process of assigning passwords is initially very similar to that described previously for DBF tables. To
assign a master password to a DB table, follow these steps:
1 Make sure the DB table you want to secure is closed.
2 From the File menu, select Database Administration. The Database Administration dialog box appears.
3 Make sure that the Current Database field is set to <None> and the Table Type field is set for Paradox (DB)
tables.
4 Click the Security button to open the Security dialog box.
5 Select the name of the table in the Table list. If the table is not in the current directory, use the Folder button
to select the directory.
6 Click the Edit Table button to open the Master Password dialog box.
7 Enter the new password for the table in the Master Password field. The password can be up to 31 characters
long and can contain spaces. Paradox passwords are case-sensitive.
8 Enter the password again in the Confirm password field.
9 Click the Set button to save the password.
drivers
dBASE Plus is an international software tool which can accommodate many languages. Each language or
language category uses its own character set, and each has its own way of sorting and relating its characters.
dBASE Plus provides comprehensive language and character set support with multiple language drivers and
automatic OEM–ANSI conversion as needed.
Users new to the Windows environment need to understand the difference between the OEM and ANSI
character sets. Users who exchange data across national or linguistic boundaries need to understand how dBASE
Plus uses language drivers to handle data in different languages.
This section explains how dBASE Plus uses the OEM and ANSI character sets and discusses techniques for
working with language drivers.
At startup, locate the desired core-product language resource file. This file is identified as PLUS_xx.dll - where
the "xx" is the two-letter language code. dBASE Plus then attempts to load a language resource file by checking
the following locations:
1 The PLUS.ini file
2 The operating system's Regional Setting.
If a language resource file was not found at either location, dBASE Plus will default to English and attempt to
load any language resource file it finds. The language resource file that is successfully loaded determines the
value of the _app. object’s language property. The value of the _app.language property is the two-letter
language code mentioned above.
The app.language setting will be used for the first attempt at locating relevant files when other language-specific
resources and documentation files are needed. For example, when _app.language is set to "it", Italian, and a user
invokes the Online Help system, dBASE Plus will attempt to locate and load a file called "dBASE_it.hlp". If this
cannot be found, the system will attempt to load the file’s English version.
When dBASE Plus converts data from OEM to ANSI, and vice versa, most alphabetic characters exist in both an
OEM code page and the ANSI character set and are converted without problem. Most of the extended graphic
symbols in an OEM code page cannot be represented in the ANSI character set at all. When such a discrepancy
exists, dBASE Plus, like other standard Windows applications, makes a guess at the nearest character, but data
loss can occur.
An exact match requires that the characters be exactly the same. For example, although the characters O and Ö
are similar, they don’t satisfy the requirement for an exact match, and a SEEK or a FIND expression treats them
as different characters. In contrast, an inexact match requires only that the characters belong in the same general
category. For example, since the characters O and Ö are similar in several languages, they satisfy the
requirement for an inexact match with many language drivers; a SEEK or a FIND expression treats them as
identical characters.
Exact and inexact matches are performed using primary weights and secondary weights, which are assigned by
a language driver to each character. Exact matches use primary and secondary weights, while inexact matches
use only the primary weights and ignore the secondary weights. For example, the SET EXACT command
controls whether characters with umlauts match their respective characters without umlauts. The following
commands open a table named VOLK.DBF and search for a record with a key value that satisfies an exact
match criterion:
set exact on
use VOLK order NAMEN
seek "KONIG" // Will NOT find "KÖNIG".
EXACT is ON and the secondary weights of O and Ö are different, so they are evaluated as different characters.
The following commands open VOLK.DBF and search for a record with a key value that satisfies an inexact
match criterion:
set exact off
use VOLK order NAMEN
seek "KONIG" // Can find "KÖNIG".
EXACT is OFF and the primary weights of O and ö are the same, so they are evaluated as identical characters.
For example, the following commands open a table file and create a new one with the LDID set to the current
global language driver:
use CLIENTS // LDID specifies a language driver other than global language driver
copy to CLIENTS2 structure extended // LDID of CLIENTS2.DBF matches the language
// driver of CLIENTS.DBF
use CLIENTS2 exclusive
create NEWCLIENT from CLIENTS2 // Create a new table with the global LDID
The following commands open a table file and create a sorted table file with an LDID set to the original table
language driver:
use CLIENTS // LDID specifies a nonglobal language driver
sort on LASTNAME to CUSTOMER // LDID of CUSTOMER the same driver as with CLIENTS
• Verdana Turkish
• Arial Baltic
• MS Gothic Cyrillic
• Courier New Central Europe
The following PLUS.ini file settings ensure that the initial font created for a new control uses the language you
want:
[DefaultFonts]
Application=<strFontName>,<intPointSize>
Controls=<strFontName>,<intPointSize>
The Application setting specifies the font used for the Navigator and Inspector, while the Controls setting
specifies the default font used for forms and controls. You can also create your own custom controls to specify
the font and language you want to use.
For example, when you create a table file with the German language driver, an LDID identifier is written to the
header region of the file. If the global language driver is set to English and you open the table in dBASE Plus,
dBASE Plus notes the discrepancy between the table’s and system’s language rules. If you create an index with
INDEX ON, the logical order of the index obeys the language driver of the table:
use VOLK // Created with the German language driver
index on NAMEN tag DIENAMEN // Orders records in the German way
By contrast, if you create a filter with SET FILTER, the filtering condition obeys the global language driver:
use VOLK
set filter to NAMEN = "KONIG" // Excludes records with "KÖNIG" in NAMEN
characters (as with ÜNAMEN in the example below) problems arise when you try to reference the field in when
using the U.S. language driver.
When such conditions exist, the following command generates an error condition:
replace ÜNAMEN with "Schiller"
You can solve this problem by surrounding the field name with the : delimiter, which treats the field name as an
identifier regardless of the rules contained in the current language driver:
replace :ÜNAMEN: with "Schiller"
When you use this command, each element in the field name ÜNAMEN, including Ü, is treated as an identifier
and the command executes successfully.
Note Converting between character sets does not change the character set you are using to view your text or program.
To change the way you view your text or program:
1 Choose Properties | Source Editor Properties.
2 Specify either DOS Text or Windows Text for Interpret text as.
dBASE Ill+/IV
To convert your application to Visual dBASE 5.7, see the section titled, "Converting a dBASE IV Application
to Visual dBASE 5.7.", on this page.
Note For dBASE III+ users: This procedure will only work for .PRG and .FMT files.
Once this has been completed, you need to convert the Visual dBASE 5.7 application to dBASE Plus. See the
section titled, “Converting Visual dBASE 5.7 Applications to dBASE Plus” on page 206.
4 Choose an install language from among the five listed in the "Visual dBASE 5.7" folder:
• DE = German
• EN = English
• ES = Spanish
• FR = French
• IT = Italian
5 Double click the desired language folder.
6 Double click the "vdb" folder.
7 Open the "Disk 1" folder and double click the “Setup.exe” file to begin the installation process.
If you are unfamiliar with Visual dBASE 5.7 you should use the "default" install, which installs the program
according to a set of pre-determined defaults.
Overview
The following is designed to help you convert an existing application to Visual dBASE 5.7, and is not a
programming guide for the language. Most of what you read here concerns how to convert your screens, reports
and labels to Visual dBASE 5.7. If you have other questions, please check the online help for Visual dBASE
5.7, as well as the Knowledgebase for dBASE Plus (which includes a Visual dBASE 5.7 section).
Suggested Steps
An application, the "Component Builder", is provided with Visual dBASE 5.7 which can be used to convert
some of your code directly from DOS code to Windows code. Create a folder to use for the new code as well as
copies of your tables. Make sure you copy all .DBF, .MDX, and .DBT files.
Start Visual dBASE 5.7. Click the “Current Directory” folder in the Navigator window and select the folder you
will use to store the Windows version of your application.
Most applications are quite diverse, however the following steps assume a relatively basic application. When
converting your DOS application to Windows you need to do the following:
1 Create or Convert your Menus
2 Convert your Screens to Visual dBASE Forms
3 Fine tune the forms
4 Convert your Report and/or Label files to Crystal Reports
5 Fine tune the reports and/or labels
6 Create any queries necessary for your reports or labels
7 Create any code needed to communicate with your forms, reports, and labels
8 Modify the menu so it calls the appropriate programs.
Note It may be possible to run your code in Visual dBASE 5.7 without doing a conversion, but doing so will cause it
to look like a DOS Screen, not a Windows application.
Sample
There will be a few screen shots for a very simple address-book style application, but for the most part there are
other chapters of the User's Guide that detail how to use the different design surfaces.
The sample is very simple and is only used to get you started.
Recreating Menus
The "Component Builder" that ships with Visual dBASE 5.7 can be used to convert screens and reports,
however you will need to manually reproduce your menus.
Note The menu designer in dBASE Plus has not changed much from the one used in Visual dBASE 5.7. For
additional information, see Chapter 7, “Creating menus and toolbars”.
The menu designer will have two windows open, "Untitled - Menu Designer", which is the design surface, and
"Untitled - Inspector". If the Inspector does not appear, select it from the View menu. The Inspector is used to
set or change properties, and other aspects, of the menu being designed. You should be able to reproduce the
menu shown in Figure 17.1 with little effort. For the time being, we're only going to visually design the menu. A
little latter, we’ll come back to tell the menu what to do when the user selects the items.
Click in the design surface window and an entrybox with a pulsating cursor will appear.
• Type the word “File”, for the first menu option, and press the down arrow key to get a “Sub menu” entrybox.
Sub menus appear beneath the main menu heading and offer it's associated options.
• Type "Add New Data” and press the down arrow key.
• Type "Edit Data" and press the down arrow key again.
For the final sub-menu option add an "Exit" option preceded by a separator. In the Inspector, click the separator
property and use the drop-down list to change it's value from F to T. Click in the design surface. Press the down arrow
key, and type "Exit". The "File" menu option is now complete.
To add a second main menu option, move the cursor back up to "File" and press the tab key. Type the word
"Reports" and press the down arrow key. Continue in this fashion, adding menu options for “Print List” and
“Print Labels”.
Save the menu and exit the designer. The easiest way to save the menu is by pressing Ctrl+W (Save and Exit)
simultaneously. You could also use Ctrl+S to save the menu, and then close the window with the 'X' in the
titlebar. When asked for a filename, call this "Address". If you look in the Navigator you should now see
"Address.mnu" listed.
Converting Forms
To convert a screen to a Windows form, use the Component Builder installed with Visual dBASE 5.7. To run
the Component Builder, you will need to change the current folder to point to the folder containing the
Component Builder.
To do this:
Click the “folder” pushbutton in the Navigator Window's "Current Directory" area
Select "Visualdb\utils\", the utils folder, and click "OK" (make sure you use the actual path for your installation
of Visual dBASE 5.7).
In the Command Window, type:
do cb
and press the Enter key. This will start the Component Builder program.
In the Command Window, type:
do cb
and press the Enter key. This will start the Component Builder program.
Figure 17.2 Sample Form
Note When the Component Builder window appears, you’ll see it’s "Help" menu. If you need assistance, this is a
good place to go.
Figure 17.3 The Component Builder
6 Click "OK"
7 You will be asked where to save the new form. Select the folder where you wish to put your Windows
application. Click "OK"
A screen will appear showing the progress of the conversion. This will show the different types of objects, the
lines, etc. Unless there is a serious error, the Component Builder will attempt to convert everything on this
screen to a Windows object. If you have complex code, some of it may converted in which case you will need
to make modifications.
When the screen is done being converted, click "OK" on the screen showing the progress bar, and exit the
Component Builder.
Use the Navigator to go back to the folder with your Windows application. If you click on "Forms" in the Navigator you
should see "Address.wfm" in the list on the right.
You will most likely need to fine-tune the job done by the Component Builder. There are some very good
instructions on using the Form Designer in Chapter 6, “Using the Form and Report designers”. While the User’s
Guide is aimed at dBASE Plus, most of what is said can be applied to the Visual dBASE 5.7 form designer.
The difficulty with using the Component Builder is that it does not understand a lot of the setup, contained in the
program file, that most dBASE/DOS programs use to display screens. All it is looking for are the @/SAY, @/
SAY/GET, and READ statements in the program.
If you choose this option:
1 Use the Navigator to go to the Visualdb\UTILS folder
2 Run the program CB.PRG
however, as the dBASE/DOS software did not have Checkboxes, they are not really created quite right. You can
delete these controls and use the Inspector to set the text property of the Checkbox "object" instead. Since the
Checkbox object defaults to a short width, and at first the text doesn't show up, widen it using the Inspector. It
will look better and allow you to manipulate a single control rather than several.
Click directly on the form's surface, to give it focus, and click the Inspector. Find the mdi property (it's under the
"Windows Properties" heading), and change it from T to F. "MDI" stands for "Multiple Document Interface".
DOS applications were generally not "MDI", and while it was possible to write MDI applications in DOS, doing
so was quite complex.
If you set the form's autoCenter property to .T., the form will be centered on the screen. If not, the form’s display is
determined by it’s top and left properties.
With a little work, your form could resemble Figure 17.5:
Figure 17.5 A Running Form
We could modify this form all day, but we're only going to add one more item - a button that allows the user to
close the form.
Visual dBASE 5.7 comes with a selection of custom controls. These are simply common controls the developers
designed to save us the trouble. Click on the Control Palette and click the tab marked "Custom" at the bottom of
the page.
You can view the name of any one of the resulting series of pushbuttons by moving the cursor over it. Find the
one named "Closebutton", and drag it to the bottom of your form. This button already has code defined that will
close the form when clicked.
Set the form's mdi property to false. Click on the Form. Bring up the Inspector and change the mdi property to F.
Set the form's autoCenter property to T to center the Form, and press Ctrl+S to save. Name the file "search".
You should now have a pushbutton the user will click to perform the search. Click on the "Component Palette",
select the "Custom Tab", drag the "Closebutton" to the form, and center it under the controls. Resize the form,
and it's done.
You should have a form resembling Figure 17.6
:
Figure 17.6 Form with PushButton
Modify the above code by replacing the "ACCEPT" command line with:
do search.wfm with .t.
This line will run the form, and the "with .t." ensures it runs as a modal form (details on "modal" versus "non-
Modal" can also be found in the Knowledgebase).
The section,
accept trim(first)+" "+trim(last)+;
" -- is this the name [Y/N]? " to cYN
if upper(left(cYN,1)) = "Y" && found a match
can be changed to use a built-in Visual dBASE dialog box that prompts for yes/no answers. This is called a
Message Box, and it's called using the msgbox( ) function.
Change both of these lines to:
if msgbox( trim(first)+" "+trim(last)+;
" -- is this the name?", "Confirm", 4 ) = 6
If a match is found, this will prompt the user to confirm that the find was correct using "Yes" or the "No"
buttons. (More details on the msgbox( ) function can be found in Help.)
To replace the code displaying the message that no match was found:
?
? "*** No match found ***"
?
call the msgbox( ) function once again:
msgbox("We did not find it.","No Match Found")
This will display only the message, and an "OK" button.
To replace the code that calls the screen (.FMT file):
do address.fmt
use
do address.wfm with .t.
At this point, your search program is ready.
1 Using the Visual dBASE 5.7 Navigator, change your current directory to the UTILs folder containing the
Component Builder.
2 Run the program CB.PRG
3 When the Component Builder screen comes up, select the File menu, and "FRM to RPT ...". The .RPT
extension is the Crystal Reports report filename extension.
4 Select the folder, and then the report you wish to convert
5 Select the table needed for the report. If you are using multiple tables in a .VUE, select that file and the
designer will attempt to create a .QBE file.
6 Select the folder in which to place the report.
7 A screen much like Figure 17.7 is displayed.
8 When done, click "OK". You can convert another, or close the Component Builder.
Open the report in Crystal Reports. You may need to modify the report somewhat (change the fonts, etc.).
To do this:
1 After closing the Component BuilderChange, use the Navigator to change the folder you are working in, to
the folder that will contain the Windows version of your application.
2 In the Navigator, select the "Reports" icon.
3 Click on your new report
4 Right click and select the option, "Design Report".
You should see something similar to Figure 17.8
You can change the font for all items, or change each one individually. To change the font for all of items, use
the Ctrl key along with the mouse. While holding down the Ctrl key, click each text control you want to change.
Then Right click, and select "Change Font ...". You can select a font, a font size, and attributes.
Once you've changed the font, especially if you use a Windows "True-Type" style font, you may need to change
the widths of some controls, and possibly re-locate a few.
:
Figure 17.8 Crystal Reports for dBASE
With two execptions, you can use the same steps for Label files as were used for Reports
• When you select the "File" menu in the Component Builder, select "LBL to RPL ..."
• Use the "Labels" icon when you return to Visual dBASE to modify the label file.
2 If the Command Window is not already visible, select it from the View menu.
3 Click in the upper pane of the Command Window and type the following:
do :DOS5Conv:Dos5Conv.wfm
This runs the Converter Wizard, which will guide you through the conversion process.
4 Read the instructions on the first screen and click the "Forward" button.
5 During this step, you’ll identify the folder containing the files to be converted, and the folder in which to
place the converted files. Click on the "Tool" button to the right of the entry areas to select the folders. Once
these folders have been selected, click the "Forward" button.
6 Click the "Convert" button. The Wizard lists each source file as it’s converted and, when finished, displays
the list of newly created files.
7 Click the "Close" button and use the Navigator in dBASE Plus to locate the folder, specified earlier,
containing the converted files.
8 In the folder you’ll see the files with the extensions .wfm and .mnu. These are the extensions for dBASE Plus
form and menu files. To open them in the Designer, right-click and choose the "Design (form or menu)"
option. Forms can be run from the Navigator by double-clicking on a selected form.
Conversion considerations
A few things to note when the converter has finished:
• This converter was designed to create dBASE Plus compatible objects from your screen and menu layouts. In
doing so, our priority was to insure the layouts converted correctly. Still, your form or menu’s design will
most likely require some modification (changing the widths of some objects, possibly moving some objects a
small amount).
• Some of your source code may not have been converted correctly. Lacking a huge language translation
utility, it simply isn’t possible to insure the correct conversion of all source code. Use the Source Editor to
correct any conversion errors.
• The converter creates forms that use the OODML (Object Oriented Database Manipulation Language) of
dBASE Plus, which is not necessarily going to be familiar to you. When tables are opened, they are opened
using Query objects, rather than the USE command, and datalinks to fields in the tables refer to the
appropriate Field objects. To become acquainted with OODML:
• Read through other parts of this User’s Guide
• Check the dBASE Knowledgebase at www.dBase.com, or from the Help menu
• Subscribe to, and participate in, a few of the many dBASE newsgroups available at news://
news.dBase.com. They’re free!
• When the converter runs, it reads all the form and menu definitions in the .DFM, .MNU and .PRG files, and
creates individual files for each one. This means you end up with more files than you started with. For
example, if you have a .DFM with two form definitions, you’ll end up with two .WFM (Windows Form)
files. The resulting filenames may look a bit strange, but this is only because the converter combines the
names of the object and source files: The ACCT_REC.DFM file from the dBASE 5.0 for DOS CUA
Samples folder is converted to ACCT_REC_ACCT_REC.WFM.
• When the converter creates a menu file, it checks to see if there is a form's menuFile property set to point to
it, and if so, attempts to set that property in the new .WFM file. Therefore, the menus should be correctly
associated with the forms.
• Properties of a form that were defined programmatically, using expressions or variables, will be converted to
their default values. For example, a .DFM may have defined the top property based on a value relative to
another form. In this case, the top property is likely to be set to zero when the .WFM is created by the
converter. This is necessary because there is no good way for the converter to know the relative value these
values refer to.
• Procedures in your forms and menus may be converted to the .wfm or .mnu file with the code itself placed
inside of a "comment block". This is a block of text that appears between the comment block symbols /* and
*/. For example:
procedure PUSHBUTTON1_ONCLICK
/*
select acct_rec
*/
The code is present and hooked up to the pushbutton, but will not execute until you have a chance to make
sure it’s correct. If the procedure involves data manipulation, it will most likely fail and you’ll need to
replace it with OODML syntax. If the code looks correct, you can remove the comment blocks, keeping in
mind that tables are not opened with the old dBASE for DOS syntax. They are opened in the new dBASE
Plus (dBL) syntax, using Query objects. The converter wizard will attempt to put referenced procedures,
from a procedure file, into the form or menu.
• If you have any "#INCLUDE" statements, make sure you copy the include files to the new source location.
• If your programs, or forms, require the use of .BIN or other external binary files, chances are they will not
work in dBASE Plus. You’ll need to come up with a dBL way to perform their function, or find another
solution (i.e., ActiveX, or other third-party tools).
• Some menu keystrokes do not work in Windows (Ctrl-Ins, for example). Opening these menus in the
Designer may result in errors pointing to these statements. The simplest way to deal with this would be to
comment that line of code out (or delete it) by placing a * or // in front of the line of code. Open the menu in
the Designer, and in the error dialog, click "Fix" and place the * or // characters in front of the line of code.
• If your form produces the error message, "Unallowed phrase or keyword: .oBForm", click the "Fix" button
and place either a * or // in front of the statement;
RELEASE _CmdWindow.oBForm
to comment this line out. Then Save and Exit (Ctrl+W) the editor.
Remember, the converter is here to help bring the screen and/or menu layouts into dBASE Plus. Expect to do
some modification to the results.
An Option
1 Copy just the screen and/or menu code from files that involve the layout. Do not copy any actual code that
manipulates the data. Basically, copy the screen design code, the "constructor code", to a new .DFM, and
save it in a new folder.
2 Run the converter to bring over the definitions of your screens and menus.
3 Run dQuery to create a dataModule.
4 Open the new dBASE Plus form in the form designer.
5 Place the dataModule object on the form surface, and change all the datalinks to the dataModule (if you have
multiple tables, make sure you get the right ones).
6 Delete the query objects that are on the form.
In the dataModule, you can place a lot of your validation, and other code, create links between tables, and so on.
This places everything in the one, re-usable, file.
Converting Forms
To convert forms from Visual dBASE 5.x (5.5, 5.6, 5.7) to dBASE Plus, you need to use Visual dBASE 5.7. The
converter program needs to be run in Visual dBASE 5.7 to perform the conversion.
In Visual dBASE 5.7, use the Navigator to point to this folder
C:\Program Files\dBASE\Plus (version)\Converters\FormConverter5x
Note This path may differ depending on where you installed dBASE Plus, and what language you are using.
You will need a folder containing your Visual dBASE 5.7 source code, and one in which to store your dBL
source code.
To perform a form conversion:
1 In the Command Window, type:
set procedure to Conv1632.cc additive
2 Using the Navigator, select the folder containing your Visual dBASE 5.7 source code.
3 Open the form to be converted in the form designer.
4 Click on the Control Palette
5 Click the 'Custom' tab of the Control Palette
6 There should be a control with the letter "A" for the icon. When you move the mouse over the control it will
display a speedTip that says "Conv1632". Drag this to the form.
7 Click the "Forward" button
8 Click the "Wrench" button next to the Entryfield that says "Select 5.x input file:"
9 Select the same form you have in the designer
10 Click the "Forward" button
11 Click the "Convert" button
12 Click the "Close" button
Close the form in the designer, but do not save changes. If you select "Yes" to save the changes, the converter’s
custom control will be saved as part of the original form.
You now have a new form in the same folder as your 5.x source code, but the file has "_fcv" added to the
filename. For example, if you converted "Customer.wfm", you would have a new file "Customer_fcv.wfm".
This form file should contain the dBASE Plus version of your 5.x form. You should try testing the form in
dBASE Plus and, once you are satisfied with it, copy or move it to your dBASE Plus applications source folder.
If you use Custom Forms, convert all of them before converting your other forms.
Important The form converter does NOT change the source code to dBL, dBASE Plus’s Object-Oriented Database
Manipulation Language (OODML). A converted form will continue to use XBase Database Manipulation
Language (XDML). If you wish to update to OODML, read the Knowledgebase which has several articles
designed to assist.
Components
The dQuery/Web Server Side Components™ and dQuery/Web™ deliver capabilities very similar to dQuery on
the desktop, but deliver them in your browser, securely over the Web. You can get live data on-the-fly, run an
existing dataModule, run reports created in dBASE Plus™, even run One-Click Web™ and Web Wizard data-
entry applications created in dQuery.
Apache
Assuming the dQuery/Web Server Side Components have now been successfully installed to a folder, you
might configure Apache by inserting this segment into the Apache configuration file (httpd.conf):
# Creates an alias in webspace for the folder containing
# the dQuery/Web Server Side Components. ‘dQWeb’ is only a
# suggestion, you may specify any name.
Alias /dQWeb/ "F:/dQWebServerSideComponents/"
<Directory "F:/dQWebServerSideComponents">
Options FollowSymLinks ExecCGI
AllowOverride None
Order allow,deny
Allow from all
# Specifies dQWeb.exe as the default index document.
DirectoryIndex dQWeb.exe
# Enable .exes for CGI.
AddHandler cgi-script .exe
</Directory>
See the Apache documentation for detailed information concerning configuration file directives.
After completing the modifications to the Apache configuration file, restart Apache to implement them. With
the above configuration file addition, the URL from which to launch the dQuery/Web Server Side Components
would be something like:
http://www.MySite.com/dQWeb/
or if installed on a local machine for testing:
http://127.0.0.1/dQWeb/
http://localhost/dQWeb/
Security
Anonymous access via the web to the dQuery/Web Server Side Components is NOT recommended. A dQuery/
Web replication component is included which might pose security problems when accessed anonymously. If
anonymous access is required, disable replication by deleting the file "qFT.exe" from the dQuery/Web Server
Side Components folder.
Consult your Web Server’s documentation for information regarding the implementation of user authentication
and authorization.
dQuery/Web Query(dataModule)
The dataModule page is the core of dQuery/Web. This is where the design of your web dataModule takes place.
Almost every option selected from this page will allow you to perform "some action", and return. When you
first arrive on the dataModule page from the main menu, you will be presented with a blank dataModule named
"UNTITLED".
A dataModule consists of:
• databases (BDE aliases that give you access to your tables)
• queries
• a view (a list of the fields).
If the current dataModule has been saved previously, the Save button will overwrite the existing .dmw file,
incorporating any changes made since the dataModule was last opened. Otherwise, the Save button will open
the "Save dataModule to Disk File" page described below.
• Save As
Opens the "Save dataModule to Disk File" page. This page contains two options:
• Option 1, "Overwrite an existing .dmw file", contains a drop-down of all saved .dmw files. The current
dataModule will be saved as, and consequently overwrite, the file selected from the drop-down.
• Option 2, "Create a new .dmw file", prompts you to supply a name for the new dataModule. Once entered,
click the "Submit" button to save. It is important to give the file a .dmw file extension, otherwise it will
not appear among the available selections when you later attempt to load an existing dataModule file.
• Open
Opens the "Open dataModule from Disk File" page, which displays a listbox containing all available
dataModule (.dmw) files. After selecting the dataModule you wish to load, click the "Submit" button to
return to the dataModule page. The dataModule will be loaded from disk, and displayed.
• New
Clears the current dataModule, and all of it's objects, from the page. This option reverts the dataModule page
to an empty, untitled state.
Warning The "New" option does not give you an opportunity to save your work! It is used to abandon your current
work when you wish to start over.
• Delete
Opens the "Delete DMW Disk File on Server" page, which displays a listbox containing all available
dataModule (.dmw) files. After selecting the dataModule you wish to delete, click the "Submit" button to
permanently remove it from the server's hard drive.
These include:
• Remove
Removes the current query from the current dataModule.
• View Fields
Opens the List Fields page which displays a list of fields names and their data type.
• View Indexes (Keys)
Opens the List of Indexes (Keys) page which displays a list of index names and their associated fields. The
expression is displayed for dBASE expression indexes.
• Edit
Opens the Edit Row page, where a primary key field and primary key value will be specified to locate the
row to edit.
• Append
Opens the Append Row page, where a primary key field will be specified to ensure that the primary key
value of the appended row is unique.
• Delete
Opens the Delete Row page, where a primary key field and primary key value will be specified to locate the
row to delete.
Query Options
The buttons in the query object under the Query Menu Bar.
• SQL
The SQL button opens a page providing two ways to edit the SQL statement on which the current query
object is based.
• Option 1allows you to edit the SQL statement directly.
• Option 2 is used to build an SQL statement using the SQL Statement Builder.
- Step 1 of the SQL Statement Builder is used to build the fields list portion of the SQL statement. Move
individual fields to the "Selected" listbox, or check "All Fields" to include all the table’s fields.
- Step 2 is used to build the WHERE portion of the select statement. This is the optimal way to filter client-
server data since only records matching the WHERE condition are returned by the server. Filtering in this
manner will work for any table type.
The Expression Builder is used to build individual filter conditions by selecting values from several
dropdown menus. Once a condition has been built, add it to the condition list by clicking the Add button on
the right. The other dropdowns will update to show only those options valid for the data type of the currently
selected field. For example, a date field will list choices for "Today", "This Week", etc.
Once one or more expressions are listed in the conditions list, you can set the expressions scope by choosing
to meet "Any of the Conditions", "All of the Conditions", or "None of the Conditions".
Custom View
Adding several query objects to the design surface creates the potential for a large number of fields being
displayed (even a single table can have 50 or more fields) and the resulting clutter can make analysis of your
data difficult. This view displays only selected fields from each query object in the current dataModule.
• Change
The "Change" button opens the Custom View page, which in turn contains two list boxes. The listbox on the
left displays all available fields from all queries in the dataModule. Click on the desired field and move it to
the right listbox by using the right arrow button. Fields can be deselected, moved out of the right listbox, by
using the left arrow button.
There are oftentimes more than one top-level query present (a query that is not the child of another query).
When this occurs, use the "Query Controlling Navigation" drop-down to select which top-level query should
be used when displaying results in a Report or a View. Set the view by clicking the "Submit" button.
• Get Results as Report
The "Get Results as Report" button displays a report of the data from the current dataModule. You must first
create a Custom View, as described above, and the resulting report will only show the selected fields. Field
names are displayed as titles across the top of the report, and fields from the Controlling Navigation Query
are displayed with a darker background than fields from child queries. All parent-child relationships are
traversed by the report, with parent rows printed once and child rows printed below respectively.
• Get Results as View
The "Get Results as View" button displays the a view of the date from the current dataModule. Parent rows
are displayed along with each child row, not on their own line. This format also traverses all parent-child
relationships, and report titles are displayed as they are in the report format.
Run Report
This menu selection opens the "Run Report" page, which allows you to select any dBASE Plus reports that have
been deployed to the web server. dBASE Plus reports may be deployed manually, or via dQuery/Web on the
desktop. Select the report from the drop-down and click the "Submit" button.
Administration
This menu selection opens the "Administration menu", which includes all global and security settings for
dQuery/Web. Administration functions are available only to system administrators.
• Add User
The Add User button opens the "Add User" page, which the administrator will use to add new users to the
dQuery/Web security system. After filling in the fields, and assigning an Access Group, click the "Submit"
button to save the new user.
• Modify User
The Modify User button opens the "Modify User" page, which the administrator will use to edit users
previously added to the dQuery/Web security system. After selecting an existing user from the listbox, click
the "Submit" button to display the user's current information in editable fields. The user name cannot be
changed. Click the "Submit" button to save the changes.
• Delete User
The Delete User button opens the "Delete User", which displays a listbox of all users who have been added to
the dQuery/Web security system. Select a user, and click the "Submit" button, to remove that user from the
system. The administrator user account cannot be deleted.
• Add Access Group
The Add Access Group button opens the "Add Access Group", which the administrator will use to create a
new Access Group (each user is assigned to an Access Group). After naming the new Access Group,
specifying the access rights of it’s users and which BDE aliases they will have access to, click the "Submit"
button to save the new Access Group definition.
• Modify Access Group
The Modify Access Group opens the "Modify Access Group", which the administrator will use to edit
Access Groups previously added to the dQuery/Web security system. After selecting an existing Access
Group from the listbox, click "Select Access Group" to display the Access Group's definition for editing. An
Access Group name cannot be changed. When editing is complete, click the "Submit" button to save the
changes.
• Delete Access Group
The Delete Access Group button brings up the Delete Access Group page. This page displays a listbox of all
defined Access Groups (except Administrators, which cannot be deleted). Select an Access Group, and click
the Submit button to remove them from the system. Note: If a user belongs to an Access Group, that Group
cannot be deleted.
• Set Default Language
The Set Default Language button opens the "Set Default Language" page, which lists all available languages
installed on the web server. Changing this setting will default all text in dQuery/Web to the selected
language. A new language may be installed on the server by translating the "English.Sif" file, and copying it
to a new file in the dQuery/Web folder with the appropriate name, such as "Deutsch.Sif" or "Francais.Sif".
• User List
The User List button displays a list of all users added to the security system. Information displayed includes
User Name, Password, Name, E-Mail and Access Level.
• Log Report
The Log Report button displays a list of all local logins to dQuery/Web. The report includes User Name,
Time (when they accessed dQuery/Web), Remote (IP) Address, and if they were authenticated.
Index I-1
placing in containers 84 custom components (Component palette) Default tab (Inno) 42
reports 136 79 default values (reports) 134
reports (table) 79 Customer support options 24 defaults
resizing 85 setting field defaults 150
selecting 84 D delete-data button 78
selecting multiple 84 deleting
spacing 87 data columns (fields) from reports 133
table access 78 accessing (table of components) 78 components from palette 60
The Component palette 75 importing 168 fields 148
user interface standard components data entry OLE object 173
(table) 76 automatic 151 rows 168
configuring BDE 27 constraints 151 DEO Folders 39
connecting to databases 27 indexing for 154 Design mode 74
container components 84 rules for updating or deleting 160 designers
control types (field components) 80 validity checks 151 Design and Run modes 74
controls 76 data model 62 Form designer 52
user interface standard controls (table) Database objects 65 Report 132
76 DataModRef objects 66 Table designer 146
converting Field objects 64 tools 73
Converting a dBASE IV Application to Query objects 62 undoing 85
Visual dBASE 5.7. 194 Rowset objects 63 windows 73
Converting dBASE 5.0 for DOS Session objects 65 designing
Screens/Menus to dB2K 204 StoredProc objects 66 forms and reports (introduction) 73
Converting Visual dBASE 5.7 Database objects 65 tables
Applications to dB2K 206 database-level security 65 determining relationships 141
OEM and ANSI text 192 databaseName property 65 field types 143
Converting to dB2K 194 default 65 hints 140
count loginString property 65 individual fields 142
finding in reports 137 database-level methods 65 minimizing redundancy 142
counting rows 169 databases 68 overview 139
creating accessing 62, 68 structure concepts 143
applications (basic steps) 33 accessing (overview) 66 tables (in Designer) 146
custom classes 58 accessing (table of components) 78 tables (with wizard) 146
custom components 59 accessing automatically 67 Determining the User Interface language
dataModules 71 accessing manually 67 185
drill-down reports 135 connecting to 27 developer support 24
forms 52 dataLink property 65 displaying default values (reports) 134
forms (in Designer) 52 and Field palette 80 DISTINCT 125
forms (with Wizard) 52 DataModRef objects 66 docking tool windows (Debugger) 110
indexes 153, 155, 157, 158, 159 filename property 66 documentation
joins (queries) 128 dataModules typographical conventions 23
menus 93, 94 creating 71 updates 23
methods 103 DataModRef object 66 dollar sign
printed labels 138 defined 70 adding to reports 134
projects 34 using in a Form or Report 72 DOS text 192
report borders 136 dBASE field types 143 dQuery/Web
reports 132 dBASE Plus 1 Query 212
reports (in Designer) 132 documentation 23 dQuery/Web Server Side Components
reports (with wizard) 129 DBASETEMP alias 26 Administration menu 216
tables (in designer) 146 dBL programming language 29 Apache Web Server 211
tables (with wizard) 146 DBSYSTEM.DB file 41 Configuration 210
using the Form designer 52 debugging Custom View 215
creating a DEO Application (Project bug types 107 customizing 217
Explorer) 39 Call Stack 114 Database Menu Bar 213
creating a project installer 41 docking tool windows 110 dataModule Menu Bar 212
creating an application (Project Explorer) event handlers 114 dQuery/Web 212
38 general procedures 108 Installation 210
Criteria Page (SQL designer) 121 methods of controlling execution 111 Query Menu Bar 213
cursor position overview 107 Run Data-Entry Application 216
using to stop debugger 114 programs 107 Run Report 216
custom class designers 73 stepping 112 security 211
custom classes The Debugger 107 drill down column (SQL designer) 123
creating 58 The Source Window 109 drillDown property 136
using 58 using breakpoints 112 drill-down reports 135
custom components using watchpoints 115 duplicate values
adding to palette 60 variables 110 hiding 157
creating 59 decimals duplicates 134
removing from palette 60 defining 147 suppressing in reports 134
default BDE session 68
Index I-3
INI tab 48 methods to events 103 multiple index (MDX) files
License tab 47 to databases 27 dBASE index concepts 153
Runtime tab 47 local tables defined 152
Script tab 49 using with remote 68 multiple queries 63
input pane 104 Locate mode 63 multiple selection (Inspector) 80
insert mode 105 locate-data button 78 multiple streamFrames 138
inserting login name 67
fields 148 Long 143 N
Inspector
Events page 82 M naming conventions
listing properties alphabetically 80 fields 147
Methods page 83 manifest file 13 tables 149
Properties page 81 master-detail relationships navigating
using 80 creating in tables 63
yellow highlighting 80 with masterRowset and masterFields Table designer 148
installation 70 navigation buttons
How to . . 26 with masterSource 70 Data Buttons page 78
uninstalling dB2K 27 with SQL JOIN 68 image-style 78
What happens during . . . 26 in local .DBF tables 70 multi-page forms 57
internal name 192 masterSource property 70 standard-style 78
International issues navigateByMaster property 63 VCR-style 78
specifying a language resource file 185 navigateMaster property 63 Navigator
international issues SQL JOIN statement 69 listing SQL tables 28
character incompatibilities in field synchronizing cursor movement 63 new features 1
names 191 maximum Numeric field type 143
character sets 186 finding in reports 137
converting between OEM and ANSI lines in the input pane 105 O
text 192 performing aggregate calculations 137
maximum line length ODBC databases
exact matches 187
code 105 connecting to 27
identifying code pages and language
configuring 105 OEM 188, 190, 192
drivers 190
MDX files 152 code pages 186
table vs global language drivers 191
memo fields 171 OLE fields 172, 173
introduction to dB2K 1
MenuFile property 90 opening
menus a file named in code 102
J and toolbars 90 Form or Report in Run mode 88
joins 128 attaching a pulldown menu to a form 90 SQL designer 117
Joins Page (SQL designer) 127 attaching popup menus to a form 90 tables 162
changing properties on the fly 97 opening a project 38
K creating 93, 94 operators
creating with designers 93 in queries 124
key expressions 158 events 97 OR 123
knowledgebase example 95 ordering fields (queries) 120
Documentation updates 23 features demonstration 94 outer joins 127
What is it . . 1 file code 95 output column name (SQL designer) 125
www.dbase.com 24 keyboard shortcuts 93 overwrite mode 105
menuFile property 90
L methods 97 P
popup 90
Label designer 73 page numbers
properties 97
Label wizard 138 reports 134
methods 83
labels pageTemplate 132
built-in 83
creating printed 138 palettes
creating 103
language drivers Component 75
deleting 83
and Character sets 186 Field 80
editing 83, 101, 102
and exact matches 187 parent tables
linking 83
character incompatibilities in field master-detail relationships 70
linking to events 103
names 191 referential integrity 159
Method menu 83
converting OEM to ANSI 192 passwords
programming (using Inspector) 83
global 188, 191 loginString property 67
unlinking 83
identifying 190 table access 150
verifying 83
table 190, 191 PLUSRun command line 8
minimum
language resource files 185 popup menu 90
finding in reports 137
ldriver 188 primary indexes
performing aggregate calculations 137
License tab (Inno) 47 creating 159
monitor execution in Debugger 107
line length printed labels 138
moving
configuring 105 printing
fields 148
linking 172 Form or Report 88
multiline commands 105
in OLE fields 172 table structure 150
multi-page forms 57
Index I-5
user profiles 181 combining selection criteria (SQL assigning field attributes 150
table privileges 178 designer) 123 Binary fields 171
table-level 176 group criteria 126 child 159
tables assigning 182 grouping criteria 123 choosing type 143
tables DB 183 including unmatched records 127 complex indexes 157, 158
tables selecting 182 inner and outer joins 127 creating (in designer) 146
user profiles Joins Page (SQL designer) 127 creating (with wizard) 146
changing 181 operators 124 creating indexes 159
creating 181 Selection Page (SQL designer) 125 creating secondary indexes 159
deleting 181 sorting 127 Data Access page 78
overview 177 summary data 125 defining fields 147
selecting fields (in SQL designer) 120 SQL tables deleting fields 148
Selecting Specialized Product Fonts 190 using with local 68 deleting indexes 156
selection criteria stack designing
adding 121 call 114 defining fields 142
combining (SQL designer) 123 standard deviation Helpful hints 140
Criteria Page (SQL designer) 121 aggregate calculations 137 minimizing redundancy 142
Selection Page (SQL designer) 125 finding in reports 137 overview 139
Session objects Standard tables relationships among tables 141
adding 68 local SQL and 139 structure concepts 143
default 65 starting a new project 34 terms and concepts 139
onProgress( ) event 65 Startup optimizations for Web applications editing
tables 65 8 add rows 168
sessions stepping 112 counting rows 169
BDE default 68 stopping execution (debugger) 114 data entry considerations 165
setting stored procedures 68 delete rows 168
custom classes 58 StoredProc objects performing calculations 170
properties 80 and Database objects 66 precautions 162
Properties Page (Inspector) 81 defined 66 selected data only 164
simple expression (queries) 121 params array 66 setting criteria 169
simple Having expression 126 rowset property 66 special field types 171
sorting using 68 toolbar descriptions 163
and language issues vs. Query objects 66 exporting data 152
character incompatibilities 191 streamFrames field types 143
character sets 186 multiple 138 hiding duplicate values 157
exact match 187 streamSource property 138 index concepts (dBASE) 153
query results (SQL designer) 127 subscripts indexes 155
Sorting Page (SQL designer) 127 See also array elements indexing 151, 154
tables 151, 152 summary calculations (reports) 137 indexing (vs sorting) 152
Sorting Page (SQL designer) 127 summary data in queries 125 indexing subset 157
sound fields 171 suppressing duplicates (in reports) 134 linking 155
Source Aliasing 6 syntactical errors 107 linking a form or report 66
Source editor system requirements 25 listing in Navigator 66
miscellaneous notes 102 master-detail relationships 70
opening 101 T creating 68
setting preferences 101 navigateByMaster property 63
using 101 tabbing order navigateMaster property 63
source window (debugger) 109 changing 51 SQL JOIN statement 69
SQL 117 guidelines 51 synchronizing cursor movement 63
designer elements 117 Table design guidelines 140 masterSource property 70
learning 117 Table designer 148 Memo fields 171
queries visual 117 abandoning changes 149 modifying indexes 156
SQL databases deleting fields 148 naming 143
connecting to 27 moving fields 148 navigating fields (Table designer) 148
listing tables in Navigator 28 navigating 148 OLE fields 172
SQL designer 118 resizing columns 148 opening 162
adding tables 120 saving table structure 149 parent 159
entering data 118 tips 146 printing structure 150
removing tables 120 user interface 147 protected 163
renaming tables 120 using 146 referential integrity 160, 161
Source editor and 118 table language drivers 190, 191 relationships 141
SQL files table pane (SQL designer) 119 restructuring 149, 150
using in forms and reports 119 Table wizard 146 restructuring guidelines 149
SQL Links 27 tables running 162
SQL property 62 abandoning changes (Table designer) saving structure 149
SQL Property Builder dialog box 119 149 searching 166, 167
SQL queries accessing 62 security (dBASE and Paradox) 65
accessing (table of components) 78 seeing in Navigator 28
adding fields 148
Index I-7