Simplicty and flexibility!

DE9 - New version and new Sample

Started by DataEase
You will need to Sign In to be able to comment on the Blog!

DE9 - New version and new Sample

Download Sample

In build#4391 we consider TabControl more or less finished and we have also implemented an Action to run ExecDQL directly from a Button or from the new ValueLoaded/ValueChanged event on Fields. The new Action event on fields are very exciting and now when you can combine it with direct DQL no less so ;-)

DQL Actions

DQL and from 8.x ExecDQL is the backbone that allow Dataease to move up and beyond. We promise that non of you have even started to see the power that DQL in the guise of Execdql will wield in DE9.

The time to completly reveal this is not yet upon us but we can spend a little time on something that in many ways was the resaon we started on

ExecDQL in 8.

The fact that one want to execute a simple DQL to do some updating, deleting of entering of data withou having to run a heavy report document.

It started with ExecDQL() function where you could run a DQL directly in the function but it was awkward because of "" needed in DQL and also to encapsulate the same DQL. 

You ended up with execdql(concat("define ",chr(34),"myvar",chr(34)," text ." etc... easy to lose control. Yes, yes we fixed all these problems as we went along with Escaping /' meaning " etc. but then there was the problem that the DQL couldn't be longer than 255. That was fixed with MemoExecDQL() and when the

problem was that you had to store the DQL in one table and look them up etc, we fixed that by adding LabelExecDQL() and in DE9 you even have anylookup() so you can read and execute the DQL in one function without having to lookup the DQL into a memo and creating a relationship etc.

But AnyLookup() was never properly released before we had already taken it one further and made ExecDQL("@DQLName") which will allow you to run a DQL store in the DQLStore directly...


We will get back to all of this as we progress to the release program but today it was all about a small rectification of something that should have been there long ago.

TabControl and Event Styling

You might have seen it - event styling in DE9 - but not really seen its potential. 

Have a look in on the TabControl document in the sample and you will star to get it. In DE9 we have added a secondary styling sheet with the same name as the .STY file used but with the extension .SUB.

The format is like an INI file (and there is plenty of functions in DEOS that allow you to manipulate this kind of file but that is for another day). It might be easier to simply edit it in Notepad for now.

The Sub file control what we call event styles i.e. styles that are not there from the beginning but are there as part of some event or logic.

The simplest one is the Zebra subform style. and you can see it in the .SUB file in TabControl called ZebraStyle.

But first a little about the logic of eventstyles:

You can define alternative/event styles for:

Another style ex. The style MyStyle

Now the style MyStyle.Hover wil be used every time someone hover over an object that is styled with MyStyle. For all other events object styled with this Style will resort to a less domineering definition or if nothing is defined on any level, no event style at all.

This is the most dominant form of styling.

Next is alternative/event styles for a object class.
HoverStyle=MyEdit.Hover (.domination is used to class styles and they will be sorted under the "first name" in the style list but they are fully functional and independent styles).

If you define this all EDIT_FIELD objects i.e. normal fields will get this hover style if they don't use a style as above.

This is the fallback style used for all objects that doesn't have dedicated styling attached to them. so if you simply want a hover, focused, negative etc. style for your entire application you simply define it here and you have a very potent effect for minimum work.

This logic is based on styles that is defined for each object-class so if the style doesn't exist in the .STY file nothing will happen.

 Have a go, more to follow on this.

StringFind and how to unwind big text 

In DE9 we have broken down the barriers between memo and text completely.

All String functions will now handle up to 4GB large text, so what you used to be able to do on a text field you can now do on a large text.

This will demand slightly different behavior.

StringFind has now been amended so you can use it to find the first occurrence of a sub-string but with the big difference that you can start anywhere

in a string.

StringFind("Hello World in the world", "world", 0, "exact") return 19

StringFind("Hello World in the world", "world", 0, "count") returns 2

StringFind("Hello World in the world", "Mars", 0, "count") return 0

If you don't specify keyword it will find the first occurence and return the start position. you can then use this position +the length of what you searched for as the new start position until you have unwound the entire large text (memo).

When you don't get a hit you will get -1.

To cut out the text you want, simply use the good old and trusted midc() that now also handled 4GB return value

Midc(MyMemo,1,400000) ex will work fine.

On the button Split Memo by line we have the following DQL:

define "retval" text 255.

define "vMemo" memo .

define "start" number .

define "stop" number .

define "linelength" number .

retval := recordsave() .

delete records in SomeData with ID=getvalue("ID") .

vMemo := getvalue("MyMemo") .

while StringFind(vMemo,chr(13),start) not = -1 do

stop :=StringFind(vMemo,chr(13),start) .

linelength := stop - start+1 .

retval := stringReplace(midc(vMemo,start,linelength),chr(10),"") .

enter a record in SomeData

ID := getvalue("ID") ;

Start := temp Start ;

Stop := temp Stop ;

SomeText := retval .

start := stop+2 .

Retval := blank .

message retval .


stop := length(vMemo) .

if start <stop then

linelength := stop - start .

retval := stringReplace(midc(vMemo,start,linelength),chr(10),"") .

enter a record in SomeData

ID := getvalue("ID") ;

Start := temp Start ;

Stop := temp Stop ;

SomeText := retval .


retval := refreshscreen() .

If you take a closer look there is plenty of new and exciting stuff in this DQL alone.

As and afterthought
We haven't told you on how RecordDelete() action/function work in forms in DE9...

RecordDelete has been changed, now the placement will decided default behaviour.

As you might now the Dataease for WIndows document is built up of sections where you start with the MainForm and MainRecord and then you can have a subform and subrecords 1 to 99.

In DE9 we have taken advantage of this and "fixed" RecordDelete - which to be honest has been a pain in the backside so it will delete from where it is placed and downwards  - no question asked. In DE9 we have removed almost all nagging dialogues that ask you if you really want to do something and added plenty of ways for you to control what is going to happen. Default functionality that take over and try to control your application make it less user friendly and less yours. If you like all these nagging dialogues you simply need to add that functionality yourself.

But this was about how RecordDelete work now. 

If you add it to a subform record see above. It will delete and update the subform immediately so the row will be gone immediately and you can keep on deleting single rows as you please. If you add the delete button to the SubFOrm form object it will delete all visible rows and update and finally if you add it to the main Record it will delte the main record and everything in all subforms that belong to that main record.

SetCurrent and GetCurrent("DeveloperVersion")

This might be a problem mostly for us at the moment but it might soon be a problem for you.

DE9 like DE8 before it will not be a "frozen" product. We are adding new features all the time and we will keep doing that for the forseable furture which make it

imperative to be able to check if your customer have the correct version to run your application.

We have looked into hardcoding this and to certain extend that will be done but only with significant upgrades.

DE9 is made in DE9 so we face the same challenge as you will if we started to block running an app in a DE9 that is too old, it is better to allow it to be started

and then warn about the probem and offer to upgrade simply because that handling can be done by programming in DE9 so you can guide your

user rather than simply tell him that he/she is "outversioned"


Your application will automatically be updated to the highest version of DE9 that has maintained it. So if you have been developing in DE9.0.0.1000 for instance

and then download our latest version lets say and open the application in it, the develper version will then be set to 2000.

But lets say that 2000 was a rotten beta and you can't use it you can use SetCurrent("DeveloperVersion") to "downgrade" your application so users won't get

a warning etc.

You simply execute the function SetCurrent("DeveloperVersion") this function does will only set the CURRENT version from the DE9 that execute it.

Finally we will just a little about Renaming of App.

A problem throughout DE8 after we introduced the Recent list was that as a developer you might have many copies of the same application.

Which is which?

In DE9 we have fixed this problem by simply allow you to rename the tile in the list. (See to the right)

but sometimes you also want to rename the application and we haven't implemeted that in the

GUI/Welcome app yet.

So what do you do?

In DE9 the goal is to hand all the power to the developer which means we take it out of the "fixed" GUI where

fuctions has been stuck for over 30 years and made it into functions anybody and everybody can use.

The function for rename an application is now part of the vast if not yet completely exhaustive

DEOS library (DataEase Operating System).

@RenameAppStringLet you rename an application of any version (4.53DOS-8.5Win) by parameters:

- Path

- Old name

- New name

Return nothing if rename is done and the reason for not renaming if there was an error.

Action Script on button:

alert(concat(DEOS("@RenameApp",Application Path,Current Application Name,New Applicaton Name),DEOS("@AppIniSet","INTERFACE","ApplicationCaption",concat("DataEase: ",New Applicaton Name))))

Since DE8 the caption on an application has been editable - not many that has realised - so when you change the name of an application you also need to change the caption. An even better idea is that you change the caption to something much better for your application.

Written by DataEase 06/12/19 at 14:36:26 DataEase 9 Developer

Re:DE9 - New version and new Sample

seems to be complicated programming tool in comparison to DFD DQL clever query language AI builder of Arun Gupta pi(half)-code... does that mean the new DE 9 is not in the modern trend of artificial intelligence epoch ?

Written by Ihor Zakharchenko 03/01/20 at 17:14:43 DataEase 9 Developer

Re:Re:DE9 - New version and new Sample

Hi Ihor. 
One thing does not exclude another. 
Improvement is not a linear event.

Moving Dataease forward is both big improvements like new editors/web server/JSON API/Full Email implication etc.

But it is also small improvements that help users maintaining existing code/applications.

ExecDQL was implemented as a more efficient way to execute DQL code than the hopeless way it was done in DFW. But obviously executing DQL code as a function leave the problem with writing and storing this code.

DQL is everything from a simple command like:

delete records in mytable . to long scripts that agreegate and process complex data.

In DE9 and DE9 Web DQL is the solution to "everything". There is no better tool to generate a dynamic web page which demand that you have both a good editor for writing the script and for making the body (html).

ExecDQL on an Action is the opposite of this. it is for simple scripts like the one above.

We don't come up with these ideas from some cheat sheet, these are practical and consistent functionality developed to help developers that actually develop exstensively in DE9 on a dayly basis and identify shortcomings that we quickly improve with little cost and it does not detract our developers from the main goals.

DQL is not a sacred grail but a simple and efficient language that should not be constrained like it has both in DFD! and DFW.

In DE8 we let it free and in DE9 it is "everything" so this is not HOW you will use DQL in DE9 but just one small addition where you can use DQL to do a job in a simple way.

Written by DataEase 22/01/20 at 11:21:31 DataEase 9 Developer