PB Book Part 1
PB Book Part 1
PowerBuilder is a 4GL client / server enterprise development tool. Its strongest strength is database
connectivity and object-orientation implementation. In its initial releases, PowerBuilder was just used
as a client --talking to the database server directly. However from version 5.0 onwards PowerBuilder
applications can be deployed as client, as a middle tier application or both. With version 6.0, it
supports transaction servers such as Jaguar CTS and Microsoft Transaction Server.
PowerBuilder features
Powersoft family of products
Various PowerBuilder editions and features available in each edition
Prerequisites:
PowerBuilder Features
SQL Support: PowerBuilder supports SQL and Stored Procedures using DataWindow and
embedded/dynamic SQL and remote procedure calls.
DataWindow: DataWindow control is the heart of PowerBuilder and is used to display data in a
wide variety of presentation styles --Freeform, Tabular, Grid, Labels, Group, N-up, RichText edit,
Graph, Crosstab, OLE 2.0 and Composite -- by executing SELECT statements or Stored Procedures in
the database. They can also be populated programmatically. DataWindow automatically updates
the datasource just by writing a few lines of PowerScript code.
Embedded/Dynamic SQL: PowerBuilder supports both embedded and dynamic SQL, including
scrollable cursors and Stored Procedure execution.
Remote Procedure Calls: It also supports calling Stored Procedures and procedures using
function-calling notation (programmers in the industry call this 'remote procedure calls' even
though the actual meaning of 'remote procedure call' is differs from this).
Database Connectivity: Database connectivity is its strong point.
ODBC Drivers: Supports all popular databases --Sybase/Microsoft SQL Server, Informix, Oracle,
and DB2-- using ODBC 3.0 drivers.
Native Database Drivers: Provides native database drivers for Oracle 8.0, Informix 6.2, Sybase
SQL Server 11.1 and Sybase Adaptive Server Enterprise 11.5.
Dynamic Data Exchange: PowerBuilder supports DDE at window object level. PowerBuilder
application can act as a DDE client or DDE server or both.
OLE 2.0 Support: PowerBuilder supports OLE 2.0 including OLE 2.0 automation from version 4.0
onwards.
OLE 2.0 Window Control: Acts as an OLE 2.0 container and OCX Controls can also be
inserted.
DataWindow Presentation Style: Data can be displayed in any of the OLE 2.0 server's
format.
OCX Control: OCX control can be inserted in DataWindow like any other object.
OLE 2.0 Automation: This feature was introduced in version 4.0. PowerBuilder can act
as an OLE 2.0 client, server or both. V6.0 supports DCOM --Distributed Component Object
Model-- also.
MAPI Support: PowerBuilder supports MS-Windows messaging standard MAPI --Messaging API.
Web Support: DataWindow can be saved as HTML table and form with only one line of code.
PowerBuilder applications can be deployed on the web in different ways:
Window Plug-in: Used to deploy PowerBuilder applications on the web. Using 'Context'
object --gives access to the browser's exposed services-- you can make use of browser's
services -- an example would be displaying an URL from other site. Supports secure mode also.
Web.PB Class Library: Used to generate HTML dynamically at the web server level.
Distributed Objects: From version 5.0, PowerBuilder applications can be deployed as client app
or application server or both. Client app and Server applications talk using TCP/IP and other popular
protocols. Supports 'Asynchronous' --Fire-and-Forget communication and server push also.
Unicode Support: V6.0 supports unicode. In case you do not know what unicode is, each ASCII
character takes 8 bits which limits the usage of Asian languages such as Japaneese, Hindi, etc.. in
computer applications since characters in those language can't fit in 8 bits. Using unicode in which
each character takes 16 bits, you can develop applications for non-English languages also. Unicode
is supported by MS-Windows 95/NT.
Built-in Support for Arabic, Hebrew Languages: These languages use right-to-left writing
style.
Translation Assistant: This tool helps you in deploying PowerBuilder application in multiple
languages with minimum efforts.
Support for Pen Computing: Class library for Pen Computing can be used on pen based
Windows systems, to implement pen computing interface in PowerBuilder applications.
Lotus Notes Support: Powersoft ships a class library for Lotus Notes, using which you can display
information from Lotus Notes in PowerBuilder and also update changes back into Lotus Notes.
Support for Operating Functions: You can use operating system functions, by declaring them
as external functions, with an exception of callback functions.
Third-Party Vendor Applications: Third party controls can be used in PowerBuilder, either as
OCX controls or as external user object.
Multi Platform support: Available for MS Windows 95, NT, 3.x (deployment only from v6.0
onwards), Macintosh, Sun Solaris, IBM AIX, HP-UX.
Support for Transaction Servers: Supports Sybase Jaguar CTS and Microsoft Transaction
Server (basic support only as of this writing).
Application Profiler and Tracing: APIs are available to log all tracing information and analysis.
PowerBuilder Foundation Class Library: Available since version 5.0. (Learn about this in
detail in the PFC session).
Synchronizer: Allows you to make sure that the user always uses the latest files. Synchronization
can be done on the web also.
ORCA: Allows you to access PowerBuilder library --a file that stores PowerBuilder objects--
functions such as copy, rename, delete, move, export, import, compile, check-in/out PowerBuilder
objects, create executables, look into inheritance hierarchy and so on, from outside programs,
typically a C program.
C++ Class Builder: Allows creating C++ classes from within PowerBuilder and uses those classes
in PowerBuilder.
Version Control Interfaces: Supports popular version control products including Object Cycle --a
RDBMS based version control software from PowerSoft and Microsoft Common Source Code
Control Interface Specification.
Till PowerBuilder version 3.0, there was only one PowerBuilder edition. However, after version 4.0,
Powersoft introduced different PowerBuilder editions, targeting different segments such as students &
single-user application developers, enterprise users, etc. The following tables list various features that
are available in different editions.
Multitier deployment
Feature DesktopProfessionalEnterprise
Multithreaded Server
Server push
Open Technology
Feature DesktopProfessionalEnterprise
Redesigned debugger
Misc...
Feature DesktopProfessionalEnterprise
The following are some important products from Powersoft which you will be using directly or
indirectly as a PowerBuilder programmer.
InfoMaker
InfoMaker is a subset of PowerBuilder, used by end users for generating reports. You can't use this
product for development. All DataWindows generated in InfoMaker are by default read-only.
PowerDesigner
PowerDesigner a new name for 'S-Designer', a product of Red-Pepper. After merging of Red-Pepper
with Powersoft, this product became a product of Powersoft. This product supports multi-user
database designing, including logic, physical modeling and process modeling. Using the 'AppModeller'
module of this product, you can generate code for popular front-ends, such as VisualBasic,
PowerBuilder, etc.
SQL Anywhere
SQL Anywhere (also called 'Watcom SQL') was a product of 'Watcom' , which later merged with
Powersoft at the time of PowerBuilder 4.0 development. SQL Anywhere is a full-featured transaction
processing SQL database management system, which performance excellently even with its fewer
resource requirements (memory space, disk space, and CPU speed) than other database management
systems.
SQL Anywhere is a fast and efficient database for many environments, from notebook computers to
servers supporting large numbers of concurrent users. It is a flexible and scalable solution for today's
diverse needs. One great feature that you don’t find in any other database is that the database files
are compatible between versions and across all operating systems.
SQL Anywhere is available for Windows NT, Windows 95, Windows 3.x, OS/2, NetWare, Solaris, HP-
UX, AIX, DOS, and QNX operating systems. SQL Anywhere can be used as a standalone database
management system or (on non-UNIX operating systems) as a network database server, in a
client/server environment.
SQL Anywhere is an ideal database for a variety of application developers --such as C, PowerBuilder,
etc. for developing single-user and/or client/server applications for workgroups and mobile usage.
Currently SQL Anywhere supports ODBC 2.1 level II, as well as other interfaces.
From version 5.0 onwards, this database completely supports Transact SQL (Transact SQL is an
enhanced version of ANSI SQL, used in Sybase SQL Server as well as Microsoft SQL Server), and also,
SQL Anywhere supports replication in different ways, which ideally is used in mobile applications.
From version 4.0, Powersoft started shipping a 'PowerBuilder library for Lotus Notes', as part of the
enterprise edition. This library comes with many user objects that fall into two categories.
User objects that are meant for inheritance (you can create PowerBuilder objects by inheriting from
them and build applications quickly)
Using this library, you can build PowerBuilder applications, which act as front-end to the Lotus Notes
databases, i.e., you can create reports and also modify data in the Lotus Notes databases. We have a
separate session on this topic.
You may be aware that on a computer that has regular MS-Windows installed, you can’t use a pen
(i.e., a special pen used to write on the computer screens) to write on the screen instead of using the
keyboard and mouse. For that, you need to install MS-Windows for Pen Computing. What if you need
to build a PowerBuilder application, for that type of computers? PowerBuilder does not support pen
interface. You need to purchase a PowerBuilder library for pen computing, (This library is not part of
any PowerBuilder edition, you need to purchase it separately.) and you can use user objects and APIs
available in that library. There are few applications written using this library for doctors, sales reps,
courier deliverymen, etc.. We have a separate session on this topic.
Translation Assistant
As company grows, competition increases. For companies which span various countries need to write
the same application for multiple languages and cultures. For example, take any multinational
company that has its branches in various countries. If it has branches in USA and France, the same
application should have two interfaces one in English and one in French. Sometimes, multiple
language might exist in the same country --such as India. Using the Translation Assistant, you can
write the PowerBuilder application once in the base language and then deploy it in multiple languages.
We are covering this topic in a separate session.
Funcky Library
This library contains many functions that are not available in PowerBuilder. However, these functions
are made available in PFC as services. Funcky library is discontinued from version 6.0.
This PowerBuilder library is not part of any PowerBuilder edition. You need to purchase it separately.
This library comes with user objects, that encapsulate various Novell NetWare APIs and reduces the
complexity of calling them as external function. We are not covering this library.
ObjectCycle
ObjectCycle is a relation database based version control system, sold by Powersoft. This product also
supports Microsoft source control APIs and is tightly integrated with PowerBuilder. From within the
Library painter, you can directly check-out PowerBuilder objects, and the versioning is taken care by
this product automatically. ObjectCycle client comes with PowerBuilder enterprise edition, however,
you need to purchase ObjectCycle Server separately. You don't have to stick to this product for
versioning PowerBuilder objects. You can choose any third party vendor products as well --such as
PVCS, LBMS, CCC, Endevor, SourceServer, etc.. We have a separate session covering this product in
depth.
In this session you have learned about various PowerBuilder features and also got an overview of
various tools that you use in conjunction with PowerBuilder in your real world projects. In the next
session, you will learn about PowerBuilder development environment.
PowerBuilder Environment
In this session you will learn about PowerBuilder environment -- such as
toolbars, toolbar customization, opening painters, etc..
Prerequisites:
You should have PowerBuilder (Desktop/ Professional/ Enterprise version)
installed on your computer.
Starting PowerBuilder
If you have PowerBuilder installed on Windows 3.x/ Window NT version prior
to 4.0, the PowerBuilder program group looks like the following picture. The
number of icons in the group may vary depending on:
As you may recall, Windows 95/NT 4.0 user interface is different from
Windows 3.x/NT 3.51. If you have installed PowerBuilder on Windows
95/NT4.0, PowerBuilder icons are added to the 'Start' button menu. Here to
start PowerBuilder, you need to click on the 'Start' button ( placed on the
windows task bar ) and select 'Programs/ PowerBuilder x.x/ PowerBuilder x.x
for Intel 32' options. After starting PowerBuilder, it looks as shown below:
PowerBuilder Startup Window
When you start PowerBuilder, it opens the last application you worked on as
the current application and displays the application name as the window
title. PowerBuilder comes with an example application named "example50".
By default PowerBuilder starts this application. You cannot work on
PowerBuilder without an application. If there are no applications installed,
PowerBuilder prompts you to select an application or create a new
application. More details on creating the application in a moment.
Creating Shortcuts
Under Windows 95/NT 4.0, the icon you create are called "Shortcut Icon". A
shortcut icon for PowerBuilder allows you to start it by double-clicking on the
icon rather than using menu options. You may want to create a shortcut icon
and start using it. Under Windows 95/NT 4.0, menu options are similar to
the picture shown below.
'Start' Menu options under Windows 95/NT4.0
PowerPanel
While developing you create/test objects using painters. Each painter has an
icon associated with it. You can see all the painter icons right below the
menu options laid horizontally. To see the descriptive text and shortcut for
each icon, display PowerPanel by selecting 'File/PowerPanel'from the menu.
PowerPanel
Application object is the entry point to any PowerBuilder application. For those from
'C' background it is like 'main()'. In the application object you can specify what
PowerBuilder should do when:
Application
Painter you start the application
In any application, screen is the main interface between a user and an application. It
allows you to do data entry, see reports and so on. In PowerBuilder, screens are called
as 'Windows'. Don't confuse the term 'Windows' with Microsoft Windows operating
Window
system; it is referred to as 'MS-Windows'. A Window Painter, as the name suggests
Painter allows you to paint and save window objects. On a window you can paint various
controls such as CommandButtons, ListBoxes, etc.
DataWindow data source definition (about the data to bring, i.e., database, table, column
Painter names, etc.)
presentation definition (about how you would like to display the retrieved data,
i.e., a table format, labels, graph and so on).
Things are very simple if use PowerBuilder. Here you can just
paint a data pipeline object in couple of minutes and execute
the pipeline. You can then reuse the data pipeline object every
time you want to copy/refresh data from the source.
An User Object allows you to reuse the code. It is nothing but a collection of one or
more PowerBuilder/ non-PowerBuilder objects. Non-PowerBuilder objects includes
objects from VB, DLLs, OCX and so on.
User Object
Painter
A Query Painter allows you to build SQL SELECT statements which can be saved as
query objects in the PowerBuilder library. If you intend to use the same SQL
statement many times in your application as embedded SQL or as DataWindow
Query Painter
source, you need to define reusable query objects.
The function painter allows you to build function objects that define a series of
frequently executed commands. In PowerBuilder, a function is a collection
ofPowerScript commands and/or embedded/dynamic SQL statements. You can also
Function
refer to these functions in your PowerScript and DataWindow painter.
Painter
The Structure Painter allows you to create structure objects. A structure is nothing but
a set of related variables (which may have different data types) grouped under a
single name. It makes management of related variables easy. You can refer to the
Structure
structures in your PowerScript.
Painter
Objects you create in PowerBuilder painters (application, windows, menus, functions,
queries, structures, user objects and DataWindow objects) are stored in an operating
system file with ".pbl" extension (pronounced as pible); In PowerBuilder terminology,
Library
this file is called a "Library". A Library Painter allows you to create and maintain
Painter PowerBuilder libraries and objects in those libraries.
Database Painter allows you to create database objects--such as table, view, index,
stored procedure, trigger, etc. without knowing the actual DDL syntax. All the
database objects that you create in this painter are stored in the connected database
Database and not in the PowerBuilder library. Objects that you create in other painters--such as
Painter window, menu are stored in PowerBuilder library. You can also do database
administration from this painter.
Project Painter allows you to create PowerBuilder Dynamic Linked Libraries (PBDs),
executables. You need to define what libraries need to be included in the project for
Project the first time. Once you define this, you can create executable files with few clicks. It
Painter also allows you to do incremental rebuild if you are using a version control system.
You guessed it right. A Run icon allows you to execute the application you are
Run currently working on.
A Debug painter allows you to view the execution of the current application step-by-
step and simplifies the discovery of bugs. It is very powerful and comes with all the
Debug debugging facilities you will ever need.
Toolbars
What is a toolbar? A toolbar is nothing but a collection of icons associated
with actions. Clicking on a toolbar icon triggers some action. All the icons
that you see across the PowerBuilder window, i.e., below the menu (as
shown in the picture), are part of the toolbar called Powerbar.
Typically, each toolbar icon represents one of the menu options, except
in Powerbar (the one you see on the screen) and Stylebar. Say you want to
represent File/Open with one icon, File/Save with one icon and so on. Toolbar
allows you to be more productive, since you will be directly clicking on the
toolbar icon, instead of selecting nested menu options. For example, to
select File/Open, first you need to select File option and thenOpen option.
If File/Open has a toolbar icon, you can simply click on the icon. You can also
create toolbars as part of your PowerBuilder application and make the
application more user friendly.
Powerbar
Painterbar
Stylebar
Unless you hide Powerbar, it is visible through out the PowerBuilder session.
Painterbar and Stylebar are available only when at least one painter is open.
In some painters like Project painter, database painter, Library painter,
Stylebar is not available. In some painters like Structure painter neither the
Painterbar nor the Stylebar are available. The options in the Powerbar and
Stylebar are static, i.e., you see the same icons irrespective of the painter in
use. Painterbar is dynamic in nature and the icons change depending on the
painter in use. Now let us examine what you can do with each of those
toolbars.
Powerbar
Powerbar
When you move the mouse pointer over toolbar icons, description for the
specific toolbar icon is shown at the bottom of the PowerBuilder window.
That area is called Statusbar.
DropDown Toolbar
All of the above mentioned can be done by selecting proper options in the
popup menu. Un-checking the Powerbar option hides it. Once you hide all
toolbars, you cannot show toolbars by selecting from the popup menu; the
reason being that you invoke the toolbar popup menu by right clicking on
the toolbar itself. Since the toolbar itself is not visible, you cannot invoke the
popup menu. Well, we have gotten ourselves into trouble here. There should
be some way of making the toolbar visible. We could try selecting
File/Toolbars from the menu.
In the dialog box shown above, along with the regular options, font related
options are also available.
To invoke a toolbar when one of the toolbars is visible, double-click in the space between icons
on the toolbar.
Painterbar
As explained in the previous sections, painters --such as Window painter,
Menu painter, DataWindow painter can be invoked from the Powerbar. Once
you invoke a painter, you will see another toolbar called "Painterbar" along
with the "Powerbar". Unlike Powerbar where the toolbar icons are static,
Painterbar toolbar icons are dynamic.For each painter you invoke different
toolbar icons are available .
If you invoke window painter, you will see icons required to paint a window -
such as an icon to paint a line, rectangle, CommandButton, etc.
If you invoke "script editor" from the window painter, Painterbar displays
icons required to write script - such as script comment icon, script
uncomment icon, etc.
Now, invoke the script editor by clicking on the script icon. You will notice
that PainterBar has different icons compared to the window painter toolbar
icons.
Close the script painter by clicking on icon. Now, you are back in the
window painter.
Stylebar
Stylebar allows you to change the text style - such as text's font, font size,
justification, etc.
Stylebar is present only in some painters like "Window" and "User Object".
You can see the Stylebar now since you are in the window painter.
The left most value is the selected control's text property value (you will be
using this in the window painter session). By default the value is "none" and
you have to change it to the value you want.
The next value 'System' is the font type. You can select the font by clicking
on the down arrow. The fonts available in this DropDownListBox depend on
the fonts installed on your system. The last three right icons represent
justification of the text. They are "right", "Center", "Left" from right side. In
versions prior to 5.0, a toolbar named "Colorbar" was prevalent. It allowed
you to change the background & foreground colors for a selected control.
With version 5.0, it was merged with the Painterbar.
If you have any problem in doing the above, click on the projector icon
and download the zipped Lotus ScreenCam file (stylebar-demo.zip) and
watch it.
Customizing Toolbar
The power of a PowerBuilder toolbar is in its flexibility. If you want to get rid
of some of the icons in the toolbar, you can do so. If you want to add some
more icons to the toolbar, you can also do it. Let us see how to customize
toolbars.
Sometimes you may want to do add custom functionality to the toolbar icon.
In that case, you need to select "Custom" Radiobutton from the "Select
Palette"; you will be presented a collection of new icons. Add one of them to
the current toolbar in the same way you added previously.
PowerBuilder prompts you for the command definition of the toolbar icon.
You need to provide the command for the Command line prompt. For
example, providing "c:\Program Files\Accessories\wordpad.exe" allows you to
invoke Wordpad by clicking on the newly added toolbar icon. The value you
provide for "Item Text" option will be displayed as PowerTip. Value of "Item
MircroHelp" will be displayed as MircroHelp on the Statusbar. Click on "OK"
CommandButton and test how the new toolbar icon works. Similarly you can
also assign a pre-defined query or a report to the toolbar button.
If you can add a button to the Painterbar when the DataWindow painter is
invoked, you can also assign a function or format to the toolbar button.
Painterbar has one exception in this matter. Once you add a toolbar icon to
Powerbar, the added toolbar icon is available whenever Powerbar is
displayed. As you know, Painterbar is displayed only when a painter is open.
The toolbar icon you add to the Painterbar would be displayed only when
that painter is open. For example, if you have added an icon to the
Painterbar when Window painter is open, it would be displayed only when
the Window painter is open. If you open say, Menu painter, you cannot see
the icon.
If you have any problem doing the above, click on the projector icon
and download the zipped Lotus Screencam file (add-toolbar-icon.zip)
and watch it.
To delete a toolbar icon, you need to invoke " Customize" dialog box by
selecting "Customize" from the popup menu and drag the icon you want to
delete from the "Current Toolbar" and drop on the "Selected Pallete" area.
If you have any problem doing the above, click on the projector icon
and download the zipped Lotus Screencam file (delete-toolbar-
icon.zip) and watch it.
Custom Toolbars
With version 5.0, PowerBuilder allows you to create your own toolbar. You
can create three more Powerbars. Similarly, you can have seven custom
toolbars for each painter. That means, you can add seven Painterbars when
the window painter is open. As soon as you close the window painter, all
Painterbars are closed. If you invoke say, User Object painter, you see only
one Painterbar which is the standard Painterbar. Here again seven more
Painterbars can be added.
To create a new Powerbar, invoke popup menu by clicking with the right
mouse-button on the toolbar and select New. Add icons as explained
inAdding a Toolbar Icon and select OK button. The new toolbar is placed
just below the "Powerbar". Similarly a new Painterbar can be created by
invoking popup menu on the Painterbar and selecting the New option.
If you have any problem doing the above, click on the projector icon
and download the zipped Lotus Screencam file (adding-custom-
toolbar.zip) and watch it .
To delete a custom toolbar, invoke the popup menu and select " Customize"
option. Select "Reset" button from the dialog box.
Till now you have learned about toolbars. There is one more area which you
need to be familiar with before programming. That is the 'Script editor'.
To customize these links, you need to edit pb.ini file that is located in the PowerBuilder installation
directory. The .INI file is a file that stores initialization values of an application such as defaults, last
used values and preferences. A .INI file is divided into sections and each section name is surrounded
by square brackets. A partial listing of section 'PB' looks like:
[PB]
CompilerWarnings=1
DashesInIdentifiers=1
DatabaseWarnings=1
Maximized=1
Each variable in the section is placed on the left and the value on the right seperated by an equal sign.
Take the example of 'CompilerWarnings'. It is placed on the left and its value 1 on the right of the '='
sign. The keywords of web links are WebLink1, WebLink2, WebLink3, WebLink4 which can be found
under 'PB' section.
To edit these web links, you need to supply the name you want to see on the menu and the actual
web site address separated by a comma. For example, open pb.ini file and replace the code for those
four variables with the code shown below and save the file.
WebLink1=&PowerSoft,http://www.powersoft.com
WebLink2=&Sybase,http://www.sybase.com
WebLink3=PowerBuilder &Online Courses,http://www.applied-software.com
WebLink4=&Yahoo,http://www.yahoo.com
In the above code, you find '&' (ampersand) characters. An ampersand creates an accelerator key for
the menu item. An accelerator key is a letter that you press in combination with an 'Alt' key to
access the menu item quickly without using a mouse. For example, you can press 'Alt + F' and 'O'
keys to access 'File/Open' from the menu.
If you restart PowerBuilder, the changed options under the 'Help' menu bar item will be as shown in
the picture.
Script Editor
Script editor allows you to write scripts for object events, functions and so
on. To start script editor for an object, invoke the right mouse popup menu
by clicking the right mouse button on an object and select Script . You can
also invoke script editor by clicking on the Script icon. For demonstration
purpose, invoke application painter by clicking on the application icon from
the Powerbar. Click on one of the Script icon or . Clicking on either of
them invokes the script editor. You can see only one at any time. The first
icon (left) means that there is no script for any event for the selected object.
The second icon (right) means that at least one event for the selected object
has the script.
Script Editor - Script Editor Popup Menu
The last icon on the Painterbar represents the object for which you are
writing the script. That is, if the script is for a window or a control in the
window, it would be a Window and if it is for a menu object, it would be a
menu object. To close the script editor, select File/Return or click the last
icon on the Painterbar; this action compiles the script and exits to the
current object. You can also close the script editor from the script editor
window control box. Closing the script editor from the control panel or
clicking on window close button (icon next to the window maximize icon) will
prompt you for the confirmation to close the script editor. All these options
do the same thing, except for the later option where you have to answer the
prompt.
PowerBuilder automatically compiles the code that was open in the script
editor when you close it. However, the script can be manually compiled by
selecting Design/Compile Script from the menu or by clicking on the Compile
toolbar button.
You can customize the script editor to suit to your tastes & needs. To
customize, when in script painter select Design/Options from the menu .
You can choose the font for the script display in script editor from
the Fonttab. Script editor has the ability to maintain color codes i.e.,
comments in one, reserved words in another and so on. You can choose the
colors from the Coloring tab. You can also specify if PowerBuilder should
automatically indent the codes like If, For, While, 'Do While' and so on as you
type in. This is available in the General tab.
You have learned how to start and stop PowerBuilder and customize
PowerBuilder environment. In the next session, let us develop a simple
application in PowerBuilder
What's a PowerTip?
PowerTip is a short description of the toolbar icon that is displayed just below the mouse
pointer when the mouse is moved over it, in a rectangle area with yellow background.
List the toolbars available in PowerBuilder.
Powerbar
Painterbar
Stylebar
PowerTip is a short description for the toolbar icon and is displayed right below the
toolbar icon.
MicroHelp is a detailed description for the toolbar icon and is displayed on the
Statusbar at the bottom of the PowerBuilder window.
When you close Script Painter, PowerBuilder compiles the code and converts it into
machine code. True/False.
False. PowerBuilder compiles the code when changes are made to the script and the script
painter is closed. However, at this point of time, it doesn't create machine code for the
compiled script.
What icons can be added to the PowerPanel?
You can't add toolbar icons to the PowerPanel. It can be done only to Powerbar or
Painterbar.
How many additional toolbars can be added to your PowerBuilder development
environment?
You can add:
Prerequisites:
Introduction
You might know that when you write a program, you need to store it in a
file. For example, a 'C' program, would be stored in a file with '.c' extension.
Similarly, a COBOL file with '.cbl' extension and a FoxPro program with '.prg'
extension. All PowerBuilder objects and scripts are to be stored in a file with
'.pbl' extension. 'pbl' stands for PowerBuilder Library. Unlike 'C', 'FoxPro' or
'COBOL, you need to create PowerBuilder library before you start creating
any PowerBuilder objects and scripts.
There is one more distinction between other languages like 'C', 'FoxPro',
'COBOL' and PowerBuilder. In them you need to create a separate file for
each program you write. Where as in PowerBuilder, you create one library
and all objects & scripts you create will be stored in that library. You seethe
difference when you search for it from the operating system (through 'dir'
command, File Manager or MS-Windows Explorer). Here you will find only
one file, i.e., 'product.pbl'; but when you open the same file in PowerBuilder,
you will find all the objects you stored in the 'product.pbl' library.
In this session, we don't go into details about Library painter and Application
painter. We will revisit them as and when required in the coming sessions .
After that, you will be implementing DDE for sending e-mails to different
users and reading e-mails from them based on certain events. Then, you will
make use of OLE to give OLE interface and to make it interact with other
applications. Later, you will convert this application to use PFC and then
convert to allow the user to use pen computing (using pen computing
interface) for your application. After that you will change the application for
international multiple language deployment.
At this advanced stage, you will be introduced to state-of-the-art technologies --such as 'Distributed
Objects', web deployment, etc. and you will be converting your application to use 'Distributed
PowerBuilder Objects' and then for web deployment.
This would be a great time for you to start real world projects and jump into preparing for technical
interviews and finally for the CPD exam.
Creating a Library
To create a library or to manage objects within the library, you need to
invoke the library painter by clicking on icon. By default, the library
whichever has the Application object is displayed in the expanded mode, i.e.,
all the objects within the library are listed. It is similar to the 'File Manager' ,
where to start with you see directories. Once you double click on the
directory, it would expand and display all the files within the directory. All
other directories are listed, but not expanded. Same is the case with
PowerBuilder. Library in which the application object resides is expanded and
other PowerBuilder libraries are just displayed.
Libraries that are not being displayed in the expanded mode have library
icon. Libraries in the expanded mode have library icon ( It is like a open
library door ).
To create a new application object you need to click on icon (Please note
that, at anytime you see a star on an icon, it means that clicking on that
icon allows you to create a new object ) or select File/New from the menu. As
explained in the previous page, for every object you create in PowerBuilder,
you need to store it in a PowerBuilder library. Same is the case with an
Application object. You need to select a library name in which you want to
store the new application object. Select product.pbl which you created
previously. Now, PowerBuilder prompts you for an application object's name.
Provide product_management_system and click OK or Savebutton depending
on the operating system you are using.
That's all. Isn't it simple to write an application; even though this might not
be a great one. Do you know what you did? You wrote the above script in
the application's Open event. When you run the application, application
object's Open event is the first one to be fired. So it executed 'MessageBox()'
function you wrote over there.
Summary
You have learned how to create a library and an application object. You also
wrote a single line of PowerScript code and executed the application. To read
the full summary of the session, click on first-app.ppt which is a PowerPoint presentation. If your
browser didn't open PowerPoint viewer automatically upon clicking on the presentation, then you may
not have it installed on your machine. Please visit 'Software Setup' page which is at the beginning of
the course and download the PowerPoint viewer free-of-cost.
Window Painter
After this session you will be able to:
Events
Scripting
At the end of each topic, you are needed to complete exercises in which you
paint few windows. As you proceed to other topics, you will be using these
windows, So, please don't skip exercises. Upon completion, you can
download windows that we painted for you and compare them with yours.
This can rectify any mistakes that you might have committed. If you still
have any questions, you can always send an e-mail to prasad@applied-
software.com.
Prerequisites:
Window is the place where the end-user does the query and sees the report,
does the data entry and so on. A window itself doesn't do all these things,
instead a Window acts as a placeholder for some controls. There are few
controls that the window allows you to place on it. For example, a control to
allow you to enter your name, a control that allows you to close the window
and so on.
Creating a Window
Invoke the Window painter by clicking on the Window icon (the one that
is filled with blue color) from the Powerbar and select the New button in the
'Select Window' dialog box. ( You will see another Window icon also which is
filled with gray color;don't click on that, you will be learning about that later
in this session ).
Image of Select Window dialog box
The rectangular area that you see in the "Window - (Untitled)" window is the
window work area. The work area is the area where you can paint the
window. If you want to have a large work area, you can do so; Move the
mouse over the border of the work area (you know the window border when
the mouse pointer changes to or or ), click on the border, drag till you
get the area you need.
Later when the user wants it at a different position, you would have opened
your program and changed the x and y co-ordinates. In PowerBuilder, you
don't have to code the x, y co-ordinates; instead you place a control that is
capable of displaying the given text and use the mouse to drag it to the
correct position. The control that is used to display the text in PowerBuilder
is called "StaticText" control. To place a 'StaticText' control in the Window
workspace, you can follow either of the following procedures:
Window Controls
In addition to the StaticText control, the following controls are also
available:
Each control has certain properties, such as border, foreground color, name,
etc. Once you place a control in the Window Workspace, you can change the
control properties either:
The following picture is the "Properties tab object" for the StaticText control.
The value you specify for "Text" attribute is the text that it displays on the
"StaticText" control; that is what the user sees. The default value for this is
"none'. For this example, change this to: "Enter Name:", without quotes.
Each control has a name. The 'Name' property allows you to refer to that
control in the script. (We will explain naming conventions in a moment).
Change the name to "st_name", without quotes. Users don't see the name,
it is meant for the programmer to refer in the script.
You can choose from four borders, 3D raised, 3D lowered, Box and Shadow
box. The Align option aligns the text you provided for the Text property.
You can select the text font properties by clicking Font tab and choosing the
appropriate option. You can choose where you want to display the control,
but we won't recommend choosing the x, y co-ordinates from this dialog
box; instead click on the control and drag it to the correct position and resize
it.
Pointer: By default, when you move the mouse pointer over the StaticText
control, you will see the standard icon. The standard mouse pointer might be
different on your computer; it depends on the pointer you select in the
Windows setup. Typically, the pointer is an arrow. If you would like to
display a different mouse pointer whenever user moves the mouse pointer
over the control you just painted, you can do so by clicking on
the Pointertab. We will explain how to preview the window you are painting
in a moment; you can test this property at that time.
Accelerator Keys: When there are lot of controls in the window and when the
user wants to jump from one control to another, he can either keep pressing
tab till he reaches the control he wants to reach OR he can click with the
mouse-button directly on the control. Remember, there is a large community
out there who are from DOS world and still use keyboard most of the time.
If they want to reach the last control in the window while the focus is at the
top, pressing tab keys would be pretty tiresome.
We can provide hot keys, by which they can jump to the controls directly by
pressing them, no matter where the cursor is. In PowerBuilder, these hot
keys are called as Accelerator Keys. User presses them in combination with
the "Alt" key. To specify an accelerator key, you need to prefix the key with
an ampersand (&). If you want "n" as an accelerator key for "Enter your
name:", you need to type "Enter your &name:". The case of the accelerator key
doesn't matter.
Please note that StaticTexts have no accelerator keys since we won't expect
the user to do anything on the StaticText control itself. Other controls have
accelerator keys but, there is a problem of displaying the accelerator keys to
the user. You will learn more about them in the "SingleLineEdit" control.
SingleLineEdit Control
With the use of a "StaticText" control, you have asked the user to enter his
name. But, there is no provision to input the data. For that you can make
use of SingleLineEdit control. This control allows the user to input data.
Auto HScroll: The "Auto HScroll" property should be checked if there is lot of
text to be entered. With this option selected, the text will automatically scroll
as the user types the text. You don't have to use up lot of screen space with
large SingleLineEdit boxes when you want the user to enter a large text.
When designing windows and sizing controls, you should also keep in mind
the various sizes and fonts that may be used.
Limit:If you don't provide any value for this property, user can type 32,787
characters. If you would like to restrict him as to how many characters he
can type, you can do so by filling up the Limit property.
If you turn-on "Display Only" property, then the SingleLineEdit control will be
used to display data only; it will not accept input from the user.
Any text that you type into this field will appear, by default, in the
SingleLineEdit control, when the window is first opened.
Password: Sometimes, you might want to accept a password from the user.
If you use SingleLineEdit control to accept a password, it will be displayed as
the user types. In this situation, you need to turn on Password property.
Turning on this property will display stars as the user types the password.
Naming Controls
When you place controls on a window, PowerBuilder automatically names
them using standard prefixes and a number to uniquely identify them. The
full list of controls and naming prefixes are as follows:
The above list has the default prefixes. If you want to have different
prefixes, you can change the defaults by selecting "Design/Options" and
changing values in "Prefixes 1" and in "Prefixes 2". You can rename any of
the controls, but it's a good idea to keep the standard prefixes so that it is
easy to identify the type of object by looking at the control name in the
script. Remember the control names within a window should be unique. That
means, you can't have more than one control with the same name in a
window. You can have a control with the same name in different windows.
The names are case insensitive. While naming, you should follow
PowerBuilder naming rules:
CommandButton
A CommandButton is used to allow the user to trigger an action. You'll
probably be familiar with the OK and Cancel buttons used in standard
Windows dialog boxes, allowing the user to take control of whether or not a
task is to be completed.
Typically, we write code for the clicked event ( We will explain about events
after couple of sessions ) of CommandButton, i.e., we specify the action to
be taken whenever the user clicks on this CommandButton. Some users are
from the DOS background, they have the habit of using keyboard than the
mouse, might even press Enter key. Whenever user hits the Enterkey, the
Clicked event script should be executed. To achieve this functionality, you
need to turn on the Default property. Border of a CommandButton which
has Default property turned on, would appear black and thicker.
PictureButton
Checking the "Original Size" property changes the picture to its original
dimensions, i.e. to the dimension the picture was given when it was first
created. Even if you check this option, you can still resize the control and the
picture will stretch to fit the size of the button. If you do this and look at the
properties of the button again, you'll see that PowerBuilder has unchecked
the "Original Size" property.
EditMask
The EditMask control allows you to take formatted input from the user. For
example, you might want to accept zip code from the user in the format
#####-####. If the user tries to input information into this control that
doesn't conform to the mask, PowerBuilder refuses to accept the keystrokes.
If you can go to properties, you can see, there are different data types
available under the "Options/Type" DropDownListBox. For each of these data
types, there are some pre-defined masks available. For example, if you
select the String data type, you can format the data in upper case (!), lower
case (^), number (#) and alphanumeric (a) characters. Most of the times,
these masks are enough for your needs. If you need a special mask, you can
as well create them by typing into the "Mask" option.
Note that the formatting of data is for display purpose only. PowerBuilder
doesn't store the data in the way it is displayed, in particular "date" type.
Dates are usually stored as a number representing the number of days from
a fixed date. This allows PowerBuilder to easily swap between formats by
simply applying the rules for the given format to this base number, rather
than performing two conversions and remembering what format the date is
currently stored in. For example, if the fixed date is 1st January 1994, then
3rd January 1994 would be stored as 2 and the 25th December 1993 would
be stored as -7. The point is that it doesn't matter to us how PowerBuilder
stores the date as long as we see it in a format that we understand and
require.
In versions prior to v5.0, there was an option in the dialog box to test the
mask you defined. However, it is no longer available in v5.0. You need to
either preview or run the window to test the defined mask.
One note from our experience is that, make sure you paint enough space
(may be a little extra than required) for the content to display in the
EditMask. For example, if you paint the height a little shorter for the
SingleLineEdit control, user can still type in data even though he can't read
the data comfortably. If you do the same to the EditMask control, it displays
no data at run-time.
The Spin Control property is most often used with numeric data to allow the
user to increase or decrease the value in the EditMask control by clicking on
the arrows that appear at the corner of the control. You can see this
property in the print dialog box while specifying the number of copies to
print, in any application under MS-Windows.
You can enter the relevant information in the appropriate fields to specify
the minimum and maximum values for the control and the size of the
increment ( which must be a whole number).
You can also use the spin control option for the "date" data type fields. In
this case, only one part of the date will increment or decrement depending
on the cursor position. For example, if the cursor is on the month part of the
date, clicking on the upper arrow will increment the month by one.
While previewing the window, you won't be able to click on the spin control
arrows because you are previewing the window.
If you type in a value which is outside the allowable range, as soon as you
try to increment or decrement it using the spin control, the value will change
to the minimum or maximum value and won't allow you to move outside this
range.
Code Tables
If you want to use spin controls with string-type data, you can make use of
Code Tables. Code Tables work like look-up tables. That means, it allows you
to display the detail value, for the corresponding abbreviation. For example,
you may want to display "New York" on the screen, and store "NY" in the
database whenever user selects "New York". All you need to do is provide
"New York" for the "Display Value" property and "NY" for the "Data Value"
property. You can provide as many entries as you want in this "Code
Tables".
If you use "Spin Control" and "Code Tables" for the String data type values,
PowerBuilder displays values from the code tables that is specified in the
"display value", as the user keep clicking on the arrows in the "Spin
Control".
Tab Order
Tab Order defines the order in which the focus changes from one control to
another as the user keeps pressing tab key. Each control in a Window has a
tab order, which is measured in numbers. Controls with tab order 0 (zero)
can't be tabbed on. It is vitally important to provide a smooth and well
disciplined tab order, so that the user can easily follow the motion of the
focus around the window. Your applications will quickly be condemned as
unfriendly if you don't provide a sensible tab order.
To see the current tab order, select "Design/Tab Order" from the menu. In this
mode, you can't do anything (including saving the window) except changing
the tab order. You can see the tab order at the top of each control in red
color. To change the tab order of a control, you need to click on the tab
order number and type a new number.
If you have ever programmed in BASIC, back in the good old days before
PCs, you might remember numbering your program lines with increments of
10 so that you could add extra lines later without having to re-number all
your lines. The same principle applies with the tab order set by
PowerBuilder.
The following controls are not included in the tab order or in other words,
have been assigned a value of zero:
StaticText
Graph
Picture
You can't tab into drawing objects or StaticText controls, so PowerBuilder
allocates zero tab value by default to these controls; which means that they
are not included in the tab order. This also applies to any RadioButtons or
any other mutual exclusive controls that you place on a Window.
If you tab to StaticText or drawing object, you can't change anything, so why
would you want to tab to it?
If you change a set of mutually exclusive controls to have an 'active', non-
zero tab order, as each control receives the focus, it is also selected. As you
might guess, this can cause some consternation among your users.
When you place a custom User Object (We didn't explain what a User Object
is. For the moment, just remember that an User Object is a collection of one
or more objects) which contains more than one object on a window and tab
onto it, you can press Tab key until every control within it has been visited.
After that, continued tabbing will take you to the next control on the
window.
Once you change the tab order, choose "Design/Tab Order" again to come
back to normal mode.
MultiLineEdit
Do not confuse the "Tab Order" with the "Tab Stop" property. The Tab Stop
property allows you to display text in a table format and will be covered in
greater detail in the PowerScript session.
To get full understanding of scrollbar properties for MultiLineEdit control, place a control as shown in
the picture (at the beginning of the page) and turn on and off different scrollbar properties and
preview the window with a few lines of text. You will get an idea about how the text scrolls with
different scrollbar options.
ListBox
A ListBox control is used to display a list of options from which the user can
select one or more. Our example shows a list of countries with a vertical
scrollbar to scroll through the list. You select from the list by clicking on one
of the countries. By looking at the properties of the control, you can see that
we've typed in the options that we want to be displayed in the Items box:
The list of options is in the order in which we typed them, but when you
previewed the window, you may have noticed that the list was in
alphabetical order, because we've checked the Sorted property.
The "Disabled Scroll" property will automatically turn off the vertical
scrollbar, if there is enough room in the control to display all options.
There are two ways to allow a user to select more than one choice from a
list. Checking the Multiple Selections property allows any number of options
from the list to be selected by clicking on them. Clicking on a selected option
will then deselect it.
In MS-Windows environment, you can select a range of files using Shift and
left mouse button together. Similarly you can select random files using Ctrl
key and left mouse-button together. You can give the same functionality to
the user by enabling the "Extended Select" property.
The "Tabs" property specifies the position to stop within the ListBox, in terms
of characters, whenever user press "Tab" within the control. You can specify
up to 16 tab stop positions. We neither saw it working nor found it is useful
in any application.
Typical usage of ListBox
Typical a ListBox is used when you want to display more than two and less
than five multiple choices. If it is only two choices, you can use
Radiobuttons, but if it were more than two, using them would occupy most
of the screen.In those cases it would be better to use a ListBox. Using
DropDownListBox would be better choice if the options are more than five
and multiple selections are not required.
DropDownListBox (DDLB)
A DropDownListBox is used to display a list of available options when you
click on the down arrow at the right side of the box. This can be used to
save space on the window, as it takes up the same amount of space as a
SingleLineEdit controland more over allows you to select from a fixed range
of options. In the above example you can select one country from the
DropDownListBox. The advantages of DDLB over ListBox is that, DDLB takes
less space, but DDLB has one limitation. You can't allow the user to select
more than one option from the DDLB.
You can select the country by clicking on the one you want, or you can type
and the list will scroll down to the first entry that starts with the letters you
typed in. This is an important feature as it allows you to put a great number
of entries in a DropDownListBox, but still allows the user to quickly find the
one they want.
Again, you can choose to have the list Sorted and can enable or disable both
the horizontal and vertical scrollbars. If you don't have a vertical scrollbar,
you can still select from a long list using the cursor keys.
The Allow Editing property allows the user to type a new entry into the
control. If Allow Editing is enabled and you supply some Text, then that is
displayed in the control and becomes one of the selectable options.
However, it is not permanently added to the list, which means that if you
select another option from the list and then decide to change it back, you
will have to type it in manually.
CheckBox
A CheckBox is used to select or deselect a given option. For example, you
may want to find whether the user is employed or not? You can achieve this
with the help of a Checkbox.
Selecting the "Three State" property allows the Checkbox to have three
states and selecting the "Third State" property makes the "Third State" the
default state.
"Left Text": The "Left Text" property displays the text to the left of the
CheckBox. By default, the text display is on the right side and the Checkbox
on the left side. Deselecting it reverses the order, placing the CheckBox on
the left of the text.
"Automatic": By default, "Automatic" property is turned on. When this option is turned on, at run-
time, the Checkbox automatically changes the state (checked/ un-checked/ third state) as the user
clicks on the Checkbox control. If the option is not turned on, you need to change the state
programmatically.
RadioButton
A RadioButton is similar to a Checkbox, with one difference. When you place
more than one Checkbox on the window, you can check any/all/one
Checkboxes on/off. Every Checkbox is independent. Similarly, if you have
more than one RadioButton placed on a window, you can always turn on
only one RadioButton, no matter how many Radiobuttons are there on the
window. This behavior makes sense in the example given below, because
you can't be single and married at the same time!
Sometimes, you might have multiple logical groups. For example, from the
above picture, Radiobuttons related to "Sex" is one logical group, while other
Radiobutton belong to another logical group "Martial Status". That means
user should be able to choose one option from each question, similar to the
picture. By default, it is not possible, since as soon as the user selects
another Radiobutton, previously selected RadioButton becomes de-selected.
For practice, paint the window as shown in the above picture and try to
select options from each logical group and see, whether you are able to or
not.
The solution for this problem is using a Groupbox. We will explain this in
"Groupbox"
Groupbox
The GroupBox control is used to group related objects together, but it is
generally used to group sets of related Radiobuttons together. When there is
no group box in the window, the window behaves as a group box. That's
why, you can select only one RadioButton, no matter how many
Radiobuttons are there on the window.
For example, you have two questions, one is "Martial Status" and another is
"Sex". In this situation, you need one answer for each question. If atleast
one question is not in a GroupBox, user can't answer both questions, since
he would be able to select only one option for both questions together. The
solution for this problem would be, either put each set of answers in a group
box separately or put at least one set of answers in a GroupBox. If you put
one set in a GroupBox, window behaves like a GroupBox for another set of
Radiobuttons.
Picture
A Picture control is used to display a bitmap, Run Length Encoded file or
Windows metafile on your window. Turning on "Invert image" property,
inverts color of the image. After placing the picture control in the window,
you might have resized few times and might want to see it in its original
size, then just turn on "Original Size" property.
OLE 2.0 Control
Since, OLE is a huge topic in itself and can't be explained here, we will about
it explain briefly; we won't go into much details at this point because it
would be too advanced at this stage.
At this initial stage we think it would be enough, rather than to introduce too
many new technologies.
Graph Control
PowerBuilder allows you to add a Graph to your window with the help of this
control, in any of the common graphical formats to present the numerical
data.
There are numerous options for the properties of this control relating to
titles, legends and axes, as well as the type of graph.
Category: Categories are the major divisions of data. For example, we can divide all transactions
into three major divisions (types) like 'Receipts', 'Issues', 'Returns'. In the above graph, there are
three categories.
Series: Suppose, say you are comparing transactions for two products then, you will find receipts
for each product, issues for each product and so on. In this example, each product is a series. Series
are a set of data points. Let's take another example, say you are comparing transactions of a product
for each month. Here you have 12 series, which means that you are comparing receipts for each
month, issues for each month as well as returns for each month.
Values: This is the value of each series or category ( if no series are present ). The total number of
receipts, total number of issues and total number of returns are values. Display of 'value' varies
between graph types.
Title: The title of the graph. By default it appears at the top of the graph.
Category Axis: Category axis is the axis where the categories (major divisions of data) are
plotted. Typically it is on the x-axis.
Series Axis: Series axis is the axis where the series (set of data points in a category) are plotted.
In two-dimensional graphs this is on the same axis as the category axis. In three dimensional graphs
it is different from the category axis. You can see this in the graph above.
Value Axis: Value axis is the axis where the values are plotted. Typically it is on the Y axis and
varies in different graph types.
Legend: Legend displays how the series are represented. For example, you may have different
colors for receipts, issues and returns. You can see the legend at the bottom of the above graphs. You
can display legend at different places on the graph such as bottom, top, left, right, etc..
Ticks: Ticks displays the starting of another value on the value axis and represents categories on
the category axis. You can display these ticks inside, outside or straddle (half on inside and half on
outside) the axis. You can display ticks for major divisions as well as minor divisions. For example, the
major division is 500 and if you want to display 4 minor divisions then PowerBuilder will display a
minor division tick 4 times (after every 125) between each major division. The ticks for minor division
can't be a straddle. Similarly, you can display label for each major division, but not for minor division.
Graph Types:
Column Graph:
Bar Graph:
Line Graph: This graph is good for displaying continuous data, for example time and
temperature. The data points are connected by lines. Graph properties such as overlap %, spacing %
do not apply for this type of graph since the datapoints are connected by a continuous line.
Area Graph: It is similar to line graph except that the area under the lines are filled with color.
When this graph has a series, each series is filled with a different color.
Stacked Graphs:
Scatter Graph: This graph is different from all the graphs explained earlier. This graph does not
use categories, instead it plots data values on both X and Y axis. This graph is used to display the
relation between two data points. For example, speed & mileage, speed & production, project team
size & time taken to complete the project, etc..
Three Dimensional Graphs:
You can specify the sorting order for the series as well as categories in the 'Series Sort' and
'Categories Sort' options. Using the 'Legend Location' you can specify the location of the legend, it can
be bottom, top, left or right.
The 'Spacing (% of Width)' specifies the space between each category. Unless you have too many
categories, you don't need to adjust this property. The 'Overlap (% of width)' specifies the percentage
that each item in the category that should overlap. This property is more useful when you use bar or
line graphs. The 'Depth (% of width)' property specifies the depth of each item in the category and
can be set only for the 3D graphs such as 3D piechart, 3D column, 3D bar, etc..
In the 'Text' tab you can specify properties for text such as title, value axis, category axis and so on.
Select the text object for which you want to set properties from the 'Text Object' ListBox and set
properties for that text object. Other than the regular font properties, you can rotate the text either
left or right in 450 or 900. This option is not available for title and legend.
Infact, the 'AutoResize' feature is the best option that you may always want to turn on. Turning on
this property will adjust the text size automatically when the graph control is resized. This can be the
case when you may want to resize the graph control in the window everytime the window is resized at
run-time. You can't specify the font size when this option is turned on, which makes sense.
You can make the background color transparent in the graph control; this option is not available in
most of the other window controls. For each text object, you can specify the display expression. For
example if you want to display the date in the title,
Stock as of 01-01-1997
On the value axis you can divide the axis into some major divisions. For example, to display 5 data
points each incremented by 100 you specify 5 for the 'Number' under the major divisions. If left to the
default zero, PowerBuilder takes care of creating major divisions. PowerBuilder displays one tick at
each major division. You can choose the tick type as 'inside', 'outside' or straddle. Similarly, you can
choose to display grid line for major division.
In case
of
three dimensional graphs you can specify rotation,
elevation and perspe
DataWindow Control
A DataWindow control is a container for a DataWindow object. The definition
of a DataWindow object contains the data source (SQL Statement/ Stored
Procedure) and the format of the results. You paint the DataWindow Object
in a DataWindow painter. DataWindow Object it self can't do anything. You
need to place a DataWindow Object in a DataWindow control. All the script
you write is for the DataWindow control.
We don't have anything for practice at this time. Only it would be after
completing "DataWindow" session
User Object
User Object is an object that is defined for reusability purpose. An example
would be to display microhelp whenever mouse pointer moves over any
CommandButton. What is the best way to do it? Method one would be
( which is not the best one ), to write script for each and every
CommandButton in the application. It works fine; but the drawback of this
method is that you duplicate code at each CommandButton. If a need to
change some functionality occurs, you need to change code in all
CommandButtons. It is time-consuming and the probability of missing some
places is more.
The indicator in the Scrollbar in the second category not only indicates the
current cursor position in terms of the percentage of the whole content, but
it also indicates the percentage of the content that is being displayed on the
screen.
In real life projects usage of Scrollbars is less than one percent, since most
of it is accomplished by a DataWindow control.
PictureListBox
PictureListBox is similar to ListBox control, only with an added advantage of
picture display capability for every option in the ListBox. In the normal
ListBox, this can't be done.
ListView
ListView and TreeView are Windows 95 controls. In simple terms, a ListView
control has functionality similar to that of a PictureListBox. However, a
ListView is more flexible and allows you to develop more user-friendly
applications.
Recall that in a PictureListBox you can assign pictures to each item, where
as in a ListView, each item can be associated with three pictures. One Large
picture, one Small picture and one picture to indicate the state of the item.
You can display a ListView in different presentation styles:
If you select "Fixed Location" property, users can't move the items in the
ListView control at run-time. Otherwise, users can drag and arrange the
icons, to suit there needs.
You can allow the user to edit labels at run-time, by turning on " EditLabels"
property. You can also allow the user to delete items, by turning on " Delete
Items"property. The label may overlap other labels if it is very large. It
would be always better to check "Label Wrap" property.
TreeView
TreeView is similar to a ListView and it is more powerful. As the name
suggests, it allows you to display items as a branch.
Tab Control
Tab control allows you to paint "organizer" like user interface. Did you
observe that you have been using tab control? The properties dialogbox of
any control uses tab control. Tab control is new to version 5.0, till then
programmers were simulating tab control with the help of User Objects. We
can skip the tedious programming techniques.
Place a tab control on the window. By default it has one page. To insert
more pages, click with the right mouse-button and select "Insert Page"
option. Invoking popup menu by clicking in the free area next to page name
( Area 1 in the picture) allows you to select properties for the tab control. If
you invoke popup menu by clicking in the area below the page name (Area
2), it allows you to specify properties for the page. , First let us see the
properties.
"PowerTips": By turning on the "PowerTips" property, you can display
PowerTips for the page names, similar to the PowerTips for the toolbar icons.
"Fixed Width": By default, the tab size automatically adjusts to the width of
the tab page name. That means, the area that displays the tab page name
may be longer and sometimes shorter, depending on the length of the tab
page name. To make all tag page's tab to have the same width turn on
"Fixed Width" property. In this case, the tab page's tab width is decided by
the longest tab page text.
In cases where there are more tab pages than the number of tab pages that
can fit in the display area, PowerBuilder automatically displays scrollbar
icons. The position of the icon depends on the "TabPosition" property.
"TabPosition" property gives a wide choice of area to display the tab page
text.
Once the tab control is painted, you may want to rearrange the tab pages.
This can be done by dragging and rearranging in the "PageOrder" tab in the
dialog box.
Wondering where to define picture name, text for PowerTip, etc.; double-
click on the page itself (area-2). You can define name for each tab page,
text and picture for the tab page in this dialogbox.
RichTextEdit Control
RTE control gives you the power of WYSIWYG text editing in PowerBuilder application. Using this
control you can provide word-processor like interface. You can see the real power of a RTE control
only when you share data from a DataWindow.
General Properties: Create a new window and place RTE control on it. Similar to any other
window control, this control has 'visible', 'enabled', 'DragDropIcon', 'DragAuto' and 'Pointer' properties.
Invisible Characters: You can control the type of characters that are to be displayed in this
control. For example, if you wish to display tab characters, you need to turn on 'Tabs Visible' property.
So are 'Returns Visible', 'Spaces Visible', 'Fields Visible' properties. 'Fields Visible'
property is useful when you share a DataWindow /DataStore with a RTE control and use DataWindow /
DataStore fields in the RTE control; otherwise, this property has no effect on the control display
behavior.
Popup menu: If you have used MS-Word, you might have used popup menu in the word-
processor for context sensitive operations such as Cut, Paste, Copy, etc.. Similarly, you can make
PowerBuilder to display the popup menu for the RTE control by enabling the ' Popup Menu' property.
Except for a single mouse click you don't need to write code to display the popup menu in the RTE
control.
Paragraph properties dialog box at run-time
RTE Control Toolbars: You can display a toolbar in the RTE control by turning on the
'Toolbar' property. Don't mix-up RTE specific toolbar with the general toolbars such as Powerbar,
Painterbar and custom built toolbar for your application. RTE has one more toolbar called a 'Tabbar',
that allows the user to set tab positions for different lines in the RTE control text. Similarly you can
make the ruler bar visible.
Properties dialog box at run-time.
Word Wrap: By turning on 'Word Wrap' property, you can control whether the text should wrap
around if it reaches the right margin of the RTE control.
Margins: Margins can be set using 'Left Margin', 'Right Margin', 'Top Margin' and 'Bottom
Margin' properties.
Undo Depth: Maximum number of undo levels can be set using 'Undo Depth' property. The
default value for this property is zero, that means nothing can be undone.
Pictures as Frames: When there are more pictures in a document or when you want to display
the RTE control faster, turn on 'Pictures As Frame' option. By default, PowerBuilder displays the
picture as it is. However, you can choose not to and instead display a frame area that is equivalent to
the picture dimensions.
Print Document Name: When a document is printed from the RTE control the name specified
in this property is used to be displayed in the print queue .
Drawing Objects
You can make use of drawing objects to improve the appearance of the
window you paint. You can notice (from the picture below) that Drag-and-
Drop properties are missing for controls that fall under the Drawing
category. Make a note that Drawing controls don't have any events and
moreover you can't define user-defined events (details in future sessions).
When you select a control, the corners turn black to indicate that it is
selected and you can then affect any changes against it. This holds true for
multiple control selections, but the actions you can perform against such
selections are less.
Some of the actions you can perform against a multiple control selection
include:
Moving them.
Aligning them, based on axis.
Resizing them, based on the size of one control.
Spacing them, based on the current spacing between the controls.
If you have any problem in selecting multiple controls, click on the projector icon, for a demo
(movie.gif).
Moving Controls
This is the easiest action to be performed in a multiple control selection. To
move all controls so that they retain their relative positions, select the
controls that you wish to move and click on one of the controls and move it
to its new position.
PowerBuilder will indicate where the controls will end up by an image of the
controls moving around the window until the left mouse button is released.
Aligning Controls
You might have experienced that you can't align controls in a window. To
align a group of controls, select controls using one of the methods outlined
above, and then select "Edit/Align" and choose one of the following methods
of aligning the controls:
If you use the Ctrl method to select controls, PowerBuilder will use the first
control selected as the reference point. The reference point control doesn't
move and all other controls conform to it. If you use the box swipe method
of highlighting multiple controls, the reference control is the last one that is
selected.
Spacing Controls
To make spaces between your controls equal, you can select "Edit/Space
Controls" and select either horizontal or vertical spacing.
PowerBuilder takes the first two controls that you select and uses the space
between them as the default space to space all other controls.
Sizing Controls
If you want several controls to have the same size you can select the
required controls and select "Edit/Size Controls".
The note that was made for aligning controls also applies here. Use
theCtrl method of selecting the reference control for the sizing to base upon.
The Grid
Using these tools to manipulate your controls can take a while to get used to
and when they do become second nature, they can still be a little unwieldy.
To help you out with this problem and to speed up the process, you can use
the Window Painter's grid as a basis for your controls positioning.
The Window Painter's grid is turned on by default when you first create a
window.
To look at the properties that PowerBuilder associated with the grid, select
"Design/Options" and click on the "General" tab.
You can change the horizontal and vertical spacing of the grid by changing
the X and Y values and, if you check the "Snap to Grid" option the size
controls will snap to the nearest grid point when you move them. This
enables you to size, space and align controls very quickly.
Duplicating Controls
If you want to add several similar controls to a window, you can use the
duplicate tool. Select the control you want to duplicate and press Ctrl + Tor
right-click on the control and select "Duplicate".
Another control of the same type is created and placed below the original
control. The new control gets all the appearance properties such as text,
colors, font, font size, borders and so on, and is named with the next
available control name. Unfortunately, any scripts or user events that were
created for the original control aren't copied to the new control.
You can't have two controls with the same name on the same window, so
you have to type in a new name before PowerBuilder creates the new
control. The control is copied directly on top of the original control, so you'll
have to move it to verify that its presence
You can also use Copy and Paste method to copy controls between windows.
PowerBuilder does allow you to have two controls with the same name in
different windows, so you won't get a naming conflict warning when you
attempt to copy a control onto the other window.
Listing Controls
As we have just seen, when you copy and paste a control, it appears directly
on top of the original. Back in the section on CommandButton, we saw that
when you deselected the visible property, the control disappeared from both
the run-time and the design view.
Both of these situations can cause you to 'lose' some controls visually to get
around this problem PowerBuilder allows you to see a list of all the controls
that you have placed on a window. This catalog of controls is called the
Control List and you can call it up by selecting "Edit/Control List..."
You can select all of the controls on your window from here, and affect
changes against any of the properties of it by selecting the Properties button
to take you to the relevant properties dialog.
Sometimes, you may place a control on the window, but don't want to
display it to the user. So set "Visible" property to false. When you do this,
you can't see the control at painting time as well as at run-time. If you want
to see all the controls including hidden controls at painting time, select
"Design/Options" and select "Show Invisibles" option in the "General" tab. This
displays the hidden controls at painting time only.
Window Properties
We've looked at all the controls available in a window and properties for
each control and seen how to manipulate these controls on a window.
However, the window itself has certain properties. To see the properties of
the window, click with the right mouse-button in the windows workspace
(the space that is not occupied by any control in the workspace) and select
"Properties" option.
You might have observed that till now, when you do the window preview,
"Untitled" is being shown in the window title. You can change the window
title in the "Title" prompt.
Each window can have a menu associated with it. For example, while
painting a window, you are in the Window painter; you see a menu at the
top and a toolbar (Painterbar) associated with the menu. The term
"associated" means that the options in the menu have a corresponding
toolbar icon in the Painterbar. Similarly, you can paint a menu (We will
explain in the next session) and associate that menu to any window you
want. A menu can be associated with any number of Windows, where as a
Window can have only one menu associated with it. (You can't associate a
menu at this moment, since we didn't paint a menu yet.) Whenever you
open the window at run-time, the menu will be automatically displayed.
Property/Window Main Child Popup Response MDI Frame MDI Frame with
Type Microhelp
Maximize box
Resizable Can't
have
Minimize box
Window Color
You can specify a color for the window itself. By default, the color of the
window is "Window Background". We know that the sentence is a bit
confusing. To get out of the confusion, we need to explain some MS-windows
color theory.
All system windows and applications that follow MS-Window's standards use
MS-Window's system colors. You can view/change system colors from the
"colors" option in the Control Panel.
Here you can specify what window's background color should, what color the
window title should have, what colors enabled/disabled menu options should
have and so on.
Coming back to "Window Background", if you select any color other than
this, the end user will always see the color you specify. Please note that
some users may not like the colors you defined or some users may be color
blind. That is one of the reasons why users start disliking the system.
If you select the window color as "Window Background", the color of the
window you painted would be the color they specify in the Control panel.
That means every user can have the color they want.
You can choose how to open the window: maximized, minimized or normal
size. The initial position of the window when it is open would be in the
position you specify.
The scrolling options allow you to specify how the standard Windows
scrollbars should work. The defaults are as follows:
Horizontal Units Per Scroll Columns 0 - 1/100th of the width of the window
Vertical Units Per Scroll Line 0 - 1/100th of the height of the window
Types of Windows
There are six types of windows available in PowerBuilder. They are all
created in the same way, but each has a specific task for which it is used.
You don't have to specify the window type before you create the window.
The default window type is: "Main".
Main Window
As sheets in MDI (Multiple Document Interface) applications. (We will explain about MDI concepts
& programming in the comming sessions.
If you open say, 3 windows of type "Main", each window behaves
independently. For the user, it looks as if they are 3 different applications.
Closing of one window doesn't exit the application unless it is the last open
window on the screen. Minimizing a window will display the minimized icon
in the "Program Manager"; Under Windows 95, it would not be displayed
anywhere.
Popup Window
The popup window is dependent on its parent window, but it can also be
displayed without opening it from the parent window.If you do not open the
popup window from another window, it will behave like a main window.
Parent window will not overlap a popup window, but if a parent is minimized
popup window will be hidden.
Response Window
A typical example of where you might encounter this type of window is when
you want to save a new document using your favorite word-processor. When
you click on the save option, the word-processor can't save the file as the
document is as still untitled and therefore displays a 'Save As' window,
asking for the required information.
Until you answer this question, the word processor will not allow you to
continue , unless you click on the Cancel button and throw away the whole
idea of saving the document.
Child Window
A child window can't be moved outside the parent window boundaries. If you
try to move a child window outside its parent window limits, all the window
area that you expect to see outside of parent window would disappear. To
see the full window area again you need to move back the child window into
the parent window.
On the other hand, if you move the parent window, the child window will
maintain its relative position within the parent.
A child window can't have a menu associated with, but a child window can
still have a title bar. When you minimize a child window, the minimized icon
is displayed at the bottom of the parent window and when it is maximized, it
occupies the entire parent window. A child window is never considered as an
active window. It doesn't mean that you can't do anything in the child
window. The interpretation of "never considered as an active window" is
from programming and not from the end-user perspective. When you close a
parent window, any children that are inside it are closed automatically.
When a window (sheet) inside the MDI Frame window minimizes, the
minimized sheet icon is displayed at the bottom of the MDI Frame window.
This window is exactly like an MDI Frame, except that it has an additional
feature of a status bar at the bottom of the window. This status bar is used
to display context-sensitive help like current time, etc..
By resizing this window's workspace, not only are you defining your design
area, but you are also defining the size of the window when the application
is run. Clearly, if you have enabled the Maximize, Minimize and Resizable
properties of the window, you will be able to alter this sizing at run-time, but
when the window is initially opened, it will be displayed within these
proportions.
Testing a Window
We've already explained how to preview a window after you paint it. In the
preview mode view how the window looks like. If there are scripts they won't
execute in the preview mode. There are two ways of running the window.
One method is, write script in the application object's script and run the
application. This method is good when you want to test the whole
application, or when this window is dependent on the application object
events. Sometimes, you may want to test the window alone. In this case,
you can run the window without running the whole application, by selecting
the window toolbar icon (The icon which is filled with gray color, NOT Blue
color) from the Powerbar.
If you haven't saved the changes, PowerBuilder prompts for saving the
changes. After that, you will be prompted for the window to run. Remember,
when you selected "Design/Preview" to preview the window, you can only
preview the currently open window. However, irrespective of the window
that is open currently, you can run any window. Note that, while running the
window, appropriate scripts will execute.
Assume that you have two windows with the same name, but in different
libraries and these two libraries are in the application "Library list".
PowerBuilder displays the first window that it finds in the library list
( PowerBuilder searches objects in the library list in the same order you list
them ) in the "Run Window" dialog box. It does not display the second window.
That means, you can't test the other window. If you really need to test the
second window, one way would be to open and save that window with a
different name and test it. Once testing is done, save it back to the original
name.
Sometimes, you might have a window with NO "Titlebar" and want to test
the window alone. You can do it, no problem. The only problem would be
closing the window with no CommandButton with script in it to close the
window. In this situation you can't come back to the development
environment. What you could do is switch to "PowerBuilder development
environment (keep pressing Alt Tab key combination till you see
"PowerBuilder - Your application Name" task). PowerBuilder prompts you as
shown below. Say, yes. It will stop running the window.
Summary
In this session, you have learned about creating a window, various window controls & objects, window
properties and various window types, previewing and running a window. To read a full summary of the
session, click on window.ppt which is a PowerPoint presentation. If your browser do not open
PowerPoint viewer automatically upon clicking on that link, you may not have PowerPoint viewer
installed on your machine. Please visit 'Software Setup' page which is at the beginning of the course
and download PowerPoint viewer at free-of-cost.
SingleLineEdit control has the Password property. When this property is set to true, at run-
time the value entered into this control is displayed as stars ( ***) instead of the actual
data. The actual value is available through program. This is useful when you don't want
other people to watch the data you type into the control.
Which control allows you to input multiple lines of text with different attributes such as
bold, subscript, tabs, superscript, colors and so on?
RitchTextEdit control
What does Extended Select property mean and which control has that property?
ListBox control has Extended Select property. This property allows you in selecting:
multiple sequential items in a ListBox using Shift key.
multiple non-sequentially placed items using a Control key.
In which of the following attributes of a CommandButton changes are allowed?
Text
Border
Background color
Name
size
Font color
You can change Text, Name, Size of a CommandButton. You can't change Border,
Background color, Font color of the CommandButton.
What advantage a PictureButton has over a CommandButton?
PictureButton allows you to display a picture along with the text on the button. You can
also display text in multiple lines which is not possible in a CommandButton.
If there are ten Checkboxs placed on a window, how many of them can you check off at
any given time?
You can check off any number of Checkboxes.
If there are ten RadioButtons placed on a window, how many of them can you check off at
any given time?
You can check off only one RadioButton at any time, unless you place some RadioButtons
in a GroupBox control.
What is an accelerator key?
Accelerator key allows you to select a control using the keyboard instead of a mouse.
Tab order specifies the order in which the focus moves from one control to another when
the user presses the tab key.
Explain the Default, Cancel properties that are available for a CommandButton.
Clicked event triggers when the user presses Enter key, if the Default property is set.
Clicked event triggers when the user press Esc key, if the Cancel property is set.
In a situation given below, how do you prevent the triggering of CommandButton's clicked
event, when the user presses the Enter key.
A "Response" window doesn't allow you to do anything within the application except in
the "Response" window.
What is a code table? Which controls have this property?
Code tables allow you to do translation. It allows you to display long names on the control
while allowing you to save short names. Only EditMask control allows you defining "Code
Tables" property.
There are few controls in a window whose visible property is turned off because you don't
want to display it at run-time. How do you make the hidden controls visible while you
paint the window.
You need to turn on Show Invisibles property by choosing Design/Options option from the
menu.
Howis Drawing objects such as circles, rectangles different from other controls such as
CommandButton, StaticText, etc.?
Drawing objects do not have Drag and Drop related events. You can't write scritps for
Drawing objects.
Which of the following controls allow multiple item selections?
ListBox
PictureListBox
DropDownListBox
PictureDropDownListBox
All of of the above
ListBox, PictureListBox
Visually how do you recognise a CommandButton that has its Default property set.
A child window can't move outside its parent window where as a popup window can.
What is the behavioral difference when you open the Child window
1. Directly
2. From another Window
When a child window is opened from another window, it behaves like a child window and
the window that opened the child window becomes its parent window.
A Child window when opened directly behaves like a main window.
What is the technique you use to display the accelerator key for a SingleLineEdit control?
You can't`display the accelerator key for a SingleLineEdit control, even though you define
one. To display the accelerator key, display the accelerator key to the StaticText control
that is used for labelling the SingleLineEdit Control.
Which of the following statements is correct?
You can specify two menus for a window of type "Main"
A window of type "Response" can't have a menu.
A window of type "MDI" can't have a menu.
Only option 2 is correct.
Note: Use the downloaded files for verification only. We strongly suggest you to do all the exercises.
Exported version of
Window Name
Window
Login Window (w_login)
Property Value
Text: "&Cancel"
Turn on "Cancel" property
CommandButton cb_cancel Tab Order: 70
Tag: "Click or Press Esc key, to cancel Login and to exit the
application."
The bottom most control is a StaticText control. Name it as "st_help". Value
of text is: "Ready". For all StaticText controls, select background color as
"Window Background" color (Marked as "W" on the toolbar icon).
Window Properties
Property Value
Type Response
The bottom four controls are CommandButtons. From left to right, cb_print,
cb_save_to_log, cb_continue and cb_abort. The text for the
CommandButtons are "&Print", "&Save", "&Continue", "&Abort" in the same
order. Save this window as "w_error".
A Full-featured window (w_product_master)
Picture of w_product_master Window
Type Main
Left Top control is a "Picture". Assign your company logo's bitmap. Name it
as "p_logo". The next two controls are StaticText controls. Provide your
company name over there.
Menu Painter
PowerBuilder offers the ability to add your custom menus to the application.
In this session you will learn about creating menus, while retaining control
over what the user can and can't do. You will be learning various techniques
to create menus, which you will be using in the 'Product Management
System' and you will also be looking at some of the other options available
in the Menu Painter.
Prerequisites:
Types of menus
You can create three different types of menus in PowerBuilder:
DropDown menus
Cascading menus
Popup menus
DropDown Menus
DropDown menus are displayed when you select an option from a menu bar
which is on the top side of a window. The available options are grouped into
logical collections and the group names are displayed horizontally on the
menu bar. The following picture illustrates a typical DropDown menu.
Some of the menu options work in toggle mode, i.e. clicking on a menu
option would turn it and selecting it again would turn it off. An example of it
would be the Print Preview option. When you select it for the first time, the
report is displayed in the preview mode and by selecting it again the report
is displayed in the normal mode. The current state of the toggle menu
options are displayed by a check mark just before the menu option (see in
the picture).
Cascading Menus
A Cascading menu can display more menu options than a DropDown menu.
In simple terms, if a menu option has a sub menu, it is called a Cascading
Menu. As you must have noticed, in the window painter all aligning options
are available under the Align menu option which is under the Edit option.
You can identify a cascading menu when you see a right arrow icon next to
the menu option. Clearly, Cascading menus are usually used in conjunction
with the DropDown type menus.
Popup Menus
Creation of a popup menu is no different from other menus, except that you
need to write few lines of extra code to invoke it.
Creating a Menu
Invoke the menu painter from the Painterbar and select New from the Select
Menu dialog box.
Items that are displayed horizontally, such as File, Edit, Window, Help are
calledMenu bar items. Items that belong to menu bar items are
called Menu Items. For example, you may want to display Print, Exit for the
File menu bar item and Cut, Paste for the Edit menu bar item and so on.
To change the name, you need to de-select the Lock Name check box. The
benefit of locking a menu item name is that, any references to it in the
application is still valid even after text change.
Microhelp Property
When using MDI windows, you can specify the help text that is to be
displayed on the status bar by typing in the Microhelp property. Enter text
for each menu item so that it will be displayed when the menu item is
selected.
A shortcut key is a single key or a combination of keys that can be used for
selecting a menu item directly, without having to first open the relevant
menu bar item. If you look at the Exit option on the File menu item, you can
see that Alt+F4 has been added to it as a shortcut key:
Click on the Shortcut tab page. A full list of available shortcut keys
includes all the function keys, letters of the alphabet and the
specializedIns and Del keys. They can be used in conjunction with any
combination of the Alt, Ctrl and Shift keys.
Note that for the highlighted menu item, selected shortcut keys are
displayed in the box next to the menu item text.
You can specify the space you want to keep before the toolbar icon in the
toolbar. The space is measured in PowerBuilder Units.
You can specify the order in which the toolbar icons are to be displayed. By
default, PowerBuilder displays icons from top to bottom for each menu bar
item starting from the left.
Other Options
There are two options available for Object Type property. They are Menu and
MenuCascade. The default is the Menu. When this option is set, toolbar icons
display in the regular mode. If you want to define DropDowntoolbars, you
need to set this option to MenuCascade. When set, PowerBuilder allows you
to change Columns and DropDown options.
You can find some good icons from one of the example applications also.
If you have Art Gallery installed, you can find hundreds of bitmap files in that directory.
The selection of the icons can be crucial. A user should be able to identify
the action an icon represents by the picture displayed on it.
You can divide a menu group into logical sections using separator lines. For
example, under a File menu bar item, you can group all the print options
together, all the Save options together and so on.
To specify a separator line, you simply supply a single hyphen as the menu
item text. PowerBuilder automatically replicates the hyphen to the length of
the longest menu option under that menubar item. PowerBuilder will
automatically give the separator line a name, like any other menu item, with
an identification number. However, if you are trying to paint more than one
separator line in a menu, PowerBuilder prompts you for a menu item name
for the separator line, instead of assigning the name.
Previewing a Menu
Summary
In this session you have learned about menu types, painting a menu and
various menu properties. For a quick summary of the 'Menu Painter'
browsemenu.ppt (a PowerPoint presentation). In the next session you will be
learning about connecting to the database from PowerBuilder.
Menu Guidelines
You have seen the mechanics behind menu creation, let's look at some of
the implications of using custom menus in your application. You should be
aware of these implications because, as opposed to adding functionality you
might be adding holes to your application.
The following list documents some of the important points concerning the
creation of custom menus for your application:
If the currently active sheet doesn't have it's own menu, then the menu and the toolbar
associated with the last active sheet remains in place and operative for the whole time the
sheet is active. If the currently active sheet has a menu but no toolbar, the previous toolbar
would still be displayed.
Menu toolbars only work in MDI frame and MDI sheet type of windows. If you open a non-
MDI window with a menu that has a toolbar, the toolbar won't be shown.
Menu toolbar buttons map directly to menu items, so clicking a menu toolbar button is same
as clicking its corresponding menu item.
Disabling a menu item will disable its toolbar button as well, but won't change the
appearance of the button.
Hiding a menu item doesn't cause DropDown or Cascading menu item toolbar buttons to
disappear. However, it does disable them by graying out of the button.
Hiding an item on a DropDown or Cascading menu doesn't cause its toolbar button to
disappear or to be disabled.
A double toolbar effect can be achieved if you have a menu with a toolbar on both the frame
and the sheet. They can be assigned in any manner.
Enabling and disabling a menu item or menu bar is less overhead to the system
thanHiding/Showing. PowerBuilder destroys the current menu and recreates the original
toolbar excluding the hidden items or menu bar items in case of Hiding/Showing. So
whenever possible, it is better to use Enable/Disable options.
This method of altering the states of controls at run-time is dealt in depth in PowerScript
session.
Menu item names are unique throughout a menu and if you use the
same text for different menu options you get an error message till
you supply a different menu nameMenu Painter - Questions &
Answers
How is a DropDown Menu different from a Popup Menu?
Accelerator key allows activation of the menu option without using a mouse. The
purpose of the shortcut key is same as an accelerator key. You can activate a menu
item with a shortcut key in a single step, where as an accelerator key needs two steps.
You can define any key as a shortcut key, where as an Accelerator key works only
with the combination of an 'Alt' key.
What is the max. length of a menu item name ?
40
What are the max. no. of characters you can display for a menu item?
64
Two icons. One for the normal display and another when the icon is down.
Starts from the left most menu bar item, from top most menu item to the bottom most
menu item and shifts towards right of each menu bar item.
How many levels of cascading menus can be defined?
There are no limitation on the levels that can be defined. Good applications won't
have more than three levels.
Can you show an ampersand (&) on a PowerBuilder menu item? If so, how?
Yes. You need to use double ampersands to display a single ampersand sign on a
PowerBuilder menu item.
Can multiple menu items display same text?
Yes. By default, when you assign the same text PowerBuilder prompts you about the
duplication and suggests a name to resolve it. You can either accept that name or
assign a different name.
I have got an excellent icon file (.ICO) and want to display it on the PowerBuilder
menu toolbar. What should I do?
Well, you can't assign a .ICO file to a toolbar.You need to either convert it into a
bitmap (.BMP) file or create a brand new bitmap file.
You need to paint three menus as part of the exercise. Again, don't forget
the fact that we will be using these menus in the PowerScript session. Don't
neglect painting these menus.
Upon creating menus, you can download files mentioned under 'Exported
Menu File Name' and import them into your PowerBuilder library in the
Library painter. Then you can compare these menus with your menu objects.
Please note that our menu object names are suffixed with '_asi'.
m_sheet_menu m_sheet_menu_asi.srm
m_mdi_menu m_mdi_menu_asi.srm
m_popup_menu m_popup_menu
m_sheet_menu
This menu doesn't need any toolbar. There are only three menubar items.
m_popup_menu
As the name says, we will be using this menu as a popup menu. So, it
doesn't need any toolbar icons and it has only one menubar item.
Database Painter
Up until now, you've been creating objects for the PowerBuilder application.
However, without a source of data, the application would be redundant and
so, in this session, we will be concentrating on this minefield and how it can
dramatically improve the usefulness of a PowerBuilder application.
Prerequisites:
Introduction
PowerBuilder 5.0 ships with SQL Anywhere (formerly Watcom database), a
database engine. All the example applications that are shipped with
PowerBuilder make use of the databases created in SQL Anywhere.
PowerBuilder can talk to different data sources, i.e.
Relational Databases, such as Sybase SQL Server, Oracle, Informix, Microsoft SQL Server,
DB2, SQL Anywhere (Watcom), etc..
Databases such as FoxPro tables.
Other sources such as Text Files, Excel Spreadsheets, etc..
The reason Powersoft ships SQL Anywhere along with PowerBuilder at free of
cost is, SQL Anywhere has a small foot print. Which means that it needs less
resources and works on your desktop. So you can develop applications by
connecting to a database created in SQL Anywhere. Once completed, you
can port it to other data sources with minimal effort.
Once the database painter is open, PowerBuilder displays all the tables that
are available in the connected database. The following picture displays the
table and the view names which you see when connected to the example
database. If you would like to see system tables, you need to check
the "Show System Tables" checkbox.
Recall that objects you create in PowerBuilder are stored in PowerBuilder
library. The exception to that are the things you create in the database
painter --such as tables, indexes, views, etc.. They don't get stored in the
PowerBuilder library, instead they are stored in the connected database.
Creating a Database
To create a new database, select "File/Create Database..." from the menu
and provide name 'product' when prompted.
PowerBuilder automatically supplies the User ID as 'DBA' and Password as
'SQL' (remember, each asterisk takes the place of a letter in
the Passwordfield). Later, we'll see how you can set up users and
permissions for a database, but for now let's enjoy the power of a Database
Administrator.PowerBuilder also generates the necessary information to
start SQL Anywhere database engine by placing it in the Start
command box.
Column Attributes
Each column in a table has a range of attributes, such as column name,
datatype, width, decimals, etc.. To view/change the schema of the units
table, invoke popup menu on the table heading. The values that you can
supply to each attribute depends on the database to which PowerBuilder is
currently connected to. Remember, the tables/indexes/etc… you create here
are specific to the connected database and would be stored in that.
Name
This is the name that you use to refer to a column and it can contain any
alphanumeric characters, spaces and the underscore character. As explained
earlier, the rules vary depending on the connected database. You need not
worry about using invalid characters, PowerBuilder gives you an error
message if you do it.
It is a good idea to use some form of naming convention for column names.
It helps you to identify them quickly in the script. In our example
application, we've used the underscore character to separate words in the
column names. In some databases, table and column names are case
sensitive. We don't know why PowerBuilder doesn't allow you to type names
in upper case.
Datatypes
This attribute defines the type of data that will be stored in the column. For
a database based upon the SQL Anywhere engine, there are 14+ possible
data types.
These include most of the common types such as char, numeric, date and
time. For explanation to the more obscure data types, you should either
check PowerBuilder on-line help for the SQL Anywhere engine or the
appropriate manuals from other sources. The list of possible data types will
change depending on the type of database you are connected to and the
version of the database.
Width
This defines the width, or the maximum number of characters a column can
contain. It is a good idea to limit the width of each column, so as to limit the
amount of memory assigned to data storage. This use of memory can be
wasteful if large amounts are allocated to store small amounts of data.
For example, if you know that the surname of all your contacts would never
exceed 30 characters then limit the column to this size. Again, all surnames
may not be exactly thirty characters, so it is a good idea to select varchar
instead of char datatype. The difference being that a "Char"datatype always
takes the amount of space allocated to it irrespective of the data inside it.
On the other hand, "varchar" takes only the space that is needed to store
the actual data.
Null
Both NULLs and zero-length strings are used to indicate that an entry has
not been made. The distinction between the two entries is based on the
reason for omission. A NULL entry indicates that the information is unknown,
while using a zero-length string shows that the information is not available.
For example, you would use a NULL in a Phone field if you don't know
whether your contact has a phone, but use a zero-length string if your
contact definitely doesn't have one.
Values must be provided for all columns in the "units" table, so all columns
are defined as "NOT NULL".
Extended Attributes
Though the allowed value for each attribute differs from database to
database, all databases support the attributes explained previously.
PowerBuilder supports few more attributes called "Extended Attributes"
which are not part of the standard table definition. PowerBuilder stores all
the extended attributes in PowerBuilder specific system tables in the
connected database.
Going back one step, whenever you connect to a database for the first time,
PowerBuilder creates five tables namely "Pbcatcol", "pbcatedt", "pbcatfmt",
"pbcattbl" and "pbcatvld". PowerBuilder manages and stores all the extended
attributes in these tables.
the display and edit styles of the data stored in the tables.
Attribute Description
Format Used to alter the format of the data when it is displayed. An example of a widely used format
style would be the alteration of European date format to the US style of presentation.
Edit Used to specify an edit mask for a column. An edit mask allows you to define a template to
format the data in a pre-defined manner.
Valid This can be used to specify a validation rule for the data; something like, all numbers must be
less than 31.
Height Used to specify the height of the box which displays the data.
Width Used to specify the width of the box which displays the data.
Header Specifies a header for the column which is different from the field name. It is used in Tabular
and similar presentation style DataWindows.
Initial You can specify a default value for the column. An example would be to insert today's date if
the user left the field blank.
Label You can specify a label for the column which is different from the column name. It is used in
Freeform and similar presentation style windows.
Comment In this attribute, you can add comments for the column.
Format Styles
Format style specifies how the data should be presented. For example, you
might want to have two different format styles, one in millions format
(comma after every three digits) and another in metric format. Note that
these are specific to PowerBuilder. PowerBuilder stores these values in the
database. Other applications such as Excel, Visual basic, etc. don't have
these format styles. There are two steps in completing the format style
definition.
The symbols used in the format mask depends on the data type that has
been defined for the field. The symbols you can use for string and number
data types are as follows:
Note that the Format attribute doesn't limit the number of characters in the
field - we've already done this by specifying the width of the field in the
table definition.
@ X X Any character.
$#,###.##;[RED]($#,###.##)
This formatting will display a positive numeric input with a dollar sign,
thousand separators and two decimal places in the default font color. Any
negative inputs use the same formatting except that the font color is red.
For date and time data types, there are an extra set of formats that can be
used to display the data. The following table lists these extra formats:
Date Time
Symbol Meaning
Type Type
d X Day as a number.
m X Month as a number.
m X Minutes.
s X Seconds.
ffffff X Microseconds.
Edit Styles
An edit style is used to limit the type of data that can be entered into a
field, while affecting how the data is entered. For example, you can limit a
date field to the month/day/year format .
PowerBuilder comes with a lot of pre-defined edit styles. You can also define
new edit styles. You can define six different edit styles, such as:
DropDownListBox
DropDownDataWindow
CheckBox
Radiobutton
EditMask
Edit
All these edit styles behave similar to the corresponding window controls.
You find the attributes in the above picture available in the window painter
also. Define an edit-style as shown in the picture, since we would be needing
it.
Validation Rules
A validation rule defines what data is allowed in a column. Some of the
RDBMSes such as Sybase support validation rules in the server.
When a validation rule is defined in the server, irrespective of the client that
is trying to manipulate the data, server validates the data by applying the
validation rules. For example, let table "transactions" have
"transaction_type" column and you define a validation rule on the
"transaction_type" saying that the valid values are 'receipt', 'issue' and
'return'. Now, you want to enter/change the data via Excel, Visual Basic, a C
program, etc.. Unless you provide a valid data, server will not allow you to
change/enter data in the table. This is called 'server side' validation.
In PowerBuilder, you can define validation rules on the client side. It means
that when you provide the data, the client (PowerBuilder) validates the data
and sends the valid data to the database.
Difference between the client side validation and the server side validation is
that the validation rules defined in a client program is used only by the client
that defines it. In the above example, say you define a validation rule in
PowerBuilder and a Visual Basic client wants to change the data in the
server. Sybase will not validate the data, since the validation rule is not
defined in the server.
Then which is the right place to define the validation rules. It depends. In
the client/server environment the best thing would be to define at both the
places. Defining at the client will reduce a lot of network traffic. That is
because the client sends valid data, instead of sending it every time and
getting validation errors. Defining at the server would also be useful,
because, if you want to add a new client type, say Java, you don't have to
worry about wrong data.
To define a rule select "Design/Validation Rule Maintenance" from the menu.
Select New from the dialog box. Let us define a rule that the product number
should be greater than zero. Provide the name as shown in the picture and
select "Number" from "Type" DropDownListBox. You need to provide
definition for the 'Rule Definition' prompt. The keyword "@Col" contains the
value provided by the user. You can use functions available under
the "Functions" dialog box.
The @col stands for the value the user types in, so the rule states that the
length of the entry must be greater than 0. If the validation rule is broken, it
is useful to display an error message to guide the user towards the type of
input that is expected. This message is fully customizable, so try to make it
as informative and useful as possible.
Another facility that PowerBuilder provides for string data types is Match.
Using this option you can specify a range of specific values for a particular
position in the string. To see how it works, click on the "Match..." button.
The ^ (hat) symbol represents the beginning of the pattern, the dollar sign
($) represents the end of the pattern and you can specify the exact values
or range of values for any of the characters in between. We can use this
feature to refine our previous validation rule.
For example, the ISBN that corresponds to a Press book is 1874916 followed
by three digits, even though in certain circumstances the last one could be
an 'X'. The validation rule to test the ISBNs would be as follows:
^1874916+[0-9]+[0-9]+[0-9X]$
We can test the rule by typing a value into the "Test Value" box and clicking
on the 'Test' button. You can see that the ISBN 187491632X is a valid input.
If the input isn't valid, the test will detect it:
Click the OK button. Now the validation rule is defined. Once you define the
validation rule, you need to assign the rule to the columns for which it
applies. For example, you define a rule 'v_valid_product' that says 'value
should be greater than zero' and want to assign the rule to 'product_no' in
'product_master' table, then you need to click with the right mouse button
on the "product_no" in the "product_master" table and select 'Validation' tab
page and select the above defined validation rule. You can't do the same
right away since you haven't defined the table yet. Do it after completing the
exercises given at the end of the session.
Similarly you can assign edit and display format styles also.
It is not mandatory to define a primary key for every table, but if you don't,
you won't be allowed to enter data into the table from the data manipulation
screen in the Database Painter.
To define a primary key, click with the right mouse button on the title bar of
the units table to bring up the table properties dialog box and click on
the "Primary" tab page.
Once you create the primary key, PowerBuilder displays the primary key with an icon
( shown beside the heading of this section ). If you would like to browse about the
primary key, click on the icon.
To define a foreign key, click with the right mouse button on the table title
and select "New/Foreign key". You see a dialog box similar to the one shown
below. Provide a name in the "Foreign Key Name" prompt. Select the table
name that has the primary key, i.e., units table. PowerBuilder automatically
displays the primary key from that table in the "Primary Key
Columns"prompt. Select "product_measuring_unit" column from the
"product_master" table.
The radio buttons allow you to specify the effect of deletion of a row in the
Primary Table. There are three options:
Option Description
Restrict If there are dependent rows in the "product_master" table, database doesn't allow you to
delete a row in the "units" table.
Cascade If a row is deleted in the "units" table, dependent rows in the "product_master" table are
deleted.
Set Null If a row is deleted in the "units" table, then a NULL value will be placed in the
"product_measurement_unit" column of any dependent rows in the "product_master"
table.
Once you create a foreign key, PowerBuilder display the foreign key with an icon
( shown at the heading of this section ). If you would like to browse about foreign key,
click on the icon.
Creating Indexes
Indexes are used to speed up data selection from a table by restricting the
number of rows that have to be searched. For example, if you had a table of
contacts with a gender field and assuming you had equal number of male
and female contacts, then indexing this field would half the number of
records that need to be searched by a query.
You've declared the "unit" column as a primary key to uniquely identify rows
in the "units" table, so this is a logical choice for an index. Click with the
right mouse button on the title bar of the "units" table and
selectNew/index option.
Name the index as xunits and click on the "unit" column. You can specify if
the indexed column must contain unique or duplicate values and you can
also have the option of indexing in ascending or descending order. We want
a unique and ascending index, so accept the defaults and click on
theOK button to add the index to the table. Please note that, most of the
relational databases don't accept the ascending/descending options.
Once you create the index, PowerBuilder displays the index with the
index icon ( shown at the heading of this section ). If you would like
to browse about index, click on the icon.
Data Manipulation
To view the data that is stored in a table or to even alter/manipulate it, click
on the table title with the right-mouse button and select "Edit Data"option on
the "Preview" icon from the PainterBar. When viewing data, PowerBuilder
uses the default presentation style, but you can use different style by
selecting "Objects/Edit Data" from the menu and selecting the appropriate
presentation style from the cascading menu.
Once you are in the 'Data Manipulation' window, you can insert new data or
change/delete existing data from the table.
Any data that is added/changed are held at the client site, that is in your
computer's memory. To reflect the changes in the back-end database, you
need to select "File/Save Changes to the database" from the menu.
Pressing the TAB key when the cursor is in the "description" column will append a new row.
U unit
lb pound
in inch
gl gallon
Save the changes to the database by selecting "File/Save Changes to the
database" from the menu.
Importing Data
At the moment PowerBuilder supports importing data from two file formats,
namely tab delimited text and the. DBF format. However, it is likely that in
future releases more file formats will be supported.
For each row you import, PowerBuilder creates an INSERT statement and
when you click on the Save Changes icon, it sends it to the database. This is
a logged operation, so if you are importing large amounts of data, first
consider the memory on your local machine and the log space that would be
required for the database. If you are connected to SQL Server, you should
consider using a Bulk-Copy Program (BCP).
When the changes are saved , data will be written to the database. If the
table has an unique index and duplicate data is imported , PowerBuilder
doesn't display error at the time of importing. However, the connected
database will generate error while saving the changes back the database.
Exporting Data
We've seen how to import data from a tab delimited text file. It may occur to
you that it would be useful to export data to some other format. To allow
this PowerBuilder provides you with tools to support several popular file
formats.
You can see that we've the information from the units table in a standard
Excel spreadsheet.
The exporting feature can be very useful. We copied the table definition of
"product_master" table into our example database, in the same way you
could export the actual data from a table into SQL Syntax or a text file and
then import it into another table.
Sorting Data
From the Data Manipulation window, PowerBuilder can be forced to sort the
displayed data in alphabetical or numerical order. Select"Rows/Sort..." in
the "units" table.
We can also alter the sorting expression so that the data is displayed in
numerical order of length.
Filtering Data
Along with sorting the displayed data can be filtered. To perform this
select "Rows/Filter..."
An expression can be built using any of the available functions from the list,
fields in the table and a selection of mathematical operators. For example to
display the rows with a description of six characters or less, we would use
the following expression:
Only those rows that pass the filter criteria are displayed. It doesn't mean
that the rest of the data is gone, it is still available on the local machine and
there are no changes made to the back-end database. Remove the filter and
all the data will be displayed.
Most of the available functions are used with a particular type of data, so
you need to verify your expression for validity. Do this by clicking on
the"Verify" button.
While sorting, filtering, deleting and modifying data in the Data Manipulation
window, you may find it useful to see the summary of the things done to the
rows. You can see it by selecting "Rows/Described..."
Zooming
After you have sorted and filtered data, you may want to change the size of
the display on screen. To do this select "Design/Zoom..."
You can print or preview the current display using the standard "File" menu
options of "Print..." and "Print Preview". In Print Preview mode, you can turn
on the "Print Preview Rulers" to let you adjust the margins and using
the "Print Preview Zoom..." feature you can alter the magnification.
Both these options are selected from the "File" menu. Note that any
magnification changes that are made in the "Print Preview" mode are
discarded when the "Print Preview" is turned off and the display returns to
the size before the "Print Preview".
Using Logs
If you are curious to see the SQL (Structured Query Language, pronounced
as 'sequel') statements that are used to create a table you would be
interested in the logs. All DBAs save the schema to an ASCII file for future
use. To see the statements that created the "units" table, select the table
"units" and select "Object/Export Syntax To Log...". When the dialog box
asks you to specify the data source, click OK. An Activity Log icon appears at
the bottom of your screen.
If you double-click on the icon, it will bring up the SQL syntax which was
used to create the table.
Scroll down the screen to see the full syntax and appreciate the simpleness
in creating a table using the Database Painter rather than using a character
based SQL utilities such as ISQL.
You might wonder why you'd want to look at these SQL statements. If you're
not familiar with SQL, it is a good method of learning the language,
moreover there is a practical reason - it allows us to copy tables from one
database to another.
PowerBuilder doesn't provide you with the ability to 'cut and paste' tables
from one database to another. You must either manually reproduce the
tables or use the logs to recreate them automatically .
Table Description
Name
PBCATTBL Contains the font information for the text, labels,headers and so
on.
PBCATCOL Contains details of the extended attributes for each column in
each table in the database.
PBCATFMT Contains definitions of the available formats.
PBCATVLD Contains definitions of the validation rules.
PBCATEDT Contains definitions of the edit styles.
The following picture illustrates the PowerBuilder system table columns and
primary keys.
Database Administration Painter
Remember you sorted and filtered data in the data manipulation window.
There both sorting and filtering was done by PowerBuilder and not by the
connected database. You can restrict and sort the results from the connected
database by using WHERE and ORDER BY clauses in the SELECT statement.
In data manipulation window and database painter custom built SELECT
statements cannot be executed. It is possible only in the database
administration painter.
The commands that can be executed in the database painter are limited to
the boundaries of the painter i.e. table/view definitions and so on. Complex
SQL statements can be run in the connected database.
Executing SQL Statement
Please notice the single quotations around 'U' in the query. For some
databases such as Sybase SQL Server/MS SQL Server, it doesn't matter
which quotations you use. But, for Watcom SQL/SQL Anywhere, you
have to use single quotations. Double quotations are for columns or
tables/view names. In MS SQL Server, from version 6.0 onwards use
appropriate quotations i.e. use double quotations so that SQL Server
interprets the special characters before it runs the query. If you don't
want SQL Server to interpret the special characters within the quotations
use single quotations.
Query Plan
To optimize a query one would like to know details such as how much I/O it
needs or which indexes it uses and so on. For that select"Design/Explain
SQL" from the menu.
Commenting Code
Sometimes, you might have big tables with long column names. We can't
remember each and every column and table/view name. PowerBuilder allows
you to paste SQL Statements in the database administration painter. For
example let us paste the SELECT statement we wrote above by
selecting "Edit/Past SQL" from the menu.
The next option "Operator" lists all the allowed operators in the connected
database. It defaults to '='. That's fine for this query.
Type 'U' under the value heading. Before you paste this SQL, you may want
to see it. Click on the "Syntax" tab page to list the SQL Syntax created as a
result of painting.
At times you may like to view/paste the source of a stored procedure. You
can do so by selecting "Design/Procedure Syntax". Select the procedure
name by clicking on the stored procedure name. The source is displayed in
the Syntax box. To read the source click on the Cancel button ( after reading
the syntax ). To paste the syntax click on the OK button.
Maintaining Users/Groups
Database Profiles
Remember the first thing we did in the session "creating a database". From
there on everything that was created is stored in the "product" database.
When creating a database there are few things that happen behind the
scenes.
All profile file names have ".ini" extension. When you install PowerBuilder, it
installs few ".ini" files such as pb.ini, pbodb050.ini, etc.. Each profile file is
logically divided into sections.
Each section name is enclosed in a square bracket. All the variables and
values related to a section are listed under that section. Under a section,
each line consists of a variable name and its value separated by a '='.
Following is a listing of two sections from pb.ini file.
[Database]
DBMS=ODBC
Database=product
UserId=dba
DatabasePassword=
LogPassword=
ServerName=
LogId=
Lock=
DbParm=Connectstring='DSN=product'
Prompt=0
Vendors=ODBC,SYB SQL Server v4.x,SYC Sybase System 10 CTLIB,IN5 I-Net v5.x,MSS (Msoft)
SQL Server 6.0,O71 ORACLE v7.1
AutoCommit=0
AutoQuote=1
Columns=8
ForeignKeyLineColor=0 0 255
IndexKeyLineColor=255 0 0
PrimaryKeyLineColor=0 128 0
NoCatalog=No
ReadOnly=0
ShowIndexKeys=1
ShowReflnt=1
StayConnected=1
TableDir=1
TableListCache=1800
TableSpace=*
TerminatorCharacter=;
HideComments=0
ShowRefInt=1
pipeline_default_source=4
StripComments=0
LEXICON=
[DBMS_PROFILES]
CURRENT=Product
PROFILES='Product','Powersoft Demo DB V5','ABNC Main DB V5','ABNC Sales DB V5'
History='Product','Powersoft Demo DB V5','ABNC Main DB V5','ABNC Sales DB V5'
[PROFILE Product]
DBMS=ODBC
Database=
UserId=
DatabasePassword=
LogPassword=
ServerName=
LogId=
Lock=
DbParm=Connectstring='DSN=product'
Prompt=0
AutoCommit=0
Any additional entries that you can add to the DBPARM are in the realms
of SQL Server rather than PowerBuilder. Please refer to the SQL Server
or to other back-end database server manuals for more information.
You don't have to create separate profiles for every database that you want
to connect to. If you check the "Prompt for Database information during
connect"option on the profile setup screen, you'll be prompted to select the
name of the database you intend to connect whenever you connect using
that profile,.
If the ODBC configuration file is not existing for a specific database, you can
configure ODBC right from this dialog box.
Infact, they can remove 'File/Configure ODBC...' menu option in the
database painter, since that option is already available in this dialog box.
ODBC
Microsoft's Open Database Connectivity standard defines a standard SQL
grammar and two sets of function calls based on the SAG CLI specification.
They are named core grammar and core functions respectively. It allows you
to connect to a vast array of database systems.
ODBC Architecture
In general the realm of ODBC can be split into four major components:
Application.
Driver Manager.
Driver.
Data Source.
Each of these components fit together to make a bridge between the two
resources that are needed to exchange data:
Application
This is the program that is used to access data from the back-end database,
typically running on the MS-Windows Operating system ( and the back-end
database can be located anywhere ). When looking at an ODBC setup a
PowerBuilder application which accesses data from Sybase SQL Server can
be considered as the application. Any ODBC functions that you need to call
are made from the application.
Driver Manager
The driver is the heart of ODBC. It takes care of network protocols that are
required to connect to the data source. It also translates and submits the
SQL statements to the data source.
Note that there are currently three standards for SQL: ANSI '86, ANSI '89 and ANSI '92. This has
lead to the proliferation of 'flavors' of SQL and prompted the need for this ODBC translation
layer. It is therefore at times necessary for the ODBC driver to translate between these
standards for effective communication between the application and the database.
This is an ASCII file which contains the DBMS name and other necessary
details such as Login Name, Password, the location of the database to
connect to and as well as any DBMS specific parameters. In the case of
Sybase SQL Server, you may be specifying the Server Name, Database
Name, Server Login ID, Password and other DBMS specific information such
as application name to display in the server's connection list and so on.
ODBC takes care of finding the SQL Server address on the network and
connecting to the SQL Server by looking into the win.ini file or windows
95/NT registry or sql.ini file.
The interesting feature of ODBC is that you can connect to more than one
data source from the application at the same time by simply using another
profile.
The ODBCINST.INI File
When you first install PowerBuilder, you are prompted to select the ODBC
drivers that need to be installed. The selected drivers are installed in
theWINDOWS/SYSTEM directory and the ODBCINST.INI file, which
contains the list of installed drivers gets updated. The [ODBC Drivers]section
of this file contains a list of the installed drivers.
PowerBuilder uses this information to set the driver options when you
configure ODBC.
[product]
Driver32=c:\PowerBuilder\pb5i32dk\WOD50T.DLL
This section has the DLL name along with the path. When you specify ODBC
as the DBMS in the profile, the ODBC Driver Manager scans this file for the
profile name and loads the appropriate driver.
A word of caution, it is important that you never try to manually alter any of the entries in
any of the .INI files, doing could have a serious effect on your ability to connect to your
databases.
Its not necessary that you fill in User ID and Password options, but if you don't then every time
you connect to this database you will be prompted for your User ID and Password. When you
distribute an application, the database profile an application uses is very important for purpose
of security - you only want users with password to get access to the database!
Click the Cancel button and exit from the database painter.
Summary
In this session you have learned about connecting to the database from PowerBuilder, creating
databases, tables, indexes and PowerBuilder extended attributes. You also learned executing SQL
statement directly in the administration painter. For a complete summary of this session, browse
'database-painter.ppt' PowerPoint presentation.
Database Painter Exercises
You need to create the following objects. The left most column in the
following table lists the object that you need to create and also has the link
to the deatil list of those objects. The second column lists the files that have
SQL statements to create those objects. You can use these files in two
different ways. One, you can execute them in the database administration
painter and objects will be created for you. We don't recommend this way.
Instead we would like you to create those objects and export those object
definitions and compare with the SQL that is listed in the files(second
column). The thid column lists the files that inserts sample data into those
tables. The data is also displayed in the picture for each table.
Tables:
Table Name SQL to create table, index SQL to create Data
units units.sql units-data.sql
product_master product_master.sql product_master-data.sql
trans trans.sql trans-data.sql
product_images product_images.sql None
Edit Styles
e_tran_type
Validation Rules
v_no_empty_column
v_no_zero_column
"units" Table
Create the 'units' table as shown in the following picture and enter the data
as shown.
Property Value
Primary key unit
Index Name xunits
Index Columns unit. Ascending, Unique
"product_master" Table
Create 'product_master' table as shown in the picture and enter the data as
shown.
Property Value
Primary key product_no
Index Name xproduct_master
Index Columns product_no. Ascending, Unique.
Foreign Key Name: fmeasurement_unit
Foreign Key product_measurement_unit referring to unit in the units table
Data
"trans" Table
Create 'trans' table as shown in the picture and enter the data as shown.
Property Value
Primary key tran_no, tran_serial_no
Index Name xtrans
Index Columns tran_no, tran_serial_no. Ascending, Unique.
Index Name xtrans2
Index Columns tran_date. Ascending, Duplicate.
Foreign Key Name: ftran_item_no
Foreign Key tran_item_no referring to product_no in product_master table
Data
'product_images' Table
Property Value
Primary key product_no
Index Name xu_product_images
Index Columns product_no. Ascending, Unique.
Foreign Key Name: fproduct_no_images
Foreign Key product_no referring to product_no in product_master table
Once you define all the above tables, it should look like in the following
picture:
In this session ( the first two devoted to this topic ) we'll introduce you to
the DataWindow Painter environment and show you how DataWindows are
used to retrieve information from a data source. We'll also cover various
methods of retrieving data and cover some of the options which relate to
them.
Building a DataWindow.
Connecting to a database.
Working with different data sources.
Importing and exporting data.
Using stored procedures.
Using different presentation styles.
Using the Design environment.
Using the DataWindow options.
Prerequisites:
Introduction
A DataWindow is a data aware object and is used to retrieve, manipulate
and display data from a database. DataWindow reduces to a minimum the
need for the code ( which has been specially developed to get the data from
a database into a presentable format on screen ) by internally creating
native database related commands.
There are two main parts to a DataWindow - retrieval of data from the
database and display of that retrieved data. Let us start with how to connect
to a database and retrieve the data and then we can learn how to present
the data in different styles.
1. Select a data source and a presentation style. In other words the way data is to be extracted from a
database and the format in which the data should be displayed.
2. Define appropriate SQL statements which would provide information to the user; this is referred to as
the 'Data Source' definition. In data source you define the data to be brought from the database, for
example a SELECT statement to retrieve all product information.
3. Paint the DataWindow (define fonts, colors, location for each field, etc.) to appropriately display the
information.
4. Associate the DataWindow object with a DataWindow control (you have learned about this control in
the window painter) on a window, so that the data held in the object can be displayed to the user.
Creating a DataWindow
To invoke the DataWindow Painter, click on the DataWindow icon from
the PowerBar. As this painter deals with the retrieval of information from a
database, PowerBuilder automatically connects to the last database used.
When connected to the database, create a new DataWindow by clicking on
the "New"button. PowerBuilder presents the following.
While designing a DataWindow object, the three main views that cross path
are:
Preview
Design
Select
Each of these views are used to look at the contents of the DataWindow in a
different way. Using "Preview" you can have a look at the data chosen from
the database with the commands in the "Select view", in a format defined in
the"Design view".
Preview View
To see the data that is the result of the SQL statements defined.
To review the layout of the data - this is the layout that appears in the DataWindow control on the
window.
Select View
In this view you define the SQL statements. The screens seen in this view
would be different depending on the type of data source selected in
the "New DataWindow" dialog box. Once the data source is defined, you
move onto"Design View".
Design View
PowerBuilder displays the default layout of the DataWindow based upon the
presentation style selected in the "New DataWindow" dialog box. The layout
can be changed according to the needs. Once happy with the data layout
move to"Preview view" ( explained earlier ) to preview.
Quick Select
SQL Select
Query
External
Stored Procedure
The interested table and the associated fields are selected by highlighting
them. PowerBuilder will add the selected fields in the box at the bottom of
the window. To further refine the information that is returned to the
PowerBuilder application specify a sort order (either ascending or
descending) and any selection criteria for each column.
SELECT
"product_master"."product_no",
"product_master"."product_description",
"product_master"."product_balance",
"product_master"."product_reorder_level",
"product_master"."product_measuring_unit"
FROM "product_master"
WHERE ((("product_master"."product_balance" <= 200)
AND ("product_master"."product_measuring_unit" = 'U'))
OR (("product_master"."product_balance" >= 450)
AND ("product_master"."product_measuring_unit" = 'GL')))
ORDER BY "product_master"."product_measuring_unit" ASC
You can also use the keywords AND and OR in a criteria for a column.
PowerBuilder automatically converts this graphical definition into SQL syntax
before requesting the information from the database. While performing this
conversion it looks at the layout of the criteria and places ANDs and ORs in
the appropriate places in the SQL statement.
A criteria can contain names of other columns in the table. This allows us to
compare two 'dynamic' values rather than having to stick with static entries
(constant values). For example, we could have specified a criteria that
required the 're-order-level' to be greater than the 'balance'.
Click on the OK button. You will be taken into the design mode. The layout
here represents the "FreeForm" presentation style. Let us don't go into
details about the layout since we will be learning about it in
the "Presentation Styles"section, so don't do anything at this time.
Switch to preview view. If there is no data enter few rows and save the
changes to the database by selecting "File/Save Changes to Database" from
the menu. Switch back to the design view. Close the DataWindow painter. If
you would like to save it do so.
Invoke the DataWindow painter again, select 'New' from the 'Select
DataWindow' dialog box and select "SQL Select", "FreeForm" and
click OK button. PowerBuilder presents the tables/views available in the
connected database. Select "product_master" and "trans" and
click "Open" button.
When the tables having foreign key relationship ( defined in the database )
are opened, PowerBuilder automatically displays the join icon and also
creates the SQL statement with the join.
The join in the above picture bring all information from the "trans" table and
also pulls the "product_description" from the "product_master" table. All
the "selected columns" appear in the 'Selection List' at the top of the
window. To rearrange the columns click on the column name (next to
the "Selected Columns" ) and drag and drop at the place where the column
is to be placed.
Where Clause
Note that you don't have to supply the quotation marks around the value.
PowerBuilder decides if it is needed based on the type of data and will add
them as needed.
Sort
This is where you specify a sort order for the columns you want to display:
PowerBuilder displays all the selected columns in the list on the left-hand
side. By dragging the columns from left to right, you can define the sort
criteria for them.
For example, we could sort based on "tran_date", simply by dragging it from
the left to the right column.
If there is more than one column in the sort order, the connected database
will sort on the first column in the list, then the second and so on from top to
bottom.
Group Clause
This allows you to group your data on one or more columns. For example,
you might choose to group your data on transaction type. This might be
useful for departments interested in a particular transaction type. Grouping
allows you to put more structure into the data by simply rearranging them.
When using SQL Anywhere database, you must include every non-aggregate
column that is to be displayed in the GROUP BY clause of the DataWindow.
This effectively invalidates the usefulness of grouping data, but with other
databases, it isn't necessary to include all the columns in the GROUP BY
clause.
Having Clause
It is used to specify criteria for a group and is created similar to the WHERE
clause. As an illustration we could further refine the above example to
select rows whose total receipts of transaction is more than 100.
You can see that the structure is exactly the same as the WHERE clause. Our
DataWindow is quite simple so we don't need to specify any extra criteria.
This clause is seldom used with SQL Anywhere database because of its poor
support for the GROUP BY clause ( Actually that's not poor support. They are
sticking to the ANSI standards where as Sybase SQL Server enhances the
ANSI SQL and allows you to do so ) .
Compute Clause
This allows defining of computed columns based upon one or more existing
columns. For example, to show the balances that are above the reorder level
you can say "excess_balance = product_balance - product_reorder_level".
Don't get confused between Sybase's transact-SQL computed columns with
COMPUTE clause in the SELECT statement. Right-clicking on the "Computed
Column", PowerBuilder brings up a menu. It allows you to select columns
from your tables as well as predefined PowerBuilder functions.
Syntax
The final tabbed dialog box displays the SQL statement created by
PowerBuilder. It is based upon the entries made in the other tabbed dialog
boxes.
The SQL statements can't be editted from here. If you know SQL and prefer
to type the syntax then select "Design/Convert To Syntax" to display the full
editable SQL. Here you can edit the SQL and if you want to see the edited
SQL in the graphical format, you can do so by selecting "Design/Convert to
graphics" from the menu.
When you are creating a SELECT statement, you can ensure that no
duplicate rows are displayed by specifying "Distinct" from
the "Design" menu. PowerBuilder adds the word DISTINCT after SELECT and
will return unique rows only in the resulting subset of information.
There won't be a match if two columns with NULL values are compared
for equality in a WHERE clause. If you are using one of the more flexible
database engines, you can get around this problem by using the
DISTINCT clause.
When using SQL Anywhere SQL, specifying DISTINCT automatically sorts the
result sets, but this isn't true with SQL Server and is something that should
be noted when porting applications from one database to another.
Retrieval Arguments
This query is called hard-coded query. Take the case where the user wants
to retrieve details of another transaction type. You got to write another
query. Well, that can be done, but then it's not efficient programming.
Instead write a generic query and accept input from the user and return the
results depending on the input. For example, you can rewrite the same
query as:
The above query is what you type in PowerBuilder. For example, if user
specified 'T', PowerBuilder replaces ":UserInput" with 'T' and sends the
following query to the database.
Even before using variables in the SQL Statements you need to declare the
variable by selecting "Objects/Retrieval Arguments..." from the menu.
Supply the name "tran_type" and specify the data type as String.
Once you define the retrieval arguments, you can use them in the query by
invoking the popup menu in the Value option and
selecting "Arguments" option.
Note that once a retrieval argument is specified, the same will be used
until the close of the current session or re-query the database by clicking
on the Retrieve icon from the PainterBar.
Joining Tables
The join operation is the hallmark of the relational database model. More
than any other feature, a join distinguishes relational database management
systems from other types of DBMSs. We've seen how PowerBuilder
automatically joins database tables which have the appropriate primary and
foreign keys defined, a process that is graphically depicted in the SQL
SELECT DataWindow between the "product_master" and "trans" tables:
Join Description
Equi or A relationship between two tables where the values in the two critical columns are compared
Natural on the basis of equality, with all the columns in both tables appearing in the results set. Note
that only one of the two joined columns is included, as they are identical.
This is the default join created by PowerBuilder.
Theta Theta joins use the comparison operators as the join condition. Comparison operators include
equal (=), not equal(!=), greater than(>), less than(<), greater than or equal to (>=) and less
than or equal to(<=).
Self A join used for comparing values within a column of a table. Since this operation involves a
join of a table with itself, two temporary (correlation) names are to be given to the table. The
correlation names are then used to qualify the column names in the rest of the query.
Outer A join in which both matching and non-matching rows are returned. The operators *= and =*
are used to indicate that all the rows in the first or second tables should be returned,
regardless of whether or not there is a match on the join column.
If primary and foreign keys are not defined for the tables, PowerBuilder
will try to join the tables based on common column names. You should
be aware of this, but it isn't bad as you can easily delete any unwanted
joins.
Saving as a Query
You may want to save a defined SQL SELECT statement for future use. The
simplest way to do this is to save it as a query for re-use. Select "File/Save
Query" or "File/Save QueryAs..." from the menu.
A query is stored in the PowerBuilder library, along with all other objects in
the current application, as opposed to saving it as a text file containing the
SQL statements themselves.
You can also create queries outside the DataWindow Painter; this
environment is called the Query Painter. You can then choose to create a
DataWindow based upon an existing query. We'll look at this next.
Create a new DataWindow and this time select Query as the data source.
PowerBuilder asks for the name of the query on which the DataWindow
should be based. Select the query that we just saved and click OK. If this
DataWindow is previewed, the "Specify Retrieval Arguments" window will
popup for the transaction type. If you type in 'R', PowerBuilder will show a
preview of the DataWindow.
The reason we use DataWindow even though we are not dealing with the
database is its power. It has a good sorting, filtering, printing, and whole lot
of other good features which work efficiently with only few lines of code.
Once you select the stored procedure, PowerBuilder displays the stored
procedure definition at the bottom of the window. PowerBuilder
automatically detects the result set of the stored procedures and defines
them. Just in case, to define the result set manually, select the "Manual
Result set" option.
Note that the stored procedure option is available only if the database to which you are
connected to supports it.
Select "dbo.sp_tables" stored procedure and click the OK button. This will
take you to the design view. when you comeback to the data source by
clicking on the icon, you see the result set of the stored procedure, as
shown in the picture below. Click "More" to see more details. Here, you see
the actual SQL statement that PowerBuilder sends to the connected
database.
Note that a stored procedure can return multiple result sets. By default,
PowerBuilder brings the first result set and the result set definition also
reflects to the first result set. To retrieve another result set, set it in
the "Result Set" option.
You can group any number of stored procedures and give them the same
name. When you do that you need to assign a number for each group
member. While executing if the group number is not specified, Sybase
automatically executes the first member in the group. To execute a specific
group member, specify the group no. after the stored procedure name
separated by a semicolon, similar to the above statement.
To accomplish this, we will look at the various presentation styles that are
built-into PowerBuilder, and also how and when each style should be used.
Just as there are several ways of populating DataWindows, there are several
ways of displaying that information. PowerBuilder provides us with a wide
variety of presentation styles, each of which can be used in different
situations to provide the best layout.
We will look at each of those in turn before we look at the design view of the
DataWindow Painter, and create some DataWindows that we will be using in
our 'Product_Management_System' application
This is the 'Design View'. Design view allows you to define what goes where
in a DataWindow. It is split into several bands depending on the type of
presentation style you are using. You can see/design the contents of a band
just above the band with the band name and an arrow next to it. For
example, all the product details shown in the above picture is in the detail
band. You can see that there is nothing painted in other bands. For getting
sufficient space in the header band to paint, click on the band and drag it
down. The following table explains different bands in the DataWindow.
Band Description
Header Displays a title at top of each page .
Header Used in Crosstab and Group styles to display group headers. ( Not shown in the
group picture.)
Detail Contains the main body of information. At design time one record is painted. In
Preview or at run-time, this band will repeat as many records as the query brings.
Trailer Used in Crosstab and Group styles to display group trailers. ( Not shown in the
group picture.)
Summary Can be used to display the summary and is printed at the end of the report. Can be
used to print report totals/averages, etc..
Footer Displays the page summary such as page no, page totals/averages, etc. at the bottom
of every page.
In the above picture, the right side column where each field is displayed in
shadow boxes, represent the columns from the database. That means, when
the DataWindow is previewed, fields from the right side column will display
the actual value. ( It can be seen in the following picture. )
The left side column where each field is displayed in boxes, represent labels
for each column. Remember specifying PowerBuilder extended attributes in
the database painter? The labels specified in the PowerBuilder extended
properties are used to create labels in the DataWindow. Sometimes you may
want a different label. Well, click on the specific label to change and type
new text.
If the above statement is the data source, the name for the data field ( right
side ) would be "product_description" and the name for the label would be
"product_description_t".
If the above statement is the data source, the name for the data field ( right
side ) would be "desc1" and the name for the label would be "desc1_t". In
database terms, the name "desc1" in the SQL statement is called aliasing.
The syntax for aliasing a column might differ from database to database.
The above example followed the Sybase/MS SQL Server convention.
Let us see how the data looks like in this presentation style. We know that
there is no data in the tables. Switch to preview view by clicking icon,
enter few rows by clicking icon, save changes to the database by
selecting "File/Save Changes to database" option from the menu.
Remember that product_measuring_unit is the foreign key from units table. That
means, values you enter in the product_measuring_unit should exist in the units table.
We typed few rows in the units table while learning the database painter. If you didn't
enter data in the units table and get error while saving product_master, create a
freeform presentation style DataWindow for units table, by following the steps listed at
the beginning of this section. Go to preview mode and enter few rows, save them to the
database and close the DataWindow painter for the units table. You will be back to
where we were.
Come back to the design view by clicking on icon. Now let's paint the
company information in the header band. Click on the header band and drag
it down till you have sufficient space.
Freeform style is similar to the database forms and is best suited for data
entry rather than data display. However, to display data one record at a time
for close examination, this style is recommended
In the free form presentation style, labels are used for data fields and are
placed in the detail band along with the data itself. In tabular presentation
style, headings are used and are placed in the header band.
This style is often used for reports, grouping columns and for DropDown
DataWindows. The number of columns and rows displayed on the screen at
any point of time depends on the size of the DataWindow control.
Grid Presentation Style
Invoke the DataWindow painter but select "Grid" instead of "Tabular".
DataWindow generated with the Grid presentation style is similar to the one
with Tabularpresentation style, except that its rows and columns are
separated by grid lines:
The added advantage with the Grid style is that, at execution time users can
resize columns and can even move entire columns around by clicking and
dragging the column heading.
Unlike the Tabular and Freeform styles, headings and columns cannot be moved in the
design view of a Grid style DataWindow. If new columns are added in the SELECT list
by editing the data source, they will always be appended to the existing columns even if
placed between existing columns. To reorder the columns, switch to preview, move the
columns and switch back to design view. Any changes made in the preview mode will
be reflected in the design view.
Whenever you invoke the popup menu on an object, you see the properties
of that object. To see the properties of the DataWindow itself, you need to
invoke the popup menu by clicking with the right mouse button on the
empty space.
PowerBuilder makes this style even more flexible by allowing alteration of
the basic grid characteristics. You can choose to:
Note that the trailer summations are always added to the DataWindow, even if the data that
is presented doesn't warrant such an addition. For example, in the above picture,
PowerBuilder is adding "product_balance" column, which doesn't make sense, since
products have different measuring units. Fortunately, we can modify the presentation styles
and so it is possible to remove the useless trailers.
PowerBuilder displays the data from left to right and then top to bottom as
you see in the example above. PowerBuilder doesn't allow you to alter this
organization, since there isn't any option to display the data from top to
bottom and then left to right.
Once you specify the number of records for the detail row and switch to the Design
View, you can't change the number of records. If you want, you need to do so from
scratch.
You can choose from a vast selection of pre-defined label sizes or create a
custom label size. You can also alter the spacing, number of labels per page
and specify top to bottom or left to right display. Unlike the "N-Up"
presentation style, you can change the specification even when you are in
the design view, by invoking the popup menu by clicking on an empty space
in the DataWindow or by selecting "Edit/Properties" from the menu.
Say for example you want to print a report that lists all the products and
quantity issued each day. That means, you list all the products one per each
row, and list the dates horizontally. Remember, each month has different
number of days, 28, 29, 20, 31. ( 20 is not a mistake, if the report is
generated on 20th of a month, then the report should list dates only till 20th
). That means you need to paint four reports and use the appropriate one
depending on the month. To print only those dates in the heading for which
there is data is really a tough job. Let the report you want look like:
To create the DataWindow, follow the same steps you followed for the
previous DataWindows, but select "Crosstab" presentation style. This time,
select "trans" and "product_master" table. Paint the data source as shown in
the following picture:
Invoke the DataWindow painter and select "Graph" and "SQL SELECT" and
select "trans" table. We assume that by this time you might know how to
paint SQL SELECT statements. Paint the data source so as to get the
following SELECT statement.
SELECT "trans"."tran_date",
"trans"."tran_type",
"trans"."tran_item_no",
sum( tran_qty )
FROM "trans"
WHERE ( "trans"."tran_type" = 'R' ) AND
( "trans"."tran_item_no" = 1 )
GROUP BY "trans"."tran_date",
"trans"."tran_no",
"trans"."tran_type"
You can type "sum( tran_qty )" in the compute tab page.
Go to the design view. PowerBuilder prompts for the properties of the graph
as shown in the following picture.
Actually this can be done with a SQL join and a single DataWindow.
Presentation becomes a problem. To overcome that, create a freeform
presentation style DataWindow for "product_master". Select all columns for
product_no 1. Save this DataWindow as "d_product_master_test". Create a
tabular DataWindow using "trans" table, select all columns from the table for
tran_item_no 1. Save this DataWindow as "d_trans_test".
Invoke the DataWindow painter and select "Composite" presentation style
and click OKbutton. Here, data source cannot be selected. PowerBuilder
prompts you for DataWindows. Select "d_product_master_test" and
"d_trans_test" in the same order. It would look like:
Nested Reports
Let's consider a business requirement where a user wants to print all
products from the 'product_master' table and transactions for each of those
items. His specification being that the product information ( from
product_master ) be listed on the left side, one field per line like the free
form presentation style and transactions ( from trans table ) be listed on the
right side, one transaction per line like the tabular report, i.e. something
similar to the picture show below.
To think about it, he is asking for a combination of a free form and tabular
presentation styles, which is not possible, since you can specify only one
presentation style per DataWindow. One solution is, choose tabular
presentation style and arrange all fields from product_master one per line
and place all fields from trans side by side, as shown in the following picture.
The idea is good. However, you find the problem only when you preview the
DataWindow. You waste space, since each record takes the sum of the
height of fields from product_master and the spaces between them.
When you preview the DataWindow, it might be different from the picture at
the beginning of this page, i.e., you might find the horizontal line you placed
at the bottom of the detail band appear at incorrect places, may be crossing
the transactions. Don't worry about that for a now, you find the solution
later in this session.
One thing you might notice is that, the fields are placed in the detail band,
as in a free form presentation style DataWindow. However, the labels to the
fields are not named, instead the labels are free text. Text can be typed
anywhere, and you no longer have to insert a text object to display a text.
Think this presentation style as a mini MS-Word program. The fields are
enclosed in curly brackets. Click on the field and it blinks. Unlike other
presentation styles, double-clicking on the field name doesn't invoke the
properties dialog box. Invoke the popup menu and choose 'Properties'
option.
Things that might surprise you would be, for input fields you can no longer
choose the edit style from a variety of edit styles --such as DDDW, DDLB,
EditMask, RadioButton, etc.. AutoSizeHeight property is no longer available,
but each field has 'AutoSizeHeight' feature enabled unless you choose 'Fixed
Width' option. Summary band is not available in this style. Objects such as
Sum() and Avg() can't be inserted in this style, though computed fields can
be created and used in them. Please note that, inserting a report in this style
is not permitted.
For example, if 'trans' has say 100 rows, of which 40 rows are of type
receipts and 60 rows are of type issues. By giving
database server sends only 40 rows. However, if you issue the first SELECT
statement and filter it in PowerBuilder, the database server sends all 100
rows and PowerBuilder filters out 60 rows and displays only 40 rows. What
exactly does that mean? It is reducing load on server in terms of searching
for eligible rows (all receipts), however, it is increasing load on the server
since it has to read all the rows and send all the rows to the client. Since
database is sending all the rows to the client, the network traffic is
increased, which is not good. Basically, filtering on the client side is good
only if the user wants to filter data from the result set.
Similarly, the whole sorting load can be moved away from the database, by
selecting "Rows/Sort" from the menu and specifying the sort criteria. If the
sort order is specified using the ORDER BY clause in the SELECT statement,
the database server sorts the results before sending them to the
PowerBuilder application. To move all the sorting load to PowerBuilder, do
not specify the ORDER BY clause, instead move the criteria to the
'Rows/Sort' dialog box.
Let's take the same example of 'trans' tables with 100 rows, of which it has
40 receipt rows and 60 issue rows. If you issue:
The database server sends the same number of rows to PowerBuilder in both
the cases. So, there is no increase or decrease of the network traffic .
However, in the first case, the database server sorts the results before
sending it to the client and in the second case, it doesn't sort the results.
Which one to choose? Good question. It depends on the type of client your
company wants to implement, a fat client or a thin client. For fat client, the
second statement will do and for thin client the first statement.
In another situation, may be you want to bring the whole data from a table
which has say 20,000 rows. The memory may not be enough to bring all
that data. Hence, select "Rows/Retrieve/Rows to Disk" from the menu.
PowerBuilder writes the data to the disk as it retrieves and you will not get
'Your system is running out of memory, Please close some applications' error
message from the MS-Windows operating system.
Suppressing Repeating Values
Sometimes you don't want to show repeating values, instead you want to
display them once. For example, the following picture retrieved a full
transaction. As you see, the tran_no, tran_date and tran_type is same for
each item in the transaction. You may want to show those details only once.
Here add, insert or delete any of the information which is saved in the
DataWindow and if the database is ready, you can also retrieve data from
the database and store it along with the DataWindow definition in the
PowerBuilder library painter.
Note that any changes made to the information at this point won't affect the data contained
in the database. This is simply another layer of data control which allows you to refine
information displayed in the DataWindow. In most cases, you would not want to alter data
at this level, as you must have already refined your data set in the appropriate SQL
statement.
DataWindow Options
You should now be confident by now to create your own DataWindow using
various presentation styles and data sources. In this section, we'll run
through some of the other options available both in Design view
and Preview.
Column Specifications
Similarly, validation rules and validation messages. You can notice in the
above picture that PowerBuilder automatically changes the validation
definition depending on the datatype. For example, we created
"v_no_zero_column" as "@col > 0", for which the datatype was a "Number".
Here the same definition is changed to "real( GetText()) > 0". That's because,
the value entered by the user is always in a string format. Before comparing
it with a numeric value, we need to convert it into a number. More
on GetText() in the PowerScript session.
Now to other properties. Sometimes, you may have image file names in the
database and images itself outside the database. For example, let's assume
that "product_master" has a column "product_image" which contains the
images file name. When a DataWindow is created and viewed, PowerBuilder
displays the image file names. It would be appropriate if it displays the
image instead of the file names. This can be done very easily. Click with the
right mouse button on the column name and invoke the properties dialog
box and turn on "Display as Picture" property in the "General" tab page. In
this case, PowerBuilder takes the column value as the name of the image file
( the image file name should have proper PATH included otherwise
PowerBuilder looks for the file in the working directory ) and reads the image
from the disk and displays it.
By default all columns have "Edit" edit style, unless defined otherwise in the
database painter. All the edit styles you saw in the database painter are
available in the DataWindow painter. We are not going into details of each
edit style, because, it was already done in the database painter. The same is
the case with the validation rule and the display format.
Any changes made to the PowerBuilder extended properties for a
DataWindow is specific to that DataWindow only. At any point of time, now
or in the future, they will not affect other DataWindows. That is not true for
the changes made to PowerBuilder extended attributes in the database
painter. They affect all future DataWindows.
Let's explain it with the help of an example. Take the table "book_details"
that stores details about books. It has a column "comments" which is of
string datatype and allows 256 characters. When you create a DataWindow
for this table, you have to make sure that the data in this column fits
properly. The space taken by 256 characters on report is lot. In there, some
records may not have data, i.e., no comments. Painting the DataWindow
with a fixed amount of space would waste stationery.
Sliding Objects
Do you remember placing horizontal line in the nested reports lesson and it
being displayed at wrong place at preview-time, as shown in the following
picture?
When a report is placed in the detail band, the detail band is set to
'AutoSizeHeight' automatically. Depending on the height of the nested
report, the detail band height changes automatically. However, if you place
any other object in the detail band, PowerBuilder displays the object exactly
at the same place where it was placed. In the above example, you were
expecting the horizontal line to be displayed at the bottom of the record and
so placed the line accordingly. However, at run-time the height is changed
because of the nested report. To get the desired results, what you need to
do is, go to the properties dialog box for the horizontal line and select
'Position' tab. Select 'All Above' option for the 'Up' prompt under the 'Slide'
group, close the properties dialog box and preview it. The horizontal line will
be at the place where you wanted it to be.
Computed Fields
Computed fields allow you to produce very complex expressions using any of
the PowerBuilder's built-in functions. For example, the difference between
"produc_balance" and "product_reorder_level" can be done in two different
ways. One method is to place this calculation in the SELECT statement itself.
When the computation is part of the SELECT statement, the connected
database does the computation and sends the results to the client
application, such as a PowerBuilder application. To have client side
computations, use "Computed Fields" feature. Select "Objects/Computed
Field" from the menu and click at the point where you want to place the
computed field. PowerBuilder prompts for the Computed Field definition as
shown in the following picture.
Print Specifications
You can specify printer parameters for printing a DataWindow in two places:
in the design view of the DataWindow painter or in the script before printing.
It is a good idea to set up options in the DataWindow painter itself, so that
each DataWindow can have its own set of custom parameters.
The document name you specify here will appear in the print queue. Like
any other document, it also has a standard margin and paper print options,
but the difference is that the margins are in PowerBuilder Units by default.
Change this to a more understandable form by
selecting "Design/DataWindow Style..." and by changing the units.
While previewing a DataWindow, all the zoom and row description options
that were available in the 'Data Manipulation' view in the database Painter
are available. An extra feature available is the ability to divide the
DataWindow into two horizontal areas, which can scroll in the sync mode,
independent of each other.
To split a DataWindow need move the cursor over the black rectangle at the
bottom left hand corner of the DataWindow. When the cursor changes to a
double arrow, click and drag it, to position the split.
This feature is most useful when the information is spread across the page
and you need to relate something on the far right to something on the far
left side of the page.
Exercises
You need to paint the following DataWindows. The necessary details are
listed below. Please don't skip these exercises. You will be using them in
your coming session, "PowerScript".
d_units_dropdown
Property Value
Data Source SQL SELECT
Presentation Style Tabular
Tables Units
Columns All
Data Source SELECT "units"."unit",
definition "units"."unit_description"
FROM "units"
ORDER BY "units"."unit"
Other issues: Remove headings from the header band and move the header band all the
way up.
d_product_custom_query
Property Value
Data Source SQL SELECT
Presentation Style Free Form
Tables product_master
Columns All
Data Source definition SELECT "product_master"."product_no",
"product_master"."product_description",
"product_master"."product_balance",
"product_master"."product_reorder_level",
"product_master"."product_measuring_unit"
FROM "product_master"
ORDER BY "product_master"."product_no"
Other issues: Set product_measuring_unit edit style to DDDW ( d_units_dropdown )
d_display_product
Property Value
Data Source SQL SELECT
Presentation Free Form
Style
Tables product_master
Columns All
Data Source SELECT "product_master"."product_no",
definition "product_master"."product_description",
"product_master"."product_balance",
"product_master"."product_reorder_level",
"product_master"."product_measuring_unit"
FROM "product_master"
WHERE "product_master"."product_no" = :a_product_no
Other issues: :a_product_no is a retrieval argument. Screen is same as
"d_product_custom_query" DataWindow. Set product_measuring_unit edit style
to DDDW ( d_units_dropdown ).
d_products_maint
Property Value
Data Source SQL SELECT
Presentation Style Tabular
Tables product_master
Columns All
Data Source definition SELECT "product_master"."product_no",
"product_master"."product_description",
"product_master"."product_balance",
"product_master"."product_reorder_level",
"product_master"."product_measuring_unit"
FROM "product_master"
ORDER BY "product_master"."product_no"
Other issues: Set product_measuring_unit edit style to DDDW ( d_units_dropdown ).
d_trans_data_entry_header
Property Value
Data Source SQL SELECT
Presentation Style Tabular
Tables trans
Columns tran_no, tran_date, tran_type
Data Source definition SELECT "trans"."tran_no",
"trans"."tran_date",
"trans"."tran_type"
FROM "trans"
Other issues: Set the edit style of 'tran_date' to EditMask.
d_trans_data_entry_detail
Property Value
Data Source SQL SELECT
Presentation Style Tabular
Tables trans
Columns All, but delete the following columns from the display.
tran_no, tran_date, tran_type
Data Source definition SELECT "trans"."tran_no",
"trans"."tran_date",
"trans"."tran_type",
"trans"."tran_serial_no",
"trans"."tran_item_no",
"trans"."tran_qty"
FROM "trans"
Other issues: -None-
d_transactions_monthy_rep
Property Value
Data Source SQL SELECT
Presentation Crosstab
Style
Tables product_master, trans
Columns tran_qty, tran_date from "trans" table. "product_description" from
"product_master" table
Data Source SELECT "product_master"."product_description",
definition "trans"."tran_date", "trans"."tran_qty"
FROM "product_master", "trans"
WHERE ( "trans"."tran_item_no" = "product_master"."product_no" )
and
((month( "trans"."tran_date" ) = :a_month ) AND
( year( "trans"."tran_date" ) = :a_year ) AND
( "trans"."tran_type" = :a_tran_type ) )
Other issues: Join two tables on "product_no". The retrieval arguments are :a_month, :a_year
and :a_tran_type. Datatype of the first two is number and the last one is a string.
d_error_info_display
Property Value
Data Source External
Presentation Style FreeForm
Tables -Not applicable-
Columns See the picture
Data Source definition See the picture
Other issues: -None-
Prerequisites:
When using Event Driven Programming, you provide scripts for events to
which you want the object to respond. When you release the object into the
programming soup, it floats around waiting for an event message to be
forwarded to it and then runs the appropriate script, when it comes across
the event.
Open ( w_script_practice )
Now, run the application by clicking on the icon or press Ctrl + R keys.
Click on the buttons, anything happening? Nothing! That is because, we
didn't write scripts to the clicked event.
If for an object, script doesn't exist for an event, nothing happens when
that event occurs and the object goes back into waiting for the next
event message.
Run the application again and now click on the cb_left button and see what
happens.
Every object in PowerBuilder has a set events. Each object can have
different events. Some may have only couple of events and others might
have a list of events. You can browse the events for each object from the
object browser by clicking on icon.
Let's see events for the CommandButton. Click on the "System" tab page
and select "CommandButton". On the right side, double click on the "Events"
option.
Apart from the events fired by the user's interaction with the basic
PowerBuilder objects, there are few other internal or system events for
which we can write the code. For example, whenever you print a
report,PrintStart event for the DataWindow is fired and
the RetrieveRow event occurs whenever PowerBuilder retrieves a row from
the database andRetrieveEnd event occurs whenever PowerBuilder
completes retrieving data from the database.
Here, the entire code is not as a single large listing. Each script is small and
compact, hence it is easier to test and debug the PowerBuilder application's
code rather than an equivalent example based in a procedural language like
COBOL.
Scripting Basics
Before we start coding, it's a good idea to establish some naming
conventions, a few guidelines about writing comments and some other basic
things that control the look and feel of the script. Here are some general
guidelines.
Identifiers
They can include letters, digits and the following special characters: dash ( - ), Dollar ( $ ), Percent
( % ), Hash ( # ) and Underscore ( _ ).
Variable Declarations
Variables have to be declared before they are used in the PowerScript code.
Compiling a script in which a variable is used even before it was declared,
gives the following error message:
For example, in the above script, we want to declare the counter and total
variables as integers:
integer li_counter
integer li_total = 0
The variable initialization is optional. In the above example the initial value
for li_total variable can be left off, as PowerBuilder assigns a default value of
zero to integer data types.
By default, string data types are assigned an initial value of "" and Boolean
data types a value of FALSE.
Datatypes Range
Boolean TRUE or FALSE.
Character (char) A single ASCII character.
String Any ASCII character. Length: 0 to 60,000.
Integer (int) -32,768 to +32,767.
Long -2,147,483,648 to + 2,147,483,647.
Real Single floating point, six digits precision,
range 1.17 E -38 to 3.4 E +38.
Decimal Single decimal numbers with up to 18
digit.
Double Single floating point, 15 digits precision,
range: 2.2E-308 to 1.7E+308.
Date Includes full year (1000 to 3000).
DateTime Date and Time together.
Time Time in 24-hour format - supports fraction
of a second (up to six digits).
UnsignedInteger (Uint) 0 to 65,535.
UnsignedLong (Ulong) 0 to 4,294.967,295.
Blob Binary large object (No limit).
To display a 'Yes' and a 'No' button in the message box invoked by clicking on the cb_left
CommandButton, write the following code in the "Clicked" Event
String ls_WindowTitle
ls_WindowTitle = w_script_practice.title
Let us hide the "cb_left" button whenever user clicks on the "cb_right"
button. Write the following for the "Clicked" event of the "cb_right" button.
cb_left.visible = false
Functions
PowerBuilder has a vast range of built-in functions which can be used in the
scripts. We've already seen some of them while creating validation rules for
your database tables. To save you from remembering the function names,
PowerBuilder allows you to paste functions from the generated list into the
code by simply selecting "Edit/Paste Function..." or by clicking the icon.
This feature also allows you to paste user-defined and external functions into
the code.
Let's redo the code for hiding the "cb_left" button in "Accessing Object
Attributes" topic. Change the code of "Clicked" event for "cb_right"
CommandButton to:
cb_left.hide()
We did the same thing, i.e., hiding the left side button, however, we are
calling a function instead of manipulating the 'Visible' attribute directly.
Function calling convention is similar to accessing object properties. Object
name and the function name are separated by a period. Here, it means that
a function that is declared at cb_left CommandButton is called.
There are some global functions, i.e., they can be called from anywhere in
the application and there is no need to prefix it with an object name. For
example,
Scripting Structures
PowerBuilder supports several common coding structures for decision
making and looping. To see the supported structures, click on the "Paste
Statement" icon :
IF <condition> THEN
<action1>
ELSE
<action2>
END IF
You can make changes to the statement, substituting specific variables, test
conditions and so on. In the previous section, we wrote code to hide
"cb_left" CommandButton, and no code to display it back. Let's do that using
the IF statement. Change the script for cb_right's clicked event to the
following.
IF cb_left.visible THEN
cb_left.Show()
cb_right.text = "&Show"
ELSE
cb_left.Hide()
cb_right.text = "&Hide"
END IF
Run the application and click on the "cb_right" button multiple times and see
what happens.
FOR...NEXT
This control structure is used to iterate one or more commands for a certain
known number of times. To see how this code works, do the following:
Place a ListBox on the window and enter values shown in the picture. Make
use of the 'Items' tab page to enter the values. Place a CommandButton
and name it 'cb_for_next_test' and set the text to 'For…Next'. Write the
following code to the clicked event of 'cb_for_next_test'. The following code
displays the text value of each item in the ListBox.
// Object: cb_for_next_test CommandButton in w_script_practice window
// Event: Clicked
Integer li_TotalItems, li_Counter
li_TotalItems = lb_1.TotalItems()
For li_Counter = 1 to li_TotalItems Step 1
MessageBox("Item No #" + String(li_Counter), lb_1.Text( li_Counter ))
Next
In the above code, two integer variables are declared. Follow the naming
conventions. The first letter indicates the scope of the variable. This includes
'l' for local, ''i' for instance, 's' for shared and 'g' for global. You will be
introduced to variable scoping in the later sessions, till then keep in mind the
above said. The second letter indicates the datatype of the variable. For
example 'i' for an integer variable. Sometimes, you come across multiple
datatypes starting with the same letter, such as a date and a datetime. Here
both are starting with letter 'd'. So, use 'd' for date and 'dt' for datetime.
There is no limitation on the number of characters you allocate for a variable
name, just end it with an underscore. For a datetime variable reportdate,
give the name as ldt_reportdate. Some people capitalize each word in the
variable instead of using underscore ( this is called 'C' language naming
convention ), i.e., lDtReportDate. PowerBuilder way of naming is to use
underscores and it is up to you and your organization to decide the
standard.
In the second line we are calling a function for the ListBox lb_1. This
function returns the total number of items available in the ListBox. Once the
total count is known, a MessageBox() function is used to display the text
value of each item in a loop.
The variable after FOR is initialized to the value after the '=' sign, i.e.,1 in the
above code. It automatically increments with the value specified after
the STEP keyword. Omitting the STEP keyword would set the increment value
to 1, the default value.
In the above case, item details are displayed from top to bottom. What if the
details are to be displayed in the reverse order? Well, it is simple. Change
the value from 1 to -1 after the STEP keyword and also interchange the first
and the last value.
In the above code, li_Counter is initialized to the largest value and is being
decremented by 1 because of the -1.
What if you need to break out of the loop for a certain condition? Well, do it
by calling Exit. To exit from the loop after displaying five items, write the
following code:
'IF' statement comes in different flavors. The above format doesn't need any
END IF keyword, since we had only one line of code and placed it on the
same line.
DO...UNTIL
DO WHILE...LOOP
This statement executes all the commands specified between DO WHILE and
LOOP, as long as the condition set on the first line ( specified on the DO
UNTIL line ) is true. FOR...NEXT statement is useful when there are counters
with fixed increments, where as this statement is used when there are no
counters and some conditions need to be checked. This statement can be
used in places where FOR...NEXT statement is used, but incrementing the
counter is programmers responsibility.
DO UNTIL...LOOP
DO LOOP...WHILE
DO LOOP...UNTIL
Comments
It is always a good idea to have comments to the code. There is nothing
more frustrating than trying to debug someone else's code ( or even your
own old code! ) with no comments to guide.
The double slash method (//). This comments out text on a line-by-line basis. For example:
PowerBuilder, with the help of the special ampersand character ( & ), allows
you to split commands that don't fit in a line. It should be the last character
of the line and note that a variable name can't be split:
Statement Separator
You can write more than one command in a single line by separating them
with a semicolon:
Generally, it isn't a good idea to put more than one statement on a single
line, simply because it makes the code difficult to read. It makes debugging
complex, since any debug error message refers to a line number and doesn't
specify the command. If there are multiple statements on a line, you would
still have to determine which statement is causing the error.
Arrays
An array is a series of memory locations that share a name and are
identified by an index number. Arrays allow us to refer to a series of
variables by the same name, but use a number ( an index ) to tell them
apart. This helps in writing a smaller yet simpler code. In many situations
loops deal efficiently with number of cases by using an index number.
For example, say there are ten students and want to display their names,
without arrays you would probably code,
Integer i
String ls_Student1, ls_Student2, ... ls_Student3
ls_Student1 = 'David R'
ls_Student2 = 'Prasad B'
...
ls_Student10 = 'Mary J'
MessageBox( "Student #1", ls_Student1 )
MessageBox( "Student #2", ls_Student2 )
...
MessageBox( "Student #10", ls_Student10 )
Integer i
String ls_Students[10] = {'David R', 'Prasad B', ...'Mary J'}
For i = 1 to 10
MessageBox( "Student #" + String(i), ls_Students[i])
Next
We know, it is not a great real world example, but it puts through the point.
All standard data types can be used in an array definition, for example:
The exception being the use of enumerated data types for the same task.
When using single dimension arrays, initial values can be assigned to them
by simply supplying them following the declaration. For example, if we want
to assign initial values for the above integer array, we could do it as:
Product No
1
2
3
Integer products[3]
products[1] = 1
products[2] = 2
products[3] = 3
Integer products[3,2]
products[1,1] = 1
products[2,1] = 2
products[3,1] = 3
products[1,2] = 350
products[2,2] = 238
products[3,3] = 793
In simple terms, the number of records are number of elements and number
of columns are number of dimensions. In the above example, we have 3
records ( 3 elements ) and 2 columns ( 2 dimensions ). To make the
example a little complex, we store receipts per product per month. In that
case, month would be the second and receipts would be the third dimension.
In readable format, data in a three dimensional array would look like:
Product No / 1 2 3 4 5 6 7 8 9 10 11 12
Month No
1 50 0 10 0 0 0 0 150 30 20 50 40
2 2 8 7 2 1 23 37 0 0 0 0 150
3 700 0 0 0 0 0 0 0 0 0 0 93
Integer products[3,12,1]
products[1,1,1] = 50
products[1,2,1] = 0
products[1,3,1] = 10
...
products[2,1,1] = 2
products[2,2,1] = 8
products[2,3,1] = 7
...
products[3,1,1] = 700
products[3,2,1] = 0
products[3,3,1] = 0
...
Single dimension arrays can also be dynamic. This enables us to use them
when the number of elements are not know. By default, PowerBuilder inserts
elements into the array starting from 1. Following this principle, the values
shown in the above example would be referred as products[1],
products[2] ... products[6].
To alter this default action, specify the starting and the finishing values as
follows:
Note that this is still a 6-element array. The elements are now labeled 3 to 8
rather than from 1 to 6.
These methodologies ( initialization and start/finish label values ) can be
applied to multi-dimensional arrays also. Care should be taken since,
PowerBuilder works in a top to bottom and left to right manner. As an
example, take the following initialization:
1,4
2,5
3,6
To test this, replace the Clicked event script for cb_left with the following:
You can observe that the second dimension started from 2, instead of 1.
That is because the array were declared that way. When you start working
with arrays, you may find it useful to programmatically identify its limits.
PowerBuilder provides two functions to determine the upper and lower
boundaries: UpperBound() and LowerBound().
Integer i, l_TotalControls
l_TotalControls = UpperBound( w_script_practice.control[] )
FOR i = 1 TO l_TotalControls STEP 1
MessageBox( "Control No: " + String( i ), &
w_script_practice.control[i].ClassName() )
NEXT
If you refer to array elements, outside of the declared size, a run-time error occurs,
which in turn terminates the application unless an error handing script is present.
Special Characters
Use special characters such as tab or new line in a string by prefixing them
with the tilde character ( ~ ). The following table lists the special characters:
MessageBox() is a global function. It takes at least two arguments. One for the
title and one for the message. If a new line character is not given in the
message, it is displayed on one line. If the above code is executed,
PowerBuilder displays the following message box.
PowerScript Pronouns
When working with controls and windows, there are three very important
pronouns that you may find useful:
Pronoun Description
This Represents the object for which the code is
written. For example, if you
write Close( this )for a window event, it closes
the window. Writing the same code for a window
control would produce an error since you can't
close a window control.
Parent Represents the object that contains the object
you are working with. For example, the Parent
for a window control is the window which
contains the control.
ParentWindow This is used exclusively in menu scripts and
refers to the window to which a menu is
attached.
Using these pronouns save time and more over make the code reusable. For
example, write a generic script which closes a window and use it for all your
windows. Let's rewrite the above code to hide and show the cb_left
CommandButton.
Till now, we didn't write code to close the window. Place a new
CommandButton in the window and write the following code for its Clicked
event:
Close( Parent )
When the user clicks this CommandButton, PowerBuilder will close the
window. That is because the CommandButton is placed in a window and
referring to "parent" from its script means that we are referring to the
window. Close ( This ) can't be used, because, you can't close a
CommandButton; you can only hide it.
If there are any errors and/or warnings while compiling the script,
PowerBuilder displays them at the bottom of the screen and won't let you
save any changes to the script until it successfully compiles ( without any
errors ).
PowerBuilder overrules these options if you try to save the actual object and
displays the generated compiler warnings.
Summary
In the next session we'll look at database connectivity and show how to
create profiles and configure ODBC connections. We'll also discuss .INIfiles
and get into advanced scripting when we add the necessary script to our
Login window.
A variable of an enumerated data type can be assigned a fixed set of value. Values of
enumerated data types always end with an exclamation mark (!).
Can a - (dash) be used as part of an identifier name?
Yes, but, before using it turn on that option by selecting "Design/Options" from the menu
in the Script Editor window. Otherwise, PowerBuilder generates an error.
What is the character used when a statement is spanned on multiple lines?
& ( Ampersand ).
Is the following statement correct?
String Test
Test = 1000 + "sometext'
PowerBuilder implicitly doesn't convert an integer value into a string. You need to
explicitly convert it by calling a "String()" function.
What is the character used when multiple statements are on a single line?
; ( Semicolon )
Which Window Object's property keeps track of all the controls in a window?
control[]
1. WindowName.Visible = False
2. WindowName.Hide()
Exercises
Please complete the following exercises. We advise you not to download the
solution till you complete the exercises. Please note that the following
exercises are not part of the 'Product Management System' project, these
are designed to give you experience in events & PowerScript only.
# Problem Description
1. Paint the window shown below. The same window is used in exercises 1 to
4. The train picture on the window is a picture control, below it is a
SingleLineEdit control and a ListBox and a StaticText control. The rest are
CommandButtons.
Solution: - w_script_practice2.srw
2. Write script to display the ListBox's selected item's text on the StaticText control.
Tip: SelectionChanged Event
Prerequisites:
To connect to a database, you must populate the transaction object and use
the "connect" statement to make the transaction object try for the
connection. If an error occurs, for example, if an invalid password is
detected or the database isn't available, then the SQLCode property will
contain a value other than zero and the SQLErrText property is populated
with an error message.
If an error occurs, you can display it and prompt the user whether to try
again or not. We'll use this feature in the code in the login window to handle
errors. When users run the application, the first thing we want them to do is
to login, using the correct profile. First let's display the login window to the
user. Write the following code for the open event of the application object:
open( w_login )
Open function opens a window and displays it on the screen. After the user
fills in the information for all the prompts, we need to validate it and connect
to the database using the user input. That means, we need to write the code
to connect to the database, for the clicked event of the OKCommandButton.
The first two lines in the code gives an idea about the object and the event
to which the code should be written. The first line specifies the object name
and the second line tells you the event for which you need to write the code.
After declaring the variables, we are populating the SQLCA properties with
the values from the SingleLineEdit controls in the w_login window. We
connect to the database using the connect statement and check if
theSQLCode property's value is zero or not. Please note that
the connectstatement is terminated with a semicolon, since, it is an
embedded SQL statement.
Since this loop is handled programmatically, it is easy to count the aborted attempts while
connecting to the database. If this number becomes excessive, there may be a possibility that
someone is attempting to hack into one of your databases. At this point, you may alert the
network administrator, so that the necessary steps in safeguarding the databases are taken.
Let us implement these checks later.
If there are database errors, but if the user wants to try again, we are
calling return 0. This statement completes the execution of the script and
returns. Does this mean PowerBuilder closes the window? No. PowerBuilder
gives the control back to the user. Zero is the script execution status.
Typically, a zero indicates a successful execution and any non-zero return
status indicates an error in the script execution.
If everything goes fine, i.e., user connects to the database, we are closing
the parent of the cb_ok CommandButton, which is the w_login window itself.
When this window is closed, the control goes to the next line in the
applicaiton object's open event. While testing this window, provide the
following details to connect to the "product" database successfully:
"DBA" for Login Name, "SQL" for Password field, "ODBC" for DBMS field,
"product" for Database Name field. Don't type the quotation marks.
Halt
If the users are on a Novell network, the user information can be got
automatically by using the Novell Network Bindery Service function
callnwDSWhoAmI(), or by using the Windows SDK call GetEnvironmentVar().
These would enable you to distribute a single .INI file for all users, calling
the relevant function rather than reading the hard coded userid from
the .INIfile.
To use these functions, you need to purchase additional Novell Network Bindery Service
DLLs from Powersoft. Register the DLLs with your application by declaring them as local
or global external functions. You can then call them like any other user-defined function in
your script. We'll look at how to use Windows SDK calls in a later session, where we cover
how to declare external functions.
If the full path for the .INI file is not specified, PowerBuilder first looks in
the directory from where PowerBuilder was started and then looks in the
working directory specified while creating the relevant program items. This is
true only when you are running the application under the development
environment, i.e., from within PowerBuilder.
If there aren't any connection errors, we close the login window and open
the w_product_master window. Append the following line of code to the
Open event of the application object.
It might seem strange, since we've already defined the data source for the
DataWindow object. There are two main benefits to this:
Database Independence
// Event: Open
// Object: w_product_master
dw_product.SetTransObject( SQLCA )
dw_query.SetTransObject( SQLCA )
Note that there is another function which allows you to set the transaction
object - SetTrans(). If you use this function, you don't have to
call Connectstatement, but, you loose control over transaction management
and the application automatically connects and disconnects to the database
whenever the Retrieve() or Update() functions are called. When you
useSetTransObject(), it gives you more control over the transactions. That
means, you need to take care of connecting to the database; as we did in
the cb_ok CommandButton script in the w_login window. Please note that, in
both the cases, you need to populate SQLCA object. You will be learning
more about transaction management in later sessions.
All the information defined in the DataWindow will be retrieved and displayed
in the DataWindow control. Sometimes, DataWindows have SELECT
statements with arguments. In those cases, you can send the arguments
within parentheses.
If you supply values exceeding the defined arguments in the SELECT
statement, PowerBuilder does not generate error. Instead it ignores the
extra arguments. PowerBuilder added this functionality only from version 5.0
onwards. In previous versions, it generates an error. Since beginning of the
course, you were doing various exercises, but didn't see the fruits of your
labor. You will be seeing it now. Run the application and click on the
'Retrieve' button and you will be seeing the data in the DataWindow
control. Happy!
Take time to review the programming you did till now using PowerScript. Especially, if you didn't have
event driven programming experience, because, it is very easy to get lost in writing scripts, at so
many places. The following is a chart of the programming you have done so far.
Long ll_InsertedRow
ll_InsertedRow = dw_product.InsertRow( 0 )
dw_product.ScrollToRow( ll_InsertedRow )
Note that Commit and Rollback are database related commands, and so
should be terminated with a semicolon.
For each function you learn here, we advise you to read PowerBuilder online
help in detail.
You may not be familiar with the words commit and rollback. This is
transaction processing in action. While using the SetTransObject(), we have
to take care of committing or rolling back changes to the database. If a
commit statement is used, it means that the changes are confirmed and
they are to be reflected in the database, but then if we rollback the
changes, the database has to return to the state it was before
the Update() function was called.
The first thing we did was get a confirmation from the user regarding
applying changes to the data. If the reply is positive, we call
the Update()function and commit the changes, otherwise we ROLLBACK. While
saving information to the database, it is a good idea to change the mouse
pointer to an HourGlass, to indicate about the on going operation.
You should always keep the user informed about the things going on in an
application. If a lengthy operation is in progress, you should give them an
indication of it, otherwise, the user might think that things have gone wrong.
The following table illustrates some of the general guidelines for lengthy
operations:
Duration Action
<= 4 seconds Optional HourGlass cursor.
5 - 15 Display the HourGlass cursor.
seconds
15+ seconds Display a message box and preferably an indicator for the
progress.
Sorting Data
Calling Sort() function for the DataWindow, sorts the DataWindow on the
specified criteria. However, Sort() itself takes no parameters. We need to set
the sort criteria with another function namely SetSort(). For example, if you
want to sort on product_no, you need to write the following code.
We hard coded the sort criteria in the above statement. That's not practical.
In real projects, we would like the user to sort data on the column(s) of
his/her choice. This makes the application more interactive, dynamic and
user-friendly.
If you don't pass parameters to this function, PowerBuilder prints the report
without displaying the above dialog box.
Print Previewing the Report
If a DataWindow doesn't fit on the screen, either horizontally or vertically, it
may be a good idea to allow the user to see a print preview before it is
actually sent to the printer.
For example, if you want to hide a DataWindow control, what you do? You
call dw_product.Hide(). The Hide() function acts on the DataWindow
control. If you want to act on the object that is in the DataWindow control,
i.e., the DataWindow object, you need to use the Modify()function.
There are two types of things that you can modify in a DataWindow object;
they are, either the DataWindow object itself or a field within the
DataWindow object.
Take the example of printing a DataWindow. Here, you won't be printing a
field, instead you will be printing the DataWindow object itself. That means,
you are acting on the whole DataWindow.
In the above code, we were trying to find if the DataWindow was in the print
preview mode. To act on the DataWindow object itself, you need to send
"DataWindow" as the parameter literally, followed by the properties.
PrintSetup()
You will be prompted the following dialog box. For fun save in different data
formats, one at a time and check out the exported data.
In version 6.0, you can generate HTML forms from a DataWindow and this feature
is explained in detail in 'PowerBuilder -WWW' session.
dw_query.BringToTop = True
dw_query.modify('datawindow.querymode = yes')
Then we need to put dw_query in the query mode. The DataWindows dealt
till now were in regular mode. Changing the DataWindow to query mode
inserts about ten blank rows and allows the user to provide a query criteria.
Once the user types in the query criteria, (s)he is going to retrieve the data
by clicking on the 'Retrieve' CommandButton. Change the Clicked event code
for the cb_retrieve CommandButton as follows:
dw_product.BringToTop = True
dw_query.AcceptText()
dw_query.Modify( "DataWindow.QueryMode=no" )
dw_query.Retrieve()
The above code brings dw_product DataWindow control to the front and puts
dw_query into regular mode and retrieves data from the database. You
might have observed a new function, AcceptText(). By default,
PowerBuilder doesn't take the changed value of the field in which the cursor
is present, unless the user press tab or clicks on some other field. Since we
are not going to ask the user to press tab after entering data in each field,
call AcceptText() to take the changed value, even the current field also.
Here's something to speculate. Did you find anything wrong in the above
code? No! Don't worry, the code's fine, otherwise you couldn't have compiled
it anyway. The problem is that we are retrieving data in dw_query , but, it is
hiding behind dw_product. Then how is the user going to see the data? Let's
solve this problem in the next section.
Though the presentation styles are different in these two DataWindows, the
datasource and the data are same. In that case, we can ask PowerBuilder to
share the data between these two DataWindows. This can be done by calling
the ShareData() function.
Append the following line of code to the Open event for w_product_master
window.
Only the data is shared between the DataWindows, not the presentation
styles. That means, DataWindows can have different sort criteria and
presentation styles. If you delete a row in one DataWindow, the data source
is same, it is also deleted from all other sharing DataWindows. Similarly, if
you add a row, it will be available in all shared DataWindows.
Sharing data allows us to utilize the resources more efficiently. At this point
run the application and see how the 'Query' and 'Retrieve' options are
working.
We wrote code for all options in the window, except for closing the window.
Write the following code for it.
The above code closes the window. Once the window is closed, the control
goes back to the application's open event ( which opened this window ).
There no code after opening this window. Hence, PowerBuilder closes the
application.
How do you retrieve data from the database into the DataWindow?
SQLCA.SQLCode
AcceptText() accepts the changed text in the current field, even if the user doesn't press the
tab key or click with the mouse button on some other field.
Is it possible to share data between two or more DataWindows? If so, how?
DataWindowControlName.Modify( "DataWindow.Print.Preview.Rulers=yes")
SetPointer( PointerName )
SetTransObject() tells the DataWindow to use a specified transaction object while talking
to the database. Using this function also gives more control over transactions to the
programmer, such as committing and rolling back the transactions.
__________ adds a row to the DataWindow.
DataWindowControlName.ScrollToRow( RowNo )
ControlName.BringToTop = True
Open( WindowName )
Let's learn about writing to a file in the next section. First let's learn about
reading an initialization file. To read an initialization file, we need to use
the ProfileString() function. It takes four parameters, the file to read,
section name, variable name and the default value if the variable is not
defined in the file or the file is not found. If the path to the file name is not
given, PowerBuilder first checks the working directory and then the PATH.
Write the code as follows:
// Object: w_login
// Event: open
sle_DBMS.text = ProfileString( "c:\workdir\product.ini" , &
"product app" , "DBMS" , "" )
sle_Database.text = ProfileString( "c:\workdir\product.ini" , &
"product app" , "Database" , "" )
sle_Name.text = ProfileString( "c:\workdir\product.ini" , &
"product app" , "Name" , "" )
The above code reads "c:\workdir\product.ini" file and reads the values
under "product app" section. The values are automatically populated into
appropriate controls in the w_login window. If the variables are not found, ""
is populated in the appropriate control.
You may wondering why we didn't just hard code the DBMS, database and
userid in the open event script. Supposedly we do that and later something
changes, for example, say you moved your database to Sybase SQL Server,
then you need to physically open up the open script for all the applications
that you have distributed, to modify the code and reflect the changes. If you
use a .INI file, all you need to do is distribute a new .INIfile containing the
updated information or ask the user to change that file on their computer.
In the above code, we are saving the value of DBMS. The function returns -
1, if it is unsuccessful. An unsuccessful SetProfileString() means that the file is
not there and so we need to create the file. FileOpen() opens a file in the
specified mode ( write mode ) with specified locks on the file ( Write
lock ). OpenFile() creates the file if the file is not existing. FileClose() closes the
file. Once the file is created, we are setting the DBMS value.
We are setting the values by reading from the SQLCA object, recall that we
set values to SQLCA in the w_login window. Whatever values you populate
in the SQLCA will remain there till you close the application, unless you
modify them in between.
Run the application and see whether it is working. It is a good idea to see
the contents of "product.ini" and how they looks like.
[product app]
DBMS=ODBC
Database=product
Name=DBA
st_help.text = This.tag
Write the following code in "LooseFocus" event for all SingleLineEdit controls
in the w_login window.
st_help.text = "Ready"
What we are doing here is, setting the tag value of the current control as the
text of the st_help control in the GetFocus event. When the control looses
the focus, we are setting the help to a generic word 'Ready'. Run the
application and see how it works.
This option is available in the DataWindow painter from the 'Rows' menu and
you must select it when you paint the DataWindow. The amount of data
retrieved depends on the size of the DataWindow control. PowerBuilder
automatically performs this calculation and adjusts the result display if you
change the size of the control.
When the user starts scrolling down the DataWindow, PowerBuilder retrieves
another screen full of data. A possible disadvantage of this method is, if you
print the DataWindow, only the displayed rows are printed. This also has an
effect on determining the number of rows a table has; you'll only receive a
count of the number of current records.
Another effect of using this method is that the remaining information is held
in the back-end database's memory, and this may use considerable system
resources and affect the server's response time.
You can get round these problems by dynamically changing the 'Retrieve
Only As Needed' status. For example, you could add the following line in the
clicked event of the Print CommandButton at the beginning of the script,
i.e., Print(TRUE) would be the last statement:
dw_product.modify( &
"datawindow.retrieve.asneeded = false" )
dw_product.Retrieve()
This cancels the "Retrieve Only As Needed" option, so all the information
would be printed.
Note that if you specify a sort order using the Rows/Sort option, or if you use any aggregate
functions such as sum() or avg() in the DataWindow Painter, i.e., in the SELECT statement,
then the Retrieve Only As Needed option will be ignored
As you learned in the DataWindow painter, you can specify the fields to
prompt the user for query criteria. If you haven't set it in the DataWindow
painter and want to do it dynamically depending on certain conditions, you
are welcome to do it. The following line sets prompt for criteria for
"product_measurement_unit":
dw_product.Modify("product_measurement_unit.Criteria.Dialog=yes")
Till now we didn't use Modify() to change the column property. The above
example shows how to use it. If you want the user to provide a value for the
column in the Criteria dialog box, write:
dw_product.Modify("product_measurement_unit.Criteria.Required=yes")
Criteria dialog box uses the edit style painted in the DataWindow. If you
want to override the edit style and allow the user to type the value in the
criteria dialog box:
dw_product.Modify("product_measurement_unit.Criteria.Override_Edit=yes")
The above code overrides the edit style and displays a regular edit control
box. This is specially useful when the edit style is DropDownListBox.
For practice, set few columns for criteria and run the application and set
them back.
Error Handling
Till now, we wrote lot of code. In some places we checked the returned
codes of functions, and in some places we skipped it. Every programmer
thinks that (s)he wrote the perfect code and it's going to work excellently,
but not in software. Remember one thing, no matter how many times you
test, it's still not enough. So, if something which we didn't expect at
design/development time happens, let's not blow the application. We need
to provide some door where we can inform the error to the user, and let him
decide the future action.
Open the application painter and add the following code to the SystemError
event:
// Object: Application
// Event SystemError
Open( w_error )
This opens up the w_error window painted in window painter session. Now,
let's display the error information. For that, we need to write some code in
the open event of w_error window.
Write the following code for the open event of "w_error" window.
// Object: w_error
// Event: Open
dw_error_info.insertrow( 0 )
Close(Parent)
Once PowerBuilder executes the script written for the application's
SystemError event successfully, it continues with the execution of the next
statement after the error line. As we don't have any more script in the
SystemError event, closing this window allows the user to continue with the
application.
If the user wants to abort the application, we call the close event for the
application, causing it to gracefully close:
Halt Close
We know that you learned about Halt command previously. Simply using
the Halt command without the Close parameter would terminate the
application immediately. By adding this parameter, we force PowerBuilder to
execute any code that was added to the application's close event.
dw_error_info.Print( TRUE )
This will print the contents of DataWindow control to the current default
printer.
This button allows the user to append the latest error information to an error
log. To accomplish this task, we need to do several jobs. These jobs include
opening an external log file, appending information in it and then closing the
file.
Int lFIleHandle
lFIleHandle = FileOpen( "Product.Err", LineMode!, Write!, &
LockWrite!, Append!)
If lFileHandle = -1 Then
MessageBox("Save to Log","Unable to open Product.Err file!")
Return 0
End If
The first section of code opens a log file 'product.err' and enables linemode,
which means each FileWrite() will put text on a new line. We also enable
writing and appending to enable us to put text into the log and also to
ensure that each line of text is appended to the file. TheLockWrite! option
ensures that when the file is open, nobody else can write to it.
The next six lines of code writes the UserId or LogId into the file depending
on whichever is relevant and then writes in the date and time.
GetItemString() returns the specified field value. Use this function if the field is
of string datatype. If the field is of number type, use GetItemNumber().
Similarly for date fields, call GetItemDate(). All these functions take two
parameters, the row number and the field number/name.
Error Signaling
Test error handling script written to the 'SystemError' event by using
theSignalError() function. Simply assign some values for the 'error' object and
call the function. This causes an application level 'SystemError' event to be
triggered, allowing you to review and test your application's error handling.
To see how this works, write the following script in the 'rButtonDown' event
for one of the CommandButtons:
error.object = "window"
error.text = "This is an error"
error.line = 10
SignalError()
This simply assigns some values to the error object and calls
theSignalError() function. When you run the application, right-click on this
button and the error Information window will be displayed with the values
assigned to the error object. Once you run this code and see the results,
remove the above code.
In version 6.0, you can specify error number and error text as arguments to
theSignalError()function. PowerBuilder automatically populates other information
in the error object and signals 'SystemError' event. Arguments to SignalError()are
optional. If you don't specify arguments, you need to take care of populating all the values in the
'error' object, even though it is not mandatory to populate all the attributes in 'error' object.
All messages under Windows can be broadly divided into three categories:
Informational, Notification and Action.
As said above, all most all Window messages are mapped to PowerBuilder
Event Ids. PowerBuilder pre-defined some event names and mapped them to
the event ids of each object. For example, a CommandButton has the
following pre-defined events.
By looking at the above table you can see that mousemove event is not pre-
defined for the CommandButton, but is pre-defined for the Window. Why
didn't PowerBuilder define all event names for each object ? PowerBuilder
pre-defined events that are most frequently used and required by the
object . Want to display MircroHelp whenever a CommandButton gets focus,
then write script in the "GetFocus" ( PowerBuilder is case-insensitive ) as
follows:
You may want to display floating help for buttons in the application ( like the
one you see when you move the mouse pointer over the PowerBuilder
toolbar ). In that case, writing code in "GetFocus" event wouldn't help,
because, "GetFocus" event triggers only when the user tabs into the
specified CommandButton or by calling SetFocus() in the PowerScript .
What you really want is to display help whenever the mouse pointer moves
over the CommandButton.
Just for this, PowerSoft made provision for defining events and mapping
them to one of the available events. Events that you define are classified as
"User Defined Events." You need to select "Declare/User Events" from the
menu in the appropriate painter. The following picture displays the defining
of "ue_mousemove" event for a CommandButton by mapping it to the
"pbm_mousemove" event id.
Provide a name under the "Event Name" and select one of the existing event
ids from the "Paste Event Id" List Box ( Selecting Event ID is not mandatory,
explained in a moment ).
An event id can be mapped to one event name at each object level. You
can't unmap pre-defined events. If you don't want anything to happen when
an event occurs, then just don't write script for that event.
The following figure illustrates event classification and valid mappings.
Typically, VBXevents ( Visual Basic events ) are used for VBX user objects,
to capture VBX events. With version 4.0, PowerBuilder supports OCX. Even
Visual Basic v4.0 moved to OCXes. PowerBuilder automatically defines OCX
events In the OLE control. We think, in the future versions, VBX events
might not be supported, since every thing is achieved with OCXs. We will
teach about OCX and OLE in later sessions.
Parameterized Events
With version 5.0, you can parameterize events. For example, prior to version
5.0, to access the SQL statement that is being send to the database you
need to call 'GetSQLPreview()' function in the 'SQLPreview' event. From version
5.0 onwards, you no longer need to call that function ( which became
obsolete ), instead you can use 'SQLSyntax' parameter of 'SQLPreview'
event. In addition to that, PowerBuilder also sends few other parameters
including the row number for the SQL statement, the SQL statements being
SELECT, UPDATE, DELETE, INSERT. Which means that in the 'Clicked' event,
you don't need to call 'GetClickedRow()' function, instead you can use the 'row'
parameter for the 'Clicked' event.
Before jumping onto the advanced stuff, I would like you to do the following.
Open the w_product_master window and go to the script editor for
dw_product DataWindow and go to the 'SQLPreview' event. Click on the
'Paste Parameters' DropDownListBox, you will find all the parameters to the
'SQLPreview' event ( as explained before ). Invoke the PowerBuilder online
help and select 'Contents' tab. Click on 'Controls' help topic and double-click
on 'DataWindow'. Go to the events option and read the help for 'SQLPreview'
event.
by Value
by Reference
as Read-only
Return 0
In the above example, after executing the event, li_counter value is still 100
even though 200 is assigned to it in the called event script 'ue_test'. I will
explain different ways of executing the event script in the next topic.
Int li_xValue
Window lWindow
lWindow = CREATE w_practice
/* This statement has no problem because we are just referring to the attribute */
li_xValue = pWindow.x
/* This statement also has no problems, because we are just changing one of its attribute
*/
pWindow.x = 100
/* This statement generates compilation error, since we are assigning another window to
it, that means, we are telling PowerBuilder to point to another window */
pWindow = lWindow
Return 0
In short,
Events can return a value including traditional data types and PowerBuilder objects.
You can define an user-defined event without mapping it to any pre-defined event-id.
You can define arguments to events that are not mapped to any pre-defined event-id.
The event arguments may be traditional data types or PowerBuilder objects.
You can pass arguments to the events 'by value', 'by reference' and as 'read-only'.
When an argument is passed by value, changes to the argument does not reflect in the
calling script.
When an argument is passed by reference, changes to the argument will reflect in the
calling script.
When an argument is passed as read-only, changes to the argument will reflect in the
calling script. You can't reassign the argument in the called event script.
Triggering an Event
Events that are mapped to regular event ids are triggered automatically. For
example, clicking on a CommandButton automatically executes the script
written for its "Clicked" event ( pbm_bnclicked event id for the
CommandButton ). Sometimes, you may want to trigger the event
programmatically. For example, you may want to trigger the 'Sort' event in
the DataWindow control, if the user selects the 'ue_sort' option from the
popup menu of a DataWindow. To trigger an event, you need to use
theTriggerEvent(), and the syntax is:
Int li_retstat
li_retstat = w_script_practice.TriggerEvent( Close! )
If li_retstat <> 1 Then
//Error handling ...
End If
Int li_retstat
w_script_practice.TriggerEvent( "ue_save" )
If li_retstat <> 1 Then
//Error handling ...
End If
TriggerEvent() function
executes synchronously, i.e., the next command after
this command will not be executed until this command is executed
completely.
As shown in the above syntax, you can also send parameters to the event in
the TriggerEvent(). When you send parameters, they are stored in the
Message object. Message Object is explained in detail in the "Inter Object
Communication" section. For the time being just note that, Message object is
a global object and is available by default in all PowerBuilder applications. In
simple terms, the main purpose of this object is to store information which
are accessed from other objects. Parameters passed to the event in
the TriggerEvent() are available
in Message.StringParm andMessage.LongParm members.
There are limitations in the number of parameters you can pass for an event
through this function. That being two. Another disadvantage with this
function is that, the return value of the event can't be trapped. The return
value of this function is the success/failure of the function call itself, and not
the return code returned in the event script.
With version 5.0, another syntax is available for executing events and
functions. PowerSoft says that the new syntax is only an enhancement, and
not a replacement for the old syntax, but I am afraid it is not so. Once you
start using the new syntax, there are chances that you will not go back to
the old syntax again. The much talked about syntax is as follows:
String ls_status
ls_status = Parent.EVENT STATIC TRIGGER ue_SendToMainFrame()
ls_status = Parent.EVENT TRIGGER ue_SendToMainFrame()
Parent.EVENT STATIC TRIGGER ue_SendToMainFrame()
Parent.EVENT TRIGGER ue_SendToMainFrame()
All the above statements are correct. The only limitation on return value
being, that the return value expression shouldn't return an array. CallType is
"static" by default. That means, compiler checks the presence of the calling
event or function and its return value type at the compilation time. If the
event or function doesn't exist, or the assigned returned value type is
incorrect, error will be generated.
// instance variables
// int ii_hours
// String ii_YarnType
NonVisualObject lnc_object
nc_MachineObject lnc_MachObj
Long li_Prod
// instance variables
// int ii_hours
// String ii_YarnType
nc_MachineObject lnc_MachObj
Long li_Prod
The above code does the same thing as the earlier code listing, using nested
function calls. As you can see here, you can't check if the returned object is
a valid object or not. Make sure to check for valid objects and for error
handling in the called objects.
Let's take a simple example of window "close" event. If you trigger it, what
you expect to happen? We expect, the window to close. In reality, that
doesn't happen. When calling TriggerEvent() or PostEvent() ( explained in the
next topic ), PowerBuilder puts the message at the top of PowerBuilder's
internal object queue and then executes it. In other words, PowerBuilder
does not place the message in the MS-Windows message queue. To test the
above theory, place a CommandButton in the w_script_practice window and
name it 'cb_event_test' and for the clicked event
write Parent.TriggerEvent(Close!). Write MessageBox("Hello!","I am in Window Close
Event") to the window's close event. Then run the window and click on the
button. Do you see the window closing when the button is clicked. No!, it
simply displays the message box.
Handle is
the handle of the window to which you want to send the message.
You can get the handle of the window by calling Handle().MessageNo is the
Windows message number.
Replace the script for cb_event_test with the following code and run the
window again. You get the expected results. The following code sends MS-
Windows's close message and closes the parent window.
The above code triggers MS-Window's "close" event, which in turn triggers
PowerBuilder window's "CloseQuery". If "CloseQuery" event is executed
successfully, PowerBuilder executes the "Close" event script and then it
closes the window.
How to find out what message number (16 in the example ) to send. For
that, select Declare/User Events from the menu in the window painter and
see what message is mapped to Close event i.e., "pbm_close". Windows
message names are nothing but "pbm" replaced by "WM", i.e., WM_CLOSE
in this case. We found the window message name, now how to find out
message no?
All Windows messages are listed in "Window.H" file. If you have Visual C++,
you will find it in "INCLUDE\WINUSER.H" file. The entry for WM_CLOSE looks
like:
#define WM_CLOSE 0x0010
Posting an Event
Sometimes, you may want to execute an event asynchronously, i.e., the
current script shouldn't wait for the completion of the posted event
execution. In those cases, you need to use the PostEvent() function. The
format is same as TriggerEvent().
You can write script in the window's open event. This works fine, but, for the
user, it means a delay in opening the window, since (s)he can't see the
window until the execution of it's open event. As an alternate, you can use
the PostEvent() function.
Summary
In this session you have learned about connecting to the database and
manipulating a DataWindow using PowerScript. You have also learned more
about events and functions. For a quick summary of this session,
browse PowerScript-db-operations.ppt ( a PowerPoint presentation ). The
application built by you till now, is a single window application. In the next
session you will be learning to create MDI applications.
TriggerEvent() just executes the script for the specified event, where as, Send() executes the script
as well as it makes the specified event to really happen.
Triggering an event which doesn't return a return code, will return ______ return code.
0 ( ZERO )
Triggering an event which doesn't have script, will return ______ return code.
-1
What is the difference between passing an argument "By Value" and "By Reference"?
In case of "By Value", the changed value ( in the called event/function ) of the variable reflects in
the calling function/event. In case of "By Reference", the changed value ( in the called
event/function ) doesn't reflect in the calling event/function.
What is the difference between passing an argument "By Reference" and "Read-Only"?
Both are same, except for one difference. Assigning another object to the argument object is not
allowed, if the object is passed as "Read Only".
False.
True.
Write the code to trigger "Close" event of "w_script_practice'. Write it by using old and new
Syntax.
Using SignalError() function.
"Error" Object.
SystemError, Application.
Setting on the "Retrieve As Needed" property makes PowerBuilder bring data, that a DataWindow
control can display at any moment of time.
Explain the difference between "Query Mode" and "Prompt for Criteria".
Query Mode allows the user to specify query criteria on all the columns that are being displayed in
the DataWindow control, and has a tab order greater than Zero. Prompt for Criteria allows the
user to specify query criteria on selected columns ( set either through PowerScript,
usingModify() function, or set in the DataWindow painter ).
________________ function sets the value of a column in the DataWindow control.
SetItem()
________________ function returns the value of a string data type column in the DataWindow
control.
GetItemString()
________________ function returns the value of a "Date" data type column in the DataWindow
control.
GetItemDate()
w_script_practice.TriggerEvent( Close! )
w_script_practice.TriggerEvent( close! )
True, because identifiers are case insensitive in PowerBuilder.
Exercises
Please complete the following exercise. We advise you not to download the
solution until you complete the exercise.
# Problem Description
1. Under normal conditions, the script written for ue_delete would work fine.
However, when the user adds a new blank row and tries to delete it, this
script neither prompts the user nor does anything. We would like you to fix
that bug, i.e, the user should be able to delete a blank row.
Tip: IsNull() function
Solution: - ex-9-1.srm
Home