Support contact: john@pixieware.com
Appendix - PixieEngine Functions
Cataloging of Programs compared to Direct Run
Differences between ActiveX and Scripting use of function libraries
System Variables and Argument Conventions
Classical Terminal/Printer I/O, "IInput", "PPrint", "Crt"
File I/O "RRead", "WWrite" etc and the new "RReadTR"
ExecutePS
String and other utility functions eg "DCount", "Field", "OConv", "Locate"
Cataloging of Programs compared to Direct Run
To call catalogued programs, scripts or ActiveX, simply
enter the verb, which is the itemid of the catalogue entry in file/table
"md". Using Microsoft Access to look at file/table "md" within account/database
"testpxe1", 1st 4 attributes only shown:
| A0 | A1 | A2 | A3 | A4 |
| test1 | ACTIVEX | px1.bp test1 | ||
| test2 | ACTIVEX | px1.bp test2 | ||
| disptest | ACTIVEX | px1.bp disptest | ||
| pxu1000 | ACTIVEX | px1.bp pxu1000 | ||
| umenu | ACTIVEX | px1.bp umenu | ||
| stest1 | VBSCRIPT | script1\stest1.txt stest1 |
XRun
Function or
Method which enables programs to "push a level" and call other programs.
Programs can also call user-defined functions from other programs eg the
supplied example script "stest1" calls a function in another script
"mycase".
For function calls to scripts, XRun supports up to 8
arguments. For calls to ActiveX .dlls, arguments are not
supported.
Program is an
ActiveX
Call XRun(Program)
Program is a Script
Call
XRun(Program [, Arg1 [, Arg2 [, Arg3 .....[, Arg8]...]]])
ReturnValue =
XRun(Program [, Arg1 [, Arg2 [, Arg3 .....[,
Arg8]...]]])
The argument
Program is a string, being either a catalogued verb (see above) or the full
startup string that you would enter at TCL.
eg, from our supplied working
example scripts "stest1.txt" and "mycase.txt"
mycase.txt consists
of:
Function MyCase(s)
MyCase =
"xxxx-" & TTag(-35) & Ucase(s) & TTag(-40) & "-xxxx"
End
Function
This is can be called from inside "stest1.txt"
with:
s = XRun("vbscript
script1\mycase.txt MyCase", s)
or, if "mycase" has been catalogued:
s = XRun("mycase",
s)
Question: How can I pass arguments to
ActiveX library calls ?
Answer:
IF your ActiveX library function is
quite self contained,
as in it does not depend on the PixieEngine
library functions
"TTag", "ExecutePS", "RRead...", "WWrite.."
THEN
You are better off not using XRun,
and instead
using the script language's own
ActiveX call syntax
eg CreateObject
ELSE
It
is nice to have XRun set up all the ActiveX library
resources for you, so use it by all means, but you
will
need to pass arguments and receive returned values with
the
"XCommon Object", which is like an in-memory file that all
program levels plus TCL have access to. "XCommon" also
resembles
a "COMMON" in its use. See "XCommon" documentation
below.
END IF
NOTE: ActiveX's have no problem making function calls to
scripts.
This is nice, for example, for setting up functions which may
need
quick and easy on-site customising.
Differences between ActiveX and Scripting use of function
libraries
Almost all functions and methods described below are
identical in their use in both Script and ActiveX programs.
IInput is the main exception, so its
documentation below gives a
separate script syntax.
There are some extras for ActiveX VB provided
not by PixieEngine proper but by source code included as module
"basPxLibrary". If you need any of these in Script, then copy the source code out of "basPxLibrary" into a
script which you can then call with
"XRun"
Mat, MatRead,
MatReadU, MatWrite, MatWriteU
TCLRead, Sentence()
script equivalent is Session("Sentence")
IInputUT, IIn, IInFor
System Variables and Argument Conventions
XCommon
System Object providing versatile in-memory
storage of both values and object references.
Like a COMMON accessible to all program levels plus
COM/ActiveX clients, hence the name.
It also behaves in many ways like an in-memory MV File. Similar also to the "Session"
object
provided by the Microsoft IIS
Webserver.
XCommon is a Microsoft Scripting Dictionary Object, so refer to MSDN for full
documentation.
Note that it can be used with ActiveX programs as well
as Scripting.
Eg
To write
values:
XCommon("cust*21") =
"ABC Consolidated Industries"
XCommon("cust*37") =
-123401
XCommon("cust*41") = True
To read
values:
sCustName =
XCommon("cust*21")
nCustBalance = XCommon("cust*37")
bCustBonus =
XCommon("cust*41")
To delete
an entry:
XCommon.Remove "cust*21"
To check existence of an
entry:
If XCommon.Exists("cust*41") Then
bCustBonus =
XCommon("cust*41")
Else
bCustBonus =
False
End If
ErrorDetail
System Variable giving status of latest function call to component PixieEngine.dll which is the provider of i/o and disk RRead/WWrite's. Returns empty string for successful calls, and a text message otherwise.
Eg
If Not RRead(Item, gfvProd, ItemID) Then
Crt ErrorDetail
Exit Sub
End
If
ErrorDetailFn
System Variable giving status of latest function call to the string handling functions eg "Oconv", "Field", "Dylete". Returns empty string for successful calls, and a text message otherwise
Eg
s3 = OConv(s1, s2)
If s3 = s1 Then PPrint ErrorDetailFn
FileVariable
A simplified connection string pointing to a file(table). An extended version helps apply VB data typing to legacy
MV data, see end of this note for details.
Usually
VB has a problem with the traditional MV practice of regarding "", the zero-length string as a zero in arithmetic expressions. This usually results in VB Error 13 "Type Mismatch". One answer is to go through all arithmetic expressions in your app and add the "Val" function. Our alternative allows you to globally correct in one hit by including a "treat these attributes as numeric" command in the FileVariable.
Eg
Classic Terminal/Printer Input/Output
Crt s
output to terminal with newline (Char(13):Char(10))IInput etc
applies only for VAR-Apps, "Object" equivalent is Pixie.Execute[TX]IInput ActiveX versions
IInput s input a string
IInput s, False input a string and suppress terminal newline
IInput s, 4 return input after 4 characters received
IInput s, 4, False return input after 4 chars and suppress newline
IInputFor
requires 4 arguments: string-to-return, buffer-length(-1 gives wait for Chr(13)), newline, timeoutIInput Script Version
IInput s [, buffer-length [, newline [, timeout]]]
The most common scripting
usage
IInput s
is therefore the same as in MV and ActiveX
Another common usage,
suppress newline, needs to look like this:
IInput s, -1,
False
In summary, the
scripting IInput resembles the classical MV
IInputFor.
Database Files(tables) OOpen, RRead, WWrite etc...
OOpen
* Checks that a File exists and is available
* Returns FileVariable for use in later RRead, Wwrite etc
OOpen is optional in PixieEngine because its FileVariables are simple string pointers so it is easy to start immediately with RRead etc, But OOpen is retained for compatibility and for getting multivalue numerical-data-type info out of dictionaries to include in the FileVariable.
General Syntax:
OOpen FFile, FileVariable
or
If Not OOpen FFile, FileVariable Then Crt ErrorDetail
Example: simple OOPen to obtain filevariable
OOPen "prod", sFVProd
Example: OOPen with error checking on generated file(table) names "jancash", "febcash", "marcash" depending on what the current month is:
sFile = Left$(OConv(IConv(Now, "d"), "dma"), 3) & "cash"
If Not OOpen(sFile, sfvCash) Then
Crt TTag(0,21) & "ERROR: Can not open " & sFile & ", system says:" _
& TTag(0,22) & ErrorDetail _
& TTag(0,23) & "Press (CR) to return to menu.", False
IInput sHandshake
Exit Sub
End
If
File RRead-ing and WWrite-ing , general syntax:
RRead Item, FileVariable, ItemID
or
If Not RRead(Item, FileVariable, ItemID) Then Crt ErrorDetail
similar general syntax for: RReadU, WWrite, WWriteU
RReadV general syntax:
RReadV Value, FileVariable, ItemID, FieldNumber
or
If Not RReadV(Value, FileVariable, ItemID, FieldNumber) Then ...
similar syntax for: RReadVU, WWriteV, WWriteVU
NEW IDEA! "RRead-simple-TRansaction" = RReadTR
Sick of users who wander off to have a cup of coffee, leaving a record locked? Turn the tables on them with "RReadTR" a simple transactional scheme that rewards the quick and wreaks your revenge upon the tardy!
General syntax:
RReadTR Item, FileVariable, ItemID
What RReadTR does is RRead the Item, but at the same time
makes a "comparison copy" of it. Then later, when the user goes to WWrite, the
Item is RRead again from the DataStore and compared with that held earlier copy.
If they match, then the WWrite can go ahead. A mismatch means that another user
has got in in the meantime and edited the record, so tough luck to this user,
WWrite will not act and will return value "False".
Delete
to delete an item(record) from a file(table). General syntax:"Execute PixieEngine System" enabling a wide range of commands to be carried out by passing a command string. Used to emulate the MV "Execute" from within your VAR-app code but also offers some PixieEngine extensions. It also acts as a useful way for us to add new features to PixieEngine in response to user demand while not changing the COM interface. VB/C ActiveX programmers will know what we mean by this, for the rest of you, it means that upgrading to new versions of PixieEngine is kept simple and relatively free from various Microsoft diseases collectively known as "dll hell".
ExecutePS is a Function, returning a string.
For SQL SELECT queries it also makes available a 2-dimensional array, "SelectArray". Put that another way, the PixieEngine equivalent of a "Select List" is a super-MatRead.
ExecutePS CommandString
Commands can be classified as:
SELECT ... eg
sReturning = ExecutePS("SELECT * FROM banks")
MySQL has the facility to do accountname.filename eg
sReturning = ExecutePS("SELECT * FROM abc.banks")
sReturning in this example returns "4þ8" ie a dynamic array of how many attributes in each row, then chr(254), then the number of rows. A limit of 1000000 bytes returned data is currently built into the system; we'll probably make that limit configurable later.
If ExecutePS returns "ERROR", then check the value ErrorDetail for any error message,
eg
sReturning = ExecutePS("SELECT A0, A1, A2, A3 FROM sfvDlyTrans WHERE A1 > 11854")
If sReturning = "ERROR" Then
Crt TTag(0,23) & ErrorDetail
IInput sHandshake
Exit Sub
End If
System variable SelectArray(Attribute, Item)
Attributes(Fields/Columns) have a range starting with 0
Items(Rows) have a range counting from 1
With "SELECT * ...", SelectArray(0, i) returns ItemIDs
With specified fields, the columns count from 0 regardless of which attributes you specify: eg
sRet = ExecutePS("SELECT A1, A3, A17, A34 FROM prod WHERE A34 < 10000")
sRet returns value "3þ463"
SelectArray(0,1) is the first returned A1
SelectArray(0,2) is the 2nd returned A1
SelectArray(1,2) is the 2nd returned A3
SelectArray(2,2) is the 2nd returned A17
SelectArray(3,2) is the 2nd returned A34
Note that when your SELECT statement returns only one value, you read its value from SelectArray(0, 1) rather than the SelectArray(0,0) that you may reach for out of habit. You need to remember that SelectArray does columns with a zero-based count and rows with a 1-based count.
DELETE, INSERT, REPLACE, ALTER, DROP
When these commands are successful, ExecutePS returns the number of rows affected as a string, eg:
sReturning = ExecutePS("DELETE FROM testpxe1.prod WHERE A34 < 1800")
sReturning returns "107"
| MySQL NOTE, the whole-file(table) DELETE syntax will always report "0" rows affected: sReturning = ExecutePS("DELETE FROM myfile") This is because MySQL builds a new file(table) using the old one as a template then deletes the old file in one fast action. If you want to report how many rows are deleted, use this one-item(record)-at-a-time slower syntax: sReturning = ExecutePS("DELETE FROM myfile WHERE 1 = 1") |
Other commands return "OK"
Any
commands proprietary to the datastore, eg the MySQL "FLUSH TABLES", "GRANT ALL PRIVILEGES ..."
that are not recognised by PixieEngine are passed through directly to the
datastore to handle by itself. If no errors returned, the ExecutePS
function returns "OK"
TCL, MV emulation : ECHO, PRINTER, DEV-MAKE, SP-ASSIGN
These all return "OK" if successful
sRet = ExecutePS("ECHO OFF")
sRet =
ExecutePS("ECHO ON")
sRet =
ExecutePS("PRINTER ON") PPrint to Printer
sRet = ExecutePS("PRINTER OFF") PPrint to Screen
sRet = ExecutePS("PRINTER CLOSE") Send assembled document to printer, also does a "PRINTER OFF"
PRINTER detail, for print-to-current-printer only
sRet = ExecutePS("PRINTER ORIENTATION 2") landscape (default = 1) < BR > sRet = ExecutePS("PRINTER PAPERSIZE 39") US Fanfold paper
sRet = ExecutePS("PRINTER PAPERSIZE 9") A4 (the default)
sRet = ExecutePS("PRINTER PAPERSIZE 1") US Letter
sRet = ExecutePS("PRINTER COPIES 3") 3 copies(default = 1) < BR > sRet = ExecutePS("PRINTER WIDTH 2835") paper width 2835 twips
sRet = ExecutePS("PRINTER HEIGHT 2000") paper height 2000 twips
Numerical values are the same as in VB, refer MSDN library for more. If you want more sophisticated control over the printer than this, eg font, printing pictures etc, use the VB Printer object within your own VAR-coding.
sRet = ExecutePS("DEV-MAKE P 3 HP400") Map printing queue 3 to the printer set up in Windows with name "HP400"
sRet = ExecutePS("DEV-MAKE P 4 'Brother 300'") Map printing queue 4 to the printer set up in Windows with name "Brother 300". Note use of single quotes for printer devicenames with embedded spaces
sRet = ExecutePS("SP-ASSIGN 3") PPrint directed to the printer mapped to queue 3 which following the above example would be "HP400"
sRet = ExecutePS("SP-ASSIGN H") PPrint directed into file "dm.printhold", queue 0 ie on hold. NOTE printhold only available for MySQL datastore and so not in Access/Jet
sRet = ExecutePS("SP-ASSIGN 4 H") PPrint directed into file "dm.printhold", queue 4 ie on hold for (in this example) a "Brother 300" printer
Note that the way
PixieEngine uses the Windows spooler makes DEV-MAKE simpler than in most MV
Spoolers, ie there is no need to deal with Port Device numbers.
TCL, MV emulation : WHO, LISTF
sReturning = ExecutePS("WHO") sReturning is UserName*Port, Account with a space separator.
eg "john*304 testpxe1"
sReturning = ExecutePS("LISTF") sReturning is a dynamic array of filenames
eg "prodþcurrþpordþcust"
Custom PixieEngine: CREATE ACCOUNT, CREATE FILE
On success, both of these return "OK"
sRet = ExecutePS("CREATE ACCOUNT samuels") Note, only available in MySQL
sRet = ExecutePS("CREATE FILE pord 83 D") Create a file "pord" for items with a max of 83 attributes and give it a dictionary
sRet = ExecutePS("CREATE FILE social_studies D") Create a dictionary for the already existing file "social_studies"
sRet = ExecutePS("CREATE FILE control 122") Create a file "control" for items with a max of 122 attributes. Do not bother to give it a dictionary
Note that files called "md" are themselves a special
dictionary and will be created as such. Any "D" argument will be ignored and
only "md" will be created, without any "md_dict". Files "dm.users" and
"dm.printhold" are of special design, and should only be created by copying the
supplied "dm" templates.
String and other utility functions
These are provided via file PxEngFns.dll and can be made available in a wide range of
programming environments eg Microsoft Word
VBA, by referencing "PxEngFns"
SegmentReplace equiv of VB6 "Replace" for those on VB5, Word 97
and below, etc.
Syntax:
sTextNew =
SegmentReplace(sTextOriginal, sFind,
sReplace)
eg
sSpacesRemove = SegmentReplace("47,85,76, 554, 33,12", " ",
"")
sDynamicArray = SegmentReplace(sSpacesRemove, ",",
Chr(254))
results
sSpacesRemove <-- "47,85,76,554,33,12"
sDynamicArray <--
"47þ85þ76þ554þ33þ12"
Sleep x or Call Sleep(x) idle app for x seconds
Delay x or Call Delay(x) same as Sleep, idle app
for x seconds
Index
Matches
Num returns True or False depending on whether argument is numeric. eg Num("89") returns True
eg
If Num(s) Then ...
Dcount returns number of subsections in a string as defined by a given delimiter. The delimiter can be of more than one character. Eg:
n = DCount(s, " ")
Field returns a substring, given delimiter and number. The delimiter can be of more than one character. eg:
sTRow = Field(s, "<tr>", 4)
Col1() , Col2() functions returning extra information from the last Field function: Col1() and Col2() give positions-in-string of the characters immediately before and after any found substring. Largely obsolete, functions like SegmentReplace or the new "Replace" in VB6 can handle most of the operations these were intended for.
Extract
RReplace
returns result of replacing a substring of a "dynamic var iable" egInsert
returns result of inserting a substring into a "dynamic variable" egDylete function "Dynamic Array Delete" returns the result of deleting a substring from a dynamic array.
eg
s = Dylete(s, 3)
s = Dylete(s, 1, 5)
s = Dylete(s, 4, 7, 2)
s = "111þ222þ333þ444"
sDel = Dylete(s, 3)
'Result: sDel <--
"111þ222þ444"
NOTE: Differences between PixieEngine and some MV behaviours:
Locate
returns True or False depending on whether or not a substring is found in a string, or a sub-substring found in a substring.Locate is most commonly used with the "BY" clause to
create and maintain sorted lists.
Step 1: Locate is
used to obtain iPos
Step 2: iPos is used in the
Insert
function.
eg
If Not Locate(SEL, "IN", MODS, 1, "SETTING", YY) Then ...
eg
If Not Locate(DEKNO, "IN", FDLIST, 1, "BY", "ar", "SETTING", Pos)
Then
FDLIST = Insert(FDLIST, 1, Pos, DEKNO)
FDITEM = RReplace(FDITEM, 4, FDLIST)
End
If
OConv
"Output Conversion" returns result of applying a "processing code" to a value."d..." Dates
formats for date
output. sInternal argument is an MV internal date format of
days-since-31-Dec-1967
PixieWeb looks at the "Regional Settings" of its host
machine to automatically select "USA" date format eg "12/31/2000" versus British
date format "31/12/2000". When publishing web material for an international
audience, we use and highly recommend the "d" code, giving results like
"31 Dec 2000" which are clearly understood by all.
"d", "d4" - date
--> dd mmm yyyy
eg OConv("11846", "d") ---> "06 Jun 2000"
"d4/" - OConv("11846",
"d4/") ---> "06/06/2000"
"d4." - OConv("11846",
"d4.") ---> "06.06.2000"
"d4-" - OConv("11846",
"d4-") ---> "06-06-2000"
"d2" - date
--> dd mmm yy
eg
OConv("11846", "d2") ---> "06 Jun 00"
"d2/" - OConv("11846",
"d2/") ---> "06/06/00"
"d2." - OConv("11846",
"d2.") ---> "06.06.00"
"d2-" - OConv("11846",
"d2-") ---> "06-06-00"
"dj" -
OConv("11846", "dj") ---> "2000158" Julian date
"dq" -
OConv("11846", "dj") ---> "2" June is in the 2nd quarter
"dm" -
OConv("11846", "dm") ---> "6" June is the 6th month
"dd" -
Oconv("11846", "dd") ---> "6" Day 6 of the month
"dmm",
"dmmm" - OConv("11846", "dmm") ---> "Jun" 1st 3 letters of month
name
"dma" -
OConv("11846", "da") ---> "June" Full name of month
"dwa" - OConv("11846",
"dwa") ---> "Wednesday" day-of-week
"dw" -
OConv("11846", "dw") ---> "3" day-of-week with MV
convention
Monday=1
"dy"
- OConv("11846", "dy") ---> "2000"
"d2y" - OConv("11846",
"dy") ---> "00"
"mr.." Numerical scaling
and formatting
General syntax
"mrIJ"
or "mdIJ" (upper case OK eg "MR43")
where I, J represent integers 0 to 9
eg "mr12", "mr32", "mr2", "mr4"
I is how many decimal places to show and
round off to.
J is how far to the left to
shift the decimal point.
Where only one digit is
shown, eg "mr2", it is treated as
both I and J eg "mr2"
and "mr22" mean the same thing.
In practice, the most common code by far is "mr2",
used to take internal amounts of money stored
as cents, and display in dollars and cents.
Examples:
OConv(12345, "mr2") ---> "123.45"
OConv(12345, "mr4") ---> "1.2345"
OConv(12345, "mr34") ---> "1.235"
OConv(12345, "mr53") --->
"12.34500"
"mc.." Character Formatting: by example:
OConv("Brown's Cows", "mcu") ---> "BROWN'S COWS"
(make uppercase)
OConv("Brown's Cows", "mcl") ---> "brown's
cows" (make lowercase)
OConv("a1b2c3", "mca") ---> "abc" (extract alpha)
OConv("a1b2c3",
"mcn") ---> "123" (extract numeric)
OConv("a1b2c-3", "mc/a" --->
"12-3" (extract non-alpha)
OConv("a1b2c-3", "mc/n" ---> "abc-" (extract non-numeric)
OConv("a1b2c-3", "mcan") ---> "a1b2c3" (extract alphanumeric)
Note "mcna" is equivalent to "mcan"
OConv("a1b2c-3", "mc/an") ---> "-" (extract non-alphanumeric)
Note "mc/na" is equivalent to "mc/an"
IConv
"dj" Julian Date
By example:
IConv("2000107" , "dj")
---> 11795
IConv("00107", "dj") --> 11795
IConv("107", "dj") --> 11795 a 3-digit Julian date
is taken as
belonging to the current year
which at time of writing is 2000.
The
argument is tested for being 3, 5 or 7 characters long, with
the right 3 characters representing a number between 1 and
366.
Any argument failing that test is output unchanged
as the result.
eg
IConv("2000403", "dj") ---> "2000403"
"mrI" ( or "mdI")
Only the single-digit syntax for
scaling is supported:
eg
IConv("123456.78", "mr2") --> 12345678
IConv("12345.678", "mr2") --> 1234568
IConv("123456", "mr2") -->
12345600
MV Special Functions for GUI interfacing
VB/ MS Office/ functions to help with "friendly" grid
and form displays via Char(253) <--> Char(13):Char(10) and use made of
output codes in dictionaries.
MVR
"MultiValue Read" converts Chr(253) eg to Chr(13) & Chr(10)
s =
Pixie.MVR(s)
MVW
"MultiValue Write" is the inverse of MVR eg
s =
Pixie.MVW(s)
MVOConv
"MultiValue Read" with processing code applied
eg
s = Pixie.MVOConv(s,
"d")
MVIConv
"MultiValue Write" with processing code
applied eg
s = Pixie.MVIConv(s,
"d")
Refer to
our Microsoft Access example "testpxe1.mdb" for more details on these
in the context of a working example.
Top Table of Contents and Chapter 1: Overview
Support contact: john@pixieware.com