Release notes - filePro Plus 6.1 - 03/28/2025 fP 6.1.XX.08 The filePro Plus software and the documentation provided with it are protected under United States Copyright Laws and is provided subject to the terms and conditions of the filePro License Agreement. PLEASE NOTE the support and fax phone numbers listed in this readme file. Open new support incidents on our website. ***************************************************************** WWW http://www.fptech.com Support support@fptech.com Sales sales@fptech.com Management filepro@fptech.com ******************************* To submit bug reports -------------------------------- 1. Login to your account portal on our website http://www.fptech.com/fptech/login.php and then go to the Support Incident Menu and submit an incident request. 2. EMail them to support@fptech.com including the text "Bug Report" with the version # and your filePro License # in the subject line 3. FAX them to (813) 354-2722 clearly marking them as bug reports and be sure to reference your filPro License # 4. Call the customer support number (800) 847-4740 ******************************* A special thank you to Jim Asman for his contribution to the functionality of our printer tables. Jim was a good friend to filePro and is dearly missed. ******************************* Contact Information Surface Mail fP Technologies, Inc. 432 W. Gypsy Lane Road Bowling Green, OH 43402 Phones Support (800) 847-4740 Sales (800) 847-4740 Fax (813) 354-2722 Email Support support@fptech.com Sales sales@fptech.com Management filepro@fptech.com It's important that you clearly describe a suspected bug and include the filePro version number. If the programmer has trouble figuring out what you meant, you might as well not have reported the bug. Be very specific. For example, if you are reporting a bug concerning a Browse, identify if it is a lookup browse or browse created by using the [F6] key. A screen shot is very helpful and sometimes better than more than 1000 words. Describe exactly how to duplicate the bug. Although it's sometimes difficult to create a working sample to demonstrate the problem, make every effort to trim down your code and provide a working sample application with test data. You may even discover that what you thought to be a bug is due to a coding error or the bug may only occur with lots of data or large processing tables. Take good notes as to any error messages and under what circumstances the error message is presented. It never hurts to provide more information rather than not enough. This is particularly true when the programmer asks for additional information. Rather than responding with a single sentence, be verbose since this may shed some light on the bug or what you may be doing wrong in your code. Read what you wrote. Closely read your bug report before submitting to make sure it's clear and complete. If you have listed steps for duplicating the bug in a sample, exercise the sample with the listed steps to make sure you haven't missed a step. *************************************** filePro and filePro Plus are registered trademarks of fP Technologies, Inc. *************************************** =================================== Bug fixes are below the New Items. =================================== ==================================== Version 6.1.02.RR New USP Only Items ==================================== Enhanced find and replace with an optional match whole word function. This makes it much easier to find places where variables like "aa" and "zz" are used. Added new F8 options to dmakemenu. You can now move, copy, delete, save, and load menu items inside of dmakemenu. Expanded menu version from 8 characters to 16 in dmakemenu and runmenu. Using a longer title and running the menu in an older version of filePro will only display the first 8 characters. Added new environmental variable PFMENUVER=0, Default 0. This globally changes how filePro menus display their version strings. 0 - Show menu version as-is. 1 - Show filePro version if menu version is blank. 2 - Show menu file name if menu version is blank. 3 - Always show filePro version. 4 - Always show menu file name. Added pseudo environmental variable @MN that can be used in the version string or menu title to show the menu file name in its place. To use, place $@MN in the menu title or menu version section when designing a menu. Added an option "7" to READSCREEN() to get cursor path. Dynamically sized, returns a list of fields separated by colons, e.g. " 1: 2:TAB:aa :". Added new option to ENCODE() and DECODE(), "URL", to handle URL percent encoding. Failure to decode will return an empty string. Example: then: x=ENCODE("URL","Hello, World!") ' x contains "Hello%2C%20World%21" then: x=DECODE("URL","Hello%2C%20World%21") ' x contains "Hello, World!" Added preliminary support for variable index selection in lookups. You can now use an expression to select which index to use for a lookup at runtime. Example: then: declare index(1,*); index="A" then: lookup myfile = test k=aa i=(index) -nx Note: The lookup wizard has not been updated at this time. Support will be added in a future version. Added READMAP(file) function. Takes the name of a filePro file and returns information from the first line of the map file. On error or if the file is an invalid filePro file, the function will return blank. Parameters: file: The name of a filePro file. Example return value: Each section is 5 characters long by default. "type:kreclen:dreclen:keyflds:" Where: type is the filePro map type; map, map2, odbc, alien. kreclen is the key record length for a record in the file. dreclen is the data record length for a record in the file. keyflds is the number of key fields for a record in the file. e.g. "map : 100: 0: 10:" Added a new function x=PRINTCODE(code [,flag]). Returns either the expanded print code for the current printer or its description. Parameters: code: The print code number to evaluate. flag: 0 - Return the "raw" expanded print code. 1 - Return the comment for the print code. Examples: Given a print code table containing the following entries: +- Number -- Sequence ------------ Description --------------------+ | 1 %2 %3 Initialize printer | | 2 <page> New Page | | 3 <font name="Courier"> Set Font | +------------------------------------------------------------------+ if: ' x will contain '<page> <font name="Courier">' then: x = PRINTCODE("1") if: ' x will contain '<page> <font name="Courier">' then: x = PRINTCODE("1","0") if: ' x will contain 'New Page' then: x = PRINTCODE("2","1") Added x=GETLOCKS(array,lookup). Returns the number of elements populated in the array. Fills the array with locked record information for a given lookup. Use '-' for current file. If passing a multi-dimensional, the array must point to the final sub array OR the second to last. This allows us to return the PID and Username/UID for the given lock. Returns "0" on Windows. Restrictions: Linux|Unix|FreeBSD Only. Parameters: array: An array to place the locked record information in. lookup: The lookup to use to check a filePro file for locked records. Examples: then: ' Fill array with the record number of locked records in the file then: dim array(10)(10,.0) then: ' x will contain the number of locks on the then: x = GETLOCKS(array,-) ' file that will fit into array then: ' Fill array with locked records including PID and Username/UID then: dim array(10,3) then: ' x will contain the number of locks on the then: x = GETLOCKS(array,-) ' file that will fit into array In the second example each "row" of the array will contain the locked record number, the PID of the locking process, and the user holding the lock. e.g. then: x = array["1","1"] ' x holds the record number then: x = array["1","2"] ' x holds the PID then: x = array["1","3"] ' x holds the username OR UID Added x = FPSTAT(lookup) function to return map information and basic access attributes for a given filePro lookup. Parameters: lookup: A lookup to a filePro file to retrive basic attributes from. Can be "-" for the current file. Returns: kfilesize;dfilesize;mdate;mtime; Blank on error. Where: kfilesize is the total sum of the size of all key segments in bytes. dfilesize is the total sum of the size of all data segments in bytes. mdate is the last date a key/data file was modified, e.g. 03/24/2025 mtime is the last time a key/data file was modified, e.g. 02:19:59 Note: The returned values are ONLY for the active qualifier on the lookup. Added n = ISDIR(fname). Test if a given path is a directory. Returns "1" if the file exists and is a directory. Returns "0" if it is not. Returns a negated system error on failure. Parameters: fname: A path to an on-disk resource. Note: Shares the same @FSTAT array used by EXISTS() in filePro. Added n = ISFILE(fname). Test if a given path is a file. Returns "1" if the file exists and is a file. Returns "0" if it is not. Returns a negated system error on failure. Parameters: fname: A path to an on-disk resource. Note: Shares the same @FSTAT array used by EXISTS() in filePro. Added n = ISLINK(fname). Test if a given path is a link. Returns "1" if the file exists and is a link. Returns "0" if it is not. Returns a negated system error on failure. Parameters: fname: A path to an on-disk resource. Note: Shares the same @FSTAT array used by EXISTS() in filePro. ISLINK() always returns "0" on Windows. Added s = GETQUAL(fname) function. GETQUAL() will return a colon delimited list of all qualifiers for the file given by "fname" Parameters: fname: A filePro file name. Example: (File invoices has 3 qualifiers 2022, 2023, and 2024) then: s=GETQUAL("invoices") ' s will contain "2022 :2023 :2024 :" Added n = GETQUAL(array, fname) function. GETQUAL() will return the number of qualifiers for the file given by "fname" while filling "array" with the list of qualifier names. Parameters: array: An array to fill with a list of qualifier names. fname: A filePro file name. Example: (File invoices has 3 qualifiers 2022, 2023, and 2024) then: DIM quals(10) then: n = GETQUAL(quals, "invoices") ' n will contain "3" then: q = quals["1"] ' q will contain 2022 then: q = quals["2"] ' q will contain 2023 then: q = quals["3"] ' q will contain 2024 Added new XLSX functions: XL_FREEZEPANE, XL_FREEZEPANE2, XL_SPLITPANE e = XL_FREEZEPANE([row [, col [, sheet]]]) Parameters: row: Row to split the cell (0 indexed) col: Column to split the cell (0 indexed) sheet: Handle to sheet to freeze the cell on. Leave blank, "0", or "-1" to use the default sheet. Notes: Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. The split is specified at the top or left of a cell and uses zero based indexing. Therefore to freeze the first row of a worksheet it is necessary to specify the split at row 2. You can set one of the row and col parameters as zero if you do not want either a vertical or horizontal split. e = XL_FREEZEPANE2([cell [, sheet]]) Parameters: cell: The Excel style cell to freeze the cell. e.g. "A1" "D6" "F6". sheet: Handle to sheet to freeze the cell on. Leave blank, "0", or "-1" to use the default sheet. Notes: Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Split is specified at the top or left of a cell and uses zero based indexing. Therefore to freeze the first row of a worksheet it is necessary to specify the split at row 2. You can set one of the row and col parameters as zero if you do not want either a vertical or horizontal split. e = XL_SPLITPANE([vertical [, horizontal [, sheet]]]) Parameters: vertical: The position for the vertical split. e.g. "1", "12.5", "15" horizontal: The position for the horizontal split. e.g. "1", "12.5", "15" sheet: Handle to sheet to freeze the cell on. Leave blank, "0", or "-1" to use the default sheet. Notes: Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. This function divides a worksheet into horizontal or vertical regions known as panes. This function is different from the XL_FREEZEPANE function in that the splits between the panes will be visible to the user and each pane will have its own scroll bars. The parameters vertical and horizontal are used to specify the vertical and horizontal position of the split. The units for vertical and horizontal are the same as those used by Excel to specify row height and column width. However, the vertical and horizontal units are different from each other. Therefore you must specify the vertical and horizontal parameters in terms of the row heights and column widths that you have set or the default values which are 15 for a row and 8.43 for a column. Added new environmental variable PFXLASCII, default OFF. If enabled, any non- printable ASCII characters will be automatically stripped from data when inserted into an XLSX document. Enhanced DIM to allow IMPORT and EXPORT commands to be mapped to an array. Example: then: IMPORT WORD ifile=(fname) then: DIM data(10):ifile(1) ' data can now be used in place of ifile then: ct(4,.0)="1" loop if: ct le "10" then: msgbox data(ct); ct=ct+"1"; goto loop then: close ifile Enhanced COPY, COPY TO, and COPYIN commands to support arrays. Each command now allows for any combination of lookups and arrays to copy data, including mapped/aliased arrays. Syntax: COPY lookup ' Copy the current record to a lookup file COPY array ' Copy the current record to an array COPYIN lookup ' Copy a lookup file record to the current record COPYIN array ' Copy an array to the current record COPY lookup TO lookup ' Copy a lookup record to a lookup record COPY array TO lookup ' Copy an array to a lookup record COPY lookup TO array ' Copy a lookup record to an array COPY array TO array ' Copy an array to an array Examples: (Copy the current record to an array) then: DIM array(10) then: COPY array (Copy an IMPORT to the current record) then: IMPORT WORD ifile=(fname) then: DIM data(10):ifile(1) ' data can now be used in place of ifile then: COPYIN data ' Copy the import to the current record then: close ifile (Copy a lookup record to an EXPORT) then: EXPORT WORD ofile=(fname) then: DIM data(10):ofile(1) ' data can now be used in place of ofile then: lookup inv=invoices r=(rec) -nx then: COPY inv TO data then: close ofile then: close inv Added x = COPY(array1, array2 [,src [,dest [,len]]]) function to copy data between arrays. Returns the number of elements copied from array1 to array2. Parameters: array1: Array to copy from. array2: Array to copy to. src: The array index to start copying from array1. dest: The array index to start copying to in array2. len: The number of elements to copy from array1 to array2. If no optional parameters are provided COPY() will copy as many items from array1 that will fit into array 2. Parameters src and dest default to the first index of each array. Parameter len defaults to the entire array length. Example: then: DIM fruit(3) then: DIM food(3) then: fruit["1"]="Apple"; fruit["2"]="Orange"; fruit["3"]="Pear" then: x=COPY(fruit,food,"1","1","2") (The food array will contain "Apple", "Orange", and "") Added XML import and export code. filePro now has the ability to import and export XML files. Export: XML [id] :CR fname - Creates an XML file. The id is optional and defaults to "0" if only one file is open at a time. If two or more are open, the id must be supplied ("0"-"99") XML [id] :CR-|:CL - Closes an open XML file. XML [id] :EL name - Starts an element in an XML file. XML [id] :EL- - Closes an element. XML [id] :AT name value - Adds an attribute to an XML element. XML [id] :TX text - Adds a text element to an XML document. Example: Then: XML :CR "/tmp/myfile.xml" Then: XML :EL "EmployeeData" Then: XML :EL "employee" Then: XML :AT "id" "21" Then: XML :EL "firstName" Then: XML :TX "Tom" Then: XML :EL- Then: XML :EL "lastName" Then: XML :TX "Anderson" Then: XML :EL- Then: XML :EL- Then: XML :EL- Then: ML :CL Output: <?xml version="1.0"?> <EmployeeData> <employee id="21"> <firstName>Tom</firstName> <lastName>Anderson</lastName> </employee> </EmployeeData> Import: XML [id] :RO fname - Opens an XML file for reading. The id is optional and defaults to "0" if only one file is open at a time. If two or more are open, the id must be supplied ("0"-"99") v = XML [id] :GV key [attr] - Get a value from an XML file using a path to a key. An attribute name can optionally be provided to return an attribute value rather than the text element value. Keys are a way to reference part of an XML document using dot syntax. An example of dot syntax would be a key, such as "name.first" or "age". There are reserved symbols used in key syntax that can be used to retrieve certain values from the XML: '#' is used to get the number of child elements inside of an element. '@' is used to specify a literal, or if at the end of the path, get the name of the current object. Index positions can also be used to reference specific elements by numeric position inside of an XML document. Indexes in Key Syntax start at position 1. x = XML :GV "food.10" will attempt to find the tenth (10) item inside a food element. x = XML :GV "food.@10" will attempt to find a key named "10" inside a food element and return its value. x = XML :GV "food.fruit[10]" will attempt to find the tenth (10) fruit element inside of the food element and return its value. x = XML :GV "food.fruit[#]" will return the number of fruit elements inside of the food element. Example: Given the following XML, here are example commands and what they return. <?xml version="1.0"?> <EmployeeData> <employee id="21"> <firstName>Tom</firstName> <lastName>Anderson</lastName> </employee> <employee id="99"> <firstName>Tiffany</firstName> <lastName>Anderson</lastName> </employee> </EmployeeData> Then: XML :RO "/tmp/myfile.xml" ' open the XML file for reading Then: x=XML :GV "EmployeeData.employee.firstName" ' x contains "Tom" Then: x=XML :GV "EmployeeData.employee[1]" "id" ' x contains "21" Then: x=XML :GV "EmployeeData.employee.1.@" ' x contains "firstName" Then: x=XML :GV "EmployeeData.#" ' x contains "2" Then: x=XML :GV "EmployeeData.2.firstName" ' x contains "Tiffany" Then: x=XML :GV "EmployeeData.2" "id" ' x contains "99" Then: XML :CL ' close the XML file Added LOOP commands. filePro now has support for basic loops. FOR loop A loop that runs from a value to a value. Built in edits are supported. If a STEP value is not supplied, filePro will determine a STEP value based on the FROM and TO expression values. A FROM value that is less than a TO value will result in a positive STEP ("1"). If FROM is greater than TO the STEP value will be negative ("-1"). Each iteration of the loop will update the value of "f", incrementing by STEP, and goto the label specified by DO. Syntax: FOR f[(len,edit)] FROM exp TO exp [STEP exp] DO label Example: then: FOR f(10,.0) FROM "1" TO "10" STEP "1" DO lp1; goto en1 lp1 if: then: msgbox f ' print the value of "f" from 1 to 10 then: end en1 if: then: FOR d(10,mdyy/) FROM "12/01/2024" TO "12/31/2024" DO lp2; goto en2 lp2 if: then: msgbox d ' print the value of "d" from 12/01/2024 to 12/31/2024 then: end en2 if: then: end Note: The FROM, TO, and STEP expressions are evaluated once when the loop is first executed. Changing these values once the loop starts executing will not change how the loop runs. WHILE loop A loop that runs while the condition is true. Each iteration checks the condition (cnd) and while the value is true goes to the label specified by DO. A condition can be an IF expression or label. Syntax: WHILE cnd DO label Example: then: declare total(10,.0) then: total="0" then: lookup inv=invoice r=(rec) -nx then: WHILE inv DO lp1; goto en1 lp1 if: then: total=total+inv(1) then: getnext inv then: end en1 if: then: close inv; end LOOP ... WHILE|UNTIL A loop that runs while the condition is true (WHILE) or until the condition is true (UNTIL). Each iteration starts by going to the label specified by DO, then the condition is checked and the loop either continues or terminates based on the value of the condition. A condition can be an IF expression or label. Syntax: LOOP label WHILE cnd LOOP label UNTIL cnd Example: then: i(10,.0)="10" then: LOOP lp1 WHILE i gt "0"; goto en1 lp1 if: then: i=i-"1"; then: end en1 if: then: end BREAK command BREAK can be used inside of a loop to terminate its execution early. Example: then: i(10,.0)="10" then: LOOP lp1 WHILE i gt "0"; goto en1 lp1 if: i eq "5" then: BREAK ' Terminate the loop early when i equals 5 then: i=i-"1"; then: end en1 if: then: end ==================================== Version 6.1.01.RR New USP Only Items ==================================== Added JSON import and export code. filePro now has the ability to import and export JSON files. Export: JSON [id] :CR fname - Creates a JSON file. The id is optional and defaults to "0" if only one file is open at a time. If two or more are open, the id must be supplied ("0"-"99") JSON [id] :CR-|:CL - Closes an open JSON file. JSON [id] :OB [name] - Starts an object in a JSON file. JSON [id] :OB- - Closes an object. JSON [id] :AR [name] - Starts an array in a JSON file. JSON [id] :AR- - Closes an array in a JSON file. JSON [id] :IT name [value] - Adds an item to a JSON file, if a value is not supplied, the resulting value will be null. JSON [id] :NO name [value] - Adds a number to a JSON file, if a value is not supplied, the resulting value will be null. JSON [id] :BL name [value] - Adds a boolean value to a JSON file, if a value is not supplied, the resulting value will be null. Note: Names will be ignored when adding an item, number, or boolean directly to an array. Example: JSON :CR "/tmp/myfile.json" JSON :OB JSON :OB "name" JSON :IT "first" "Tom" JSON :IT "last" "Anderson" JSON :OB- JSON :NO "age" "37" JSON :AR "children" JSON :IT "" "Sara" JSON :IT "" "Alex" JSON :IT "" "Jack" JSON :AR- JSON :IT "fav.movie" "Deer Hunter" JSON :OB- JSON :CL Output: { "name": { "first": "Tom", "last": "Anderson" }, "age": 37, "children": ["Sara", "Alex", "Jack"], "fav.movie": "Deer Hunter" } Import: JSON [id] :RO fname - Opens a JSON file for reading. The id is optional and defaults to "0" if only one file is open at a time. If two or more are open, the id must be supplied ("0"-"99") value = JSON [id] :GV key - Get a value from a JSON file using a path to a key. Keys are a way to reference part of a JSON document using dot syntax. An example of dot syntax would be a key, such as "name.first" or "age". There are reserved symbols used in key syntax that can be used to retrieve certain values from the JSON: '#' is used to get the number of elements inside of an object or array. '@' is used to specify a literal, or if at the end of the path, get the name of the current object. Index positions can also be used to reference specific elements by numeric position inside of an object or an array. Indexes in Key Syntax start at position 1. x = JSON :GV "fruits.10" will attempt to find the tenth (10) item inside a fruits object or array. x = JSON :GV "fruits.@10" will attempt to find a key named "10" inside a fruits object and return its value. Example: Given the following JSON, here are example commands and what they return. { "name": { "first": "Tom", "last": "Anderson" }, "age": 37, "children": ["Sara", "Alex", "Jack"], "fav.movie": "Deer Hunter" } Then: JSON :RO "/tmp/myfile.json" ' open the JSON file for reading Then: x=JSON :GV "name.first" ' x contains "Tom" Then: x=JSON :GV "name.1.@" ' x contains "first" Then: x=JSON :GV "age" ' x contains "37" Then: x=JSON :GV "children.#" ' x contains "3" Then: x=JSON :GV "children.1" ' x contains "Sara" Then: x=JSON :GV "fav\.movie" ' x contains "Deer Hunter" Then: JSON :CL ' close the JSON file filePro now has the ability to place fill-in-the-blank PDF objects on output formats and also retrieve values from PDF documents that have fill-in-the-blank fields to be used in Processing. There are four types of PDF Form Objects that can be used: Textbox Dropdown Checkbox Radio When a PDF output is generated, placed objects will be interactive in any supporting PDF viewer/editor. These PDF files can be saved after filling in fields, and processing can be written to retrieve values from these fields. NOTE: Using the new generation features in a report can lead to unintended results. Fields are shared across records and pages. Updating one field updates all matching instances of that field throughout the document. It is recommended to use output forms over output report Please See Fill In PDFs in the manual for more information on document creation. Manual Link If the PDF was created with filePro, field names will be either the real-field or dummy field used to create the PDF object. e.g. "1", "42", "aa", "ab". Use these commands to read filled-in PDF documents: handle = PDF_OPEN(pdf_path) Returns a handle value (10,.0) that points to a PDF document with pdf_path as the filename. Returns a negative value on error. error_value = PDF_CLOSE(handle) Frees all values and memory associated with a PDF handle and closes the document. Returns a non-zero number on error. num_fields = PDF_GETNUMFIELDS(handle) Returns the number of fields in the PDF document. name = PDF_GETFIELDNAME(handle, index) Returns the full name of a field in a PDF document, given its index. The index is a number between "1" and the num_fields value returned by PDF_GETNUMFIELDS. type = PDF_FIELDTYPE(handle, fieldname) Returns the field type name of the specified field fieldname, which is one of: NONE BUTTON RADIO CHECKBOX TEXT RICHTEXT CHOICE UNKNOWN name = PDF_FIELDTYPE2(handle, index) Returns the field type name of the specified field index, which is one of: NONE BUTTON RADIO CHECKBOX TEXT RICHTEXT CHOICE UNKNOWN The index is a number between "1" and the num_fields value returned by PDF_GETNUMFIELDS. value = PDF_GETVALUE(handle, fieldname [, richtext]) Returns the field value, e.g. the text in the field, checkbox status, combo box index, etc. for the given field name fieldname. Optionally, richtext can be set to "1" to return rich text data if it exists. value = PDF_GETVALUE2(handle, index [, richtext]) Returns the field value, e.g. the text in the field, checkbox status, combo box index, etc. for the given field index index. Optionally, richtext can be set to "1" to return rich text data if it exists. The index is a number between "1" and the num_fields value returned by PDF_GETNUMFIELDS. ret = QRCODE(str, dest [, size [, logo [, fg [, bg]]]]) Create a QR Code from a text string. str is the text to store in the QR code. dest is the full name and path to the QR code to be generated. size is the size of the QR code to be generated in pixels. Must be large enough to store the full QR code. logo is an optional logo to place in the center of the QR code. fg is the foreground color of the QR code in hexadecimal. bg is the background color of the QR code in hexadecimal. Returns the size of the generated QR code, or -1 on error. Example: Then: ret=QRCODE("fptech.com","/tmp/website.png") Added QRCODE FPML print code. <QRCODE TEXT="qr text" [SIZE="size"] [COLOR="color"] [FILL="bg color"] [X="x-pos"] [Y="y-pos"]> Adds a QR code with the specified text to the PDF document. All attributes, except for "TEXT", are optional. TEXT is the text to add to the QR code when generating the image. SIZE is the width and height of the QR code, must be large enough to fit the entire generated image. COLOR is the foreground color of the QR code (in hexadecimal). FILL is the background color of the QR code (in hexadecimal). X X position. (Default: current X position.) Y Y position. (Default: current Y position.) FPML print codes can now use field names for any attribute. Any attribute inside of an FPML print code can now reference a real field or variable inside of processing. Use "@" to reference a field. e.g. <IMAGE FILE="@1"> ' reference a real field <IMAGE FILE="@im"> ' reference a dummy field <IMAGE FILE="@image_path"> ' reference a long name variable Note: Print codes can also be stored in a print code table and do not need to be placed directly on the output to work. Added a new F5 shortcut in Define Processing for calls. F5 will now open a call for editing, or, will prompt you to create the call if it does not exist. subscript = INDEXOF(array, value) Find the subscript of some value in an array. Example: array["1"]="cat" array["2"]="dog" array["3"]="bird" subscript = INDEXOF(array, "dog") ' subscript will contain "2" Added initial support for multi-dimensional arrays. DIM array[n1,n2,...,n8](l,e) Multi-Dimensional array of fields with length "l" & edit "e". Array edit is optional. Example: dim array(2,2) array["1","1"]="John" array["1","2"]="Smith" array["2","1"]="Sarah" array["2","2"]="Jane" Existing array functions can also use multi-dimensional arrays by referencing one of an array's sub arrays. Example: CLEAR array["1"] value = A_MAX(array [, array2 [, array3 [, ... [, arrayN]]]]) Find the maximum value between the passed in arrays. Example: array1["1"]="5" array1["2"]="7" array2["1"]="30" value = A_MAX(array1, array2) ' value will contain "30" Note: This method supports multi-dimensional arrays. value = A_MIN(array [, array2 [, array3 [, ... [, arrayN]]]]) Find the minimum value between the passed in arrays. Example: array1["1"]="5" array1["2"]="7" array2["1"]="30" value = A_MIN(array1, array2) ' value will contain "5" Note: This method supports multi-dimensional arrays. value = A_TOT(array [, array2 [, array3 [, ... [, arrayN]]]]) Total all of the values in the passed in arrays. Example: array1["1"]="5" array1["2"]="7" array2["1"]="30" value = A_TOT(array1, array2) ' value will contain "42" Note: This method supports multi-dimensional arrays. value = A_AVG(array [, array2 [, array3 [, ... [, arrayN]]]]) Find the avereage of all of the values in the passed in arrays. Example: array1["1"]="5" array1["2"]="7" array2["1"]="30" value = A_AVG(array1, array2) ' value will contain "14" Note: This method supports multi-dimensional arrays. =================================== END OF NEW USP ITEMS =================================== =================================== 6.1.XX.08 NEW ITEMS =================================== Added support for read-only PDF fields when generating a fill-in-the-blank PDF document. Each field type now contains an option to flag the field as read-only. Updated how 'C' continue works in the debugger. The debugger should now correctly maintain the "step" mode when switching between processing and entering and leaving calls. Previously, using continue while inside a call would take you out of single-step mode when returning from said call. Now, if you were in single-step mode before a call, continuing inside of the call will place you back into single step mode upon returning or entering a new processing table. Enhanced F9 search in dcabe/rcabe to allow for whole word searching by using a single quote before the search term, e.g. 'WORD. This makes it much easier to find places where variables like "aa" and "zz" are used. Added -MN command line option to hide [NONE] qualifier from the qualifier list in dclerk, rclerk, dreport, rreport, and dxmaint. Same as PFNOQUAL=OFF. =================================== 6.1.XX.07 NEW ITEMS =================================== Added a F7 last record option to clerk. Added new system controlled fields for creation time (@CT), update time (@UT), and batch time (@BT) per record. Note: The time is stored in 2 second intervals. =================================== 6.1.XX.06 NEW ITEMS =================================== Added a new option to show a stacktrace on a runtime error if PFERRTRACE is set. Default OFF. Dxmaint will now always show qualifier if PFQUAL is set. =================================== 6.1.XX.04 NEW ITEMS =================================== Added PFOLDCHAIN to allow CHAIN to return to the top of processing when a record is saved and the chain was performed inside of an event. Added basic reconnect functionality into ODBC mirroring upon communications link failure. Added the ability to directly assign to a longvar when declaring it. e.g. declare myvar = "Hello!" Updated Fuzzy search screen in clerk to be larger and show correct button prompts. n = STACKTRACE(array) Fill an array with a processing trace, listing the current and past processing tables and their line numbers to the current line being executed. This will show lines "jumped" from gosubs and follow calls and functions. Returns the number of elements that could fit into the array. Added new debugger option "T" to show the current stacktrace while debugging. =================================== 6.1.00.03 NEW ITEMS =================================== Updated all programs to no longer require unixODBC by default. unixODBC will now only be required when an ODBC related function is used. If unixODBC is not found when an ODBC function is required, a filePro error will be returned. Added the ability to assign directly to a longvar when creating it. e.g. declare myvariable(32,*)="Hello, World!" Reworked tokenization engine to no longer require setting PFTOKSIZE or related variables. Variable will now be silently ignored. Added PFPDFAUTOBREAK=ON (default OFF) to allow PDFs to automatically break pages based off of selected paper type. Added menu letter to menu script editor. =================================== 6.1.00.00 NEW ITEMS =================================== You can now use: @wlf<letter>* ex. @wlfT* This will apply to any dummy/associated field that begins with 'T' Overrides any other @wlf* Added logging to ddefine. ddefine can now optionally track changes made to filePro file layouts. This includes the name of the file, who changed it, and what fields were changed. Requires a logging configuration file to be added under the ./fp/logs directory named 'ddefine.cfg'. Format of the config file is the same as the servlog.cfg file that comes shipped with filePro. Example ddefine.cfg: ROLLING,DEBUG,ddefine.log,60000 xx=FORMERROR syntax: xx=FORMERROR() returns: errno from last FORM or FORMM command. e.g. 2=file not found, 13=permission error Validate menu script before prompting for removal Added new option 'C' to F8 Extended Functions for dmoedef to show a list of all print codes on an output format. Selecting an item from the list will jump the editor to it. TRIM command to remove spaces aa=ltrim(fld) left trim aa=rtrim(fld) right trim aa=trim(fld) trim both left and right PFIXGT can now be set in dxmaint F8 options. This is backwards compatible, so if PFIXGT is still set in config, then it is honored by clerk *if true*. If false, the index header is checked for the flag. Windows fPTransfer now will accept wildcards. A compress-filePro file routine fppack Function: Remove deleted records from a filePro file, and then (optionally) rebuild all automatic indexes. Syntax: fppack [ filename | - ] [ -H heading ] [ -E ] [ -R ] [ -X ] [ -EX ] [ -C ] [ -M name | -MD | -MQ mesg | -MA ] [ -BG ] [ -BS ] -H "heading" custom title to display in box. -E don't actually pack the records, just give statistics. -R rebuild the automatic indexes even if no records were deleted. -EX skip statistics -C skip continue and finished prompts -X skip rebuilding the auto indexes. -M name qualifier file name to use. -MD ask for qualifier with default prompt. -MQ "mesg" ask for qualifier with "mesg" as the prompt. -MA use all qualified files & main file. UNIX/XENIX only: -BG work in the background. -BS suppress "completed in background" message. Added various enhancements to PDF engine. See on-line or ~/fp/docs PDF documentation. Added optional error message suppression and basic password auditing to filePro. PFERRSUPPRESS=ON, default OFF PFPWAUDIT=ON, default OFF Password auditing also requires a ./fp/logs/pwaudit.cfg file. Same structure as servlog.cfg. Any error that would be sent to mail will still be mailed on unix/linux based systems. Errors reported in the background will still be suppressed. Including the program name. Invalid password and license errors will still be reported. Password errors omit the filename. dcabe and rcabe are exempt from the error suppression. These functions lock or unlock bytes of the file specified by handle. x=lock(handle,how[,nbyte]) handle - an open handle to a file how - U|0 : unlock bytes L|1 : lock bytes N|2 : lock bytes non-blocking nbyte - How many bytes in the file to lock, if omitted, lock the billionth byte in the file (file does not have to be that large) x=unlock(handle[,nbyte]) handle - an open handle to a file nbyte - How many bytes in the file to unlock, if omitted, unlock the billionth byte in the file (file does not have to be that large) (returns "1" on success and returns negated system error on error) ddefine will now create new screens the same as dscreen does instead of just mono. NEW command OPENDIR2 to handle long-named files and paths. Syntax: N = OPENDIR2(mask, path, fmt_sz, ext_sz, nam_sz) All arguments are optional. Format Length Extension Length Fullname Length *cabe lookup wizard will now honor PFQUAL and show qualified indexes Added new FPML commands to control the appearance of underlines. (See PDF Docs) New RINSTR, and INSTR now allows negative positions for working backwards. New GIadmin that will count GUI (GI or Web) sessions, ease of system and user configuration files and additional security. Added PDF syntax as an option for printer maintenance (pmaint): Windows only Lookup Wizard in cabe now allows long vars as key. Added alias and arrays to F6-D-L display in *cabe. Updated color with new routines and corrected the shell escape codes. Automated processing table backups. CABEBACKUP ON|OFF (on by default) CABEBACKUPMINS n (minutes between backups) CABEBACKUPCT n (backup files per process) Menu maintenance (makemenu) now asks if you wish to remove an unused menu script if the menu item is not used. *report now allows one to use .outs from a pathed directory library SCREEN command can switch fields in a POPUP UPDATE -, provided no screen name is passed to the SCREEN command. MEMO EDIT now accept maxsize to limit the number of characters that can be intered into a memo field. memo NNN edit (row,col,lines,width,startLine,startcol,maxSize) (Text mode only) Added option 7 to dxmaint to clear qualifier New -SE *report flag to allow report to edit/save a selection set. Added @EXIT label to *clerk processing. This is executed whenever a record is exited or broken out of. Events that trigger this are 'X' while not in update mode, 'BRKY' while not in update mode, and 'exit' in processing. It is the opposite of @entsel, and is the last thing executed when leaving a record. Assignment of real fields is not allowed, this is similar to @once in that the processing that is executed is NOT sitting on a record, but rather record '0'. Partial lookup flag added to *cabe lookup wizard. -O on an exact lookup now does partial key matching. This kills a lookup once the begining of the key value no longer matches the lookup key value. BUSYBOX BUSYBOX "my message" BUSYBOX("10","10") BUSYBOX("10","10") "my message" Added PFPPFULLPATH as an ehancement to PDFPOSTPRINT and added an PFNEWPOSTPRINT alias to name to PDFPOSTPRINT Added PFPPFULLPATH to augment the filename passed to the post print handler, default ON, this causes the filename passed to the postprint script to contain the full path to the file, not just the file name. Set to OFF to revert to old behaviour. PFPOSTPRINTnnn will now work with normal file destinations. Same rules as the old global PFPOSTPRINT but also supports PDF files. Clerk will now allow a full path to a form when using the FORM and FORMM command in processing. User defined functions Forward declare functions to be used: (function|func) [file.]name([dim|var] var1, [dim|var] var2, ...) e.g. function fplib.showlock(var pid) function fplib.log(file, line, what) function somefunc(dim myarray) Call a function: [x=][file.]name(var1, var2, ...) Return a value from a function: return(value) Can pass fields: real, dummy, longvar Can pass arrays: Alias and system arrays are copied to a non-aliased array. Non-aliased arrays are passed by reference. Function names must be at least 3 characters in length. Functions cannot modify values outside of its scope. Functions do not call automatic processing. Functions cannot modify real fields. Functions cannot be called unless it they are declared. Functions can pass values by reference (changes made to the value will carry back out of the function, only to arrays). Functions can optionally return a value. Parameter names must be at least 3 characters in length. Parameters will be passed to the function using the name they were defined with in the declaration statement. Environment variables: PFFUNCDBG=(ON|OFF), default OFF. If ON the debugger will be allowed to continue into the function call. If OFF the debugger will skip over user defined functions. NOTE: Debug statements inside of functions will still be able to be activated. If debug is set inside of a function, it will continue even after the function is left. Example: Processing table for fibonacci: If: ' Declare for future use Then: function fibonacci(nval) If: ' Get the parameter Then: declare extern nval If: nval le "1" ' Return the result Then: return(nval) If: ' Return the result Then: return(fibonacci(nval-"1")+fibonacci(nval-"2")) Usage: If: ' Declare for future use Then: function fibonacci(nval) If: ' Call the function Then: n=fibonacci("9") If: ' Display the result Then: msgbox ""{n ' Prints "34" EXTERN and GLOBAL arrays DIM GLOBAL name(size) DIM EXTERN name Only non-aliased arrays can be declared GLOBAL/EXTERN. Functions similar to GLOBAL/EXTERN longvars. New compare condition for Associated Fields Added new selection set relational operators: AEQ - Associated field, all equal ANE - Associated field, all not equal ACO - Associated field, all contain These require ALL components of an associated field to match the comparison being done, rather than just one of its component fields. New functions for creating XLSX documents from filePro. e = XL_OPEN(file [, name]) Start building an XLSX output file. Parameters - file : Path to the file to create. If no full path is given the generated file will be placed in the PFTMP or equivalent directory. name : The name for the default sheet that will be created. Defaults to Sheet1. If the filename does not end in ".xlsx" it will be added on creation. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Note: Only one XLSX file can be created at a time. e = XL_SAVE([password]) Save the current XLSX file. Parameters - password : If specified, encrypt the XLSX output file using Agile encryption (AES128). Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Note: Encrypted XLSX files cannot be opened with most third party programs such as LibreOffice and OpenOffice. They are fully supported by Excel however. The documents are saved in an encrypted CFB file. handle = XL_ADDSHEET([name]) Add a new sheet to the XLSX document. Parameters - name : The name for the sheet to be created. Defaults to auto naming the sheet based on the Sheet1, Sheet2, ..., SheetN template. Returns a handle to a new sheet object on successs and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_ADDCELL([data [, style [, sheet [, row [, col]]]]]) Add a new cell to the XLSX document. Parameters - data : Data to be inserted into the document. A cell starting with '=' will be treated as a formula. style : Handle to style to be used for this cell. Use blank to use the default style. sheet : Handle to sheet to insert the cell on. Use blank, "0", or "-1" to use the default sheet. row : Row to place the cell (0 indexed). col : Column to place the cell (0 indexed). Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Note: Using an empty or negative row/column value will cause the cell to be added using the auto counter in the sheet, incrementing the column value after the cell is added. Specifying a location will reposition the auto counter. Formulas can be used as part of the data as well by prefixing the string with '='. e = XL_ADDCELL2([data [, style [, sheet [, cell]]]]) Add a new cell to the XLSX document. Parameters - data : Data to be inserted into the document. A cell starting with '=' will be treated as a formula. style : Handle to style to be used for this cell. Use blank to use the default style. sheet : Handle to sheet to insert the cell on. Use blank, "0", or "-1" to use the default sheet. cell : The Excel style cell to insert the cell. e.g. "A1" "D6" "F6". Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Note: Using an empty cell number will cause the cell to be added using the auto counter in the sheet, incrementing the column value after the cell is added. Specifying a location will reposition the auto counter. Formulas can be used as part of the data as well by prefixing the string with '='. handle = XL_FORMAT(format) Create a new format to use with the XLSX document. Parameters - format : Excel format string to use to format the a style. e.g. "$ #,###,nnn.nn" "% ##n.n" "m/d/yyyy" Returns a handle to a new format object on successs and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_COLWIDTH(width, firstcol, lastcol [, sheet]) Change the default column width for a sheet between a range. Parameters - width : Width of the column(s). e.g. "24" "12.5", "11" firstcol : Zero based column index or column letter to set from. lastcol : Zero based column index or column letter to set to. sheet : Handle to sheet to change the cell widths. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. handle = XL_FONT(font, [size [, attr [, color]]]) Create a new font to use with the XLSX document. Parameters - font : Name of the font to use. size : Point size of the font. e.g. "11" "8.42" "12", default "11.0" attr : List of attributes to apply to this font, separated by commas. e.g. "bold,italic" Values: "bold" "italic" "underline" "strike" "unlocked" "hidden" "wrap" "shrink" "fill" "left" "center" "right" "justify" "top" "bottom" "vjustify" "vcenter" color : The RGB Hex value to set the font color. e.g. "000000" "ADD8E6" Returns a handle to a new font object on successs and "-1" on error. XL_ERROR() can be called to return the last error. handle = XL_BORDER(borderstyle [, color]) Create a new border to use with the XLSX document. Parameters - borderstyle : The style to use with this border. Must be one of the following values: "thin" "medium" "dashed" "dotted" "thick" "hair" "medium_dashed" "dash_dot" "medium_dash_dot" "dash_dot_dot" "medium_dash_dot_dot" "slant_dash_dot" color : The RGB Hex value to set the border color. e.g. "000000" "ADD8E6" Returns a handle to a new border object on successs and "-1" on error. XL_ERROR() can be called to return the last error. handle = XL_FILL(bg [, fg [, fill]]) Create a new fill to use with the XLSX document. Parameters - bg : The RGB Hex value to set the background fill color. e.g. "000000" "ADD8E6" fg : The RGB Hex value to set the foreground fill color. e.g. "000000" "ADD8E6" fill : The fill pattern to use, defaults to "solid" fill. Value must be one of the following. "solid" "medium_gray" "dark_gray" "light_gray" "dark_horizontal" "dark_vertical" "dark_down" "dark_up" "dark_grid" "dark_trellis" "light_horizontal" "light_vertical" "light_down" "light_up" "light_grid" "light_trellis" "gray_125" "gray_0625" Returns a handle to a new fill object on successs and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_ADD_DT(date, time [, style [, sheet [, row [, col]]]]) Combine two fields into a single spreadsheet datetime field and insert it as a new cell in the XLSX document. Parameters - date : filePro date field. time : filePro time field. style : Handle to style to be used for this cell. Use blank to use the default style. sheet : Handle to sheet to insert the cell on. Use blank, "0", or "-1" to use the default sheet. row : Row to place the cell (0 indexed). col : Column to place the cell (0 indexed). Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_ADD_DT2(date, time [, style [, sheet [, cell]]]) Combine two fields into a single spreadsheet datetime field and insert it as a new cell in the XLSX document. Parameters - date : filePro date field. time : filePro time field. style : Handle to style to be used for this cell. Use blank to use the default style. sheet : Handle to sheet to insert the cell on. Use blank, "0", or "-1" to use the default sheet. cell : The Excel style cell to insert the cell. e.g. "A1" "D6" "F6". Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. handle = XL_CHART(type [, title [, xname [, yname [, row [, col [, stylenum [, sheet [, xoff [, yoff [, xscale [, yscale]]]]]]]]]]]) Add a new chart to the XLSX document. Parameters - type : Type of chart to create. Must be one of the following values. "area" "area_stacked" "area_stacked_percent" "bar" "bar_stacked" "bar_stacked_percent" "column" "column_stacked" "column_stacked_percent" "doughnut" "line" "line_stacked" "line_stacked_percent" "pie" "scatter" "scatter_straight" "scatter_stright_markers" "scatter_smooth" "scatter_smooth_markers" "radar" "radar_with_markers" "radar_filled" title : The title for this chart. xname : The title for the x-axis. yname : The title for the y-axis. row : Row to place the cell (0 indexed). col : Column to place the cell (0 indexed). stylenum : Number of the built in Excel style to use. Must be between "1" and "48". The default style is 2. The value is one of the 48 built-in styles available on the "Design" tab in Excel 2007. sheet : Handle to sheet to insert the chart on. Use blank, "0", or "-1" to use the default sheet. xoff : X axis offset to place the chart, in pixels. yoff : Y axis offset to place the chart, in pixesl. xscale : Scale the chart along the x axis. e.g. "1", "0.5" "2". Value cannot be negative. yscale : Scale the chart along the x axis. e.g. "1", "0.5" "2". Value cannot be negative. Returns a handle to a new chart object on successs and "-1" on error. XL_ERROR() can be called to return the last error. Note: The chart functions do not use the auto counter found in the sheets and instead will default to "0", "0" or "A1" when used for insertion. handle = XL_CHART2(type [, title [, xname [, yname [, cell [, stylenum [, sheet [, xoff [, yoff [, xscale [, yscale]]]]]]]]]]) Add a new chart to the XLSX document. Parameters - type : Type of chart to create. Must be one of the following values. "area" "area_stacked" "area_stacked_percent" "bar" "bar_stacked" "bar_stacked_percent" "column" "column_stacked" "column_stacked_percent" "doughnut" "line" "line_stacked" "line_stacked_percent" "pie" "scatter" "scatter_straight" "scatter_stright_markers" "scatter_smooth" "scatter_smooth_markers" "radar" "radar_with_markers" "radar_filled" title : The title for this chart. xname : The title for the x-axis. yname : The title for the y-axis. cell : The Excel style cell to insert the cell. e.g. "A1" "D6" "F6". stylenum : Number of the built in Excel style to use. Must be between "1" and "48". The default style is 2. The value is one of the 48 built-in styles available on the "Design" tab in Excel 2007. sheet : Handle to sheet to insert the chart on. Use blank, "0", or "-1" to use the default sheet. xoff : X axis offset to place the chart, in pixels. yoff : Y axis offset to place the chart, in pixesl. xscale : Scale the chart along the x axis. e.g. "1", "0.5" "2". Value cannot be negative. yscale : Scale the chart along the x axis. e.g. "1", "0.5" "2". Value cannot be negative. Returns a handle to a new chart object on successs and "-1" on error. XL_ERROR() can be called to return the last error. Note: The chart functions do not use the auto counter found in the sheets and instead will default to "0", "0" or "A1" when used for insertion. handle = XL_CHARTSHEET(type [, title [, xname [, yname [, stylenum]]]]) Add a new chartsheet to the XLSX document. A chartsheet is a full chart that occupies it's own sheet and cannot contain any cells. Parameters - type : Type of chart to create. Must be one of the following values. "area" "area_stacked" "area_stacked_percent" "bar" "bar_stacked" "bar_stacked_percent" "column" "column_stacked" "column_stacked_percent" "doughnut" "line" "line_stacked" "line_stacked_percent" "pie" "scatter" "scatter_straight" "scatter_stright_markers" "scatter_smooth" "scatter_smooth_markers" "radar" "radar_with_markers" "radar_filled" title : The title for this chart. xname : The title for the x-axis. yname : The title for the y-axis. stylenum : Number of the built in Excel style to use. Must be between "1" and "48". The default style is 2. The value is one of the 48 built-in styles available on the "Design" tab in Excel 2007. Returns a handle to a new chartsheet object on successs and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_SERIES(chartnum, sheet, namerow, namecol, cfirstrow, cfirstcol, clastrow, clastcol, vfirstrow, vfirstcol, vlastrow, vlastcol) Add a series to a chart or chartsheet. Parameters - chartnum : Handle to a chart or chartsheet to add series. sheet : Handle to sheet to get values from. Use blank, "0", or "-1" to use the default sheet. namerow : Series name row (0 indexed). namecol : Series name column (0 indexed). cfirstrow : Categories first row (0 indexed). cfirstcol : Categories first column (0 indexed). clastrow : Categories last row (0 indexed). clastcol : Categories last column (0 indexed). vfirstrow : Values first row (0 indexed). vfirstcol : Values first column (0 indexed). vlastrow : Values last row (0 indexed). vlastcol : Values last column (0 indexed). Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_SERIES2(chartnum, sheet, namecell, cfirst, clast, vfirst, vlast) Add a series to a chart or chartsheet. Parameters - chartnum : Handle to a chart or chartsheet to add series. sheet : Handle to sheet to get values from. Use blank, "0", or "-1" to use the default sheet. namecell : Series name Excel style cell. e.g. "A1" "D6" "F6". cfirst : Categories first Excel style cell. e.g. "A1" "D6" "F6". clast : Categories last Excel style cell. e.g. "A1" "D6" "F6". vfirst : Values first Excel style cell. e.g. "A1" "D6" "F6". vlast : Values last Excel style cell. e.g. "A1" "D6" "F6". Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_PROTECTSHEET(sheet, password) Add a password to restrict editing of a sheet. Parameters - sheet : Handle to sheet to protect. Use blank, "0", or "-1" to use the default sheet. password : Password to use to protect this sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_PROTECTCHARTSHEET(cs, password) Add a password to restrict editing of a chartsheet. Parameters - cs : Handle to chartsheet protect. password : Password to use to protect this sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_ERROR() Return the last error generated by the XLSX set of functions. Returns the last error string generated by the XLSX engine. e = XL_SETPOS(row [, col [, sheet]]) Set the auto counter position for a sheet. Parameters - row : Row to move auto counter to (0 indexed). col : Column to move auto counter to (0 indexed). sheet : Handle of sheet to set. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_SETPOS2(cell [, sheet]) Set the auto counter position for a sheet. Parameters - cell : Excel style cell to set the auto counter to. e.g. "A1" "D6". sheet : Handle of sheet to set. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_NEXTROW([sheet]) Move the auto counter down a row for a sheet. Parameters - sheet : Handle of sheet to set. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_NEXTCOL([sheet]) Move the auto counter one column for a sheet. Parameters - sheet : Handle of sheet to set. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. handle = XL_STYLE([font [, fill [, fmt [, btop [, bbot [, bleft [, bright]]]]]]]) Add a new style to the XLSX document. Parameters - font : Handle to font object to use. fill : Handle to fill object to use. fmt : Handle to format object to use. btop : Handle to border object to use for top border. bbot : Handle to border object to use for bottom border. bleft : Handle to border object to use for left border. bright : Handle to border object to use for right border. Returns a handle to a new style object on successs and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_IMAGE(img [, row [, col [, sheet [, xoff [, yoff [, scalex [, scaley [, flag]]]]]]]]) Add a new image to the XLSX document. Parameters - img : Path to image file to use. row : Row to insert the image on (0 indexed). col : Column to insert the image on (0 indexed). sheet : Handle of sheet to insert image. Use blank, "0", or "-1" to use the default sheet. xoff : X-axis offset for the image, in pixels. yoff : Y-axis offset for the image, in pixels. scalex : Scale the image along the x-axis. e.g. "1", "0.5" "2". Value cannot be negative. scaley : Scale the image along the y-axis. e.g. "1", "0.5" "2". Value cannot be negative. flag : Option of how to position image. "0" - Default positioning. "1" - Move and size image with the cells. "2" - Move but don't size image with the cells. "3" - Don't move or size the image with the cells. "4" - Same as "1" but wait to apply hidden cells. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Note: The image functions only support PNG, JPEG, and BMP files. e = XL_IMAGE2(img [, cell [, sheet [, xoff [, yoff [, scalex [, scaley [, flag]]]]]]]); Add a new image to the XLSX document. Parameters - img : Path to image file to use. cell : Excel style cell to insert the image. e.g. "A1" "D6" "F6". sheet : Handle of sheet to insert image. Use blank, "0", or "-1" to use the default sheet. xoff : X-axis offset for the image, in pixels. yoff : Y-axis offset for the image, in pixels. scalex : Scale the image along the x-axis. e.g. "1", "0.5" "2". Value cannot be negative. scaley : Scale the image along the y-axis. e.g. "1", "0.5" "2". Value cannot be negative. flag : Option of how to position image. "0" - Default positioning. "1" - Move and size image with the cells. "2" - Move but don't size image with the cells. "3" - Don't move or size the image with the cells. "4" - Same as "1" but wait to apply hidden cells. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Note: The image functions only support PNG, JPEG, and BMP files. e = XL_LASTCMD() Get debug information about the last XLSX call. Returns the last evaluated command parse string. e = XL_MARGINS([left, [right, [top, [bottom, [sheet]]]]]) Set the worksheet print margins. Parameters - left : Left margin in inches, e.g. "0.5", "1", "0.75". A blank or negative value will use the default of "0.7". right : Right margin in inches, e.g. "0.5", "1", "0.75". A blank or negative value will use the default of "0.7". top : Top margin in inches, e.g. "0.5", "1", "0.75". A blank or negative value will use the default of "0.75". bottom : Bottom margin in inches, e.g. "0.5", "1", "0.75". A blank or negative value will use the default of "0.75". sheet : Handle of sheet to set the margins. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_LANDSCAPE([sheet]) Set the worksheet to print in landscape mode. Parameters - sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_PORTRAIT([sheet]) Set the worksheet to print in portrait mode. Parameters - sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_GRIDLINES(option [, sheet]) Set if the worksheet should display gridlines when printed. Parameters - option : Which Gridlines to print. Cannot be blank. Must be one of the following values. "hide_all" "show_all" "show_screen" "show_print" sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_FITPAGES([height, [width, [sheet]]]) Fit the printed area to a specific number of pages both vertically and horizontally. Parameters - height : Number of pages vertically. A value of "0" or blank will set the height as necessary. width : Number of pages horizontally. A value of "0" or blank will set the height as necessary. sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_PAPERTYPE(type [, sheet]) Set the paper format for the printed output of a worksheet. Parameters - type : The paper format to use with a printed worksheet. Must be one of the following values. "default" "letter" "tabloid" "ledger" "legal" "statement" "executive" "a3" "a4" "a5" "b4" "b5" "folio" "quarto" "10x14" "11x17" "note" "envelope" "envelope_9" "envelope_10" "envelope_11" "envelope_12" "envelope_14" "c" "d" "e" "envelope_dl" "envelope_c3" "envelope_c4" "envelope_c5" "envelope_c6" "envelope_c65" "envelope_b4" "envelope_b5" "envelope_b6" "monarch" "fanfold" "german_std_fanfold" "german_legal_fanfold" sheet : Handle of sheet to change type. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_CENTERH([sheet]) Center the worksheet data horizontally between the margins on the printed page. Parameters - sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_CENTERV([sheet]) Center the worksheet data vertically between the margins on the printed page. Parameters - sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_PRINTACROSS([sheet]) Change the default print direction to across then down. Parameters - sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_SETHEADER(string [, margin, [limage, [cimage, [rimage, [sheet]]]]]) Set the printed page header. e = XL_SETFOOTER(string [, margin, [limage, [cimage, [rimage, [sheet]]]]]) Set the printed page footer. Parameters - string : The header/footer definition string. See below for format options. Cannot be blank. margin : The margin in inches to use for the header/footer. A blank, "0", or negative value will use the default margin of "0.3". limage : Full path to an image to use in place of the left image placeholder. cimage : Full path to an image to use in place of the center image placeholder. rimage : Full path to an image to use in place of the right image placeholder. sheet : Handle of sheet to set header/footer. Use blank, "0", or "-1" to use the default sheet. Format Options - +-----------------------------------------------------------+ | Control Category Description | +-----------------------------------------------------------+ | &L Justification Left | | &C Center | | &R Right | +-----------------------------------------------------------+ | &P Information Page number | | &N Total number of pages | | &D Date | | &T Time | | &F File name | | &A Worksheet name | | &Z Workbook path | +-----------------------------------------------------------+ | &fontsize Font Font size | | &"font,style" Font name and style | | &U Single underline | | &E Double underline | | &S Strikethrough | | &X Superscript | | &Y Subscript | +-----------------------------------------------------------+ | &[Picture] Images Image placeholder | | &G Same as &[Picture] | +-----------------------------------------------------------+ | && Miscellaneous Literal ampersand & | +-----------------------------------------------------------+ Text in headers and footers can be justified to the left, center and right by prefixing the text with the control characters &L, &C and &R. For example, "&LHello, World!", "&CHello, World!", "&RHello, World!" For simple text, if the justification is not specified the text will be center aligned. However, you must prefix the text with &C if you use any other formatting. You are limited to 3 images in a header/footer. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Note: The image types supported are PNG, JPEG, and BMP files. There is a hard limit of 255 characters in a header/footer string, including control characters. Strings longer than this will not be written to the document. e = XL_SETBACKGROUND(image [, sheet]) Set the background image for a worksheet. Parameters - image : Full path to an image to use as the sheet background. sheet : Handle of sheet to set background image. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Note: The image types supported are PNG, JPEG, and BMP files. e = XL_HIDEZEROS([sheet]) Hide zero values in worksheet cells. Parameters - sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. e = XL_SHOWROWCOL([sheet]) Show row and column headers on the printed page. Parameters - sheet : Handle of sheet to change mode. Use blank, "0", or "-1" to use the default sheet. Returns "1" on success and "-1" on error. XL_ERROR() can be called to return the last error. Rebuild All Indexes on a file. item '8' on the dialog. Note: this is in the "extended" dialog which shows when a filename is not specified from the command line. Indexes can be selected individually, or all (with F7). Press SAVE, and rebuild begins Ability to SPLIT data into array Usage: sz=SPLIT(array, string, delimiter) array is the array that the data will be placed into string is the data to split delimiter is the sequence of characters to split on NOTE: The array being used must have the size defined for its elements and cannot be an alias. Added the ability to show record locks from *clerk. Can also be used to terminate sessions directly. New option !L added to *clerk. Using !L will activate the new locked records list. Enter on a selected entry will give additional options to the user, including the ability to Kill or Terminate a locked process without having to go to the command line. Note: This option is only available on Unix/Linux/BSD Added UID mapping to filePro, ddir/dprodir option F5. This allows for UIDs (User IDs) to be aliased to specific usernames. In the event that a login account is removed from your system, this can be used to maintain the link between the removed login's UID and those stored in filePro, effectivly allowing system variables such as @CB and @UB to be mainained. Windows Only: This also has the added benefit of allowing @CB and @UB to function on Windows by linking a "pseudo" UID to a given username. These UIDs are automatically generated but can also be manually added. When a user opens filePro and their username does not exist in the UID map file, a UID will be generated for that user. filePro will find the next available UID in the list, starting from 2000, and assign it to that username. On all platforms, UIDs stored in this program must be unique and in the range 0-65535. Usernames can be duplicated on Unix and Linux platforms, but must be unique on Windows. Usernames are case-sensitive on Unix and Linux platforms and are case-insensitive on Windows platforms. Environmental Variables: PFUIDMAP = /path Alternate filePro UID map file. (Use full path) Note: Must be set in the environment. PFUSEUIDMAP = ON Allows filePro to do UID mapping. Also expands the maximum username length returned by @CB, @UB, and @ID to 32. Default: ON String Functions All "is" functions return "1" for true and "0" for false. x=isalpha(fld [, pos]) Is the character at the position given a letter? x=isdigit(fld [, pos]) Is the character at the position given a number? x=isalnum(fld [, pos]) Is the character at the position given a letter or number? x=isspace(fld [, pos]) Is the character at the position given a whitespace character? ' ', '\t', '\n', '\r', '\v', '\f' x=islower(fld [, pos]) Is the character at the position given lowercase? x=isupper(fld [, pos]) Is the character at the position given uppercase? x=isxdigit(fld [, pos]) Is the character at the position given a hexadecimal character? '0'-'9', 'A'-'F' x=iscntrl(fld [, pos]) Is the character at the position given a control character? ASCII codes 0x00 (nul) - 0x1f (US), and 0x7f (del) x=isprint(fld [, pos]) Is the character at the position given a printable character? ASCII codes greater than 0x1f (US) not including 0x7f (del) x=ispunct(fld [, pos]) Is the character at the position given a punctuation character? x=isgraph(fld [, pos]) Is the character at the position given a character with a graphical representation? The characters with graphical representation are all those characters than can be printed (as determined by isprint) except for space. x=tolower(fld [, pos]) Return the character at the position given as a lowercase character. x=toupper(fld [, pos]) Return the character at the position given as an uppercase character. str=strtolower(fld) Return the entire string converted to lowercase. str=strtoupper(fld) Return the entire string converted to uppercase. Added new array size function to get the size of an array. Can be used with GLOBAL, EXTERN, LOCAL, and SYSTEM arrays. x=ARRAYSIZE(array) Where array is the name of the array. Where x is the returned size of the passed array. Added new DECLARED function to check if an array or longvar is defined, meaning it is either declared LOCAL or GLOBAL or is declared EXTERN but has a matcing GLOBAL definition. x=DECLARED(var) Where var is either a longvar or an array. Where x is the return value. Returns 0 if the variable is not fully defined. Returns 1 if the variable is fully defined. Increased ACTION length in debugger from 60 characters to full 128. Should now be the same as *cabe. Added new flag -DM to [dr]clerk to disable the Index Mode prompt from @ENTSEL. Only works when not in update mode. Added flag -RH to report to disable the automatic record number reporting in the middle of the screen. This enables placing text on the center of the screen without it being overwritten when the display updates. x=@GUI.PAUSE() Pauses automatic screen updating while in GI/Web. x=@GUI.RESUME() Resumes automatic screen updating while in GI/Web. REPLACE() enhancement - allow null characters Enhanced REPLACE() to accept null characters FORM WITHPROC FORM WITHPROC "formname" FORMM WITHPROC "formname" Added additional command switch to FORM and FORMM commands to allow the associated processing table to run while in input processing. Note: You cannot call the WITHPROC variant from within another form UNLESS the calling form is a processing only form. Addqual Program Addqual allows you to easily add qualifiers to your files either interactively or through the command line. This runs interactively: addqual [filename] This runs automatically: addqual filename -q <qualname> as does this: addqual filename -q <qualname> -x <qual-to-copy-from> The automatic commands will display graphics on errors. You can keep graphics off with "-s" and errors will be printed on the command line if they occur. example: addqual filename -q <qualname> -s List of switches: -q qualifier to create -x qualifier to copy indexes from -s silent, no graphics -h --help syntax help XFER - encrypted transfers server-peer CABE F6 list files from F8 L-Load =================================== 6.1.XX.08 Bug Fixes =================================== Fixed the F7 last record option when selecting a record in dclerk/rclerk while running under fileProWeb or filePro GIclient. Corrected an issue where an ODBC table wouldn't report as existing. Corrected an issue with Find and Replace in dcabe/rcabe where control codes were incorrectly being interpreted as character and color codes. Corrected an issue in dreport/rreport where exiting with an EXIT action in @DONE would not use the supplied exit value if zero records were selected. Updated F6-D-L listing in dcabe/rcabe to restore typedown behaviour. Fixed an issue in rcabe, dcabe, and dclerk where a syntax error could cause a crash upon saving or continuing. Fixed a show map (F6 - View Fields) regression in dcabe/rcabe where button labels were missing valid options. Fixed an issue with the bottom screen display on Windows in dscreen. Reworked the SPLIT() command to work with all standard array types. Fixed SPLIT() return value. There was an issue where the number of elements returned could have been more than the returned type allowed. SPLIT() now clears the array before updating values and will now honor the edit type(s) of the array, rather than always treating the data as a string. Fixed a crash when using READOUTPUT() in processing. Corrected a memory leak in LISTBOX() and SELECTBOX(). Corrected an issue with the "!L" escape in dclerk/rclerk. Previously, the calculation to determine the locked record number was incorrect. Added an additional check when saving a record in dclerk/rclerk so that a zero length must-fill field will be treated as filled. Corrected an issue with fields resetting when using user defined browses in clerk when a screen contains scrolling fields. =================================== Version 6.1.XX.07 bug fixes =================================== Fixed UID import feature in ddir where it wasn't finding any files. User can now save a blank UID map in ddir. Corrected a lock issue with UID maps. Added additional error messages when importing files for UID mapping. Fixed an issue with VARCHAR fields not working when using some ODBC drivers. Corrected an issue with script cleanup causing a crash in dmakemenu. Fixed a crash when adding an index to an existing empty file in ddefine. Fixed a crash in fppack when rebuilding an index containing system controlled fields. Corrected an issue in fpsql where viewing a file's layout would not retain the previous seleciton. Fixed an issue in all runtime programs where aliased real fields in an array would not explicitly write on end. Corrected a potential crash when adding a duplicate key to an index. Fixed a crash caused by inserting a new unique key after a very long chain of duplicate keys to an index. Fixed a break key issue in cabe F6 label lookup in F9 search. filePro was requiring twice as many break key presses than was actually required. Fixed a crash when creating a selection set and pressing F6 while in a relationship field. =================================== Version 6.1.XX.06 bug fixes =================================== Corrected an issue on Linux/BSD where fuzzy search could cause a crash. Fixed array handling in user defined functions that could cause a crash. Fixed associated field comparisons in clerk and report. Was previously only comparing the first field in a set. Corrected some command line arguments being ignored in ddefine, autoshuf, and doresync. Corrected edit types not being tokenized correctly in rcabe. Added duplicate variable check when saving in ddir/dprodir. Updated fuzzy search to better handle long fields. Fix a crash when moving through a line that contains a malformed CALL statement in cabe. Fixed a crash in find and replace in cabe. Fixed a crash when copying lines that don't exist in the file in cabe. Corrected various files not being copied correctly in fpcopy. Fixed indexes on qualified files in fpcopy. Added sanity check to locked records check in clerk. SPLIT() - Removed restriction on delimiter size. Size of array elements still need to be defined for destination. Fixed syntax error line reporting in cabe when jumping to a different place in a prc file. Cabe now shows the line number in the editor correctly. Corrected an issue loading tokenized global arrays in rclerk and rreport. =================================== Version 6.1.XX.05 bug fixes =================================== Corrected an issue when using the Rebuild Indexes option in dxmaint where options were not toggling correctly. Fixed a regression where scrollable fields in a popup weren't displaying correctly. Fixed message boxes to better handle filePro escape codes. Fixed -pv flag and print to screen to no longer corrupt the output. Fixed alternate automatic processing loading in cabe, preventing variables from resolving correctly during syntax check. Fixed a too many open files bug in fpcopy when working on a file with many qualifiers and indexes. Corrected fppack to correctly handle encrypted files. Changed index rebuild message location on the screen to no longer be hidden behind the progress updates. Corrected an issue preventing GI/fileProWeb from loading [dr]report and [dr]clerk on Windows. Fixed a crash with the PDF import code. Corrected a crash when opening more than one JSON file at a time. =================================== Version 6.1.XX.04 bug fixes =================================== Fixed an issue where libodbc would not correctly be found when initializing features that use ODBC. Corrected an issue with RINSTR() where the starting position wasn't honored correctly. Option 'C' to clear selection set in [dr]clerk will no longer cause an infinite loop when going back into index selection. Updated PNG support for PDF outputs. Previously, some PNG files would appear corrupted when imported. Corrected a potential crash when moving/reordering blob fields inside of dmoedef. Added PFOLDCHAIN to allow CHAIN to return to the top of processing when a record is saved and the chain was performed inside of an event. Updated listbox and selectbox code to no longer go outside of screen bounds. Fixed date handling in XLSX generation when not using the datetime functions. Fixed an issue where blobs/memos could become corrupted if assigning to the field more than once without writing the record. =================================== Version 6.1.XX.03 bug fixes =================================== Updated tokenization engine to increase parsing speed. Corrected Memory fault in FPSQL Corrected licinfo to read license fallback file. Corrected memory leaks in [dr]clerk and [dr]report. Corrected issue where a select or list box would not clear correctly from the screen. Fixed positioning and moving objects (memo) on a form. Corrected button text in F6 cabe. Fixed an early error exit condition in ddir to report an error rather than exiting. Corrected "stair step" issue in cabe when using the -C flag on Linux/Unix. Corrected a crash in clerk when using F5 to duplicate fields between records. Updated F5 duplicate key in clerk to work with scrolling fields. Added PFREUSEADDR=ON (default ON) to enable a port to be rebound more quickly when using sockets. Added code to prevent a dummy field from being used as a foreign key when performing a fuzzy search. Corrected and reverted wildcard behaviour during selection in clerk. Corrected type checking for associated fields in selection sets. Added buttons to clerk fuzzy search for scrolling the file map. Increased the number of fields shown in fuzzy search in clerk. Fixed some button shifting for F6 key in cabe. Corrected ALL operator in short selection to properly update the selection popup. =================================== Version 6.1.XX.02 bug fixes =================================== Task #1948 Autosave not honoring config flags Corrected an issue where Autosave was not correctly reading config variables. Addded initial change backup. Task #1950 Scrolling fields in popups break placement Corrected an issue when drawing a popup that contains a scrolling field. Task #1951 Enhanced runtime format for WHEN flags Enhanced runtime format to support extended WHEN flags. Added support for @WUKx* @WHPx* and @WBLx*. New WHEN values will be ignored in older versions of filePro. =================================== Version 6.1.XX.01 bug fixes =================================== Task #1945 ALL fields search in selection broken Corrected ALL field search code for selections. Task #1947 Short selection prompting twice Corrected an issue where short selection was displaying the old selection screen. Task #1949 Enable REVERT command Correctly enabled the REVERT command for release. =================================== End End End End End End End End End ===================================