What's New in Alpha Five Version 8

 

Improved Performance

Improved Appearance

Layout Editors

Browse Improvements

Working with SQL Databases - AlphaDAO

Tasks Lists

DragDrop List Improvements

Script Editor Improvements

Action Scripting Improvements

Web Applications Improvements

Field Rules

Improvements in Queries

Miscellaneous Improvements

What's New in Xdialog

New Xbasic Functions and Methods

 

Improved Performance

Alpha Five V8 performs better than any other version of Alpha Five. Performance improvements have been made in several different critical areas.

Speed Improvements - In a word, Version 8 is fast! Alpha Five V8 is significantly faster than previous versions of Alpha Five. Significant speed improvements have been made across the board - Alpha Five loads much more quickly, databases are opened more quickly, you can switch between open windows significantly more quickly, tables are opened more quickly, and forms repaint more smoothly. The user experience with V8 is considerably more satisfying than any previous version of Alpha Five.

Xbasic is Faster - In general, Xbasic scripts in V8 will run faster than in previous versions of Alpha Five.

Application Server is Faster - The Application Server in V8 is faster than previous versions of the Application Server.

Much Smoother Screen Repainting - Forms now open much more smoothly than in previous versions of Alpha Five. This is achieved by using a technique called 'double buffering' in which screens are drawn to an internal memory location and then only displayed when the form has been completely redrawn. This results is extremely smooth transitions from one form to another. Also, when resizing forms, there is no flicker. When running in maximized mode, the improvements are especially noticeable. In addition, when in maximized mode, switching from one form to another is now significantly faster than in previous versions of Alpha Five. Double buffering does require extra RAM and it can be turned on or off using the following Xbasic commands:

? a5.System_Mode_Get("form_double_buffer")
"True"
a5.System_Mode_Set("form_double_buffer","false")
a5.System_Mode_Set("form_double_buffer","true")

 

Resource Utilization - When Alpha Five is in an idle state, it no longer consumes as many CPU cycles as previous versions of Alpha Five. This results in less drain on your computer and faster performance of Alpha Five, and other applications that are running at the same time as Alpha Five.

 

Improved Appearance

Version 8 has a completely new look. It looks fresh and modern and the applications you create will look stunning.

There are several different themes, designed to match your operating system theme. When the standard XP theme is selected, Alpha Five uses a blue theme:

 

 

When the Olive Green Windows theme is selected, Alpha Five uses a green theme:

 

 

When the Silver Windows theme is selected, Alpha Five uses a silver theme:

 

 

 

Gradient Fills - Gradient fills can be used throughout on Layouts. For example, form can have gradient backgrounds, buttons can have gradient backgrounds, frames can have gradient fills. etc. This gives your applications a cutting edge look. For example, this form has a gradient fill on the form background, on the buttons and on the title bar across the top of the form. Over 20 different gradient fill styles are supported.

 

 

Gradient Fills on Browses - Gradient fills can even be used in Browse layouts. For example, in this picture, alternating row colors, using a gradient fill have been defined. In addition, the title bar is using gradient fills. Gradient fills can also be used in the row selectors.

 

 

Layout Editors

 

There have been substantial improvements in all of the Layout editors (Forms, Reports, Labels, Letters and Browse).

 

Gradient Fills - Almost all objects now support gradient fills, giving layout a much more professional look.

Fill Style Picker - A new gallery control makes it easy to pick the control's fill style.

 

 

Buttons Shapes - New button shapes have been added and a new Button Shape gallery control makes it easy to pick the button shape.

Advanced Frame Object - The Frame object has been substantially improved. You can now create great looking frames to highlight different sections of your form.

Here is an example of an 'old' style and a new, modern style frame. Notice that the modern frame has gradient fills in both the frame body and the frame title.

 

 

 

Static RTF Fields - Now support transparent background colors.

Improved Color Picker in Layout Editors - More Color Choices - The color picker in the layout editors (Form, Browse, Report, etc.) is now greatly improved. You are no longer restricted to the built-in colors defined in Alpha Five, or the other colors you defined manually in View/Settings. You can now choose any color that you want, and the color picker gives you access to a "Custom" palette that you can easily define, and also to a palette of your recent choices.

Color picker shows the standard "System" colors as well as tabs for the user-defined "Custom" palette and a tab for your recent color choices. The "More Colors" button opens up an extremely powerful and easy to use color picker - see below.

 

Advanced Color Picker - The color picker that displays when you click the "More Colors" button in the in the Layout Editor color picker, as well as in other parts of Alpha Five, (such as designing CSS style sheets, Web Components, etc.) is now significantly improved. In addition to picking colors of a standard color map (shown on the HLS - Hue, Luminance, Saturation - tab below), you can also pick "relative" colors (shown in the image with the "Relative" tab selected).

 

 

Stylesheets - There have been several improvements in stylesheets for Form, Reports, Labels, Letters and Browses.

- new stylesheets that take advantage of the new gradient fill features in V8 have been created.

- older stylesheets are still available by checking the 'Show legacy stylesheets' checkbox when you apply a stylesheet.

- stylesheets can now be used in the Report, Label and Letter editors.

- when you drop a label object on a layout, you now get a sub-menu asking you to choose the style of the control.

Style menu allows you to pick a style for text objects

 

- when you drop a frame object on a layout, you get a pop-up menu letting you choose the frame style

Frame menu when dropping a frame object on a Layout

Resulting frame object after selecting the 'Styled' option.

 

 

Layout Editors - Interactive Window - The Layout editors now have a new 'Interactive Window' which is available as one of the Task Lists in the editor's Task Pane. The Interactive Window operates in the same session as the layout that you are editing. Because the Interactive Window and the layout share the same session, you could (for example) type this in the Interactive Window shown in the Task Pane:

LastnameLabel.text = "Last Name"

 

This would set the text shown in the 'LastnameLabel' control on the form to 'Last Name'.

Setting properties for objects in the layout in the Interactive window is equivalent to setting them using the properties dialog boxes and toolbars.

 

The image below shows off several new features of the Layout editors: 1. The Interactive Window task pane is visible, allowing you to execute Xbasic commands against the layout object that is being edited, 2. The form editor is displaying a new 'advanced' frame object with rounded corners, a gradient fill for the frame title section, and a gradient fill for the frame body and 3. a static RTF object with a transparent fill (showing that the frame's gradient fill shines through).

 

 

 

Browse Improvements

 

There have been a large number of improvements to the Browse object in Version 8. Both the stand-alone browse, and the embedded browse have been improved. The improvements fall into the following categories:

- performance

- appearance

- events

 

Alternating Row Colors -  (Professional and Enterprise Edition) You can now define alternating row colors. The row colors can use gradient fills to create a very modern look. You can specify up to 4 alternating colors (e.g. color1 for row 1, color2 for row 2, color3 for row 3, color 4 for row 4 etc.). A genie makes defining alternating row colors very easy.

For example:

 

The Default Browse Style The 'Alphasports' Style

 

 

Right click on the Browse and select Properties. Then click the 'Row Color Properties' button to bring up the Genie. The Genie lets you set up to 4 alternating row colors.

 

 

Advanced Cell Formatting -  You can now put images, and buttons in browse cells. (Professional and Enterprise Edition). For example, this browse shows buttons that will open a detail view of each customer, and other buttons that will dial the phone number for each customer.

 

The image to use or button text to display for each row in the browse can be conditional - based on other data in the current browse row.

Browse Line Styles -  (Professional and Enterprise Edition) You now have control over the line style and colors of the vertical and horizontal lines in a browse, as well as the lines under the titles and in the row selector (at the left edge of the browse).

 

 

Browse Images - (Professional and Enterprise Edition) You have complete control over the various standard images used in the Browse. You can set the image used for marked records, the record that has focus, the ascending and descending sort icons, the image used in the top left corner, and the new record image.

 

 

Browse - Row Selector - When you define the color/fill style for the row selector in a browse object you now have much finer control than you previously had. You can define different styles for the selected rows, the row with focus and all other rows. The row selector can use gradient fill styles.

Browse - Title Colors - When you define the color/fill style for column titles, you now have much finer control than you previously had. You can define different styles for when the column is selected, has focus or is neither selected nor has focus.

Browse - Mouse Wheel - Previously, when using the wheel on the mouse, when you got to the last record, using the wheel would move into the new record. Now, the wheel will not move you from the last record to the new record.

Browse Events - New Browse Events - Several new browse events are now supported for both stand alone and embedded browse layouts. OnSave - fires when a record in the Browse layout is saved. CanSave - fires when the user tries to save a record. The event can be cancelled by calling the cancel() function. <Column>_onChange - fires when data in a browse column is changed. The <Column> events are defined by inserting the appropriate functions calls into the Browse, Events script. For example, here is how to define an event handler for the 'lastname' column in a browse:

For a stand alone Browse, select Browse, Events, Events. For an embedded Browse, select Object, Event, Event, or right click on the Browse and select Events, Events

In the 'Events' script, define this function:

function lastname_OnChange as v ()

    ui_msg_box("On Change Event for Browse. Browse name is: ",this.name())

end function

Note that the 'this' alias refers to the browse object that contains the browse column.

Browse - Column Heading Click Behavior - Column Title Events  - You can now define different behaviors for responding to clicks in a column heading a Browse object. In V7 the only behavior was to select the column. Now you can specify that the data in the column should be sorted, or you can define an event that should be fired when the column heading is clicked (in this case the column heading behaves like a button). The behavior is set by setting the browse object's 'title.onclick_behaviour' property. For example:

 

browse1.title.onclick_behaviour = "Sort"

browse1.title.onclick_behaviour = "Select"    'this is the V7 option

browse1.title.onclick_behaviour = "Event"
 

To define the click behavior, open the Browse Properties dialog box.

Browse - Title section height - You can now explicitly set the height of the title section in a browse, or you can set the height to 'auto' which will cause the height of the title section to automatically adjust based on the font size or layout of the browse titles. You can set the title height by setting a property value in the Browse Properties dialog, or you can drag on the sizer where in design mode. The ability to set the title height is especially important in V8 because you can now define multi-line browse column titles, and you can insert images and buttons in browse column titles. The following example show how you can adjust the setting using Xbasic:

invoices:browse1.title.client_height = 12*2  'set to 24 point

invoices:browse1.title.client_height = 0  'set to auto

 

Browse - Titles - You can now define title font settings for stand alone browses. (You could previously define these properties for embedded browses).

Browse Layouts - Tab stop Property - You can now set a tab stop property for browse columns. If the tab stop property for a column is set to False, then the column will be skipped when you press Enter or Tab to move from column to column.

Browse Layouts - Field Rules - Skip Rule - The skip field rule is now honored in Browse layouts. Previously, it was only honored in Form layouts.

Browse - Titles - XP Themes - Browse titles can now be displayed using XP Themes. (Column titles in the Control Panel are an example of XP Themes - assuming that you are running under XP or Vista)

 

Browse - <Browse>.Fetch_Last() Method - This method has been improved. It now tries to keep as many records as possible visible in the browse window. Previously, the last record was displayed in the first row of the browse window, leaving the rest of the window empty.

Browse - <Browse>.Set_Viewport_row(n Rownumber) Method - This method allows you to set the active row in the browse window. The rownumber  must be between 1 and the number of rows shown in the browse window. This method is the Xbasic equivalent of clicking in a particular row in the browse window.

Browse1.set_viewport_row(5)

Browse - <Browse>.Get_Viewport_row() Method - Returns the row number of the active row in a browse window.

 rownumber = Browse1.Get_viewport_row()

 

 

Forms with Linked Browses - (Advanced Users Only) A form can contain both 'embedded' and 'linked' browses. A 'linked browse' is a browse that exists as a stand-alone browse (i.e. it is visible in the Browse tab on the Control Panel). When a form contains a linked browse is it now possible for advanced users to override some of the browse settings that are stored in the saved browse definition. This is done by setting the value of the Browse object's 'overrides' property at design time. Here are some examples of how the 'overrides' property can be set. Assume that you have a form with an linked browse. The form is called 'CustForm' and the browse object is called 'browse1':

 

CustForm:Browse1.overrides = "<browse style=\"<Ambient>\" />"

This causes the linked browse to use the same style sheet as its container form (i.e. the 'CustForm').

CustForm:Browse1.overrides = "<browse style=\"Dark Modern\" />"

This causes the linked browse to use the 'Dark Modern' stylesheet (regardless of the stylesheet used by the container form).

 

xmlstring = <<%xml%

<browse new_record_text="&lt;New record&gt;" showrowselector="yes" show_vscrollbar="yes" show_hscrollbar="yes"

gridline_horizontal="yes" gridline_vertical="yes" outline_level="1" data_entry_style="default" row_height="13">
    <border color="#147,147,147" style="Beveled-Single line" width="1" has_left_edge="yes" has_right_edge="yes" has_top_edge="yes" has_bottom_edge="yes"/>
    <shadow style="None" color="Black"/>
    <title showtitles="yes" color="Rose" accent_color="#249,249,249" fill_style="Gradient Horizontal"

    line_style="solid" line_color="#147,147,147" top="2" onclick_behaviour="Select">
        <font color="Black" name="Arial" size="8" bold="yes"/>
         <flyover color="#224,244,244" accent_color="#195,195,195" fill_style="Gradient Horizontal"/>
         <selected color="#249,249,249" accent_color="#221,221,221" fill_style="Gradient Horizontal" font_color="Black"/>
         <focused color="#249,249,249" accent_color="#221,221,221" fill_style="Gradient Horizontal" font_color="Black"/>
    </title>
    <background color="Tan" accent_color="Black" fill_style="Transparent"/>
    <row_selector color="Pink" accent_color="White" fill_style="Gradient Vertical Glass" line_style="solid" line_color="#147,147,147">
         <selected color="#249,249,249" accent_color="Black" fill_style="Transparent"/>
         <focused color="#249,249,249" accent_color="Black" fill_style="Transparent"/>
    </row_selector>
    <splitter color="Pink"/>
    <horizontal line_color="#221,221,221" line_style="default"/>
    <vertical line_color="#221,221,221" line_style="default"/>
    <separator_top line_style="default"/>
    <separator_left line_style="default"/>
    <separator_right line_style="default"/>
    <cells>
        <cell color="#255,255,255" accent_color="Rose" fill_style="Gradient Horizontal glass" font_color="#0,0,0" count="1"/>
    </cells>
    <selected color="System-Highlight" accent_color="Black" fill_style="Transparent" font_color="System-HighlightText"/>
    <focused color="White" accent_color="Black" fill_style="Transparent" font_color="System-HighlightText"/>
    <currentrow color="Win3D" accent_color="Black" fill_style="Transparent" font_color="System-HighlightText"/>
    <currentcolumn color="Win3D" accent_color="Black" fill_style="Transparent" font_color="System-HighlightText"/>
    <new_record_appearance color="Win3D" accent_color="Off White" fill_style="Transparent"/>
    <fill color="Rose" accent_color="#249,249,249" style="Gradient Horizontal"/>
</browse>
%xml%

CustForm:Browse1.overrides = xmlstring

 

This causes the linked browse to use the set of properties defined in the XMLString variable.

 

 

 

Working with SQL Databases - AlphaDAO

Note: To work with SQL databases (using either AlphaDAO or ADO, you must have the Enterprise edition of Alpha Five).

AlphaDAO - AlphaDAO (Alpha Database Access Objects) is a collection of objects that can be used to connect to, and interact with remote SQL databases. It provides a much easier to use and understand object model than ADO ('ActiveX Data Objects'). An important benefit of AlphaDAO is 'portable SQL' which allows you to define SQL statements using Alpha SQL syntax. By using portable SQL, your SQL statements will work on all supported remote databases. (Enterprise Edition only).

Passive-Link Tables - Passive-Link tables are regular Alpha Five tables (i.e. .dbf files), that are created by importing data from a SQL data source (e.g. an Access database, an Excel file, a SQL server database, a MySQL database, etc). The source from which the data was imported is stored in the table's dictionary, so that at any time you can right-click on the table and select the 'Refresh' command. This causes the SQL query that was executed to populate the passive-link table to be re-executed, thus repopulating the passive-link table with up-to-date data from the remote database. Any changes made to the data in a passive-link table are NOT made in the remote database, and are lost when the passive-link table is refreshed. Passive-link tables are therefore ideally used for reporting and analysis applications involving data in remote databases. You can create passive-link tables in several ways: 1) right click on the white space when the Tables/Sets tab of the Control Panel has focus, 2) use the AlphaDAO import genie, 3) right click on a table in the SQL Database Explorer. Passive-link tables can be easily identified in the Control Panel because they are shown with a special icon showing a red chain-link:

 

 

AlphaDAO Import Genie - (Enterprise Edition) The AlphaDAO Import Genie is replaces the ADO Import Genie in Version 7. (The ADO Import Genie is still available for backward compatibility). The AlphaDAO Import Genie allows you to define very powerful and flexible import operations to import data from remote SQL databases (including Excel files). Key features of the AlphaDAO Import Genie include:

- uses AlphaDAO to connect to the remote database

- ability to import tables as either standard Alpha Five tables, or as passive link tables.

- ability to specify any SQL statement to define what data gets imported.

- full graphical SQL query builder to help you define the SQL statement to select records from the remote database.

- use of arguments in the SQL statement to prompt for parameters at run-time.

- ability to consolidate all prompting for arguments into a single dialog. For example, say you defined an import operation that imported data into 3 different tables. Each of the 3 SQL Select statements might use arguments. Rather than prompting for arguments as each SQL statement is executed, all prompting could be consolidated into a single prompt.

- ability to control the field definition of each field in the imported table.

 

Database Explorer - Provides an expandable tree view of the tables in a remote SQL database.

 

SQL Query Genie - Allows you to build and edit SQL SELECT statements. The genie is a 'two-way' editor - meaning that you can paste make edits directly on the SQL statement, or in the builder. If you make edits directly on the SQL statement, Alpha Five will automatically parse the SQL and show a graphical representation of the query in the builder.

 

SQL Command Window - Allows you to enter any SQL command to be executed by a remote database server. In the case of commands that return data, the Result window will show the rows that were selected. In the case of an action query (such as an Update), the Result window shows how many records were affected. The command window can be used to execute both native and portable SQL statements. The drop-down connection box allows you to easily execute the same command against different backend databases.

 

 

 

Reporting - Reports, Labels and Letters can now be created using data from remote SQL databases.

 

AlphaDAO Connection Strings - Named and Evaluated Connections - When opening a connection to a remote database using AlphaDAO, you can use both named and evaluated connection strings.

Examples:

'Open a named connection called 'Northwind'

dim c as sql::connection

c.open("::Name::Northwind")

 

'If you are running on a machine called 'MainServer' use the 'RealAccountingData' named connection,

'else use the named connection 'TestAccountingData'

dim c as sql::connection

c.open("::Eval::IIf(api_getmachinename()="MainServer","::Name::RealAccountingData","::Name::TestAccountingData")

 

Tasks Lists

The Script Editor, Layout Editors, and HTML Editor all now support dockable 'Task Panes'. Task Panes are a major innovation because they make working in the various Alpha Five editors more efficient by making commonly used tools more accessible.

Form Editor Task Pane shown in its default position. This shows the Task Pane in its 'un-collapsed' state.

Note that the Task Pane shows two Task Lists - The DragDrop list and the Toolbox - each in its own resizable window.

Clicking the 'Maximize' icon in the title bar of either Task List will cause that window to be maximized and the other window(s) to be reduced to just their title bars.

Form editor Task Pane shown in its collapsed state. Clicking on the 'Toolbox' button will display the Task Pane at its previous width (before it was collapsed) and will also maximize the 'Toolbox' Task List. Similarly, clicking on the 'DragDropList' button will maximize the DragDropList Task List.

 

However, clicking on the 'Restore' icon (at the top of the bar) will restore the Task Pane keeping the same layout that it had when it was collapsed.

Any Task List in a Task Pane can be pulled off the Task Pane and floated. Any floating Task List can be dragged on top of a docked Task Pane (on the left or the right) and it then becomes docked in that Task Pane.

 

In this picture, the Toolbox has been dragged off the Task Pane and is now floating.

   
   

 

 

 

DragDrop List Improvements

The DragDrop list in the Layout editor has been substantially improved and has many useful new features, as described in the images below.

 

This picture shows how different sections in the DragDrop List can be collapsed and expanded. This is useful when you are working with a Set that has many tables in it.

The DragDrop list now supports a right click menu. This menu allows you set properties for the list, such as:

  • drag field and label

  • drag field only

  • drag label only

  • group field and label, or un-group field and label

You can sort the fields in the DragDrop list in natural order (the order in which the fields were defined), or in alphabetic order.

 

Notice the menu items 'Select object for INVOICE_HEADER->Pay_method' and 'Extend select object for NVOICE_HEADER->Pay_method'.

In this case, the user has right clicked on the 'Pay_method' field in the 'INVOICE_HEADER' table. The first option will select any objects in the layout that are bound to the 'Pay_method' field. If any other objects on the layout were selected, they will become unselected.

The second option will also select any objects on the layout that are bound to the 'Pay_method' field, but if any other objects on the layout are selected, they will  remain selected.

This feature is extremely useful when you have a  layout that is based on a table or set with a large number of fields, and  you quickly want to find the objects that are bound to a particular field.

 

You can search for fields in the DragDrop list. This is very useful if you have a table with a large number of fields. The search feature supports wildcard characters.

In this picture, the user has selected the 'Find fields that match...' command and has entered 'bill*' as the search criterion. This will find all fields that start with 'bill'.

Notice that the search can be limited to a single table in the Set (in this case the 'Customer' table), or it can search in all tables in the Set.

 

 

After running the search, the DragDrop list now highlights the fields that were found.

 

Layout Editors- Drag/Drop List - Summary Field Genie - Previously, when you selected multiple fields from the DragDrop list and dropped the fields into a report summary section, the Summary Field Genie did not appear. Now, it does appear and you can select a summary option for all selected fields. This makes is much quicker to place multiple fields in a summary section.
 

 

Script Editor Improvements

Code Editor - Scripts/Functions Task List - The Code Editor now has a new Task List - the 'Script/Functions' Task List. This window displays a list of all of the global scripts and UDFs in the current database. Double clicking on any entry in the list will open the script or UDF in the editor. You can type a partial script name in the text box at the top of the list and it will filter the display, making it very easy to find a particular script or UDF when you have a large number of scripts and UDFs in your database.

 

 

Script Editor - Much Improved Undo/Redo - The undo/redo functionality in the script editor is now greatly improved. When undoing actions, Alpha Five now undoes 'blocks' of work rather than a single character at a time. Also, the number of undo levels has been increased to 50 from 20. Since undo works at the 'block' level rather than the character level, the effective increase in the size of the undo buffer is significantly bigger.

Script Editor Tabs - Rightclick Menu- You can now right click on a tab to close the tab, or save the script.

Script Editor - Switching Tabs - When you switch tabs from one script to another, Alpha Five remembers whatever text was selected when you return to a script.

Action Scripting Improvements

Action Scripting - Xdialog Genie - Set Dialog Background - The Xdialog Genie now allows you to specify the background for the Xdialog. You can specify a solid fill of any color, a gradient fill, or an image background.

 

Action Scripting - New 'SQL' Category - There is a new category in Action Scripting called 'SQL'. These actions all use AlphaDAO to connect to the remote database. Under this category the following new actions can be selected:

 

Execute DELETE query on a SQL Database Execute a query to delete records in a SQL database.
Execute UPDATE query on a SQL Database Execute a query to update records in a SQL database.
Execute INSERT query on a SQL Database Execute a query to insert records into a SQL database.
Execute SELECT query on a SQL Database Execute a query to select records in a SQL database.
Connect to SQL database Open a connection to a SQL database.
Close connection Close a connection.

 

These actions are an ideal way for Xbasic programmers to learn the syntax for using AlphaDAO to work with remote databases.

 

Action Scripting - Forms Category - 'Open EmbeddedBrowse Companion Form' Action -  This action allows you to open a modal, pop-up form to edit the current record in an embedded browse, or to add a new record to the table whose records are shown in an embedded browse.

 

Action Scripting - Xdialog Genie - Property Grid Control - The Xdialog genie now allows you to create dialog boxes that contain property grid controls. A property grid is a very powerful way for collecting information from a user. Property grids can have multiple levels of headings (like a tree control), they allow the properties to be sorted and they allow you to define "builders" (i.e. pop up dialog boxes) to set the values of properties. See example in 'Learning Xdialog' for methods to set focus to individual items in the PropertyGrid and to control the open/close state of categories. There are seven different 'styles' available for the property grid. Shown below are 3 of the available styles:

 

 

Action Scripting - New 'Prompt using Check List Box Dialog' action - A new action allows you to create check box listboxes as shown below:

 

 

Action Scripting - Open Form/Browse Action  - 'Base' or 'User' Filter -  Now lets you decide if the filter that you specify in the genie should be applied as a "base" filter or a "user" filter. Previously the genie did not offer a choice and always applied the filter as a "base" filter. This meant that after the form/browse had been opened, the user could not remove the "base" filter - any filters defined by the user were applied in addition to the base filter. Now, if you choose the "user" filter option in the genie, once the form has been opened, the user is free to remove the filter and apply another filter.

 

Web Applications Improvements

Application Server - Speed - The speed with which the Application Server can serve up resources (i.e. images, linked CSS and JS files etc.) has been speeded up significantly.

 

Security Framework - The Security Framework allows you to easily add robust security to your web application. It creates log-in pages for users to log into the application and it lets you specify security for each page in your application. You can specify security down to the field level in a Grid components. Security is specified at the Group level. I.e. permissions are assigned to specific groups of users and then users are assigned to particular groups. The Security Frameworks automatically deals with issues such as lost passwords, 'remember me', session duration, etc. so that you don't have to program these behaviors yourself. If you are building a web app that uses a security framework, then V8 Security Framework will save you a huge amount of programming effort.

 

Grid Components - Arguments - Arguments are a major new feature that allow you to more easily define filter expressions that reference variables, or cookies. Previously, if you wanted to reference a page, session or cookie variable in a filter expression, you needed to use Xbasic to override the settings for the component in the .A5W page that loaded the component. Now, you can define an argument and specify where that argument gets its value from. For example, you could define an argument called :whichUser and specify that this argument gets its value from the session.user variable. When you define the Grid component, you can specify the Filter property as: Username = :whichUser. At run-time, if the variable that the argument is bound to does not exist, you can optionally tell your Web application to dynamically generate a page to prompt for the missing arguments.

 

Grid Designer - Selected Fields Show in Bold - The Grid designer now shows selected fields in bold. This makes it easy when you have a lot of fields in a table to see which fields have been selected, and which have not been placed on the Grid.

 

 

Grid and Dialog Designer - Show Icon for Control Type - The list of selected fields/controls is now shown with an icon representing the type of control that will be used to display the field. This makes it very easy to see, for example, that the City field in a grid is being displayed in a Dropdownbox control.

 

 

Grid and Dialog Designer - Complex Layouts - Multi-column layouts -   When you define a Columnar or Stacked style for a Grid or Dialog Component, you can now specify how many columns to use for the layout. Previously, (in the case of a Columnar layout), Alpha Five automatically assumed a two column layout (one column for labels, and another for controls). With a multi-column layout, you can specify that certain controls must always end a row, or must always start a row. The list of selected Fields shows where forced breaks have been inserted.

 

 

 

 

Here is an example of a Grid using a 3-column layout (using the column breaks shown in the above diagram):

 

 

 

Dialog Component - Layout Calculation mode - There are two modes - Standard and Pre-calculated. The pre-calculated mode computes the HTML at design time, and so at run-time, the Dialog component displays extremely quickly. Of course, if you use the pre-calculated mode, then you can't use any Xbasic that would recalculate the layout of the dialog in an event handler.

New Control Types - Blurbs and Headings (apply only to 'form' type layouts)

 

Dialog and Grid Components - New Layout Options - There are several new options that allow you much more control over the layout of Dialog and Grid components.

Dialog Components - Client side calculations. You can now define dialog components that have client side calculations. For example, you might have a field called 'price' and another called 'quantity'. After the user has filled in these two fields, the total will be displayed in the browser without requiring a server round trip. Alpha Five automatically converts your calculated field expression into the necessary Javascript.

Dialog Components - Show/Hide - Enable/Disable - You can now define expressions that will automatically cause certain controls on your dialog to show or hide or become enabled or disabled without requiring a server round trip. For example, you might have a field on your dialog asking if someone has ever been pregnant. Your dialog component can automatically hide this control if the user entered 'male' as their sex.

SQL Reports in Web Applications - You can now create Web Applications that include SQL Reports (which are displayed in the browser as PDF files). Requires Enterprise Edition of Alpha Five. Previously, it was only possible to display reports that were based on native Alpha Five tables (i.e. .dbf files).

SQL Reports are standard Alpha Five reports, labels and letters that are based on data from remote SQL databases. Unlike reports that are based on native Alpha Five tables (in which the reports definitions are stored in the table library files - tablename.ddd, tablename.ddm and tablename.ddx, or the set library files - setname.sex, setname.sem and setname.sex), SQL report definitions are stored in the 'Database Library' files (databasename.alb, databasename.alm and databasename.alx - where databasename is the name of the Alpha Five database - the .adb file). When you publish your Web project files, these 'Database Library' files must also be published. The Publish dialog therefore has a new checkbox that allows you to publish the Database Library files.

The following sample .A5W page shows how you can print a SQL Report:

Notice how the fully qualified report name references the Database Library in which the report is stored (in this case 'sqlreporting.alb').

<%a5
Dim filename as c
filename = session.session_folder + chr(92) + "tempreport.pdf"
dim reportname as c
'The <databasename>.alb, .alm and .alx files (which contains the report definitions) are always published in the application
'root folder (same folder as the .a5i) file
dim libfolder as c
libfolder = a5_removetrailingbackslash(Request.ApplicationRoot) + chr(92)

' 'sqlreporting' is the name of the Alpha Five database that contains the SQL Report definitions.
reportname = "report1@" + libfolder + "sqlreporting.alb"
filename = report.saveas(reportname,"pdf","","",filename,.f.)
if file.exists(filename)
    response.redirect(session.session_url + "tempreport.pdf?" + time("hms3"))
else
    ?"Report 1 did not print"
end if
%>

In this next example, we show how argument values can be passed to the report. This example assumes that the SQL query on which the report is based contains an argument (e.g. SELECT * from Customers WHERE city = :whatcity).

 

<%a5
dim args as sql::arguments
args.set("whatcity","paris")
Dim filename as c
filename = session.session_folder + chr(92) + "tempreport.pdf"
dim reportname as c
dim libfolder as c
libfolder = a5_removetrailingbackslash(Request.ApplicationRoot) + chr(92)
reportname = "report3@" + libfolder + "sqlreporting.alb"
filename = report.saveas(reportname,"pdf","","",filename,.f.,null_value(),args)
if file.exists(filename)
    response.redirect(session.session_url + "tempreport.pdf?" + time("hms3"))
else
    ?"Report3 did not print"
end if
%>

 

When defining SQL Reports for use in a Web application, it is recommended that you always used named connection strings rather than hard coding a connection string into the report's data source. By using a named connection string, you can specify the actual value for the connection string in the Profile that is used to publish your web application.

Web Applications - Defining Profiles - Named Connection Strings - The Profile definition dialog now allows you to define different values for named connection strings for each Profile that you define. You can define named ADO and AlphaDAO connection strings.

The Xbasic code in an .A5W page can reference that value of a named connection string using the following example code:

For AlphaDAO connection strings: _A5_AlphaDAO_ConnectionStrings.get("myConnectionStringName")

For ADO connection strings: _A5_ADO_ConnectionStrings.get("myConnectionStringName")

 

 

Web Components - Grid and Dialog Component - Hyperlink Builder Genie - A typical requirement when building Web applications is to link from one page to another page that contains a Grid component, showing a filtered list of records in the target page. While this has always been possible, a new genie in V8 makes it very easy to construct the syntax for the hyperlink control.

 

 

Web Applications - Component CSS Files - Previously when the user modified style sheets for the Grid, Dialog and Navigation System components, the edits were stored directly in the Alpha Five program folder. Now, when a user wants to edit a style, a copy of the style (i.e. CSS files) is made and edits are applied to the copy. The copy can be made in the same folder as the current web project (this then becomes a 'locally' defined style), or in the parent folder of all of the web projects in the current Database (then then becomes a 'globally' defined style, and it  is visible to all web projects created in the current Database).

HTML Editor - Now allows you to open multiple documents in a single editor, with each document being displayed in its own tab. Previously, you could edit multiple documents, but each document opened a new instance of the HTML editor. The tabbed editor is much quicker and more convenient than multiple editors.

Format menu has 'Edit Style...' menu choice that allows you to edit embedded or linked CSS styles using the new CSS Style Builder.

Format menu allows you to attach CSS style sheet files to the current document.

Revert to Saved command

Html Editor - Source View - Source view now supports the same status bar as the Script Editor - this gives you single click access to any function in the .a5w page being edited in the editor.

HTML Editor - Editing 'Code only' Pages - If you open an .a5w page that contains only code (i.e. contains only <%A5 ...%> blocks, and no HTML tags), then the HTML editor will automatically open on the Source tab, regardless of what preference you have set in View/Settings/Preferences/HTML Editor/Default tab.

Web Components - Maintenance Component - The new Maintenance component is of use to users who build web applications against native Alpha Five tables (i.e. .dbf tables). It allows the tables on the server to be packed and re-indexed.

Web Control Panel - CSS Files - The Web Control Panel now has a new category, CSS Files. You can now create CSS files and save them as part of your project. Your .html and .a5w pages can link these CSS files. Alpha Five now includes a full-featured CSS Style Sheet builder. See "CSS Builder" for more details.

 

CSS Style Builder - Powerful new builder for editing and creating CSS style sheets.

 

 

Field Rules Improvements

Speed Glossary - The Speed Typing Glossary can now be dynamically changed using Xbasic. Previously, all Databases shared the same speed typing glossary. Now, using Xbasic, it is possible to dynamically populate the speed typing glossary. See description of the a5_load_speed_glossary() function for details.

Field Rules - Speed Typing Glossary - Previously, if a speed typing glossary had been defined, it was automatically used for all character fields, regardless of the setting for the 'Use speed typing glossary' checkbox in the Field Rules editor. Now, this setting is honored, allowing you to turn on/off the speed typing feature on a field by field basis.

Field Rules Editor - Field Selector - When you are editing field rules for a table with a large number of fields, navigating to a particular field to edit its rules can be difficult because the Field Rules editor lists the fields in natural order (i.e. the order in which the fields are defined). A new Field Selector dialog has been added that makes it very easy to go to any field in the table. To open the Field Selector, select Rules, Field Navigator from the menu. You can quickly find any field by typing into the Search box. Alpha Five will dynamically filter the list showing only those fields that include the search string that you type in.

Field Rules Editor - Field Selector
Field Selector in the Field Rules Editor

 

Field Rules Editor - Find Errors Utility - If you have a table with a lot of fields and many different field rules, finding errors in your Field Rules can be very difficult and time consuming. A new utility is available in the Field Rules editor (Professional and Enterprise Edition), that automatically checks for invalid expressions in your Field Rules. To launch the utility, select the Rules, Find Errors in Field Rules command.

Field Rules Editor - Find Errors Utility
Find Field Rule Errors Utility in Field Rules Editor

 

Field Rules - Tables Lookups - New Fresh Look for Popup Lookup Window - The buttons on the lookup window have a more modern look and the browse rows automatically implement alternate row shading.

 


 

Field Rules - Table Lookup - Memo, Image and RTF memo fields can now be filled in by a lookup field rule.

Improvements in Queries

 

Forms - Queries - Query Genie and Query By Expression. When you run a query and there is already a query in place, Alpha Five currently gives you the choice of searching in all records, or in the currently selected records. A new option will allow you to extend the current selection of records. So, for example, if you have run a search for "State = 'MA'", and you now search for "State = 'NY'", and you chose the "Extend current selection of records" option, the resulting selection of records will have customers in both 'MA' and 'NY'. 

 

Query Genie - Searching on Date and Time Fields - The query genie now has many more built-in options when searching on date and time fields. The new operators are:

 

 

Miscellaneous Improvements

Window Bar - New improved look for the Window Bar on the main Alpha Five screen.

The Window Bar has a fresh new look.

 

Printing ActiveX Controls - Support has been added for printing activeX controls in layouts.

 

E-mail - SSL and TLS Support - V8 can now send mail through SSL (Secure Sockets Layer) or TLS (Transport Layer Security <http://en.wikipedia.org/wiki/Transport_Layer_Security>). This feature is important because many SMTP servers require SSL or TLS connection when connecting remotely. Just as with web applications, SSL and TLS provide a layer of encryption when sending email. SSL SMTP connections ordinarily use port 465 and TLS SMTP connections use port 25. SMTP over SSL is sometimes referred to as SSMTP (Secure SMTP) or more recently, SMTPS.

Socket and SSLSocket Classes - Advanced developers who want to work directly with sockets can now use the new Socket and SSLSocket classes.
Alias Image Names - You can define aliases for image names. This is useful because you can change the images used in your code without having to change the code itself. You just change the alias definitions. For example:

ir = ImageResource.get()
nm = ir.GetBitmapNameMap()
nm.Initialize(<<%str%
a5_control:browse=$a5_browse
%str%)
ui_dlg_box("","{image=a5_control:browse}")
 

Memo field repair - You can now check the integrity of Memo fields, and repair damaged memo fields by right clicking on the table in the Control Panel and selecting the Utilities, Check/repair memo fields command.

Timer Object - A new high precision timer object allows for more precise timing of scripts. The following example demonstrates how to use the timer object:

Example:

 The following example can be executed in the Interactive window

dim t as util::timer ‘ Note that the timer starts automatically as soon as it is DIMmed

for i = 1 to 10;?t.elapsedmicroseconds;next

46206168.000000

46206215.000000

46206246.000000

46206277.000000

46206307.000000

46206338.000000

46206368.000000

46206399.000000

46206430.000000

46206460.000000

 

The time object has two methods:

    .Start() - restarts the timer after it has been stopped and resets the start time to the current time.

    .Stop() - stops the timer and saves the elapsed time

The timer object has three properties:

    .ElapsedMicroseconds

    .ElapsedMilliseconds

    .ElapsedSeconds

 

You can examine these properties at any time. You don't need to first stop the timer.

Statusbar - The status bar that appears at the bottom of the main Alpha Five window has been substantially improved.

You can now put an 'Abort' button (or hyperlink) in the status bar so that the user can have the option of aborting long running operations. You also have complete control over the layout of the statusbar. In support of the new 'Abort' button, the statusbar object now has two new methods:

.abort_check() - returns true if user hit an 'Abort' area on the statusbar.
.abort_reset() - allows you to check if the user really meant to abort, and if not, reset the abort state

In addition to the existing placeholders ( '$p' (percent), '$c' (count) and '$o' (out of count)) which can be used in the statusbar.percent() method, there are now the following new placeholders:


$g - progress meter placeholder - allows the progress meter to be placed anywhere within the statusbar text. If omitted, the progress meter is placed before any text (as in all previous versions of Alpha Five).
$b - abort button  - text will be 'Abort' unless you specify alternate text in between '{}' delimiters (i.e. $b{Quit import...})
$h - abort 'hyperlink' - instead of an 'Abort' button, you can use a hyperlink. Hyperlink text is specified between '{}' delimiters (i.e. $h{Click here to cancel})

 

Statusbar showing a percent indicator, an abort button and a hyperlink (as an alternative to a button for aborting)


Example:

' Reset the abort button...
statusbar.Abort_Reset()
for i = 1 to 40
    statusbar.Percent(i,40,"$b $g count: $c of $o percent $p% - $h{You can also click this hyperlink to abort}")
    if statusbar.Abort_Check() then
        if ui_msg_box("Stop","Abort the loop?",UI_YES_NO) = UI_YES_SELECTED then
            exit for
        else
            'If the user did NOT want to abort, simply reset the abort state...
            statusbar.Abort_Reset()
        end if
    end if
    'If you don't put in a sleep, the loop will run so fast you won't see anything
    sleep(1)
    'allow the user interface to be updated
    ui_yield()
next i
statusbar.clear()

 

Statusbar - Setting Update Frequency - The frequency with which the statusbar gets updated can be controlled using Xbasic (or from View/Settings/Preferences/Statusbar). The Xbasic command is:

a5.System_Mode_Set("statusbar_refresh_rate","1")
 

Running Alpha Five - Security Settings - Alpha Five now no longer requires Administrator rights to run. It will run with 'normal user' rights.

VISTA Support - Version 8 is designed to work with Microsoft Vista. Of course, it can also be used with Windows NT, 2000, and XP.

Compatibility - V8 is fully upwardly compatible with previous versions of Alpha Five. Version 8 is not downwardly compatible with previous versions. Layouts that are edited in V8 cannot be used in older versions. There are some layout created in V1 of Alpha Five that cannot be read by V8. The solution is to edit and resave these layouts in V7.

PDF Printing - PDF File Size Compression -  A new option is available to control the compression of JPEG images in a PDF file. You can now set JPEG Quality to 'High', 'Medium', 'Low' or 'No compression'. Setting JPEG Quality to 'Low' can result in as much as 95% compression in the resulting PDF file, with very little noticeable difference in the appearance of the PDF file. The default setting in V8 is 'Low'.

Control Panel - In 'Detail View' the columns are now wider so that in most situations all data is visible without having to manually resize columns. Sorting items by date now works correctly.
 

Network Optimization - Refresh Shadow - There was a limit on the number of tables in a network optimized database. This limit was hit when you tried to refresh a network optimized database. This limit has now been removed.

 

Reports and Letters - Shrinking Objects at Print Time -  Conditional objects and sub reports now support the 'can shrink' property. To set this property, you right click on the object and select 'Can shrink'. This now allows you to remove unwanted empty space in a layout when a sub-report or conditional object does not have any data.

 

Printing Reports and Other Layout Types - New Options in Xbasic Methods -  All of the methods that deal with printing/previewing layouts (e.g. .print(), .preview(), .saveas(), .send(), .archive()) take new optional arguments that are relevant when the layout is based on a SQL Data Source, or is based on a Passive-Link table. The new arguments are 'Arguments' and 'Options'.

The syntax for Report.Print() is now (other print/preview methods have similar syntax):

Report.Print(C LayoutName, [C filter [,C order [,p Arguments [, P Options]]]])

 

Where:

 

Arguments This parameter is used when the layout is based on a SQL Data Source, and the SQL query used to define the SQL Data Source uses arguments.

This parameter is used to pass in values for arguments used a SQL query. See example below.

Tip: If you want to specify an 'options' parameter, but no 'argument' parameter, you can specify null_value() for the 'argument' parameter.

Options When the Layout is based on a SQL Data Source (not a Passive-Link table):

 

Options.filter - Specify an optional filter that should be applied when the SQL query is executed on the server.

Options.order - Specify an order clause to replace the ORDER BY clause in the SQL query.

 

It is important to understand the difference between a filter specified using 'options.filter' and a filter specified as the second argument in report.print() method.

The filter specified using 'options.filter' is executed on the remote database server and therefore you must use SQL syntax to express the filter condition.

The filter specified by the 'filter' argument (the second argument in report.print()) is a local filter that is applied by Alpha Five after the data has been retrieved from the remote database.

Since it is a local filter, it must be expressed using regular filter syntax for .dbf tables. In general, filtering records on the server will be more efficient than filtering them locally.

You can specify both a remote filter and a local filter.

The same comments apply to the 'options.order' and the local 'order' parameter.

 

When the Layout is based on a Passive-Link table:

Options.PassiveLinkTables.Refresh - Options are 'Prompt', 'Yes', 'No'.

 

'Prompt' - display a prompt asking if the passive-link table should be refreshed

'Yes' - automatically refresh the passive-link table

'No' - do not refresh the passive-link table.

 

The default option for Alpha Five is 'No' (Note that for QReportBuilder, the default option is set to 'Prompt')

 

See examples below.

 

Examples

Example 1

Assume that you have a report that is based on a SQL Data Source that uses this query:

SELECT * FROM customers WHERE city = :whatCity

dim args as sql::arguments

args.set("whatCity","Boston")

report.print("CustomerList","","",args)

 

Because the 'args' object is passed in to the report.print() method, Alpha Five will use the value of 'Boston' for the ':whatCity' argument and will not prompt for a value. If 'args' was not passed in, Alpha Five would prompt for a value for the ':whatCity' argument.

 

Example 2

In this example, which which is also based on a SQL Data Source, we specify a filter clause (a WHERE clause in SQL terminology) to be executed on the server:

 

dim options as p

options.filter = " balance > 1000 AND balance < 2000"

report.print("customerList","","",null_value(),options)

 

Notice that since we did not want to pass in a value for 'arguments' we specified 'null_value()' to indicate that we wanted to use the default value for this optional parameter.

 

Example 3

In this example which is based on a passive-link table, we cause a dialog to be displayed asking the user if they want to refresh the data:

dim options as p
options.PassiveLinkTables.Refresh = "Prompt"
report.preview("CustomerList","","",.f.,.f.,null_value(),options)
 

File, Open Database Command - Automatic Import of Access and Excel Data - When you select the File, Open Database command from the top menus, the resulting dialog box now lets you select .mdb (Access) and .xls (Excel) files in addition to .Adb (Alpha Five Databases) and .dbf (Alpha Five tables). If you select a .mdb or .xls file, Alpha Five will automatically create a new database with the same name as the .mdb or .xls file, and it will import all of the data in the Access or Excel files.


 

Import Genie - Ascii Files - Many improvements in the Import Genie for importing delimited and fixed length ascii files. If the ascii file includes values with a currency prefix, these values will now be automatically recognized and imported as numeric values. Previously, they were imported a text values.

 

Global Table Search Utility - The new Global Table Search utility allows you to search across all tables in your database for a particular piece of data. This utility is useful if you have many tables in a database and are not sure in which table a particular piece of data is stored. To access the Global Table Search, right click on white space in the Control Panel when the Tables/Sets tab has focus and select Utilities, Find tables that contain a specified data value. You can also launch this utility using the SearchTables() Xbasic command.

 

Global Table Search allows you to search for data across all tables

 

Table Finder Utility - The new Table Finder Utility allows you to search for the tables that contain a specified fieldname. Wildcard searches are allows. E.g. find call tables that contain the 'lastname' field. To access the Table Finder Utility, right click on the white space in the Control Panel when the Tables/Sets tab has focus and select Utilities, Find tables that contain a specified fieldname. You can also launch this utility using the Tablefinder() Xbasic command.

 

Table Finder allows you to find tables that contain a specified field name.

 

 

 

Command Line Switches to Start Alpha Five - Two new command line switches are supported when Alpha Five is started.

-HIDE Starts Alpha Five and immediately hides it.
-EXECUTEANDEXIT Shuts down Alpha Five after the command executes. The motivation for this switch is that it allows existing scripts to be called without having to modify these scripts and add a command to close Alpha Five at the end of the script. Note: The command will execute before the Control Panel has loaded. Therefore, you will need to fully qualify table names in scripts (e.g. table.open("c:\data\customer") as the Control Panel will not be available to resolve short names.

 

Example:

start /wait alpha5 “c:\test\batchcommandtest\batchcommand” –hide –nosplash –executeandexit –command=script_play(“MyCommand”)
 

 

 

 

What's New in Xdialog

Summary of New Xdialog Features

Background Images You can now specify an image to use as the background for an Xdialog.
Background Colors for Regions Different regions on an Xdialog can now have their own background colors.
Background Gradient Colors Xdialog can now have gradient backgrounds. The same set of gradients that are supported for From backgrounds can be used for Xdialogs. See the {windowstyle} command.
Clipboard change events
When the contents of the clipboard changes, the specified event will fire. See the {on_clipboard_change} command.
Colors You now have extremely fine control when you specify the color of any object on an Xdialog. You can adjust hue, luminosity and saturation, and can specify relative colors.
Color Picker Control When you use the %C% directive to turn a text box into a color picker, a new enhanced color picker is displayed.
Comments in Xdialogs You can now add comments to Xdialog body strings in the same way that comments are added to scripts (i.e. by using a single quote). The {removecomments} command must be included in the Xdialog body.
Conditional Sections Creating conditional sections in an Xdialog is now easier, especially if you have nested conditions. See the {condition_begin} and {condition_end} commands.
Contexts The new {context} command allows you to create an Xdialog that is automatically shown/hidden when a context is activated/deactivated.
Cursor Icon You can now specify what bitmap to use for the cursor when the mouse is over a control. See the {cursor} command.
Drop-Down Dynamic Buttons Drop-Down Dynamic buttons are useful when you have limited real estate on a dialog and you have a button that can perform several different actions.
Foreground/Background Colors of Controls You can now set the foreground and background color for the following controls on an Xdialog: Textbox, Frame, Line, Radio Buttons, Checkboxes and Buttons. The background color setting is only honored for textbox controls.
Frame Object Improvements The frame object now allows you to use blue text for the frame label. This is in compliance with the standard Windows conventions. See the {blueframe} command.
Hyperlink buttons The {hyperlink} command allows you to create buttons that look like hyperlinks.
Images The {ImageViewer} control allows you to load image from files on disk and view them in a window on an Xdialog.
Improved Xdialog Layout Features The {cellspillover} command now makes it easier to lay out Xdialogs.
MDI Windows are Easier to Create Creating MDI Xdialog windows is now much easier because Alpha Five can take care of showing/hiding/closing the menus and toolbars for the window automatically when the window gets and looses focus, or is closed. Previously, you had to script all of these actions yourself in the Xdialog's Activate and Deactivate events. See the {context} command.
Property Grids Xdialogs can now include Property Grid controls. Property Grids are used extensively throughout the Alpha Five user interface. For example, the AlphaDAO Import Genie is built using a Property Grid. Use the Xdialog Genie in Action Scripting to create a Xdialog with a Property Grid.
Show/Hide Events You can now specify event handlers for when an Xdialog is shown or hidden. See the {On_show} and {On_hide} commands.
Scrollable Regions The {beginembedded}, {scrollable} and {endembedded} commands can now be used to create scrollable regions in an Xdialog.
System Colors You can now use system color names so that your Xdialogs will look good even when the user changes their theme settings.
Tab Control Improvements Many more options for creating tab controls on Xdialogs. See the {tabband} command.
Tree Control Improvements - Use the {Data=value} directive to specify what value is returned when each node in the tree is selected

- Specify a custom message to display when a branch in a dynamically populated tree control is expanded. See the {Expand} command.

New Xdialog Commands and Features

Background Images - You can now specify an image to use as the background for an Xdialog. This allows you to create extremely nice looking Xdialog windows. You can specify an image filename (.jpg, .bmp or .png file), you can specify an internal image (i.e. an image stored in the Database - and shown in the Code tab on the Control Panel).

Xdialog with an image as the background

 

There are four different Xdialog commands for specifying image backgrounds. These are:

For Absolute option, you can specify an image alignment option. The alignment options are top left, top right, bottom left, bottom right, top center, bottom center, right center, left center and center. For an example, "Images as Backgrounds" in the "What's new in V8" section in the sample "Learning Xdialog" database.

 

 

Background Colors for Regions. Previously the background color an an Xdialog could only be set using the {Background} command and the same color was used for the entire Xdialog. Now you can define a color for each region in the Xdialog. Regions are defined using the {Region} command. For an example, see "Learning Xdialog - What's New in V8 - Regions can have their own background colors."

 

Regions in Xdialog can now define their own background colors.

 

Background Gradient Colors - Xdialog boxes can now have gradient backgrounds. The new {windowstyle=GradientStyleName} command is used to specify a gradient style. Alpha Five ships with over 22 different gradient background styles. For more examples, see "Learning Xdialog - What's New in V8 - Different Gradient Background Styles."

Example of gradient background using the 'Gradient Horizontal Top' style and a blue color with a white accent color.

Example of gradient background using the 'Gradient Vertical Glass' style and a yellow color with a white accent color.

 

Clipboard Change Events - the {on_clipboard_change} Xdialog Command - Allows you to watch for changes in the clipboard contents and fire an event when the clipboard contents is changed.

dim clipb as c = ""
clipb = ""
dlg_title = "Clipboard watcher"
ui_modeless_dlg_box(dlg_title,<<%dlg%
{on_clipboard_change=clip}
[%M%.50,30clipb];
<&Close!close>
%dlg%,<<%code%
if a_dlg_button = "close" .or. a_dlg_button = "" then
a_dlg_button = ""
ui_modeless_dlg_close(dlg_title)
else if a_dlg_button = "clip"
a_dlg_button = ""
if clipboard.Has_Data()

    'we only want to respond to clipboard events if text was placed onto the clipboard.

    'if a bitmap is placed on the clipboard, for example, we want to ignore it.

    'clipboard.Has_Data() (with no arguments) will only be .t. if text is placed on the clipboard
    clipb = clipboard.Get_Data()+crlf()+replicate("=",30)+crlf()+clipb
end if


end if
%code%)
 

 

Colors  - Specifying Color Values and Tweaking Colors - You now have extremely fine control over colors when you specify color values in Layouts and in Xdialogs. You can adjust the hue, luminosity and saturation of any color, or specify an explicit red, green or blue content for any color.

The following table summarizes the codes for the different tweaks that can be applied to a color:

H Hue -  Range of values: (0-360) (Wraps around if you specify a value greater than 360)
L Luminosity - Range of values: (0-100)
S Saturation- Range of values:  (0-100)
R Red- Range of values:  (0-255)
G Green - Range of values: (0-255)
B Blue - Range of values: (0-255)

 

The following examples show more detail:

Relative Adjustments - Use + or - to indicate direction of change
+L10Red Start with 'Red' and increase luminosity by 10
-L10Red Start with 'Red' and reduce luminosity by 10
+H25#60,180,30 Take "#60,180,30" and shift the hue by 25
Absolute Adjustments - Use ## to mark the beginning of an 'absolute' tweak followed by a list of color component value pairs. The list is delimited by '+'
##B50+G25Red Take the color 'red' and set the blue value to 50 and the green value to 25
##H240+L50+S100 This would create the color blue (set the hue to 240, luminosity to 50, saturation to 100)
Combining Relative and Absolute Ajustments
-H25##L75Light Blue Take "Light Blue", shift the hue -25 (more towards green), and force the luminosity to be 75


Example:

ui_dlg_box("Tweaking Colors",<<%dlg%
{region}
{background=-L10Red}
The background has been 'tweaked'
{endregion};
{lf};
{region}
{background=Red}
The background has NOT been 'tweaked'
{endregion};
%dlg%)
 

 

 

Color Picker Control - When you create an Xdialog that prompts for a color name, the %C% construct, which is used to turn a regular textbox into a color picker has been enhanced to call the new color picker. For example:

 

dim color as c = "White"
ui_dlg_box("Select Color",<<%dlg%
Color name: [%C%.40color];
%dlg%)

 

 

 

Comments in Xdialog - Adding Comments to the Body String - It is now easier to add comments to the body of an Xdialog. You no longer have to use the {comment=} command. You can now just type any comment as you would in a script, by starting the line with a single quote. The single quote must be the first character on the line, and the Xdialog body must include the {removecomments} command on a line by its self. For example:

 

ui_dlg_box("test",<<%dlg%
{removecomments}
'This is a comment - it won't show up because of the \{removecomments} command;
{lf};
Name: [.20Name];
{lf};
<10OK> <10Cancel>;
%dlg%)

 

Conditional Sections - {condition_begin=logical_expression} and {condition_end} Xdialog Commands - Allows you to make portions of an Xdialog visible if a logical expression is .T. This command is a variant of the {condition} command, and is particularly useful when you have nested {condition} statements. Each call to {condition_begin} adds the specified logical expression to the current 'ambient' logical expression (i.e. the logical expression which controls whether the controls in an Xdialog are visible or not). The corresponding {condition_end} command removes the most recently added logical expression from the current 'ambient' logical expression.

 

a = .f.
b = .f.
c = .f.
ui_dlg_box("",<<%dlg%
(a) A;
{condition_begin=a}
(b) B \(requires A is true);
{condition_begin=b}
(c) \(C requires A and B are true);
{condition_begin=c}
This is 3 conditions deep \(requires A, B and C are true);
{condition_end}
{condition_end}
{condition_end}
This is at the top level \(does not require that A is true);
%dlg%)

 

Here is how the same Xdialog would be created using the older {condition} command:

a = .f.
b = .f.
c = .f.
ui_dlg_box("",<<%dlg%
(a) A;
{condition_begin=a}
(b) B \(requires A is true);
{condition=a.and.b}
(c) \(C requires A and B are true);
{condition=a.and.b.and.c}
This is 3 conditions deep \(requires A, B and C are true);
{condition=.t.}
This is at the top level \(does not require that A is true);
%dlg%)
 

 

Contexts - The {Context} Command - A 'context' allows you to create menus and toolbars in memory without actually showing them. The menus and toolbars are created within a 'named' context, and are not actually shown until the ui_context_set() command is used to set the named context as the active context. Once a context has been created, switching between named contexts is extremely fast. The following script demonstrates how contexts can be created and activated. A more practical example of how contexts are used can be found in the demo 'Learning Xdialog' database. See the 'What's new in V8 - MDI Style windows' script.

 

menucode = "ui_msg_box(\"Command\",\"Command = \"+a_command)"

'Create a new context and create a menu and toolbar in the context
'Notice that when you execute the ui_top_menu() command the menu does NOT display and that when you
'execute the ui_modeless_dlg_box() command, the toolbar does NOT display. Notice also that the Xdialog definition for the toolbar
'includes the command {context} indicating that the Xdialog is being created in the context. Without the {context} command, the Xdialog would have
'been immediately visible.
ui_context_create("Context1")
ui_top_menu(comma_to_crlf("One,Two,Three"),menucode)
ui_modeless_dlg_box("test1","{context}{dockable=top}<one><two><three>")


'Now create another context and create a menu and two toolbars in this context.
'Again, nothing is visible yet.
ui_context_create("Context2")
ui_top_menu(comma_to_crlf("A,B,C"),menucode)
ui_modeless_dlg_box("test1","{context}{dockable=top}<A><B><C>")
ui_modeless_dlg_box("test2","{context}{dockable=top}<D><E><F>")



ui_modeless_dlg_box("Test Context",<<%dlg%
<set context 1!context1> <set context 2!context2>;
{lf};
<Close>;
%dlg%,<<%code%
if a_dlg_button = "Close" then
    ui_modeless_dlg_close("Test Context")
else if a_dlg_button = "context1" then
    ui_context_set("context1")
else if a_dlg_button = "context2" then
    ui_context_set("context2")
else if a_dlg_button = "restoreContext" then
    ui_context_set(currentcontext)
end if
%code%)

 

 

 

Cursor Icon - {cursor} Xdialog Command - Allows you to specify the bitmap to use for the cursor when the mouse is over a control for which a flyover format string has been defined .

To turn on a custom cursor insert the command {cursor=image name} in the Xdialog before the controls for which the command will apply. To turn off the custom cursor, use the command {cursor=}.

The following system cursor bitmap names can be used, in addition to any user defined or built-in bitmap:

 

$sys_cursor_normal
$sys_cursor_ibeam
$sys_cursor_wait
$sys_cursor_cross
$sys_cursor_up
$sys_cursor_size
$sys_cursor_icon
$sys_cursor_sizenwse
$sys_cursor_sizenesw
$sys_cursor_sizewe
$sys_cursor_sizens
$sys_cursor_sizeall
$sys_cursor_icocur
$sys_cursor_no
$sys_cursor_hand
$sys_cursor_appstarting
 

 

ui_dlg_box("Cursors",<<%dlg%
When button 1 has focus, the standard cursor is used:;
{cursor=}
<%B=N;O={J=C,C}{C=Blue}{F=Tahoma,8,u}Button1;OF={J=C,C}{C=Light Blue}{F=Tahoma,8,U}Button1%!Button1_clicked>;
{lf};
{lf};
{lf};
When button 2 has focus, the Windows 'hand' cursor is used:;
{cursor=$sys_cursor_hand}
<%B=N;O={J=C,C}{C=Blue}{F=Tahoma,8,u}Button2;OF={J=C,C}{C=Light Blue}{F=Tahoma,8,u}Button2%!Button2_clicked>;
{lf};
{lf};
{lf};
When button 3 has focus, the Alpha Five 'save' bitmap is used for the cursor:;
{cursor=$a5_save}
<%B=N;O={J=C,C}{C=Blue}{F=Tahoma,8,u}Button3;OF={J=C,C}{C=Light Blue}{F=Tahoma,8,u}Button3%!Button3_clicked>;
%dlg%,<<%code%
if left(a_dlg_button,6) = "button" then
ui_msg_box("Event",a_dlg_button )
a_dlg_button = ""
end if
%code%)

 

Note that this example could have been coded more easily using the new {hyperlink} command.

 

 

Drop-down Dynamic Buttons  (DDD Buttons) - DDD buttons are useful if you want to have a button perform several different actions (by allowing the user to select from a menu), but still have single click access to the most recently performed action (by clicking on the button). The images below indicate how a DDD button appears on an Xdialog. For examples of how to use DDD Buttons in an Xdialog see "Learning Xdialog - What's New in V8 - Drop-down dynamic buttons".

 

 

When the mouse is not over the 
DDD Button it shows as a button
with a drop down arrow.

When focus is over the button,
the selection rectangle

When the down arrow is clicked,
the menu appears.

After a selection is made, the
button image is the last selection.

 

 

Foreground/Background Color of Controls - {color=foregroundColor On backgroundColor} Command - Allows you to set the foreground and background color for the following controls on an Xdialog: Textbox, Frame, Line, Radio Buttons, Checkboxes and Buttons. The background color setting is only honored for textbox controls. To turn off the color setting and revert to the system default colors, use {color=}.

The following example shows an Xdialog that uses the {color} command:

 

dim lastname as c = "Jones"
dim sampleText as c = a5.color_enum()
ui_dlg_box("",<<%dlg%
{font=tahoma,10,B}Color and Font Styles Demo;{font=}
{wrap=140}
The controls shown here \(line, frame, button, radio button, checkbox and textbox) use the default font color - WinText on Win3D background.;
{line=1This is a Line Control};
{lf};
{frame=1,1Frame}
{region}
<Button> Radio buttons: (num:One)(num:Two) Checkbox:(checked) {sp=5}Edit control: |[.40lastname];
{endregion};
{lf};
Here, we repeat all of the controls, but we set the color to Blue on a Yellow background. Note that the background color only applies to textbox controls.;;
{color=Blue on Yellow}
{lf};
{line=1This is a Line Control};
{lf};
{frame=1,1Frame}
{region}
<Button> Radio buttons: (num:One)(num:Two) Checkbox:(checked) {sp=5}Edit control: |[.40lastname];
{endregion};
{color=}
{lf};
Here we set some static text to Red on a White background. Note that despite the fact that we set the background color, the static text still has the same background color as the Xdialog. That's because the background color only applies to textbox controls. To create static text with a background color, you must use an 'owner draw' static text string.;
{color=Red on White}
This is red on white.;
{color=}
{lf};
{lf};
Here is a read-only textbox. Because the background color is Win3D, it suggests to the user that the control is read-only. Note however, that the control is not disabled. The User can still scroll the text.;
{color=WinText on Win3d}
[%M;R%.100,4SampleText];
{color=}
%dlg%)



 

 

Frame Object Improved - {blueframe} Command - Same as the {frame} command, but draws the frame using blue text.

 

 

ui_dlg_box("Blue Frame",<<%dlg%
{blueframe=1,1:Information}
{region}
Name: | [.20name];
Title: | [.20title];
{endregion};
{lf};
<OK> <Cancel>;
%dlg%)

 

 

Hyperlinks Buttons - {hyperlink} Command - Allows you to create buttons on an Xdialog that look like hyperlinks.

 

Example:

dim button1Enabled as l = .t.
dim dlg_body as c
dlg_body = <<%dlg%
When button 1 has focus, the Windows 'hand' cursor is used:;
{hyperlink=Button1!Button1_clicked?Button1Enabled};
{lf};
(button1Enabled) Enable button?;
%dlg%

ui_dlg_box("Cursors",dlg_body,<<%code%
if left(a_dlg_button,6) = "button" then
    ui_msg_box("Event",a_dlg_button )
    a_dlg_button = ""
end if
%code%)

 

Images - {ImageViewer} Command - Allows you to display image files on an Xdialog. See Learning Xdialog for an example

 

Improved Xdialog Layout Features - Easier Table Layout using the {CellSpillover} Command - Layout out Xdialogs is made easier now using the {cellspillover} command. This command allows you to achieve the same control over a tabular layout that the 'colspan' command gives one when laying out an HTML table. See "Simulating the HTML 'colspan' command using {cellspillover}" in the "What's new in V8" section in the sample "Learning Xdialog" database.

 

Property Grids  - Xdialogs can now contain property grid controls. A property grid is a very powerful way for collecting information from a user. Property grids can have multiple levels of headings (like a tree control), they allow the properties to be sorted and they allow you to define "builders" (i.e. pop up dialog boxes) to set the values of properties. See example in 'Learning Xdialog' for methods to set focus to individual items in the Property Grid and to control the open/close state of categories. Creating Xdialogs with Property Grids is easy, using Action Scripting. There are seven different 'styles' available for the property grid. Shown below are 3 of the available styles:

 

 

Show/Hide Events - {On_show} and {On_hide} Commands - Xdialog now has two new events, OnShow and OnHide that can be used when the Xdialog also includes a {Context} command. The {Context} command causes the Xdialog to automatically be hidden when the context loses focus, and to automatically be shown when the context regains focus. The OnShow event fires when the Xdialog is shown and the OnHide event fires when the Xdialog looses is hidden because the context looses focus.
Example:
To test this example, open the script editor and create a new script. Paste into the script editor and run. Then change to a different window and then return to the script editor.

ui_modeless_dlg_box("Test",<<%dlg%
{on_show=showit}
{on_hide=hideit}
{startup=init}
{context};
State: [.40state];
<close> <hide>
%dlg%,<<%code%

if a_dlg_button = "close" .or. a_dlg_button = "" then
ui_modeless_dlg_close("Test")
else if a_dlg_button = "init" then
state = "Initialized"
else if a_dlg_button = "showit" then
state = "Shown"
else if a_dlg_button = "hideit" then
state = "Hidden"
end if
%code%)
 

 

 

Scrollable Regions - The {beginembedded}, {scrollable} and {endembedded} commands can now be used to create scrollable regions in an Xdialog. For example:

dim dlg_title as c
dlg_title = "Alpha Five"
ui_dlg_box(dlg_title,<<%dlg%
This text is outside the scrollable region.;
{lf};
{blueframe=1,1:The region inside this frame is a scrollable region - 100 characters wide and 10 lines high.}
{beginembedded=100,10}
{scrollable}
{region}
Name1: |[.20name1];
Name2: |[.20name2];
Name3: |[.20name3];
Name4: |[.20name4];
Name5: |[.20name5];
{endregion};
{endembedded};
<Close>;
%dlg%,<<%code%
%code%)
 

System Colors - You can now use system color names when specifying colors in Xdialog. This allows you to create Xdialogs that will look correct even when run on a system where the user has set their machine to a different color scheme from the settings on your machine. For example:

ui_dlg_box("test","{background=system-threedshadow}name [.20name];")
ui_dlg_box("test","{background=system-threeddarkshadow}name [.20name];")

 

 

The various system colors are listed in the example below. The following Xbasic script can be used to demonstrate the different system colors:

dim systemColors as c
systemColors = <<%txt%
ActiveBorder
ActiveCaption
AppWorkspace
Background
ButtonFace
ButtonHighlight
ButtonShadow
ButtonText
CaptionText
GrayText
Highlight
HighlightText
InactiveBorder
InactiveCaption
InactiveCaptionText
InfoBackground
InfoText
Menu
MenuText
Scrollbar
ThreeDDarkShadow
ThreeDFace
ThreeDHighlight
ThreeDLightShadow
ThreeDShadow
Window
WindowFrame
WindowText
%txt%
'Make a CRLF delimited string using owner-draw Xdialog syntax that

'sets the background color for each row to the named system color.
systemColors = *for_each(x,"{B=system-" + x + "} " + x,systemColors)

ui_dlg_box("System Colors",<<%dlg%
[%O={@@}%.100,20selected^#systemColors];
{text=20,1selected};
%dlg%)

 

 

Tab Control Improvements - The standard {Tab} command now has new styling options, and a new {tabband} command gives even more options.

The {tab} command now supports the '%s=tabband%' and '%s=styled%' directive. (in all of the examples, the tabs could be positioned on top, bottom, left or right by using J=T, J=B, J=L, or J=R) For example:

Using this tab command: {tab=%s=tabband;J=T%page} Using this tab command: {tab=%s=styled;J=T%page} Using this tab command: {tab=page}

The new {tabband} command allows you to create a tab strip with more options than the {Tab} command. See Learning Xdialog for a complete example.

 

Tab band with images on the tabs Tab band with no images


 

Tree Control - {EXPAND=message} Command - Used in a dynamically expanding tree control to display a message while the function that expands a branch of the tree is executing.

 

Tree Control - {Data=value} Directive - You can now you the {Data=value} command in each branch of tree control to indicate what value should be returned when this branch of the tree is selected. Previously, Alpha Five returned the full path of the current selection.  For example, say that the tree control displayed the following data:

 

CA|Los Angeles|Studio 1
CA|Los Angeles|Studio 2
CA|San Francisco|Apple
MA|Boston|Fidelity
MA|Burlington|Alpha
MA|Burlington|Oracle

 

If 'Alpha' was selected in the tree, the tree control variable would be set to 'MA|Burlington|Alpha'. Now, if the data displayed by the tree control uses the {Data=value} directive in a branch, the 'value' is returned. For example, assume that the tree now displays:

 

CA|Los Angeles|Studio 1
CA|Los Angeles|Studio 2
CA|San Francisco|Apple
MA|Boston|Fidelity
MA|Burlington|{Data=0001}Alpha
MA|Burlington|Oracle

 

Now, when 'Alpha' is selected, the tree control variable is set to '0001'. However, when 'Oracle' is selected, the tree control variable is set to 'MA|Burlington|Oracle' because there is not {Data=value} directive in that branch of the tree.

 

Tree Control - Dynamically Expanding Branches - It is now easier to create dynamically expanding trees by specifying functions as the event handler to expand tree branches. Dynamically expanding trees are useful when it takes a long time to fully populate all levels in a tree control. For example, assume that a tree control showed this data (a list of the scripts, functions, tables and colors defined in the current database):

 

txt = <<%txt%
scripts\{EXAPND=Getting list of scripts}!a5.script_enum(2)
functions\!a5.udf_enum(2)
colors\!a5.color_enum()
tables\!a5.table_enum()
%txt%
ui_dlg_box("test",<<%dlg%
[%X;S=BRL;D="\";%.60,15current^<txt]
%dlg%)

 

When the user expands the 'scripts' branch, the event handler (specified by the text after the '!' symbol)  is called. The event handler in this case is the function 'a5.scripts_enum(2)'. This function returns a CR-LF delimited list of scripts. You can optionally include an {EXPAND} directive before the event handler. This directive specifies the message that should be shown in the tree control while the event that handles the expansion of the tree is executing.

 

 

New Xbasic Functions and Methods

Summary of Selected New Functions and Methods

*AT_Multi() Returns the position of the Nth occurrence of any one of the strings in a CR-LF delimited list of search strings in another string.
*ATC_Multi() Case insensitive version of *AT_Multi()
*Tree_from_dependencies() Takes a CRLF delimited list of parent-child relationships and creates a string that can be used by a tree control on an Xdialog.
*Tree_from_dependencies() Takes a CRLF delimited list of parent-child relationships and creates a string that can be used by a tree control on an Xdialog.
A5_decrypt_string() Decrypts a string that was encrypted using a5_encrypt_string()
A5_decrypt_binary() Decrypts a blob that was encrypted using a5_encrypt_binary()
A5_encrypt_string() Encrypts a string using a specified algorithm.
A5_encrypt_binary() Encrypts a blob using a specified algorithm.
A5_get_base_filter() Takes a pointer to an open form and returns the base filter for the form.
A5_get_base_order() Takes a pointer to an open form and returns the base order.
A5_load_speed_glossary() This function can be used to populate the speed typing glossary with information from any table.
A5_open_EmbeddedBrowse_CompanionForm() This function is designed to be used in a button or an event on a form that is based on a set with one-to-many child tables. It opens a pop-up form to edit the current record in an embedded browse, or to add a new record to the table whose records are shown in an embedded browse.
a5_is_PassiveLinkSet() Returns .t. if the set includes one or more passive-link tables.
a5_is_PassiveLinkTable() Returns .t. if the specified table is a passive-link table.
a5_PassiveLinkTableDefine() Create a passive link table using Xbasic (rather than using the user interface).
a5_RefreshPassiveLinkSet() Refreshes the data in a set that is based on one or more passive-link tables.
a5_RefreshPasiveLinkTable() Updates the data in a Passive-Link table.
a5ws_ExportUsers()Export selected records from the current project web users table to an external table.
a5ws_Get_Group_Assignments()Return a CR-LF delimited list of users assigned to a particular group in the current project.
a5ws_Get_Groups()Return a CR-LF list of web groups for the current project.
a5ws_Get_Guid_From_User()Returns a web user GUID from a userid.
a5ws_Get_Guid_From_Group()Returns a web group GUID from a group name.
a5ws_Get_Page_List()Get a List of Pages Currently allowed by the Web Security settings in CR-LF list.
a5ws_Get_Security_Ques()Get Web Security Questions in CR-LF list.
a5ws_Get_User_Assignments()Return a CR-LF delimited list of groups assigned to a particular userid in the current project.
a5ws_Get_User_From_Guid()Returns a userid from a user_guid in the current project.
a5ws_Get_User_Values()Return values from web user table as CurrentForm.<fieldname>.value for each field in user table.
a5ws_Get_Users()Show a CR-LF list of users for the current project.
a5ws_ImportUsersDBF()Import selected User records from an external table into the current project web users table.
a5ws_lockoutUserRelease()Release a web user that is currently locked out. May be used on a Web Page, desktop script, or UDF.
a5ws_lockoutUserSet()Lock out a user for a specified period of time. May be used on a Web Page. May be used in a desktop script or UDF.
a5ws_logged_In_User_Values()Show available field values for current loggin in user.
a5ws_logoutUser()Remove all login information for current logged in user. May be used on a Web Page.
a5ws_OpenWebSecurity()Display the Web Security options Menu for this project.
a5ws_PageSecurity()Set security for web pages. May be used on a Web Page. May be used in a script or UDF.
a5ws_Save_User_Values()Save values in the CurrentForm controls that match fields in the user table.
a5ws_SecurityActive()Determine if web security is active.
a5ws_SecuritySettings() Opens the Web Security Settings dialog for project. May be used in a script or UDF.
a5ws_SecurityQuestions() Opens a list of current Web security questions for project. May be used in a script or UDF.
a5ws_User_File_Field_List()Retrieve a list of active fields in CR-LF list for web user table.
a5ws_User_Groups_Dialog()Displays the add user and groups dialog for the current Web project.
BlobCompare() Compares two blob variables and returns 0 if they are identical, 1 if the first blob is greater than the second blob and -1 if the second blob is greater than the first one.
BlobEqual() Compares two blob variables and returns .t. if the blobs are identical.
Compilestringtemplate() Takes a string template that contains placeholders for variables or expressions and creates an object that is a compiled version of the string. Once the compiled version of the string has been created, the object's .Output() method can be called to replace the placeholders with their actual values.
date_FirstDayOfMonth() Returns the first day of the month for a given date.
date_FirstDayOfPreviousMonth() Returns the first day of the previous month for a given date.
date_is_anniversary() Returns .t. if a date has the same month and day as a reference date.
date_is_in_last_month() Returns .t. if a date falls in the previous month.
date_is_in_previous_quarter() Returns .t. if a date falls in the previous calendar quarter.
date_is_in_previous_week() Returns .t. if a date falls in the previous week. (Weeks are defined using the ISO standard - i.e. they begin on a Monday)
date_is_in_previous_year() Returns .t. if a date falls in the previous year.
date_is_in_same_week() Returns .t. if a date falls in the same week as a reference date. (Weeks are defined using the ISO standard - i.e. they begin on a Monday)
date_is_in_this_month() Returns .t. if a date falls in this month.
date_is_in_this_month_todate() Returns .t. if a date falls in this month-to-date.
date_is_in_this_quarter() Returns .t. if a date falls in this calendar quarter.
date_is_in_this_quarter_todate() Returns .t. if a date falls in the current calendar quarter-to-date.
date_is_in_this_week_todate() Returns .t. if a date falls in the current week-to-date. (Weeks are defined using the ISO standard - i.e. they begin on a Monday)
date_is_in_this_year() Returns .t. if a date falls in this year.
date_is_in_this_year_todate() Returns .t. if a date falls in the current year-to-date.
date_is_today() Returns .t. if a date is the same as today's date.
date_is_yesterday() Returns .t. if a date is the same as yesterday's date.
date_LastDayOfMonth() Returns the last day of the month for a given date.
date_LastDayOfPreviousMonth() Returns the last day of the previous month for a given date.
date_quarterNumber() Returns the calendar quarter in which a date falls.
date_QuarterStartEnd() Returns a pointer with two properties, .StartDate and .EndDate with the start and end date for a specified calendar quarter in a specified year.
Evaluate_String() The evaluate_string() function is useful if you have a string that contains placeholders for variables or expressions. The function replaces the placeholders with the variable's value.
Fedex_delivery_status() Contacts the Fedex web site and returns the delivery status of a package.
Form.ViewLinked() This new method is similar to the .ViewQueried() method in that it opens a form showing selected records. However, with the .ViewLinked() method, you can specify how the target form (i.e. the form that is opened by this method) is linked to a parent table, and Alpha Five will automatically ensure that the correct values are entered into the linking fields when a record is edited or created, ensuring that the records edited/created in the target form remain properly linked to their 'parent' record.
Form.ViewQueried() This method now takes an additional optional argument specifying if the filter that is applied to the form should be a base query, or a regular query.
<layout>.get_field_objects() Method This method is available for all layout objects (e.g., Form, Report, Label, etc). It takes a fully qualified fieldname as an argument (e.g. customer->lastname), and returns a CRLF delimited list of all of the object on the layout that are bound to that field.
OSName() Returns the formatted name of the operating system. E.g. "Microsoft Windows XP"
OSPlatform() Currently returns "Windows" but future versions of Alpha Five might run on other platforms.
OSVersion() Returns the version of the operating system as a string. XP is version "5.1". Vista is "6.0". Note: a5_os_info() returns the same information and more, but is much slower because it uses WMI.
Page_First() For use in Report Layouts, for a calculated field placed in a page header or footer. Displays the value from the first record printed on the page.
Page_Last() For use in Report Layouts, for a calculated field placed in a page header or footer. Displays the value from the last record printed on the page.
SelectBestProcessor() This function takes no arguments and assigns the process affinity to the highest CPU index (0, 1, ...) with the lowest number of occurrences of alpha5.exe, a5desktopserver.exe and a5applicationserver.exe.
ShortTime_Extract() Extracts the hours, minutes or seconds from a short time value.
Sql_query_builder() Opens the SQL Query builder.
SQL_QueryImport() Imports the result of a SQL query from a remote SQL database using AlphaDAO to connect to the remote database.
SQL_resultset_preview() Opens a dialog box to preview the first n rows in a resultset created by executing a SQL query on an AlphaDAO connection to a remote database.
SQL_TableExport() Exports data from a local Alpha Five table to a remote SQL database using AlphaDAO to connect to the remote database.
SQL_TableImport() Imports a table from a remote SQL database using AlphaDAO to connect to the remote database. ou to import the result of an arbitrary SQL query.
StrEqual() Returns .t. if two strings are equal based on the options selected.
Table.OpenMap() Opens a table and returns a pointer to the table. A "view" of the fields in the table is shown. The view specifies which fields from the underlying table are to be shown. Each field in the view can map to a single field in the underlying table (in which case the field in the view will be updateable), or it can map to an expression (in which case the field in the view will not be updateable).
<tbl>.Record_Content_Get() Same as table.external_record_content_get(), but works on an open table pointer.
UI_dlg_event_occurred() Instructs an Xdialog to refresh on the next idle cycle.
UI_dlg_Parent_Get() Returns the title (if any) of the Xdialog from which a specified Xdialog was launched.
UI_get_check2() Displays a set of choices in a multi-column checkbox - listbox.
UI_get_check2P() Same as Ui_get_check2() function, but instead of returning a character result (with the list of selected choices), returns a dot variable with three properties - .lastbutton ('OK', 'Cancel'), .selected (list of choices that were selected) and .selected_in_selection_order (list of choices that were selected, in the order in which they were selected).
UI_Wait_Until() Same as the wait_until() function, except it processes pending UI before going into the wait loop.
UniqueNameGet() Takes a CRLF delimited list of existing names and a suggested name and increments a counter at end of suggested name until it is unique.
UPS_delivery_status() Contacts the UPS web site and returns the delivery status of a package.
USPS_delivery_status() Contacts the USPS web site and returns the delivery status of a package.
USPS_Zipcode_Lookup() Contacts the USPS web site and looks up the zip code for the specified address.
Win_Create_Shortcut() Creates a Windows shortcut in the specified location.
Win_Special_Folder()  Returns the path to the Windows special folder specified, such as the Desktop folder, the Start Menu folder, and the Personal Documents folder.
Word_duplicates() Takes a CR-LF delimited list of words and returns a CR-LF delimited list of the words in the list that are duplicated.

 

 

 

 

*AT_Multi() Function - Returns the position of the Nth occurrence of any one of the strings in a CR-LF delimited list of search strings in another string. Is case sensitive. Use *ATC_Multi() for case insensitive.

Syntax: N position =  *AT_MULTI(C search_strings,C string[,N occurrence])
Example:

? *at_multi(comma_to_crlf("oranges,apples"),"This string contains apples and oranges")
= 22
? *at_multi(comma_to_crlf("oranges,apples"),"This string contains apples and oranges",2)
= 33
? *at_multi(comma_to_crlf("oranges,apples"),"This string contains apples and oranges",3)
= 0

 

*ATC_Multi() Function - Case insensitive version of *AT_Multi()

 

*Tree_from_dependencies() Function - Takes a CRLF delimited list of parent-child relationships and creates a string that can be used by a tree control on an Xdialog.
Syntax: result = *tree_from_dependencies(C Relationships, C FormatString)
Where:

Relationships CRLF delimited string that defines the parent-child relationshipds.
FormatString String that defines how to parse each line in Relationships for the parent and child data. Formatstring must contain 'P' and 'C' placeholders to designate the parent and child. For example, if the data in Relationships is of the form parent|child, then FormatString should be "P|C".

Example:

dim relationships as c

relationships = <<%str%
Beverage|Wine
Beverage|Beer
Beer|Lager
Beer|Ale
Lager|Cervesa
Lager|Pilsener
Ale|Stout
Ale|Porter
Ale|Weizen
Wine|White Wine
Wine|Red Wine
White Wine|Reisling
White Wine|Chardonnay
White Wine|Pinot Gris
Red Wine|Cabernet
Red Wine|Shiraz
Red Wine|Nebbiola
Red Wine|Pinot Noir
Red Wine|Merlot#%str%

 

Dim result as c

result = *tree_from_dependencies(relationships,"p|c")
 

'Display the result in an Xdialog. The 'D="|"' directive tells the Xdialog tree control that the | is the tree delimiter

ui_dlg_box("",<<%dlg%
[%S=BLR;D="|"%.100,20indx^<result];
%dlg%)
 

 

A5_BaseQuery_to_Filter() Function  - Converts a base filter to a query. End users cannot remove a form's base query, but they can remove a filter. For example, if a form  is opened using the Form.ViewQueried() method, the filter specified as an argument to this method is applied as a base query (by default), which means that the 'show all' button is not enabled, and the user cannot remove the base query. This function converts the base query to a regular filter, which means that the 'show all' button becomes enabled, and a user can therefore remove the filter from the form.
 

A5_decrypt_string() Function - Decrypts a string that was encrypted using a5_encrypt_string()

A5_decrypt_binary() Function - Decrypts a blob that was encrypted using a5_encrypt_binary()

A5_encrypt_string() Function - Encrypts a string using a specified algorithm. Supported algorithms include "blowfish", "des3", "desx" and "idea". This function is much more secure than the encrypt_string() function which has been in all previous versions of Alpha Five.

A5_encrypt_binary() Function - Encrypts a blob using a specified algorithm. See a5_encrypt_string().

A5_get_base_filter() Function - Takes a pointer to an open form and returns the base filter for the form. If a filter is specified in the form's Filter property at design time, it becomes the form's base filter. The 'show all' command cannot be used to release the base filter. If a user applies a filter to a form at run time, the filter is applied in addition to the base filter.

A5_get_base_order() Function - Takes a pointer to an open form and returns the base order. If an order is specified in the form's Order property at design time, it becomes the form's base order.
 

A5_load_speed_glossary() Function - This function can be used to populate the speed typing glossary with information from any table.

Syntax: a5_load_speed_glossary([dbfname [, OldValueFieldName [,  NewValueFieldName]]])

Where:

dbfname Name of the table from which speed typing glossary entries should be loaded. If dbfname  is blank, the default speed typing glossary is loaded. If dbfname  is '<Clear>' then all entries in the speed typing glossary are cleared from memory.
OldValueFieldName The name of the field in dbfname that contains the lookup value in the glossary. When the user types the lookup value, it is replaced by the long value. E.g. "alpha" is replaced by "Alpha Software"
NewValueFieldName The name of the field in dbfname that contains the long value.

 

A5_open_EmbeddedBrowse_CompanionForm() Function - This function is designed to be  used in a button or an event on a form that is based on a set with one-to-many child tables. It opens a pop-up form to edit the current record in an embedded browse, or to add a new record to the table whose records are shown in an embedded browse. While it has always been possible to write the Xbasic code to do this, this function simplifies the process by automatically performing the resynchronization necessary to cause the embedded browse to correctly display the edits that were made in the pop-up form. A new action in Action Scripting has been added to automate calling this function.

The syntax for the function is:

a5_open_EmbeddedBrowse_CompanionForm()  as p (mode as c, targetFormName as c, formPointer as p, browseName as c, targetTablePrimaryKey = "Recno()", linkDef = "", otherOptions = null_value())
 

 Where:

Mode

"Edit" or "Add" - indicates if you want to edit the current record in the embedded browse, or add a new record

targetFormName Name of the form to open to edit the records.
formPointer A pointer to the form whose records you want to edit. If this function is called from an event on the form whose records you want to edit, then you can specify 'topparent.this' to get a pointer to the current form.
browseName The object name of the embedded browse whose records you want to edit.
targetTablePrimaryKey If the Mode is set to 'edit', you need to indicate a primary key expression for the target table (the table whose records you will be editing). This allows Alpha Five to find the correct record to show in the pop-up form. The default value for this argument is 'recno()'. If you are editing data in local .dbf tables, then the default value for this argument should be sufficient. However, you could also specify any expression that uniquely identifies a record in the target table. E.g. 'invoice_number'.
linkDef This optional argument defines the link between the target table (the table whose records you will be editing)  and its parent table. The default value for this argument is blank. If it is blank, then Alpha Five will automatically determine the link definition from the definition of the set on which the form is based. However, if the set definition links the target table and its parent table on an expression, rather than on matching field names, you will need to specify a link definition. The link definition tells Alpha Five what values to put into the linking fields in the target table when a new record is created. Without this information, the new record would not be properly linked to its parent record. The format for the linkDef parameter is a CR-LF delimited list of this form: targetTableFieldName = parentTableFieldName
otherOptions A optional dot variable that specifies additional optional properties. These are:

otherOptions.X_position - x co-ordinate of the pop-up form. Can be 'left', 'center', 'right' or an absolute position in pixels.

otherOptions.Y_position - y co-ordinate of the pop-up form. Can be 'top', 'center', 'bottom' or an absolute position in pixels.

otherOptions.RestrictNavigation - (defaults to .t.) - Indicates if the user can navigate to other records when the pop

Example:

a5_open_embeddedBrowse_companionForm("edit","editLineItems",topparent.this,"browse1")

 

This will open a form called 'editLineItems' to edit the current record shown in the embedded browse called 'browse1'. The 3rd argument, 'topparent.this' is just a pointer to the current form.

 

a5_is_PassiveLinkSet() Function - Returns .t. if the set includes one or more passive-link tables.

a5_is_PassiveLinkTable() Function - Returns .t. if the specified table is a passive-link table.

a5_PassiveLinkTableDefine() Function - Create a passive link table using Xbasic (rather than using the user interface).

Syntax: A Result = a5_PassiveLinkTableDefine(A DataSourceDef  [,C Tablename  ])

Where:

Result If DataSourceDef is a dot variable with a definition of the datasource for the passive-link table, result will be a dot variable with two properties: HasError (.t. or .f.) and ErrorText (with the text of any error that was encountered).

If DataSourceDef is "Help", then a text string is returned describing the syntax for the dot variable that defines the datasource.

DataSourceDef Either "Help" (to get the syntax for the datasource definition), or a dot variable that defines the datasource. When defining the DataSourceDef, the only required properties are:

ds.ConnectionString = 'specify the connection string
ds.SQLSelectStatement = 'specify the SQL SELECT statment, or stored procedure name
 

Tablename The filename of the table to create. If DataSourceDef is "Help" then no tablename need be specified. Otherwise, you must specify this argument.

Example:

?a5_passiveLinkTableDefine("help")
= dim ds as p
ds.ConnectionString = 'specify the connection string
ds.SQLSelectStatement = 'specify the SQL SELECT statment, or stored procedure name
ds.Arguments = 'specify what arguments (if any) are used in the SQL statement. Format is a comma delimited list with :argumentName|type. e.g. :whatCity|C,:whatId|N
ds.SQLType = 'specify the syntax type: "Portable" or "Native"
ds.AdvancedOptions.SizeToFit = 'specify if character columns are automatically sized to fit: .T. or .F.
ds.AdvancedOptions.ConvertTimeToDate = 'specify if Date/Time values should be convert to Date values: .T. or .F.
ds.AdvancedOptions.DefineFieldOverrides = 'specify if column definition overrides will be supplied: .T. or .F.
ds.AdvancedOptions.OverrideDefinitions = 'A crlf delimited list of fieldspecs to override. E.g. Customer,C,20,0 ""

'In this example, we create a passive link table. Notice that we only specify the two properties for the DataSourceDef.

'All other properties of the DataSourceDef have default values.
delete ds
dim ds as p
ds.ConnectionString = "{A5API='Access',A5Syntax='Access',FileName='C:\Northwind\northwind.Mdb',UserName='Admin'}"
ds.SQLSelectStatement = "select customerid, contactname, city from customers"
a5_passiveLinkTableDefine(ds,"c:\pl_customers.dbf")

 

'In this example, we create a passive link table that uses arguments. Notice that the ds.Arguments property is defined.

'All other properties of the DataSourceDef have default values.
delete ds
dim ds as p
ds.ConnectionString = "{A5API='Access',A5Syntax='Access',FileName='C:\Northwind\northwind.Mdb',UserName='Admin'}"
ds.SQLSelectStatement = "select * from customers where city = :whatcity"

ds.Arguments = ":whatCity|C"
a5_passiveLinkTableDefine(ds,"c:\pl_customers.dbf")
 

 

'In this example, we create a passive link table on a table in an Excel spreadsheet.

'Since Excel does not return the size of each column, Alpha Five defaults to creating all character columns with a width of 255.

'This is very inefficient and it slows down the import.

'Therefore, for Excel, we set the ds.AdvancedOptions.SizeToFit property to .t.

delete ds
dim ds as p
ds.ConnectionString = "{A5API='Excel',A5Syntax='Excel',FileName='c:\myexceldata.xls'}"
ds.SQLSelectStatement = "select * from [sheet1$]"

ds.AdvancedOptions.SizeToFit = .t.
a5_passiveLinkTableDefine(ds,"c:\pl_exceldata.dbf")

 

'In this example we define the field types for certain of the columns in the passive-link table.

'This overrides the default column sizes for these columns that Alpha Five would otherwise use.

delete ds
dim ds as p
ds.ConnectionString = "{A5API='Access',A5Syntax='Access',FileName='C:\Northwind\northwind.Mdb',UserName='Admin'}"
ds.SQLSelectStatement = "select customerid, contactname, city from customers"

ds.AdvancedOptions.DefineFieldOverrides = .t.

ds.AdvancedOptions.OverrideDefinitions = <<%txt%

customerid,c,10,0

city,c,50,0

%txt%

a5_passiveLinkTableDefine(ds,"c:\pl_customers.dbf")
 

a5_RefreshPassiveLinkSet() Function - Refreshes the data in a set that is based on one or more passive-link tables.

a5_RefreshPasiveLinkTable() Function - Updates the data in a Passive-Link table.

Syntax: P Result = a5_RefreshPasiveLinkTable (tablename as c, FlagReportResults = .f.)

Where:

tablename Name of the passive-link table
FlagReportResults If .t. then displays message box with results of operation, including error messages
Result Contains the result of the operation. Result has two properties, 'Error' (.t. or .f.) and 'ErrorText' (a description of any errors)

 

A5WS_ExportUsers() Function - Used in Web Security. Displays a dialog to export selected records from the current project web users table to an external table.  It is normally called from an option on the web Users and Groups dialog.

A5WS_Get_Group_Assignments() Function - Used in Web Security. Returns a list of members of a named group.

Syntax:Result as C = a5ws_Get_Group_Assignments( Group_Name as C [, Request as P [, FlagWeb as L ]] )

Where:

Group_name The name of a security group in the current project.
request Optional. The Request system variable. This variable explicitly passes all request variables to the function. Required if run from a web page.
FlagWeb Optional. Default = .F. .
  • .T. = Format suitable for use in a list, checkbox, or radio control on a web page
  • .F. = CR-LF delimited list of userid values only
Result CR-LF delimited list of users by userid assigned to a particular group in the current project.

 

a5ws_Get_Groups() Function - Used in Web Security. Returns a list of security groups defined for the current web project.

Syntax Result as C = a5ws_Get_Groups( [ Request as P [, FlagWeb as L ]] )

Where:

request Optional. The Request system variable. This variable explicitly passes all request variables to the function. Required if run from a web page.
FlagWeb Optional. Default = .F. .
  • .T. = Format suitable for use in a list, checkbox, or radio control on a web page
  • .F. = CR-LF delimited list
Result Contains the result of the operation. A list of security groups in the current web project.

 

It can be used without parameters to return a list of groups defined for the current selected web project.

It can be used on a web page or in a web componetn event to retrieve a list of user security groups for use in a check box control, a dropdown list, a radio lbutton list, or a listbox control in a dialog component. Typically used in the Server Activate event of a dialog component.

 

a5ws_Get_GUID_From_User() Function - Used in Web Security. Returns the unique ID (GUID) assigned to a userid in the web security user table.

Syntax: Result  as C = a5ws_Get_GUID_From_User( User as C [, Request as P ] )

Where:

User The userid value of a person in the web security user table.
request Optional. The request variable. Required if run from a web page.
Result The unique ID assigned to the user. (GUID)

Example:

?A5WS_Get_GUID_From_User("alfred")

= "d2756e91632942ac93472e5423f0de58"

 

a5ws_Get_GUID_From_Group() Function - Used in Web Security. Returns the unique ID (GUID) assigned to a security group in the web security group table.

Syntax: Result  as C = a5ws_Get_GUID_From_Group( Group_Name  as C [, Request as P ] )

Where:

User The group_name value of a group in the web security group table..
request Optional. The request variable. Required if run from a web page.
Result The unique ID assigned to the group. (GUID)

Example:

?A5WS_Get_GUID_From_Group("Administrators")

= "78f972bb35644ffc95fbf894bc524382"

 

a5ws_Get_Page_list() Function - Used in Web Security. May only be used in a web component. Retrieves a CR-LF delimited list of pages for use in a drop down list control in a dialog component. The pages are those allowed or defined as needing login for the current project security. Typically used in the Server Activate event of a dialog component. The request system variable is required

a5ws_Get_Security_Ques() Function - Used in Web Security. May only be used in a web component. Retrieves a list of security questions for use in a drop down list control in a dialog component. Typically used in the Server Activate event of a dialog component. The request system variable is required

a5ws_Get_User_Assignments() Function - Used in Web Security. Returns a list of the groups to which a person belongs.

Syntax: Result  as C = a5ws_Get_User_Assignments( User as C [, Request as P ] )

Where:

user The userid of a person in the web security user table.
request The request variable. Required if run from a web page.
Result A list of web security groups to which the specified user belongs.

Example:

?A5WS_Get_User_Assignments("doris")

= "Marketing"

 

a5ws_Get_User_From_GUID() Function - Used in Web Security. Returns the guid for a userid value in the user table. Is the opposite of a5ws_Get_GUID_From_User().

Syntax: Result  as C = A5WS_Get_User_From_GUID( GUID as C [, Request as P ] )

Where:

GUID The unique identifier of a person in the web security user table. (GUID)
request The request variable. Required if run from a web page.
Result A list of web security groups to which the specified user belongs.

Example:

?Adim guid as C

guid = A5WS_Get_GUID_From_User("doris")

? guid

= "9036155807a2443782ba61ed2a974471"

 

? A5WS_Get_User_From_GUID(guid)

= doris

 

a5ws_Get_User_Values() Function - Used in Web Security. Can only be used in the events in a dialog component to populate control values from fields in the User table. The name of each control in the dialog must exactly match the name of the field in the user table. A list of valid field names can be found by using the A5WS_User_File_Field_List() function. Typically used in the Server Initialize event of a dialog component. You can also use this function in the Server After Validate event to repopulate values after a save.

Syntax: Result  as P = a5ws_Get_User_Values( CurrentForm as P, Request as P [, FlagWeb as L ] )

Where:

CurrentForm The CurrentForm variable defined in the web dialog component
request The system request variable
FlagWeb Optional. Default = .T .
  • .T. = Indicates it is being run from a web page
  • .F. = Internal Use Only
Result Returns a pointer variable with two possible values
Result.errors = .F.
Result.error_text = ""
error_text will be blank if no errors were reported

Example:

a5ws_get_user_values(CurrentForm,request)

 

a5ws_Get_Users() Function - Used in Web Security. Returns a list of the userid values in the user table.

Syntax: Result  as C = A5WS_Get_Users( [ Request as P [, FlagWeb as L ]] )

Where:

request Optional. The Request system variable. This variable explicitly passes all request variables to the function. Required if run from a web page
FlagWeb Optional. Default = .T .
  • .T. = Format suitable for use in a list control on a web page
  • .F. = CR-LF delimited list
Result A CR-LF delimited list of the userid values in the web security user table.

 

a5ws_ImportUsersDbf() Function - Used in Web Security. Displays a dialog to import selected user records from an external table into the current project web users table.  It is normally called from an option on the web Users and Groups dialog.

a5ws_LockOutUserRelease() Function - Used in Web Security. Releases a locked User Value. If the function finds no match in the locked out list, nothing happens. Will return True or False to indicate if the lock is released

Syntax: Result_Flag as L = a5ws_LockOutUserRelease( User_Value as C )

a5ws_LockOutUserSet() Function - Used in Web Security. Locks out a user value for a specified amount of time.

Syntax: Result_Flag as L = a5ws_LockOutUserSet( User_Value as C [, Until_Time as T ] )

Where:

user_value A user value to be temporarily disabled.
until_time Optional time value. Default = user is locked out indefinitely. A time value in the future, when the user ID will be enabled.
Result_Flag T. = The lock out was set.
.F. = The lock out was not set.

Example: This example locks out the user with the user id of "joe@email.com" until Jan 1, 2008 at 10:00 pm.

dim ut as T
ut = ctodt("01/01/2008 10:00:00 00 pm")
a5ws_LockOutUserSet("joe@email.com", ut)

 

a5ws_Logged_In_User_Values() Function - Used in Web Security. May only be used on A5W pages or components. Populates a dot variable with field values from the user table for the current logged in user. A list of valid field names that may be returned can be found by using the a5ws_User_File_Field_List function. All property values are character values regardless of the field type. If a user is not logged in, all returned values will be blank. There are a few restricted field values that are not returned for security reasons.

Syntax:a5ws_Logged_In_User_Values( Return as P, Request as P, Session as P )

Where:

request The Request system variable. This variable explicitly passes all request variables to the function.
session The Session system variable. This variable explicitly passes all session variables to the function.
Return A dot variable containing returned values from the user table.

Example: The following code on a web page defines a dot variable called pUser and then populates the variable. If the userid and email parameters are found for pUser, the values are shown on the web page.

<%A5
dim pUser as p
a5ws_logged_in_user_values(pUser,request,session)
if eval_valid("pUser.userid") = .T. then
?"User id: " + pUser.userid +"<br>"
end if
if eval_valid("pUser.email") = .T. then
?"User Email: " + pUser.email +"<br>"
end if
%>

 

a5ws_LogoutUser() Function - Used in Web Security. May only be used on A5W pages or components. Removes all login information for the current logged in user.

Syntax: Result_Flag as L = a5ws_LogoutUser( Session as P, Request as P, Response as P )

Example: a5ws_LogoutUser( Session, Request, Response )

 

a5ws_OpenWebSecurity() Function - Opens the Web Security dialog menu on the desktop

a5ws_PageSecurity() Function - Opens the Page Security Assignment dialog on the desktop.

a5ws_Save_User_Values() Function - Used in Web Security. Can only be used in the events in a dialog component to validate and save values from controls in the component to fields in the web security user table. The name of each control in the dialog must exactly match the name of the field in the user table. A list of valid field names can be found by using the A5WS_User_File_Field_List() function. Typically used in the Server Validate event of a dialog component. If validation errors are detected, the CurrentForm will return an error ans the form will be redisplayed with the error messages shown at the top of the form. The user can then make corrections and resubmit the form.

Syntax: Result  as P = a5ws_Save_User_Values( CurrentForm as P, Request as P [, FlagWeb as L ] )

Where:

CurrentForm The CurrentForm variable defined in the web dialog component
request The system request variable
FlagWeb Optional. Default = .T .
  • .T. = Indicates it is being run from a web page
  • .F. = Internal Use Only
Result Returns a pointer variable with two possible values
Result.errors = .F.
Result.error_text = ""
error_text will be blank if no errors were reported

Example:

a5ws_save_user_values(CurrentForm,request)

a5ws_SecurityActive() Function - Used in web security to determine if web security is active. May only be used on A5W pages and web components in web applications. If the security framework is not activated, or the current security configuration has security inactive, the function will return False. It will return True if both conditions are met.

Syntax: Result_Flag as L = a5ws_SecurityActive (request AS P )

a5ws_SecurityQuestions() Function - Used in Web Security. Opens the Login Recovery Security Questions dialog, which allows you to edit the list of security questions for the current project. Can only be used on the desktop.

a5ws_SecuritySetting() Function - Used in Web Security. Open the Security Settings dialog, which allows you to configure web security for the project. Can only be used on the desktop.

a5ws_User_File_Field_List() Function - Used in web security. Retrieve a list of active fields in CR-LF list for the web security user table in the current project. The field list will be determined by the current security settings and will show only fields currently used. The Request system variable is only needed if the function is used on a web page or in a web component.

Syntax: Result as C = a5ws_User_File_Field_List AS C ( [ format as C,[ request as P]])

Where:

request Optional. The Request system variable. This variable explicitly passes all request variables to the function. Required in run from a web page
Format Optional. A display format information to use to output field information. Options are:
  • "n" = fieldname
  • "t" = simple field type
  • "w" = field width

    Default is fieldname only. If format is specified, the output will use the "|" delimiter between values.

Result A CR-LF list of web security user table fields used in the current web project.

Example:

?a5ws_User_File_Field_List("ntw")
= Email|C|40
Guid|C|36
PassEnt|T|17
PassExp|T|17
Password|C|40
RedirPage|C|60
RememberMe|L|1
Ulink|C|40
Userid|C|60

 

a5ws_User_Groups_Dialog() Function - Used in web security. Opens the Web Users and Groups dialog on the desktop

Syntax: a5ws_User_Groups_Dialog( [ Project as C ] ) Project is optional and is the name of a web project. A blank entry uses the currently selected project.

 

BlobCompare() Function - Compares two blob variables and returns 0 if they are identical, 1 if the first blob is greater than the second blob and -1 if the second blob is greater than the first one.

BlobEqual() Function - Compares two blob variables and returns .t. if the blobs are identical.

 

Compilestringtemplate() Function - Takes a string template that contains placeholders for variables or expressions and creates an object that is a compiled version of the string. Once the compiled version of the string has been created, the object's .Output() method can be called to replace the placeholders with their actual values. The placeholders are contained in curly brackets. This function is useful when you have a loop and would otherwise have called the evaluate_string() function. The following example shows how the function can be used to create an HTML table with data from query. If you are using Xbasic to code .a5w pages that display tables of data, this function will allow you to get significant performance improvements in your pages.

 

dim templateRow as c
templateRow = <<%txt%
<tr>
    <td>{t.CUSTOMER_ID}</td>
    <td>{t.FIRSTNAME}</td>
    <td>{t.LASTNAME}</td>
    <td>{t.COMPANY}</td>
    <td>{t.PHONE}</td>
    <td>{t.BILL_ADDRESS_1}</td>
    <td>{t.BILL_CITY}</td>
    <td>{t.BILL_STATE_REGION}</td>
    <td>{t.BILL_POSTAL_CODE}</td>
</tr>
%txt%

dim tableHTML as c = ""
t = table.open("customer")
dim p as p
p = compilestringtemplate(templateRow)
while .not. t.fetch_eof()
    *concat(tableHTML,p.output())
    t.fetch_next()
end while
tableHTML = "<table>" + crlf() + tableHTML + "</table>"
t.close()

a5_show_html(tableHTML)

 

 

 

date_FirstDayOfMonth() Function - Returns the first day of the month for a given date. If no argument is supplied, first day of current month.
Syntax: D Date = date_FirstDayOfMonth as d ( [date as D])
Where:

date Date relative to which the first day of the month is computed. If no date is supplied, today's date is used as the reference date.

 

date_FirstDayOfPreviousMonth() Function - Returns the first day of the previous month for a given date. If no argument is supplied, returns last day of the previous month for the current date.

Syntax: D Date = date_FirstDayOfPreviousMonth as d ( [date as D])
Where:

date Date relative to which the first day of the previous month is computed. If no date is supplied, today's date is used as the reference date.

 

date_is_anniversary() Function - Returns .t. if a date has the same month and day as a reference date.
 

date_is_in_last_month() Function - Returns .t. if a date falls in the previous month.
 

date_is_in_previous_quarter() Function - Returns .t. if a date falls in the previous calendar quarter.
 

date_is_in_previous_week() Function - Returns .t. if a date falls in the previous week. (Weeks are defined using the ISO standard - i.e. they begin on a Monday)
 

date_is_in_previous_year() Function - Returns .t. if a date falls in the previous year.
 

date_is_in_same_week() Function - Returns .t. if a date falls in the same week as a reference date.  (Weeks are defined using the ISO standard - i.e. they begin on a Monday)
 

date_is_in_this_month() Function - Returns .t. if a date falls in this month.
 

date_is_in_this_month_todate() Function - Returns .t. if a date falls in this month-to-date.
 

date_is_in_this_quarter() Function - Returns .t. if a date falls in this calendar quarter.
 

date_is_in_this_quarter_todate() Function - Returns .t. if a date falls in the current calendar quarter-to-date.
 

date_is_in_this_week_todate() Function - Returns .t. if a date falls in the current week-to-date. (Weeks are defined using the ISO standard - i.e. they begin on a Monday) 
 

date_is_in_this_year() Function - Returns .t. if a date falls in this year.
 

date_is_in_this_year_todate() Function - Returns .t. if a date falls in the current year-to-date.
 

date_is_today() Function - Returns .t. if a date is the same as today's date.
 

date_is_yesterday() Function - Returns .t. if a date is the same as yesterday's date.
 

date_LastDayOfMonth() Function - Returns the last day of the month for a given date. If no argument is supplied, last day of current month.
Syntax: D Date = date_LastDayOfMonth as d ( [date as D])
Where:

date Date relative to which the last day of the month is computed. If no date is supplied, today's date is used as the reference date.

 

date_LastDayOfPreviousMonth() Function - Returns the last day of the previous month for a given date. If no argument is supplied, returns last day of the previous month for the current date.
Syntax: D Date = date_LastDayOfPreviousMonth as d ( [date as D])
Where:

date Date relative to which the last day of the previous month is computed. If no date is supplied, today's date is used as the reference date.

 

date_quarterNumber() Function - Returns the calendar quarter in which a date falls.

date_QuarterStartEnd() Function - Returns a pointer with two properties, .StartDate and .EndDate with the start and end date for a specified calendar quarter in a specified year.
 

Evaluate_String() Function - The evaluate_string() function is useful if you have a string that contains placeholders for variables or expressions. The function replaces the placeholders with the variable's value. The placeholders are contained in curly brackets. If you need to include a curly bracket character in the string you can escape it by using a backslash (e.g. \{ or \} ). If you need to use the evaluate_string() function in a loop (as is typical in a web application where your 'string' is a template for a row in an HTML table and you need to loop over all of the rows in a query building up the complete HTML table), a related function, compilestringtemplate(), can be used for dramatic performance improvements. See "Compilestringtemplate() Function" for more details.

 

dim firstname as c = "Lenny"
dim lastname as c = "Brown"
dim dob as d = {12/12/1980}

string = "My name is {firstname} {lastname} and I was born on {dob}"
?evaluate_string(string)
= "My name is Lenny Brown and I was born on 12/12/1980"

dim v as p
v.firstname = "Sheila"
v.lastname = "Smith"
v.dob = {1/1/1972}
?evaluate_string(string,v)
= "My name is Sheila Smith and I was born on 01/01/1972"
 

Note that the placeholders can be expressions of arbitrary complexity. For example, the following is a valid string template:

string = <<%txt%

My full name is {upper(firstname) + " " + upper(lastname)} and I was born in {year(dob)}

%txt%

 

Fedex_delivery_status() Function - Contacts the Fedex web site and returns the delivery status of a package. See also UPS_delivery_status().

? fedex_delivery_status("9612019051986004770443")

= "Delivered"

? fedex_delivery_status("9612019051986004770000") 'invalid number

= ""

 

Form.ViewLinked() Method - This new method is similar to the .ViewQueried() method in that it opens a form showing selected records. However, with the .ViewLinked() method, you can specify how the target form (i.e. the form that is opened by this method) is linked to a parent table, and Alpha Five will automatically ensure that the correct values are entered into the linking fields when a record is edited or created, ensuring that the records edited/created in the target form remain properly linked to their 'parent' record.

 

P formPointer = Form.ViewLinked (C LayoutName , C LinkDefinition  [, C filter_expn  [, C order_expn [, C style  [, C  x_position [, C  y_position  [,  OtherOptions ]]]]]])

OtherOptions.Restrict_Navigation = .f.

 

 Where:

formPointer

A pointer to the form that is opened.

LayoutName The name of the form to open. This is called the 'target' form.
LinkDefinition A CR-LF delimited list of link conditions in the form of:

linkTableField = linkValue

 

e.g.

firstname = "john"

lastname = "smith"

Filter_expn An optional filter to apply (in addition to the filter implied by the LinkDefinition) when the target form is opened. For example using the sample LinkDefinition shown above, the target form is automatically filtered using

 

firstname = "john" .and. lastname = "smith"

 

If you only wanted to see records for John Smith where the transaction date was in January, you might specify a filter_expn of:

month(transactionDate) = 1

Order_expn An optional order expression.
Style The style in which the target form should be opened. Options are: null - open as a regular modeless form, 'dialog' - open as a modal form, 'dialog_newrecord' - open as a modal form showing a new record, 'hidden' - hidden until the .show() method is called on the form pointer, 'hidden-dialog' - hidden until the .show() method is executed on form pointer (or some other method that causes the form to become visible, such as .new_record() is called). Default value is null.
X_Position Left, Center, Right, Fill or an absolute position expressed in pixels. Default value is null, which uses the definition stored in the form layout.
Y_Position Top, Center, Bottom, Fill, or an absolute position expressed in pixels. Default value is null, which uses the definition stored in the form layout.
OtherOptions A dot variable. Currently supports a single property. OtherOptions.Restrict_Navigation. Indicates if navigation from record to record is allowed when the target form is opened. Typically, when the user is viewing the last record in a query and he/she navigates to the 'next' record, Alpha Five displays a new record. If you want to prevent the user from navigating to a new record, set this property to .t.

 

 

Example:

The following command opens the 'InvoiceItems' form and ensures that any records either edited or added are automatically linked to the correct parent record (which has an InvoiceNumber of 'INV1234'). Assume for demonstration purposes that the InvoiceNumber field in the target table (i.e. the table on which the target form is based) is called 'InvNum' (and not 'InvoiceNumber' as it might be called in the parent record).

 

dim LinkDef as c

LinkDef = "InvNum = \"INV1234\""

dim p as p

p = Form.ViewLinked("InvoiceItems",LinkDef)

 


 

Form.ViewQueried() Method - This method now takes an additional optional argument specifying if the filter that is applied to the form should be a base query, or a regular query. The default for this argument is .t., which means that the filter is applied as a base query. In V7, the filter is always applied as a base query. If the filter is applied as a base query, the 'show all' command cannot be used to release the base query. However, if the filter is applied as a regular query, the form will open showing the filtered records, but the user can use the 'show all' command to release the query and show all records in the form. In addition, the 'style' argument has a new option - 'Dialog_newrecord', which allows you to open the form as a modal dialog, displaying a new record.

 

<layout>.get_field_objects() Method - This method is available for all layout objects (e.g., Form, Report, Label, etc). It takes a fully qualified fieldname as an argument (e.g. customer->lastname), and returns a CRLF delimited list of all of the object on the layout that are bound to that field.

 

OSName() Function - Returns the formatted name of the operating system. E.g. "Microsoft Windows XP"

OSPlatform() Function - Currently returns "Windows" but future versions of Alpha Five might run on other platforms.

OSVersion() Function - Returns the version of the operating system as a string. XP is version "5.1". Vista is "6.0". Note: a5_os_info() returns the same information and more, but is much slower because it uses WMI.

 

Page_First() Function - For use in Report Layouts, for a calculated field placed in a page header or footer. Displays the value from the first record printed on the page.

Page_Last() Function - For use in Report Layouts, for a calculated field placed in a page header or footer. Displays the value from the last record printed on the page.

 

 

SelectBestProcessor() Function - This function takes no arguments and assigns the process affinity to the highest CPU index (0, 1, ...) with the lowest number of occurrences of alpha5.exe, a5desktopserver.exe and a5applicationserver.exe.  This function should balance the processor load better for terminal services and multiple server processes. The function returns true if the affinity was changed and false if it was not.

ShortTime_Extract() Function - Extracts the hours, minutes or seconds from a short time value.

Syntax: N Result = ShortTime_Extract(shortTime as Y, TimePart as c )

Where:

shortTime The short time value to analyze
TimePart Can be 'h', 'm', or 's' to return the hours, minutes, or seconds in the short time value.

 

Example:

st = ctot("8:32 45.345 pm")
?shortTime_extract(st,"h")
= 20
?shortTime_extract(st,"m")
= 32
?shortTime_extract(st,"s")
= 45.345

 

Sql_query_builder() Function - Opens the SQL Query builder.

Syntax is:

C Result = sql_query_builder(P Connection [, C DefaultSQLQuery])

 

The SQL Query Builder

 

The following Interactive Window example shows  how you can use Xbasic to open the query builder:

dim cn as sql::connection
cn.open("{A5API=Access,FileName='C:\Program Files\A5V8\MDBFiles\Alphasports.mdb',UserName='Admin'}")

?sql_query_builder(cn,"")
= SELECT [CUSTOMER_ID], FIRSTNAME, LASTNAME, COMPANY
FROM Customer

 

SQL_QueryImport() Function - Imports the result of a SQL query from a remote SQL database using AlphaDAO to connect to the remote database. Table imported as a .dbf file. See also SQL_TableImport().

Syntax: Result P = SQL_QueryImport(P SqlConn ,C query ,C localfilename [,* TableInfo [,L ShowProgress [,L AllowCancel [,L AddTableToDatabase [,* ArgumentsPassedIn [,C StatusBarFormatString ]]]]]])"
 

Where:

Result Result has the following properties:

.HasError  - .T. if the import does not complete because of an error.

.ErrorText  - Contains the text of the error message.
.UserCancelled  - .T. if the user cancelled before the import was completed.

SQLConn A pointer to an open AlphaDAO connection.
Query A SQL query that returns the data you want to import.
LocalFileName The name of the local Alpha Five table (i.e. .dbf file) that you wish to create from the imported data.
TableInfo An object of type sql::tableinfo that contains the definition of the local .dbf file to be created from the imported data. If you want to accept the default field sizes and types for each column you can accept the default value for this parameter. To accept the default value, specify null_value().
ShowProgress Allows you to specify if a progress meter should be shown on the status bar.
AllowCancel If ShowProgress is set to .T., then should the status bar show a Cancel button (which would allow the user to cancel the import before it has completed)?
AddTableToDatabase If .T., then the imported table will be added to the Alpha Five database (i.e. the .adb file), and it will be visible in the Control Panel.
ArgumentsPasedIn An object of type sql::arguments that contains values for any arguments used in the Query. If the Query does not use arguments, then you don't need to pass in any arguments, and you can specify null_value() for this parameter.
StatusBarFormatString Allows you to specify the layout of the status bar when the import is running. The default format is:

"$b{Cancel...} $g Importing  <tableName> ' ($c of $o)", where <tableName> is the name of the table you are importing.

 

SQL_resultset_preview() Function - Opens a dialog box to preview the first n rows in a resultset created by executing a SQL query on an AlphaDAO connection to a remote database.

 

For example, the following commands executed in the Interactive window will display the dialog box shown below:

 

dim cs as c
cs = "{A5API=Access,FileName='C:\Program Files\A5V8\MDBFiles\Alphasports.mdb',UserName='Admin'}"
dim cn as sql::connection
dim rs as sql::resultset
cn.open(cs)
cn.Execute("select * from customer")
rs = cn.ResultSet
sql_resultset_preview(rs)
 

 


SQL_TableExport() Function - Exports data from a local Alpha Five table to a remote SQL database using AlphaDAO to connect to the remote database. You can specify a filter and order to apply to the local table before exporting. You can specify which fields (or expressions) from the local table to export. You can export into a new table in the remote database, or into an existing table in the remote database.

Syntax: Flag L = SQL_TableExport(P sqlconn ,L createTable ,* sourcedbf_or_pointer ,C owner ,C table , [ByRef] ResultMessage [,C filter [,C order [,C queryflags [,C ExportFieldList [,* arguments [,C CreateStatement [,L ShowProgress [,L AllowCancel [,C StatusBarFormatString [,C argumentDefinitions ]]]]]]]]]])"
 

Where:

Flag .T. if the export was successful.
SQLConn A pointer to an open AlphaDAO connection.
createTable If .T. then a new table will be created in the remote SQL database to contain the exported data.
sourcedbf_or_pointer You can either specify the name of a table to export (e.g. "customers"), or a pointer to an already open table. If you specify a pointer to an already open table, only the records in the current query are exported.
Owner The owner of the table in the remote database into which you are exporting records.
Table The name of the table in the remote database into which you are exporting records.
ResultMessage This variable is passed in by reference. It will contain any error messages returned by the remote SQL database.
Filter If sourcedbf_or_pointer  is a table name (rather than a pointer to an already open table), then this filter will be applied to the table before the records are exported.
Order If sourcedbf_or_pointer  is a table name (rather than a pointer to an already open table), then this order will be applied to the table before the records are exported.
QueryFlags If sourcedbf_or_pointer  is a table name (rather than a pointer to an already open table), then these query flags will be used if a Filter and Order are specified.
ExportFieldList A comma delimited list of fields from the source table to export. If this parameter is blank, then all fields are exported.
Arguments An object of type sql::arguments that supplies values for any arguments that are specified in the Filter. For example, the Filter might be: state = :whatstate. In this case, the value for the 'whatState' argument must be passed in. If there is no filter, or the filter does not contain arguments, then null_value() can be specified.
CreateStatement If the createTable flag is .T. then Alpha Five will automatically generate an appropriate SQL CREATE TABLE command to create the target table in the remote SQL database. You can override this and supply your own CREATE TABLE statement.
StatusBarFormatString Allows you to specify the layout of the status bar when the import is running. The default format is:

"$b{Cancel...} $g Importing  <tableName> ' ($c of $o)", where <tableName> is the name of the table you are importing.

ShowProgress Allows you to specify if a progress meter should be shown on the status bar.
AllowCancel If ShowProgress is set to .T., then should the status bar show a Cancel button (which would allow the user to cancel the import before it has completed)?

 

This example exports a table to an Access database:

dim cn as sql::connection
flag = cn.open("{A5API=Access,FileName='C:\Northwind\northwind.Mdb',UserName='Admin'}")

if flag = .f. then

    ui_msg_box("Error",cn.callresult.text)

    end

end if
dim message as c = ""
flag = sql_tableexport(cn,.t.,"customer","","CustomerAlphaSports",message)
ui_msg_box("Result",message)

 

This examples exports data from an already open table to an Excel spreadsheet:

Notice that the export includes both fields, and expressions. The Table.OpenMap() function is used because we want to export expressions. See discussion of Table.OpenMap() in this document:

fieldlist = <<%txt%
fullname = ut(firstname) + ", " + ut(lastname)
lastname
firstname = upper(firstname)
date = date()
number =123*23
%txt%
dim tblPointer as p
tblPointer = table.OpenMap("customer",fieldlist)
dim cn as sql::connection
flag = cn.open("{A5API=Excel,FileName='c:\customer_alphadao.xls'}")
if flag = .f. then
ui_msg_box("Error",cn.CallResult.text)
end
end if
dim message as c
flag = sql_tableexport(cn,.f.,tblPointer,"","Customer",message)
tblPointer.close()

 

SQL_TableImport() Function - Imports a table from a remote SQL database using AlphaDAO to connect to the remote database. Table imported as a .dbf file. See also SQL_QueryImport().

Syntax: Result  as P= SQL_TableImport(P SqlConn ,C owner ,C tablename ,C localfilename [,L ShowProgress [,L SizeToFit [,L AllowCancel [,L AddTableToDatabase [,C StatusBarFormatString ]]]]])"

Where:

Result Result has the following properties:

.HasError  - .T. if the import does not complete because of an error.

.ErrorText  - Contains the text of the error message.
.UserCancelled  - .T. if the user cancelled before the import was completed.

SQLConn A pointer to an open AlphaDAO connection.
Owner The owner of the table you wish to import.
Tablename The name of the table you wish to import.
LocalFileName The name of the local Alpha Five table (i.e. .dbf file) that you wish to create from the imported data.
ShowProgress Allows you to specify if a progress meter should be shown on the status bar.
SizeToFit If .T.,  then the fields in the the imported table (i.e. the .dbf file) are sized as small as possible. For example, the remote table might have a field defined to be 40 characters, but the largest piece of data in this field might be only 20 characters. The local table field size will be set to 20 and not 40 if this flag is .T.
AllowCancel If ShowProgress is set to .T., then should the status bar show a Cancel button (which would allow the user to cancel the import before it has completed)?
AddTableToDatabase If .T., then the imported table will be added to the Alpha Five database (i.e. the .adb file), and it will be visible in the Control Panel.
StatusBarFormatString Allows you to specify the layout of the status bar when the import is running. The default format is:

"$b{Cancel...} $g Importing  <tableName> ' ($c of $o)", where <tableName> is the name of the table you are importing.

 

Contrast SQL_TableImport() with SQL_QueryImport(). The SQL_QueryImport() function is a more flexible function because it allows you to import the result of an arbitrary SQL query.

 

StrEqual() Function - Returns .t. if two strings are equal based on the options selected. You can specify if the comparison is case sensitive or not and whether white space should be ignored.

Table.OpenMap() Function - Opens a table and returns a pointer to the table. A "view" of the fields in the table is shown. The view specifies which fields from the underlying table are to be shown. Each field in the view can map to a single field in the underlying table (in which case the field in the view will be updateable), or it can map to an expression (in which case the field in the view will not be updateable). Once the mapped table has been open, it can be used like any other table pointer. For example, you can use the <tbl>.export() method to export records to another file, or the <tbl>.copy() method to copy records to another table, etc. Only the fields in the view will be operated on. The following example shows how you can open a view on the customer table in AlphaSports.

 

dim fieldlist as c

fieldlist = <<%txt%

fname = firstname

lastname

fullname = alltrim(lastname) + ", " + alltrim(firstname)

date = date()

number = 123.45

%txt%

dim tbl as p

tbl = table.OpenMap("customer",fieldlist)

ui_msg_box("Fullname",tbl.fullname)

'Now browse the data

dim cn as sql::connection

'Get a resultset from the open table

rs = cn.ResultSetFromDBF(tbl)

'Display a window showing the rows in the resultset
sql_resultset_preview(rs)

 

'Now export the results to a text file

export.type = 0
export.names = .T.
export.file = "c:\customer.txt"
export.options = ""
export.field_sep = ","
export.record_sep = "<CR><LF>"
export.fields = 5
export.field1 = "fname"
export.field2 = "lastname"
export.field3 = "fullname"
export.field4 = "date"
export.field5 = "number"
t.export()
sys_open(export.file)

tbl.close()

 

 

<tbl>.Record_Content_Get() Method
 table.external_record_content_get() is a frequently used function to get data from a table in the form of a CR-LF delimited string. There is now a new variant of this function that works with an existing table pointer. Because this new function does not have to open the table, or close it, it is faster than table.external_record_content_get()

Syntax: <tbl>.Record_Content_Get(C Expression [, C order [, C filter]])

If order is not specified, the current order is used. If filter is not specified, the current filter is used.

For example:

 

t = table.open("customer")
t.query_create("","bill_state_region = 'ny'")
?t.record_content_get("lastname + bill_state_region")
= Feld NY
Dubi NY
Phillips NY
Carr NY
Barber NY
Bernstein NY
Baker NY
Harris NY

?t.record_content_get("lastname + bill_state_region","lastname",".t.")
= Abrams NE
Adams HI
Baker NY
Barber NY
Bernstein NY
Boschetti SC
Burtonski CA
Cario MA
Carr NY
Clifton VA
Copen MA
Dawson MA
Dodds AZ
 

Toolbar.Open() Method  - Now takes a second optional argument. The syntax is now toolbarPointer = Toolbar.Open(C Toolbarname [,L FlagGlobal ] ). The default value for FlagGlobal is .T.. If FlagGlobal is .t. then the toolbar remains open even when the window from which the toolbar was launched looses focus, and it is the developer's responsibility for eventually closing the toolbar. However, if FlagGlobal is .f. then the toolbar is automatically hidden when the window from which it was launched (i.e. the parent window) looses focus and the toolbar is automatically shown when its parent window gains focus. The toolbar is automatically closed when its parent window is closed.

 

UI_dlg_event_occurred() Function - This is an advanced function. Under some extremely rare conditions (such as when code that is running in a background - and this code has some impact on an Xdialog), an Xdialog will not refresh when it should because Xdialog does not know that there has been a state change. This will cause the Xdialog state to change and result in the Xdialog refreshing itself. The Xdialog will refresh on the next idle cycle.

UI_dlg_Parent_Get() Function - Returns the title (if any) of the Xdialog from which a specified Xdialog was launched.
Syntax: C parent_dialog_title = ui_dlg_parent_get( C dialog_title)

Example:

ui_modeless_dlg_box("Dialog1",<<%dlg%
<Who is my parent!parent1>;
<Launch Dialog2!showdialog2>;
<Close>;
%dlg%,<<%code%
if a_dlg_button ="Close" then
    ui_modeless_dlg_close("Dialog1")
end if
if a_dlg_button ="parent1" then
    myParent = ui_dlg_parent_get("Dialog1")
    if myParent = "" then
        ui_msg_box("","I don't have a parent dialog")
    else
        ui_msg_box("","My parent Xdialog is: " + myParent)
    end if
end if
if a_dlg_button = "showdialog2" then
    showDialog2()
end if
%code%)


function showDialog2 as v ()
ui_modeless_dlg_box("Dialog2",<<%dlg%
<Who is my parent!parent1>;
<Close>;
%dlg%,<<%code%
if a_dlg_button ="Close" then
    ui_modeless_dlg_close("Dialog2")
end if
if a_dlg_button ="parent1" then
    myParent = ui_dlg_parent_get("Dialog2")
    if myParent = "" then
        ui_msg_box("","I don't have a parent dialog")
    else
        ui_msg_box("","My parent Xdialog is: " + myParent)
    end if
end if
%code%)
end function

 

UI_get_check2() Function - Displays a set of choices in a multi-column checkbox - listbox as shown below:

 

 

Note: This dialog can be created automatically using Action Scripting - see the new 'Prompt using Check List Box Dialog' action in the 'Dialog Boxes' category.

 

Syntax:

C Result = ui_get_check2(C title, C  selected, C choices, [C headingText  [,L hasSelectAllLink  [, L  hasUnselectAllLink [, L hasWildcardSelectLink [,N width [,N height [,L flagReturnValuesInSelectionOrder ]]]]]])
 

 Where:

Title Title of the dialog box.
Selected A CR-LF delimited list of options that should be shown as selected when the dialog is opened.
Choices A CR-LF delimited list of choices to show in the dialog box.
HeadingText A string of text to show above the actual checkboxes. Can include Xdialog syntax, e.g. {LF}, {Font=}, etc. Default value is null.
HasSelectAllLink Specify if the 'Select All' hyperlink should be shown. Default is .t.
HasUnSelectAllLink Specify if the 'UnSelect All' hyperlink should be shown. Default is .t.
HasWildCardSelectLink Specify if the 'Wildcard Select' hyperlink should be shown. Default is .t.. The wildcard select option is useful if the dialog shows a large number of choices.

It allows you, for example, to select all entries with the string 'address' in the choice.

Width Width of the dialog. Defaults to 80.
Height Height of the dialog. Defaults to 80.
FlagReturnValuesinSelectionOrder Should the Result be in the order that the entries where selected, or the order in which they appear in the dialog box? Defaults to .f. (order in which entries appear in the dialog box).

 

For example:

dim colors as c

colors = a5.color_enum()

ui_get_check2("Select Colors","Red",a5.Color_Enum(),"{lf};Selection your favorite colors. You may select as many colors as you want.;{lf};",.t.,.t.,.t.,100,10)
 

 

UI_get_check2P() Function - Same as Ui_get_check2() function, but instead of returning a character result (with the list of selected choices), returns a dot variable with three properties - .lastbutton ('OK', 'Cancel'), .selected (list of choices that were selected) and .selected_in_selection_order (list of choices that were selected, in the order in which they were selected).

 

UI_Wait_Until() Function - Same as the wait_until() function, except it processes pending UI before going into the wait loop. This function should be used when the condition is testing if some UI component is present or not.
Syntax: L Flag_Result =UI_WAIT_UNTIL(L Logical_Expression [,N Every_N_Seconds [,N Timeout_After]])
 Where:

Logical_Expression

An Xbasic expression that resolves to either .T. (TRUE) or .F. (FALSE).

Every_N_Seconds Optional. Default = .001 seconds. The interval in seconds between checks of Logical_Expression.
Timeout_After Optional. Default = forever. The number of seconds to wait before returning to the script, regardless of Logical_Expression.

 

Example:

dim code as c

code = <<%code%

ui_modeless_dlg_exist("MyModelessXdialog") = .f.

%code%

flag_result = ui_wait_until(code)

if flag_result = .t. then

    'specify code here that executes when MyModelessXdialog has closed

end if

 

UniqueNameGet() Function - Takes a CRLF delimited list of existing names and a suggested name and increments a counter at end of suggested name until it is unique.
Syntax: C UniqueName =  UniqueNameGet(existing as c, suggested as c )

Example:

Dim existingNames as c

existingNames = comma_to_crlf("Firstname,Firstname1,Firstname2")

?UniqueNameGet(existingNames,"Firstname")

="Firstname3"

 

UPS_delivery_status() Function - Contacts the UPS web site and returns the delivery status of a package.

?ups_delivery_status("1Z410E7W0275046137")

= "Delivered"

?ups_delivery_status("1Z410E7W0276916249")

= "Delivered"

?ups_delivery_status("1Z410E7W0276910000") 'invalid number

= ""

USPS_delivery_status() Function - Contacts the USPS web site and returns the delivery status of a package.

?usps_delivery_status("01038555749770454000")

= "Delivered"

?usps_delivery_status("12345678900000000")

= "There is no record of this item."

?usps_delivery_status("123456789")

= "Delivery status information is not available for your item via this web site."

USPS_Zipcode_Lookup() Function - Contacts the USPS web site and looks up the zip code for the specified address.

?usps_zipcode_lookup("70 blanchard road","burlington","ma")

= "01803-5100"

Win_Create_Shortcut() Function - Creates a Windows shortcut in the specified location.

Syntax: lResult = win_create_shortcut(Shortcut as c, Target as c[, Description as c[, StartIn = as c[, IconLocation = as c[, Arguments as c]]]])

Where:

Shortcut Name and path to the shortcut to be created.
Target Shortcut target - the program to run upon clicking the shortcut.
Description Comment text for the shortcut. Default is blank.
StartIn The shortcut's 'Start In' folder. Defaults to the target's path.
IconLocation The path to the icon to be displayed as the shortcut icon.
Arguments Optional command-line arguments for the shortcut.



Examples:

dim desktop as c
desktop = win_special_folder("desktop")
'Create a shortcut to Alpha Five on the desktop
?win_create_shortcut(desktop + "\Launch Alpha Five",a5.Get_Exe_Path() + "\alpha5.exe")
= .T.


'Create the shortcut with a different icon
?win_create_shortcut(desktop + "\Launch Alpha Five",a5.Get_Exe_Path() + "\alpha5.exe","Alpha Five is cool","","c:\windows\notepad.exe")
= .T.


'Create a shortcut to Alphasports
?win_create_shortcut(desktop + "\Open Alphasports",a5.Get_Exe_Path() + "\alpha5.exe","Launch the Alphasports sample application","","", "\"" + a5.Get_Exe_Path() + "\samples\alphasports\alphasports.adb\"")
= .T.
 

Win_Special_Folder() Function -  Returns the path to the Windows special folder specified, such as the Desktop folder, the Start Menu folder, and the Personal Documents folder. Returns an empty string if the requested folder is not available or not valid. For example, Windows 95 does not have an AllUsersDesktop folder and returns an empty string if folder is specified as AllUsersDesktop.
The following special folders are available:

Word_duplicates() Function - Takes a CR-LF delimited list of words and returns a CR-LF delimited list of the words in the list that are duplicated.