Support contact: john@pixieware.com

Appendix 1 - Technical Reference: PixieEngine Functions and Data Transfer.
A summary listing of commands and functions, grouped by purpose

Cataloging of Programs compared to Direct Run
Differences between ActiveX and Scripting in 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"
Data transfer methods to/from PICK-etc Engines

Appendix 2 - PxEngWeb interface for Web Apps and some COM Clients


Guide for upgrade from PixieEngine 1.x        Older Methods still supported.


Cataloging of Programs compared to Direct Run
To call catalogued programs, scripts or ActiveX, simply enter the verb, which is the key used in file "PixieEngine.ini"  under group heading "[Catalog]".  Some example programs are already catalogued for you.

[Catalog]
stest1=vbscript script1\stest1.txt stest1
umenu=activex px1.bp umenu
admin=activex pxadmin.bp umenu
test1=activex px1.bp test1
test2=activex px1.bp test2
pxu1000=activex px1.bp pxu1000
disptest=activex px1.bp disptest

Entries have the syntax:
Verb=ProgramType ProgramLocation ProgramRoutineName

The string after the = sign is the same as what you would enter from TCL to start the program as a direct run command.
Note that for "ActiveX", the type closest to existing PICKBASIC programs, the "ProgramLocation" is the COM "Class Name" which is usually filename.publicClass eg "px1.bp". 
For scripts, ProgramLocation is the pathname to the script file, usually relative to the PixieEngine folder eg "script1\stest1.txt".  It can also be absolute eg "c:\m3475\scripts\stest5.vbs".

The classic MV keyword "RUN" is supported as a synonym for "ACTIVEX"
eg
activex px1.bp umenu
run px1.bp umenu


We also continue to support the PixieEngine 1.x  
classical-style cataloging using file/table "md"


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.
XRun is mainly intended for use with scripts.  With XRun you can easily call scripted functions from ActiveX programs, which is useful for building apps which mostly run with the speed of a compiled ActiveX, but have some scripted functions which are therefore easily customisable eg for particular sites or even particular users or classes of user.

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


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 XCommon("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
accountname.filename eg "testpxe1.prod", "testpxe1.invoices", "statistics.survey1"
What this means is that you can skip OOpen statements and go directly to RRead etc
with error checking there.  If you usually rely on OOpen for checking file availability,
then continue doing that.  From Version 1.3 (May 2001), PixieEngine has a fast OOpen so there
is no longer any significant time lost by retaining legacy OOpen statements.
Eg
If Not RRead(Item, "testpxe1.prod", ItemID) Then
  Crt ErrorDetail
  Exit Sub
End If


Or: for a more versatile code which enables switching to test accounts (test databases) :
If Not RRead(Item, gsAccount & ".prod", ItemID) Then
  Crt ErrorDetail
  Exit Sub
End If

Here gsAccount is dimensioned as a public variable, and on app startup
is assigned the account(database) name with:

gsAccount = Field(ExecutePS("WHO"), " ", 2)
Place such code in "Sub Callback" in the "bp" class because that "Callback" routine always runs first no matter how you start or test your app.  See example VAR app, or even better, copy it and use it as a starting point for your Apps.


Classic Terminal/Printer Input/Output

Crt s             output to terminal with newline (Char(13):Char(10))
Crt s, False      output to terminal with newline suppressed
PPrint s          output to terminal or printer depending on settings
PPrint s, False   output with newline suppressed

IInput  etc applies only for VAR-Apps, "Object" equivalent is Pixie.Execute[TX]
ActiveX and Script have different syntaxes: Script has the pure VB style and ActiveX has some fancy footwork with optional arguments applied to more closely emulate classical MV practice.


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, timeout
IInputFor s, -1, False, 5
or
If Not IInputFor(s, 0, False, 5) Then Crt "Timeout on IInputFor"


IInput 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
General Syntax:
OOpen FFile, FileVariable
or
Call OOpen(FFile, FileVariable)  'VB7 will require this syntax

or
If Not OOpen(FFile, FileVariable) Then Crt ErrorDetail
Example: simple OOPen to obtain filevariable
Call 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
Call RRead(Item, FileVariable, ItemID) 'VB7 will require this syntax

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:
Delete FileVariable, ItemID 
or

If Delete(FileVariable, ItemID) = False Then ...


ExecutePS

"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
or
sReturning = ExecutePS(CommandString)

Returns the string "ERROR" if command fails, with more details returned in system variable ErrorDetail

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 property SelectResult(Attribute, Item)
Attributes(Fields/Columns) have a range starting with 0
Items(Rows) have a range counting from 1

With "SELECT * ...", SelectResult(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"
   SelectResult(0,1) is the first returned A1
   SelectResult(0,2) is the 2nd returned A1
   SelectResult(1,2) is the 2nd returned A3
   SelectResult(2,2) is the 2nd returned A17
   SelectResult(3,2) is the 2nd returned A34
Note that when your SELECT statement returns only one value, you read its value from SelectResult(0, 1) rather than the SelectResult(0,0) that you may reach for out of habit.  You need to remember that SelectResult does columns with a zero-based count and rows with a 1-based count.
Note, new January 2002. For the D3 and UV datastores only, SelectResult row 0 returns column information from the dictionaries eg "L30" for a left-justified column of width.

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"

Login for "The Microsoft Way" ie when using PixieEngine as  a connectivity component in Word, Excel, custom VB apps etc:
Call Pixie.ExecutePS("LOGIN jeffrey biscuit")
An encryption version with keyword LOGINCR is available to paying customers.

System Information: "SYSTEM PATH", "SYSTEM DATASTORE","SYSTEM LOCKTIMEOUT", ...
sRet = ExecutePS("SYSTEM PATH")

  Returns Path where master component "PixieEngine.dll" is installed.
  NOTE that this Path ends with "\" eg "C:\Program Files\PixieEngine\"
  This is useful when building programs in separate working folders which need to 
  find and work with PixieEngine folders eg "..\ItemText",  "..\DataDump"
sRet = ExecutePS("SYSTEM DATASTORE")
  Returns the current DataStore driver: 
  ie (currently)
 "MSSQL", "MYSQL", "D3", "UV", "JET"
sRet = ExecutePS("SYSTEM LOCKTIMEOUT")
sRet = ExecutePS("SYSTEM LOCKTIMEOUT 900")
  1st example reads and returns the LOCKTIMEOUT value.
  2nd example sets LOCKTIMEOUT to 900 sec and returns "OK"
sRet = ExecutePS("SYSTEM USERINST")
sRet = ExecutePS("SYSTEM USERINST 234329873")
sRet = ExecutePS("SYSTEM USERINST 234329873 900")

  The USERINST is the SYSTEM identifier for the current session.
  By default it is username*datastore_session_id eg "john*53"
  1st example returns the current USERINST
  2nd example sets the USERINST to 234329873 and returns "OK"
  In web apps, it often makes sense to set USERINST to the Webserver Session ID.
  3rd example sets both USERINST and LOCKTIMEOUT in one fast call, which
  reconfigures PixieEngine for non-persistent web apps.
sRet = ExecutePS("SYSTEM ACCOUNT")
sRet = ExecutePS("SYSTEM USERID")

  Straightforward return of current ACCOUNT, and login USERID

 

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.
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 testpxe"
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 pord N D")   Create a TYPE-N file "pord" (any number of attributes with some querying restrictions) 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 can be made available in a wide range of programming environments
eg Microsoft Word VBA, by referencing "PixieEngine"
VB convention is to setup the "PixieEngine.Functions" object as follows:
Public PxFns As PixieEngine.Functions
...
Set PxFns = New PixieEngine.Functions

This then makes the functions available in dot-syntax eg PxFns.OConv, PxFns.DCount
Note the change from earlier versions where this reference was "PxEngFns.Functions".

We also supply a module "basPxFunctions" as file "basPxFunctions.bas"
Copy this into any VB or VBA/Microsoft-Office project and the
functions can then be used directly in your VB code as though they were
part of the VB language eg sDate = OConv(Extract(Item, 14), "d")
Refer examples PX1, PX2 and template PxEngTemplate to see this in use.

SegmentReplace equiv of VB6 "Replace" for those on VB5, Word 97 and below,
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
   returns position in a string of the nth occurrence of a substring, eg
n = Index(s, "<", 4)


Matches
    returns True or False depending on whether or not the string matches a formatting code.
Note that PixieEngine requires text constants to be quoted in single quotes.
eg
b = Matches(s, "0N")
eg
If Not Matches(s, "0N'.'2N") Then ...  useful for testing user input of money amounts, here we are testing for any numerical input "0N", then a decimal point, then 2 numeric digits "2N".
Formatting Codes:
N = Numeric only, A = Alphabetical only,  X = accept any character
0 (zero)= any number of characters; other integer values set number of characters.
Examples:
b = Matches("kbl%&* blah blah blah FRED876", "0X'FRED'3N")
b <-- True
b = Matches("1234567890123-1234-12", "13N'-'4N'-'2N")
b <-- True


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  
returns substrings of "dynamic variables" eg
sSub = Extract(s, 4)  equivalent to modern MV s<4>
sSub = Extract(s, 2, 5)    equivalent to modern MV s<2, 5>

RReplace    returns result of replacing a substring of a "dynamic var iable" eg
s = RReplace(s, 4, sNew)
s = RReplace(s, 4, 7, 2, sNew)

Insert    returns result of inserting a substring into a "dynamic variable"  eg
s = Insert(s, 4, 3, sNew)

Dylete   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: Difference between PixieEngine and some MV behaviours:
1. As of June 2000, RReplace, Insert and Dylete only work down to
the CHAR(252) level. The "text mark" CHAR(251) is not yet supported.
eg
s = Insert(s, 4, 3, 3, sNew) - OK
s = Insert(s, 4, 3, 3, 1, sNew) - NOT SUPPORTED


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. 
Emulating Locate in VB was especially challenging because of the variable number and type of arguments.  This led us to use "IN", "BY" and "SETTING" as dummy arguments to flag special meanings for their following arguments. The argument following "IN" is the string or substring to look in. The argument following optional "BY" gives a flavour of assumed sorting of the substrings when looking for a position to fit a new one into. The argument following "SETTING" returns the position into which the substring-to-look-for fits, or should fit considering any "BY".

Syntax:
b = Locate(sFind, "IN", sStringIn [,iOccurrence][,"BY", sSortCode][, "SETTING", iPos])
Where
b           -  returned Boolean value: True or False
sFind       -  substring to find
"IN"        -  placeholder
sStringIn   -  dynamic array or attribute in which to look for sFind
iOccurrence -  optional, default = 1, occurrence to take
               if sFind is expected to repeat
"BY"        -  placeholder, tells the function that sSortCode follows.
               Also switches on a method that if sFind is not found, Locate
               will nominate a position where it should go based on an
               assumption that there is a sorted list to fit it into.
sSortCode   -  2 characters:  eg "ar", "al", "dr", "dl"; upper case is OK
               1st character: "a" for "ascending" or "d" for "descending"
               2nd character: "r" for "right-justified" usually used for numeric
               data; "l" for "left-justified" usually used for general text.
"SETTING"   -  placeholder
iPos        -  value, sub-value or sub-sub-value position in sStringIn 
               where sFind is found...
               OR, if a "BY" clause is present, the recommended position 
               into which to insert sFind to add it to a sorted list.

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 I
f


OConv "Output Conversion" returns result of applying a "processing code" to a value.
syntax:
sOutput = OConv(sInternal, sProcessCode)
eg
sInternal = 47500
sOutput = OConv(sInternal, "mr2")
'sOutput <-- 475.00

Processing codes, OK as upper or lower case.

"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  
"Internal Conversion".  PixieEngine/PixieWeb implement 
a simplified inverse of OConv.
Syntax:
nInternal = Pixie.IConv(sExternal, sProcessCode)
eg
sExternal = "475.00"
nInternal  = Pixie.IConv(sExternal, "mr2")
'nInternal <-- 47500

Codes: "d", "dj", "mrI"

"d"
Conversion to internal date values, by example:
IConv("23 Dec 99", "d") --> 11680
IConv(Now, "d") ---> (today's MV date)
NOTES: There is no need to specify "d4", "d2/" etc
as the VB date recognition functions used behind the
scenes here automatically date-convert a wide range
of formats, and any other "d...." code except "dj" will be
treated as "d".  That means that automatic conversions
giving "d2/", "d2." etc will run just fine.
Handling of USA vs British/European date formats is
also handled automatically with results depending
on the machine's Windows Regional settings.
The PxUSADate property only affects OConv.

"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.


Data Transfer Methods

PixieEditor is a separate program for transferring data over a network. 
Commercial customers for PixieEngine get PixieEditor as part of their package deal.

For Version 2.0 we have given PixieEngine built-in data transfer methods of its own.

In both cases, start the utility programs from the TCL environment provided by PxEngLink.exe with the command  admin


Top     Table of Contents and Chapter 1: Overview      Alternative older methods still supported.
Guide for upgrade from PixieEngine 1.x

Support contact: john@pixieware.com