"Pixie" is used as the example
object name throughout this document.
Method
explanations have an example call as a heading eg
Call
Pixie.ExecuteET(request, expected_response)
Property explanations have just the lone keyword as a
heading eg
ResponseRaw
"PixieWMA.clsAgent" - latest version, use
in most cases
"PixieSerialA.clsAgent" - serial line
version, for use with older servers or for dial-up.
"PixieWeb.clsAgent" - older version,
included for backwards compatibility, or for non-MV servers eg "FilePro"
Note, for those upgrading, the new main active file is
"PixieWMA.dll" with the most common function used being "ExecuteET".
But, the PixieWeb package also installs a "PixieWeb.dll"
designed for backward compatibility with your existing scripts and
applications. "PixieWeb.dll" --> "PixieWeb.clsAgent" delivers best
performance with the new "ExecuteET" function but it also supports the old
"Execute" syntax.
For ASP scripts:
Dim Pixie
Set Pixie = Server.CreateObject("PixieWMA.clsAgent")
We use "Pixie" as the object name, but you can call it anything you like as long as you are consistent.
"Pixie" can also be stored as a "Session Object", which gives it a continuous PICK user session matching the IIS WebServer User session. This is especially useful with FBF interactive apps using XML-Download or IFRAMEs For more details refer Chapters 6 and 7. The supplied "Terminal Emulators" are the simplest examples of this principle in action.
'-- Start of example code
Pixie.Port = 23
Pixie.Host = "127.0.0.1"
Pixie.TimeOut = 4
Call Pixie.Connect("{AUTO}")
Call Pixie.ExecuteET("myusername", "password:")
Call Pixie.ExecuteET("mypassword", "<<< Pick Systems")
Call Pixie.ExecuteET("term mm-mon", ":")
Call Pixie.ExecuteET("echo off", ":")
'-- Simplified validation to show the general idea.
' In real life, we do several steps then check the state
If Pixie.State = "ERROR" Then
s = "<HTML><BODY>"
s = s & "ERROR in connecting to Server, Please try again"
s = s & "</BODY></HTML>"
Response.Write s
Response.End
End If
'-- End of example codePort Integer, TCP/IP port, usually 23
Host String, can be dot address as above, or network name
eg "ntserver"
CommPort (PixieSerialA) Integer, Serial Port number, default is 3
Settings (PixieSerialA) String, default is "19200,N,8,1"
Usually the only alteration needed is the first value, which
you can tune higher for fast hosts or newer modems,
or reduce eg to "9600,N,8,1" for older hosts.
TimeOut Numeric with decimals allowed, eg 4, 8, 2.5
Default = 3 sec
Time in seconds allowed to wait for PICK responses.
NOTE, in a significant change for ver 3.2 December 2000,
the TimeOut starts counting from the most recent chunk
of data received from PICK etc.
IF for example, a long report takes 12 sec to output,
AND the TimeOut = 4, THEN
The TimeOut error fires at 12 + 4 = 16 seconds.
ie 4 seconds after PICK stops feeding out
chunks. You can choose to ignore the error
and use the value Pixie.ResponseRaw,
and this can be a good technique
in "screen-scraping" situations.
END IF
State Returns a string to let you check the state of
the object, possible returned values are:
"STARTUP" = not connected to PICK etc
"TCL" = connected and last execution was successful
"PAGE" = working through a page-by-page response
"ERROR" = error on last execution
PixieWeb does NOT stop when in a state of "ERROR",
rather it will happily allow you to try to execute
something else.
Call Pixie.Connect(expected_response)
"expected response" is a string, case-sensitive by default although
you can change that with Pixie.ExecuteCompareMethod = 1
"{AUTO}" is a special argument to switch on automatic detection. eg:
Call Pixie.Connect("{AUTO}")
If auto-detection does not work, try some characters
from the server connection response.
Eg "er" covers "user id", "user name", "kernel"
Call Pixie.ExecuteConnect(request_to_server, expected_response)
Special for PixieSerialA. When using a modem for dial-ups you connect
in 2 stages. Pixie.Connect gets you to the modem, then you need
Pixie.ExecuteConnect for first contact with host when you dial the number.
eg
Set Pixie = Server.CreateObject("PixieSerialA.clsAgent")
Pixie.TimeOut = 4
Pixie.CommPort = 2
Pixie.Settings = "115200,N,8,1" '-- fast modern modem
Call Pixie.Connect("")
'Now initialise the modem, modems reply to this with "OK"
Call Pixie.ExecuteET("AT&F&C1&D2", "OK")
Call Pixie.ExecuteET("ATE1S0=0", "OK")
If Pixie.State = "ERROR" Then Call ErrorHandler("Modem not available")
'If this machine has more than one modem then
'we can use a loop to work through the possible CommPorts
'
'Ready to make the call, give lots of timeout for dialling
'Make sure the ASP script timeout is generous, at least 40 sec
Pixie.TimeOut = 40
Call Pixie.ExecuteConnect("ATDT3338885555", "{AUTO}")
If Pixie.State = "ERROR" Then Call ErrorHandler("Dial-up failed")
Pixie.TimeOut = 8
(Deprecated: Use ExecuteET)
Call Pixie.Execute(request_to_server, expected_response)
Or
sResponse = Pixie.Execute(request_to_server, expected_response)
Older syntax provided only for backward compatibility
and only by creating your object from class "PixieWeb.clsAgent".
Use Pixie.ExecuteET for all new work.
Call Pixie.ExecuteET(request_to_server, expected_response)
Or
sResponse = Pixie.ExecuteET(request_to_server, expected_response)
Both arguments are strings.
"expected_response" is any text which you would
expect to find at or near the end of a successful response.
We suggest "</TX>" within PICKBASIC as a
standard end-of-transmission tag. When working in TCL you can
often use ":" for PICK and ">" for UNIVERSE.
NOTE that by default, Pixie will add a carriage return CHAR(13)
to the end of any request but you can suppress that
by ending your request string with the escape {NOCR}
eg, to send a CTRL-BREAK
Call Pixie.ExecuteET(Chr(3) & "{NOCR}", "*")
The new function syntax "sResponse = ..." gives a result in
one process call instead of the old 2-step.
The "Call ..." syntax is useful where you do not need results at
every conversation step. It will also be a preferred syntax
of Microsoft's new "dotNET" technologies.
Call Pixie.ExecuteTX(request_to_server)
Or
sResponse = Pixie.ExecuteTX(request_to_server)
Similar to ExecuteET, with an expected_response of "</TX>".
but it ALSO returns a string extracted from between
the "<TX>" and "</TX>" tags.
eg
raw string = "Debug: ItemID=NN8088<TX>Michael</TX>"
ExecuteTX returns "Michael"
eg
raw string = "John Calder</TX>"
ExecuteTX returns "John Calder"
Call Pixie.ExecutePM(request, expected1 [, expected2 [, ...]])
Or
sResponse = Pixie.ExecutePM(request, expected1 [, expected2 [, ...]])
Similar to ExecuteET, but you can give a number of
alternative expected responses. This is useful
when getting data from legacy apps where you do not
have source code access to do web-friendly changes.
eg:
sResponse = Pixie.ExecutePM(sRequest, "(Y/N)", "F9=Find", Chr(27) & " = ")
Methods/Functions
Call Pixie.ExecuteET(request, expected_response)
sResponse = Pixie.ExecuteET(request, expected_response)
Call Pixie.ExecuteTX(request)
sResponse = Pixie.ExecuteTX(request)
See above
Call Pixie.ExecuteRaw(request)
"Request" is a string
With ExecuteRaw, Pixie does NOT check that a
response from PICK is complete.
It is up to you to code analysis of the
raw response into your ASP or other code.
We use this ourselves for requests which could result in
a variety of responses, BUT we nearly always then find
a way of using the more efficient ExecuteET or ExecutePM instead.
Call Pixie.ExecutePage(request, expected_response, lines_per_page)
Call Pixie.ContinuePage
"Lines_per_page" = 25 on every MV Engine we have worked with so far.
"ExecutePage" and "ContinuePage" work together to handle
very long expected responses. You can stream a response
to the user 1 page at a time. This makes it possible for
very large responses to appear on the user's screen as they
come from PICK rather than waiting for the entire response
to arrive before displaying it.
This also lets you set an upper limit to
how much data you are prepared to let a user have before
issuing "Q" or CHAR(24) to put a stop to the stream.
Call Pixie.ResponseCleanup
Removes non-printing characters eg CHAR(0), CHAR(1)
from Pixie.Response
ResponseRaw
Returns a string giving the "raw response" from PICK.
Like all TCP/IP servers, PICK sends larger strings by
the "packet" method which breaks them up into pieces
called "chunks". So the value Pixie.ResponseRawmay
be incomplete. PixieWeb therefore gives you the
ExecuteET etc methods to do a test-for-completeness for you
and give you the nicely processed Pixie.Response
Response Returns a string giving a complete PICK response
already validated for you by the ExecuteET, ExecuteTX,
ExecutePage or ContinuePage methods.
If validation fails, Pixie.Response returns an error
message giving details of the problem, while
Pixie.State returns "ERROR"
Pixie.ResponseRaw returns whatever string has been received.
ExecuteCompareMethod
Sets whether end-of-transmission is to be recognised
by a case-sensitive comparison, eg
whether "</tx>" recognised as an alternative to
"</TX>". Default value is 0,
giving case-sensitive comparisons.
The alternative value is 1
eg, to allow case-insensitivity for end-of-transmission marks:
Pixie.ExecuteCompareMethod = 1
property = Pixie.ExecutePS("propertyname")
A device to make future expansion smoother by letting us add properties
without changing the external "COM Interface" structure.
At present only one propertyname "PATH" is implemented, where
PixieWMA.dll reports back what folder it is in. eg
sPath = Pixie.ExecutePS("PATH")
A typical returned value would be "C:\Program Files\PixieWeb\"
Note that such PATHs include "\" on the end.
Until now (June 2001), we always wrote custom backservers in PICKBASIC for data handling. But some users have been asking for a way for VB etc to be a one-stop-shop for all operations. Our experience with another of our products, PixieEditor, has given us the idea of a PICKBASIC "Universal Backserver Program", now supplied with this package in source code form as PX.BACKSRV. It should be clear from its code that while you could run everything "raw" with Pixie.ExecuteTag, the conversation strings need to be heavily "escaped", "delimited" and "tagged" and so we have provided friendly functions "PxRowset", "RRead", "WWrite" etc with similar syntaxes to their traditional PICKBASIC equivalents. eg the INPUT buffers in PICK D3 and UNIVERSE can handle 4096 bytes max at each pass so our WWrite function automatically measures the data you want to Write and if longer than 4096 bytes it will break it up and feed it in for you via the necessary number of conversational steps.
For ALL of these functions, you must get PX.BACKSRV running first, usually by login to TCL then:
If Pixie.ExecuteTag("PX.BACKSRV", "<TXA>",
"</TXA>") <> "OK" Then
Call ErrorHandler("Backserver not available")
End
If
PICK engines, eg D3, need an extra configuration
step to give well-behaved output.
Call
Pixie.ExecuteTag("PICK" & Chr(254) & "1", "<TXA>",
"</TXA>")
Ultimate Plus
also has a custom step:
Call
Pixie.ExecuteTag("ULTPLUS" & Chr(254) & "1", "<TXA>
File RRead-ing and WWrite-ing , general syntax:
Pixie.RRead Item, FileName, ItemID
or
Call Pixie.RRead(Item,
FileName, ItemID) 'VB7 will require
this syntax
or
If Not Pixie.RRead(Item, FileName, ItemID)
Then sMsg =
Pixie.ErrorDetail
similar general syntax for: RReadU, WWrite, WWriteU
RReadV general syntax:
Pixie.RReadV Value, FileName, ItemID, FieldNumber
or
If Not Pixie.RReadV(Value, FileName, ItemID, FieldNumber)
Then ...
similar syntax for: RReadVU, WWriteV, WWriteVU
Delete to delete an item(record) from a file(table).
General syntax:
Call Pixie.Delete(FileName,
ItemID)
or
If
Pixie.Delete(FileName, ItemID) =
False Then ...
PxRowset takes a PICK etc query sentence and
returns the result as a 2-dimensional "SelectResult"
Or,
you can query for only a list of ItemIDs and work through that with RRead statements giving
a similar way of working to the "Select list .... ReadNext"
of PICKBASIC.
boolSuccess = PxRowSet(FileName
[[[[,FieldCount], Query], FieldList],
RetTimeOut ])
PxRowset creates Pixie.SelectResult(Field,
Row) from where you can read values.
Field is zero-based, Row is
one-based.
FieldCount is 1 by default, giving a
list of keys where
Field is always 0.
Query is an
optional SELECT or SSELECT query in the syntax of your MV Engine.
FieldList
(1) for raw data is a list of attribute numbers
separated by CHAR(253) marks eg "4ý6ý7ý13".
OR (2) can
be a LIST statement including dictionary item names, eg "LIST CUST CONTACT TEL
FAX"
in
which case PX.BACKSRV looks up dictionary processing codes and
applies them.
When using
LIST, give 0 as the argument for FieldCount.
RetTimeout is
an optional Timeout in seconds for this function because you may need to give
complex queries
more time than your usual timeout.
Pixie.SelectUbound(1) gives the highest
number column. This is the number-of-columns-minus-one because columns
count from 0.
Pixie.SelectUbound(2) returns the number of
rows. Rows do count from 1. There is a Row 0 but this is used only
when "FieldList" starts with "LIST" and it is used to return additional column
information from the dictionary, eg column width.
Examples:
' Using a "Select List" approach
Call Pixie.PxRowSet("PROD", 1, "SELECT PROD
WITH A1 = ""[MOUSE]"" ")
For i = 1 To
Pixie.SelectUbound, 2)
Call
Pixie.RRead(sRow, "PROD", Pixie.SelectResult(0,i))
Response.Write
"<tr><td>Pixie.SelectResult(0,i)</td>"
Response.Write
"<td>Pixie.Extract(sRow,1)</td>"
Response.Write "<td>Pixie.Extract(sRow,
4)</td>"
Response.Write
"<td>Pixie.Extract(sRow, 5)</td></tr>"
Next
'Using the SelectResult directly.
'Note that if the attribute selection arg 4 is used
then
'its number of multivalues must match arg 2
FieldCount
Call Pixie.PxRowSet("PROD",
4, "SELECT PROD WITH A1 = ""[MOUSE]"" ", "0ý1ý4ý5")
For i = 1 To
Pixie.SelectUbound(2)
Response.Write
"<tr><td>Pixie.SelectResult(0,i)</td>"
Response.Write
"<td>Pixie.SelectResult(1,i)</td>"
Response.Write
"<td>Pixie.SelectResult(2,i)</td>"
Response.Write
"<td>Pixie.SelectResult(3,i)</td></tr>"
Next
The first approach is better for very large quantities of data because it breaks up the conversation into a greater number of timeout-manageable steps. However for one-shot retrieval in web apps, the second approach will be faster and easier in most circumstances. Success depends heavily on having well designed queries that run reasonably fast. You can check them first from TCL using a trad terminal. A good safety net for web apps is to add limiting clauses like " SAMPLING 1000" to your queries. Be warned that the "SAMPLING" syntax varies slightly between different PICK-like engines.
Note the subtle but effective error handling built into
the above. If Pixie.PxRowset
should fail then
Pixie.SelectUbound(2), which returns the
number of rows, will return 0,
and so the For ..
Next will not happen.
Note that VBSCRIPT and the new VB7 insist on Next by itself rather than the Next i we know and love.
For a good example of SelectResult in action, and its alternatives, look at the source code of the "PixieExcelW.xls" example spreadsheet provided. Chapter 8 gives a code commentary on "PixieExcelW.xls".
(Deprecated: use
SelectResult)
Pixie.SelectArray - returns a
2-dimensional array after Pixie.Rowset is run. But it can be slow to
return after a large query and some environments have
problems passing arrays across object boundaries, eg VBSCRIPT fails with
SelectArray. It is included for backwards compatibility only: use
Pixie.SelectResult instead.
PICK etc have CHAR(251) to CHAR(255) as reserved
characters, used to separate
records, fields and
subvalues(multivalues) of data. This can cause problems with languages
eg Russian, German where such characters can appear in
documents for storage. Images and
other binary
data stored as ANSI strings can also have problems.
PxEscape changes "problem" characters into 2 characters,
the first one being "`", the back-apostrophe.
The
back-apostrophe itself becomes doubled to "``".
The source code is no secret and is a good way of documenting the method. You may choose to code your own version based on this idea, eg if you only have a small number of difficult characters, or if you have other escaping systems you want to be compatible with.
Public
Function PxEscape(ByVal
sItem As String _
, Optional
ByVal bQuote As Boolean =
False) As String
If InStr(sItem, "`") > 0 Then sItem = Replace(sItem, "`", "``")
If
InStr(sItem, Chr(255)) > 0 Then sItem = Replace(sItem, Chr(255), "`*")
If
InStr(sItem, Chr(254)) > 0 Then sItem = Replace(sItem, Chr(254), "`^")
If
InStr(sItem, Chr(253)) > 0 Then sItem = Replace(sItem, Chr(253), "`]")
If
InStr(sItem, Chr(252)) > 0 Then
sItem = Replace(sItem, Chr(252), "`[")
If InStr(sItem, Chr(251)) > 0 Then sItem = Replace(sItem, Chr(251),
"`~")
If InStr(sItem, Chr(13)) > 0 Then sItem = Replace(sItem, Chr(13), "`C")
If
InStr(sItem, Chr(10)) > 0 Then sItem = Replace(sItem, Chr(10), "`L")
If bQuote
Then
If
InStr(sItem, "\") > 0 Then
sItem = Replace(sItem, "\", "`B")
If InStr(sItem, Chr(34)) > 0 Then sItem = Replace(sItem, Chr(34),
"`Q")
If InStr(sItem, "'") > 0 Then sItem = Replace(sItem, "'", "`A")
End If
PxEscape = sItem
End Function
sProcessed = PxEscape(string_to_process [,
quote_process_flag])
Use PxEscape to
process data before storing in an MV engine.
The
optional flag can be set to True to do additional
escaping on the quotation marks.
The
quote_process_flag is
for PICK database engines where the fastest way of feeding data in
is via the TCLREAD technique, also known as SENTENCE(), but
that technique is intolerant
of quote marks and
needs them escaped. This also explains
why we
have used back-apostrophe as our escape character rather than
the backslash beloved of Java and C aficionados.
sRetrieved = PxDescape(raw_retrieved_string_from_MV)
Use PxDescape to
"unpack" or "decode" data previously processed with PxEscape
Example of use
Call
Pixie.WWriteV(PxEscape(sData), "PROD", sItemID, 1)
Note that Dynamic Variable strings should not be escaped because that would mangle the separator marks. Instead apply PxEscape to separate attributes(fields, segments) within such strings. Also be careful with WWrite; PxEscape usually goes best with WWriteV.
Example
Pixie.FormAnalyse Pixie.ItemTop = 4 Pixie.ItemLeft = 22 Pixie.FormItemGet sDescription = Pixie.Response
Methods
Call Pixie.FormAnalyse
Call this first before calling FormItemGet.
Analyses the PICK response by tagging all separate text
strings with their associated @(x,y) co-ordinates
Call Pixie.FormItemGet
Loads a text string into Pixie.Response based on what
ItemTop (y co-ordinate) and ItemLeft (x co-ordinate) location
you nominate to look for it. Properties
ItemTop Integer. y co-ordinate
ItemLeft Integer. x co-ordinate
Use these properties to nominate where on a terminal
screen you want to read from. You can find out what
these values should be by:
EITHER running the Terminal program with PixiePeekaboo
OR looking in its DATABASIC code for the @(x,y) functions
byteArray = Pixie.FileGetStream( filename_with_full_path)
Get disk file as an array of bytes. Useful for
detailed manipulation and control of binary files
such as page image and sounds, or executable downloads.s = Pixie.FileGetText( filename_with_full_path)
Get disk file contents as a string.
Especially useful for keeping control of the
issuing of .htm pages-as-templates by feeding them out
through a controlling .asp script.
The <% = myVariable %> facility in IIS does much the
same thing, but FileGetText gives flexibility like:
* Select from several templates depending on
the situation.
* Enables use of the nice Response.End statement
which does not work with the <% = myVariable %>
technique.
* Use this within your compiled ActiveX .dll
web app to get a "webclass" effect without
the ugly "webclass" baggage.Call Pixie.LogBook( log_stub_name, log_message)
Keep logs of your site visitors and their activities.
The "log stub name" is a path plus the generic log file name.
PixieWeb adds suffixes .. "book.txt", "bak1.txt",
"bak2.txt", "bak3.txt"
eg with a "stub" of "C:\InetPub\wwwRoot\Log", you will get
files "Logbook.txt", "Logbak1.txt", "Logbak2.txt", "Logbak3.txt"
Logbooks are allowed to reach a max size of 32K, the limit for
easy reading with "Notepad", before they are moved to bak1, with
bak1 moving to bak2, bak 2 moving to bak3, and the former contents
of bak3 being discarded.eg Use of LogBook for privilege-controlled file download.
sUserID = Session("UserID")
If Vartype(sUserID) <> vbString Then sUserID = ""
If sUserID > "" Then
Call Pixie.LogBook(Session("LogStub"), sUserID & " download Maestro")
Response.Redirect "http://www.mysite.com/downloads/Maestro.zip"
Else
'Enforce login before allowing download
s = Pixie.FileGetText(Session("Folder") & "login.htm")
Response.Write s
End If
String and other utility functions
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 = Pixie.Matches(s,
"0N")
eg
If Not Pixie.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 = Pixie.Matches("kbl%&* blah
blah blah FRED876", "0X'FRED'3N")
b <-- True
b =
Pixie.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 Pixie.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 =
Pixie.DCount(s, " ")
Field returns a
substring, given delimiter and number. The delimiter can be of more than
one character. eg:
sTRow = Pixie.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 = Pixie.Extract(s, 4) equivalent to modern MV s<4>
sSub =
Pixie.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 = Pixie.RReplace(s, 4, sNew)
s = Pixie.RReplace(s, 4, 7, 2, sNew)
Insert returns
result of inserting a substring into a "dynamic variable" eg
s = Pixie.Insert(s, 4, 3, sNew)
Dylete function "Dynamic Array Delete" returns the result of deleting a substring from a dynamic
array.
eg
s =
Pixie.Dylete(s, 3)
s = Pixie.Dylete(s, 1, 5)
s =
Pixie.Dylete(s, 4, 7, 2)
eg
s =
"111þ222þ333þ444"
sDel = Pixie.Dylete(s, 3)
'Result: sDel <-- "111þ222þ444"
NOTE: Differences between these emulations 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 = Pixie.Insert(s, 4, 3, 3, sNew) - OK
s = Pixie.Insert(s, 4, 3, 3, 1, sNew) - NOT
SUPPORTED
2. Arguments
of zero used as dummy placeholders are not yet supported.
eg
s = Pixie.Insert(s, 4, 3, sNew) - OK
s = Pixie.Insert(s, 4, 3, 0, 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 using 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 =
Pixie.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 Pixie.Locate(SEL,
"IN", MODS, 1, "SETTING", YY) Then ...
eg
If Not Pixie.Locate(DEKNO, "IN", FDLIST, 1, "BY",
"ar", "SETTING", Pos) Then
FDLIST =
Pixie.Insert(FDLIST, 1, Pos, DEKNO)
FDITEM = Pixie.RReplace(FDITEM, 4,
FDLIST)
End If
OConv "Output Conversion"
returns result of applying a "processing code" to a value.
Syntax:
sOutput =
Pixie.OConv(sInternal, sProcessCode)
eg
sInternal = 47500
sOutput = Pixie.OConv(sInternal, "mr2")
'sOutput <-- 475.00
Processing codes, OK as upper or lower case, fall into
3 categories depending on the starting one or 2 characters:
"d..." - date formatting and conversion
"mr.." - numeric scaling, formatting and rounding-off
(older
"md.." syntax also supported)
"mc.." - character
filtering
"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
implements
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
"MVX2D"
Use for a derived parallel multivalued calculation. MVX2D(Attr1, Attr2) where
Attr1 is multiplied by Attr2 and the result presented in a new attribute.
Example of use is the query "ORDERS_Query":
SELECT ORDERS.A0 AS ItemID, ORDERS.A1 AS CustCode, OConv([A2],"d") AS InvDate,
ORDERS.A3 AS Rep, ORDERS.A4 AS OrdNo, ORDERS.A5 AS Source, ORDERS.A6 AS Freight,
MVR([A7]) AS ProdCode, MVOconv([A9],"mr4") AS Qty, MVOconv([a10],"mr2") AS Price,
MVX2D(Price, Qty) AS ExtPrice, FROM ORDERS ORDER BY ORDERS.A0;
Note in the above, that ExtPrice is the result of multiplying Qty and Price together.
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.