NEW! Functions in DataEase 8.0 to 8.5 (Page 1)
Some of you might be aware of it but it seems a lot isn't so it might be time to advertise a little the vast number of new functions and functionalities that has been added to DataEase 8.0 through 8.5.
For a long time the only way new functions found their way to DataEase was through active and ingenious users which developed CDF's. As much as the CDF's alleviated the obvious short-comings in DataEase 5.x to 7.2 it was cumbersome, undocumented and "secretive" i.e. not everyone was in the know.
With 8.x we decided that the focus needed to be on moving DataEase forward, rather than the constant dance around the "bug fixing" fire.
Have a look and a try for yourself.
Due to the number of new functions we had to publish the short description in two articles, of which this is the last.
Also have a look on the blog synopsis found in the list to the right.
This simple function will return the corresponding ASCII character for any numerical value. It is to be used in combination with concat(), MemoCopy(), MemoMemoCopy(), MemoReplace(), MemoFind() etc.
It is a very useful function for building advanced strings or documents.
The console is basically screen print in DFD, and in version 1 it even looks like DOS ;-) The console will have many purposes.
1. You can use it as a DEBUG window and use ConsoleCopy() to put messages on the console during a procedure run instead of Window/Dialog messages.
2. You can use it as a report output the way you used to in DFD. You will have to build your own output, but that is what most of us did in DFD anyway (OUTPUT)
3. You can use it to generate a print or export. You can of course already do that via the new file functions, but this way you will be able to visualise it too. The nice thing with the console is that it is unique for each application, but there is only one, so you can add stuff to it from anywhere in your application and when happy, you can simply save it to a file with ConsoleWriteTofile() or print it to a Windows device (printer) with the same function.
Plenty of other uses too, this is just the start.
The console is basically screen print in DFD, and in version 1 it even looks like DOS ;-) The console will have many purposes.
1. You can use it as a DEBUG window and use ConsoleCopy() to put messages on the console during a procedure run instead of Window/Dialog messages.
2. You can use it as a report output the way you used to in DFD. You will have to build your own output, but that is what most of us did in DFD anyway (OUTPUT)
3. You can use it to generate a print or export. You can of course already do that via the new file functions, but this way you will be able to visualise it too. The nice thing with the console is that it is unique for each application, but there is only one, so you can add stuff to it from anywhere in your application and when happy, you can simply save it to a file with ConsoleWriteTofile() or print it to a Windows device (printer) with the same function.
Plenty of other uses too, this is just the start.
This function hide or show the console window. Console Window is initially hidden.
The console is basically screen print in DFD, and in version 1 it even looks like DOS ;-) The console will have many purposes.
1. You can use it as a DEBUG window and use ConsoleCopy() to put messages on the console during a procedure run instead of Window/Dialog messages.
2. You can use it as a report output the way you used to in DFD. You will have to build your own output, but that is what most of us did in DFD anyway (OUTPUT)
3. You can use it to generate a print or export. You can of course already do that via the new file functions, but this way you will be able to visualise it too. The nice thing with the console is that it is unique for each application, but there is only one, so you can add stuff to it from anywhere in your application and when happy, you can simply save it to a file with ConsoleWriteTofile() or print it to a Windows device (printer) with the same function.
Plenty of other uses too, this is just the start.
To create a table during runtime that can be used for storing history, data-manipulation and eventually direct user interaction.
In version 1 this function will only be usable from ExecDQL as all other Documents/procedure can only access pre-defined tables.
To allow the user to choose a date from a calendar instead of having to key it in.
To close a document by "remote". Many times when you have open a form for information or run a report/procedure with output, you want that document to be closed. If focus has been returned to another document this is not always straight forward so we have added DocumentCloseName() so you can close a document from anywhere in an app.
If the document in name is already closed or does not exist no action will be taken, and no error message returned.
To check if an object is available in the current form or to find the number of objects with the same name.
When you use a subform or a multi-record form the object names are cloned so if you have 40 rows in a subform you will have 40 object clones with the same name. If you want to manipulate or populate them all you need to loop through them, so it will be useful to know how many clones of the object there is.
Another use is to check if a specific clone exist for instance nr. 13. DoesObjectExist("CustomerName#13").
To run a DQL script as a function from anywhere.
DQL is the most useful part of a DE application but it has had its limitations because it has been part of the DQL document (report). With ExecDQL we have liberated it, and you can now call a DQL from anywhere at anytime. It follow normal DQL syntax rules and it will generate an variable length export file if you include a file name as the last parameter (parameter 6).
Because it is a function you have to reference the Data-entry fields (transfered as parameter 2-5) with fixed names i.e Field1, Field2, Field3 and Field4. Other than that it is completely traditional DQL.
The ExecDQL has the GUI context of the document from where it is called, so you can read and manipulate the document from the DQL. This means that ExecDQL is not only a Data manipulating procedure it can also be a GUI manipulating procedure.
If you need more input variables than 4 you can simply pick them out of the Form you are calling the ExecDQL from with GetValue()
To make ExecDQL and other parts of DE8 more effective we have also introduced ESCAPE values in DE8 Strings.
Early in 8.0 we introduced CHR() to make it easier (possible) to use reserved letters in DE derivations and DQL etc. However it is a little awkward when you have to use ConCat() to joint things together for instance in a ExecDQL etc.
Ex.
ExecDQL(concat("message ", chr(34), "Hello world!",chr(34)," window.","","","","","")
So now you can simply do this with the escape charcter for ".
Ex.
ExecDQL("Message /'Hello World!/' window .")
The observant reader also see that we don't add all the "" at the end of the function. This is news in 8.2 too. We have introduced variable number of parameters to make the functions more user friendly.
Up to now you had to be exact with your parameters and that could be a chore when the only thing you wanted was to execute a small line of commands with no export, and no input.
You will still have to follow the numbers so if you want to include an export file for ExecDQL you will need to include 4 empty "" as parameters before the export file name, but if you only need two data-entry parameters you can now simply add the two and skip the 3 last parameters.
To run a DQL script stored in a file as a function from anywhere.
DQL is the most useful part of a DE application but it has had its limitations because it has been part of the DQL document (report). With ExecDQL we have liberated it, and you can now call a DQL from anywhere at anytime. It follow normal DQL syntax rules and it will generate an variable length export file if you include a file name as the last parameter (parameter 6).
Because it is a function you have to reference the Data-entry fields (transfered as parameter 2-5) with fixed names i.e Field1, Field2, Field3 and Field4. Other than that it is completely traditional DQL.
The ExecDQL has the GUI context of the document from where it is called, so you can read and manipulate the document from the DQL. This means that ExecDQL is not only a Data manipulating procedure it can also be a GUI manipulating procedure.
If you need more input variables than 4 you can simply pick them out of the Form you are calling the ExecDQL from with GetValue()
FixedWidth return a space (blank) padded string "Length" long where Value is positioned according to the position switch. The purpose of the function is to make it easier to build columns in a text file/export/console output. The function is created to make DFW more compatible with DFD style thinking and output. Especially useful in combination with WriteToFile(), ConsoleCopy() etc.
Reorganize means really to structure and update registers. There is two reasons why you want to reorganize a table or all tables.
1. You have a lot of deletions in your tables and you want to compact the tables to save space and increase efficiencies.
2 .DataEase report inconsistency in your data. Inconistency is really when the size of a .DBM (Data file) is not corresponding with the recorded size in RDRR (Registry).
The GetCurrent() functions is closely related to the old Current functionality in DataEase and is an addition to the existing Current values up to and including 7.2.
The New GetCurrent() function is a function to retrieve current information from DataEase. The first increment returned paths to different parts of the DE structure, then we added features for navigating in the Form to help with setting and getting information on objects and now we are adding features to get information on the forms.
The new GetCurrent functions are all File paths and are included to make it easier to navigate from inside a DataEase App.
Everything from Images, to files, documents, exports etc. can be located in a dynamic structure and up to now it has been impossible to address them "relative" to the Application, to the installed DataEase or to the users My Document structure.
The time when DataEase was installed on C:\DEASE and the app was in the program catalogue is long gone, and we now need to be able to navigate freely on different installations.
Labels, Buttons and Tabs (on tab control) have a string property which contain the text displayed on the item.
GetLabelText will query the object and return the text property stored in the object. Combined with SetLabelText() labels etc, can be used for storage of text between records etc.
SetStyle() is maybe one of the most "revolutionary" new functions in DataEase 8.
We have already introduced new functions like SetColor(), SetLabelText(), SetState() etc. Using SetColor() to manipulate the look of an object can be cumbersome, so why not use the much more powerful SetStyle()?
SetColor() can only change the color of Text, Fill and Border of objects, while SetStyle() can change all styleable properties on an object in one stroke. All color properties, font type, size and style etc..
Since changing the style of an object will be "permanent" throughout as session it is important to be able to revert to the original style when you have finished with the manipulation and this is where GetStyle() can help.
Simply Pick up the style and store it in a SetVar() before you start the manipulation, and then you can re-set it when you are finished.
To get the value of an object. This function is very useful in ExecDQL or to pick values out of non-referable fields like editable form virtual fields etc.
Remember that you can use this function to pick any field value but if you pick a Memo it will only return the first 255 characters.
This is a GUI function so it will return the value of the GUI object rather than the PRISM column that has populated it.
Together with SetVarl() to allow users to transfer any number of values from any one part of the application to any other part of the application.
It will allow the user to name the variable and retrieve it by using the same name. GetVarl() and SetVarl() will automatically translate all DataEase Data types, so you can transfer Text, Numbers, Numerical Strings, Choices, Dates, Time etc.
htmltopdf is able to put several objects into the output file, an object is either a single webpage, a cover webpage or a table of content. The objects are put into the output document in the order they are specified on the command line, options can be specified on a per object basis or in the global options area. Options from the Global Options section can only be placed in the global options area
A page objects puts the content of a singe webpage into the output document.
(page)? <input url/file name> [PAGE OPTION]...
Options for the page object can be placed in the global options and the pageoptions areas. The applicable options can be found in the Page Options and Headers And Footer Options sections.
A cover objects puts the content of a singe webpage into the output document, the page does not appear in the table of content, and does not have headers and footers.
cover <input url/file name> [PAGE OPTION]...
All options that can be specified for a page object can also be specified for a cover. A table of content object inserts a table of content into the output document.
toc [TOC OPTION]...
All options that can be specified for a page object can also be specified for a toc, further more the options from the TOC Options section can also be applied. The table of content is generated via XSLT which means that it can be styled to look however you want it to look. To get an aide of how to do this you can dump the default xslt document by supplying the --dump-default-toc-xsl, and the outline it works on by supplying --dump-outline, see the Outline Options section.
DataEase in "default" mode will update index after each record modification. This insure consistency and immediate "correct" index but when one run a big update this will be stealing a lot of processing power and will be the main reason for slow performance.
IndexUpdate function has to main purposes:
1. For developers to insure that a index is consistent before a major update/transaction so records are not left out without having to resort to reorganizing a table.
2. For developers to temporary disable index updating for big transactions to speed up performance and then simply build the index at the end of the transaction.
IndexUpdate() has three modes:
On (Full): Default
This mode will update the index after each updated row.
Quick:
This mode will update the index for each transaction. A transaction is a update of one table (relationship). DO NOT USE THIS MODE IF YOU ARE DOING NESTED UPDATES/DELETES/INSERTS!
Off:
This is the ADVANCED (Manual) mode. If you use this the index will not be updated at all. This will leave the index "wrong" until you manually update it with IndexUpdate("YourTableName").
This is the best mode to use if you are doing heavy nested transactions. Just make sure you update manually the indexes for all tables involved in the transaction.
NB! When you have used any other mode then ON(Full) you need to revert to ON at the end of your DQL if not all DQLs in your session will keep on running in the last used mode.
LabelExecDQL() is part of the ExecDQL library and is complimentary to MemoExecDQL() etc. LabelExecDQL will execute the DQL script that is stored in a label in a document.
One of the challenges with ExecDQL is to store the DQL in the form from where you want to execute it. Especially if the DQL is of any size.
ExecDQL is limited to 255 charcters and even though it was much improved with the introduction of ESCAPE characters, it is still quite limited as you have to write the DQL on one line in a derivation etc.
So the Big Hitter in the ExecDQL department has been MemoExecDQL(). It is brilliant as you use the strong DE relational behaviour in combination with virtual Memo fields to lookup the DQL from a DQL storage (table) anywhere in your app. It is great since you can share a DQL between different parts of your APP, but it is limiting in the way you have to build the Relational structure and as well edit the DQL out of context.
With LabelExecDQL you can simply write the DQL into the form as a text (label) and then execute it by reference it via its Object Name.
Obviously its not very nice to have a big ugly DQL written into your form, but that is easily resolved by executing a SetState("LabelName",0) somewhere on startup.
To "decompile" or "unwind" a Memo field into 256 long chunks that can be handled by ordinary DataEase functions and saved in Text fields.
Pre DataEase 8 there was no way one could manipulate of use the content of Memo fields. The only way one could add to the was by manually keying in the content and the only way one could exploit the content was via reading it on screen.
In 8 Memo fields are one of the most important field types and visual controls.
We have added a entirely new class of functions simply to manipulate, populate and extract data from memo fields.
MemoChunk() is a function that will simply retrieve a 256 bytes large chunk from a Memo field and return it as a normal text string(256).
The usage of MemoChunk() can be for saving the content of a Virtual Memo Control into normal text fields for indexing, searching etc.
!Hint to legacy DataEase users!
If you have problems with your old style Memo fields being migrated to new style from 6.5x to 7.x you can use this function to unwind your data back into a Fields structure like the old style Memos. You can also use the New Style memo for editing and then unwind it back into a standard field structure.
The console is basically screen print in DFD, and in version 1 it even looks like DOS ;-) The console will have many purposes.
1. You can use it as a DEBUG window and use ConsoleCopy() to put messages on the console during a procedure run instead of Window/Dialog messages.
2. You can use it as a report output the way you used to in DFD. You will have to build your own output, but that is what most of us did in DFD anyway (OUTPUT)
3. You can use it to generate a print or export. You can of course already do that via the new file functions, but this way you will be able to visualise it too. The nice thing with the console is that it is unique for each application, but there is only one, so you can add stuff to it from anywhere in your application and when happy, you can simply save it to a file with ConsoleWriteTofile() or print it to a Windows device (printer) with the same function.
Plenty of other uses too, this is just the start.
Insert or append a standard DataEase field or string value into a Memo Field.
Memo is a new field class in DataEase 8 with it's own functions to manipulate and bridge the gap between traditional DataEase functionality and Memo. Memo will not work with standard functions like Jointext(), Concat() etc. because they can only manipulate 246 bytes at a time.
MemoCopy() is designed to insert/append any traditional DataEase value into any Memo field. You can insert it at the beginning, overwrite the Memo, delete/blank the current value or simply append it at the end.
It is designed to be used for building Memo content dynamically or to manipulate Memo fields by adding content. It can be used both for normal text adding (export etc.) or it can be used for adding coding like html/CSS etc.
This function can be called from a Button (Action), a derivation (i.e field derivation or validation) or be used as a part of a DQL query to populate a Memo list, export creation, web page build etc.
To extract a coded value from a value pair inside a Memo field.
DataEase have always been very good at storing structured data and retrieving it. What it has not been so good at is to store and exploit unstructured data or dynamically generated data.
In DataEase for DOS you had a limited ability with OUTPUT in DQL to create your own Exports and you could decode the import in a DQL but it was always a little awkward and laborious. In DFW this venue was closed of as well.
DataEase is all about making advanced stuff simple and changing memo from being something dead and dour into something living has been a fun challenge.
When you Pair MemoDecodePair() with MemoCopy(), MemoWriteToFile() and MemoReadFromFile() as a start you have a very exciting tool for importing, exporting, adding and extracting data from a unstructured format.
Have a look at the example and use your creativity and you will amaze yourself.
MemoExecDQL is the most used ExecDQL function simply because you can make your own editor form in an application where you store all your DQLs and then you transfere them to the form where they are needed via a simple lookup to a virtual memo field.
When it is looked up in the virtual memo field, you can simply execute it in the form via MemoExecDQL().
You can execute a DQL up to 64k in length this way.
Find out if the search string occurs in a Memo field.
Sound simple, is magic! This function will simply return the position in a memo of the first occurrence of a given search string.
The position information might not be so useful, but the fact that it is there is! This is in essence freetext search and you can use it to find out which record contain a certain text in a memo.
We use this in this help and we use it on our web to search articles etc.
Return the Memo value set with MemoSetGlobal() and set it into a local Memo Object.
Memos can't be queried the normal way due the the size, so all manipulation and moving around have to be done via Memo Objects.
MemoSetGlobal() will set the content of a local Memo into a Global Memory variable (named) and MemoGetGloba() will retrieve it and insert it into a local Memo fields object.
To find out the length (number of characters) in a Memo Field.
Can also be used to figure out if a Memo Field is Blank.
Insert, append, overwrite or delete the value of a Memo field with the content of another memo field.
In the new Memo class the essence is to be able to manipulate and "play" with memo fields in any way you like. We have MemoCopy() that works the same way as MemoMemoCopy() but it simply appends/copies a normal DataEase field rather than a memo.
MemoMemoCopy() allow you to move the information in Memofields around and merge them together.
To replace a tag in a memo with the content of another memo.
Memo manipulation in DE8 is much more tha simple manipulation of text. The Memo in question can be a HTML template, a invoice template, a report template etc. You can build the template with partly formatted code and partly with tags that will be replaced with content of columns and memos when you build the document.
You can for instance build a letter where you have "custom" headers, footers etc and simply replace the tags when you build the letter or you can build a custom made offer with full descriptions etc. from a library stored in the database.
To read the content of a text file into a Memo field. You can overwrite the existing Memo Field, Append the content of the file to it or insert the file content at the beginning of the Memo Field.
It is no secret that Import and Export possibilities has been somewhat "stumped" in DFW. In fact it hasn't bee technically so limited as our users seem to think, but for various reasons it has been perceived as much more limited than in DFD. This has mostly been down to niggling small bits that shut the functionality away from the users.
MemoReadFromFile() is simply a tool to read any formatted text into a Memo Field. This can be as an import/export feature in combination with MemoDecodePair(), part of processing in combination with MemoWriteToFile() - You build a text file instead of directly into a Memo Field and then read it back into DataEase via MemoReadFromFile(). It can be part of using HTML in your App... You decide!
In short this is simply a very flexible FileRead function that you can use for anything you like.
To replace all occurrences of a string in a Memo with another string.
Can be used to populate a template with the content of a table etc.
To copy the content of a local memo field into a global named variable where it can be retrieved later with MemoGetGlobal()
Memos can't be queried the normal way due the the size, so all manipulation and moving around have to be done via Memo Objects.
MemoSetGlobal() will set the content of a local Memo into a Global Memory variable (named) and MemoGetGloba() will retrieve it and insert it into a local Memo fields object.
To return the string between to search values inside a memo. It will return first occurrence it finds, so make sure you use unique values for both startvalue and end value.
It will return the value non-incluse of the search values.
Return the remainder of string from Search but not inclusive of search. Will return a maximum of 255 characters.
Return the beginning of Memo upto search but not inclusive of search. Will return a maximum of 255 characters.
Will return the number of words in a Memo field.
To write the content of a Memo to a text file. THe content will be written as is, so if the content is HTML you will create a HTML file (remember to use the right extension).
You can overwrite (mode:1), Append (Mode:0-Default) and delete a file with this function. It also include modes for appending with new line etc.
Moving an object (and all its children) from its current position to any new position. The function contains functionality to allow the object to be moved to an absolute position, a relative position or to be centred within the current window.
You can use this function to move a single object to a wanted position, or you can use it to move an entire Record Object, Tab Control or Subform to a centred or relative position.
To print the content of a text file as HTML via the built in HTML object. Will print the file as formatted HTML, but can be used to print normal text files as well. They will then be printed with the standard formatting of the HTML object.
Currently will only print to default printer (which can be changed via CDF) but will be changed to print to named printer.
Print the Content of a Memo as formatted HTML. Typical use is when you have used HTMLEditor to create a document stored in a Memo, you use this function to automatically print the content. You can use it anywhere including DQL etc.
All new DataEase 8 functions and functionality look after their own screen update and refresh. But sadly, not all historic "new" functionality do the same.
The combination of Tab Control and Subforms and simply advanced Tab Controls have a tendency not to Refresh correctly.
RefreshForm() will simply refresh the current Document according to the "virtual" data record that is valid.
It will no re-read data from the database, simply update the GUI controls with the current values they should display.
It will not change any data.
When RefreshForm() refresh the form without re-reading the data from the saved record, RefreshScreen() do the opposite i.e. replace the content of the visible form with the latest saved Data in the table.
This is used to display changes that is done by another process/user or done via ExecDQL directly on the PRISM columns/tables.
Function that will automatically refresh all status/info/system documents in DE8. You can now run this function and after you will be sure that all these info tables are up to date.
This is very useful if you use the Status Tables for programming or information purposes. We use the as basis for manipulation of data throughout the table, as well as input in UserMode based Editors etc.
Sending emails from anywhere inside a DataEase application. You can use it from a button, derivation, DQL or OML.
We have had a Email functionality included in DE8 since DE8.0 but it had one big limitation and that was that it couldn't use SMTP with TLS which in reality is most modern SMTP services.
Services like GMAIL etc will demand that you use TLS and so will most public SMTP services. We are therefore happy to include SenEmail (command line tool) in our distribution to improve the direct emailing functionality in DE8.
To change the color of an object during runtime. You can change font, fill and border color.
To move the cursor/focus to an object. This function will move the focus to any object that can take input/action. You can use this to control the tab order of your app depending on values inputted in fields etc.
This has been a focus long wished for as it will give you complete control on the input order of your form. Combine with SetState(Show/Hide/Enable/Disable and Clicked) to give the best user experience possible.
To change the text property on a Label, Button, Tab. This can be used for error message, further information, to store information in the page/form for future query, to change the label on a button or tab etc.
To Insert the content of a PRISM Memo into the EditControl of a MemoField in a form.
If you are running an ExecDQL that manipulate a memo and you then want to insert this memo into the active form (the form that called the Memo) you cannot use Modify Records in the DQL directly as this will render the Current record invalid doe to data being changed in another session, so you need to use the FORM control to populate the column.
SetMemoValue() is the bridge between a PRISM column (any) and the active Memo Edit Control on the form.
SetState is a function that will make it possible to manipulate objects from a derivation/DQL without having to use OML properties. SetState will hide/show, enable and disable.
Latest addition is ClickObject which will remotely call the click event on a button or any other object. Very useful for controlling execution.
In DataEase 8 manipulation is one of the new key elements. Pre 8, you had to use OML to manipulate or change DT properties in RT. In DataEase 8 we have introduced a number of new functions to give the developer the opportunity to change the appearance of the form based on runtime actions. SetColor() and SetState() being to key functions. SetColor() has the "drawback" that it basically change the colour of an object (Limited to Font,Fill,Border if applicable).
SetColor() is a great addition but as "web style" approach is what we are going for in DE8, it would be nice if one could change the style on objects the same way one can in HTML/CSS. This way the developer can simply change a style instead of finding the code where he changed the colour. You will also be able to change all the properties of an object in one small action.
When using SetColor() for for-instance mouse-over on a button, you will need to know the colours to change back to on mouse out etc, but with SetStyle you can simply have ButtonNormal and ButtonOver and toggle them with SetStyle().
Published: 23/02/15 - 10:00:00 (Amanda Higgins)
Related Articles
Some of you might be aware of it but it seems a lot isn't so it might be time to advertise a little the vast number of new functions and functionalities that has been added to DataEase 8.0 through 8.5. For a long time the only way new functions found the...
This is the first page of 3 where we recapitulate the Blog entries made by our development team through the development from pre 8.0 to 8.5. We have edited and updated the entries, but the appear in the order they were made and with the ideas, experienc...
This is the Second page of 3 where we recapitulate the Blog entries made by our development team through the development from pre 8.0 to 8.5. We have edited and updated the entries, but the appear in the order they were made and with the ideas, experien...
This is the third page of 3 where we recapitulate the Blog entries made by our development team through the development from pre 8.0 to 8.5. We have edited and updated the entries, but the appear in the order they were made and with the ideas, experienc...