Simplicty and flexibility!


Started by Simon B
You will need to Sign In to be able to add or comment on the forum!


Experimenting with this new function in  a dql but unable to even get it to complile let alone run.  he format is taking directly from the website 'help' for MemoReadFromFile.

I've clearly got it in the wrong context but the help just tells me what the command does and how to format IT.

So using a table called order_raw_data, what is wrong with the following DQL (This is not a valid token in this position):

for order_raw_data ;
MemoReadFromFile (orderemail,"J:\dataease\_testmemo\folder4orders\smb.txt",0) .

Tried it on a button in a table to see if that worked:

BUTTON ON TABLE (does nothing)

Execute function/derivation

MemoReadFromFile (orderemail,"J:\dataease\_testmemo\folder4orders\smb.txt",0) .


Written by Simon B 11/03/15 at 10:33:27 Dataease [{8}]FIVE


1. THis is a prism function so it will update the Column in the Form not the GUI object, so it will actually read into the Column without you seeing it. This is intention as the same function is being used in DQL's etc, and all the GUI updating will slow it down. So if you want to see the result in the form, simply add RefreshForm() at the end of the script.

2. MemoReadFromFile() is a function, and you can't call a function directly in a DQL. A function need to be used as a parameter, or being allocated to something. So you can't do:

for order_raw_data ;

MemoReadFromFile (orderemail,"J:\dataease\_testmemo\folder4orders\smb.txt",0) .

but you can do 

for order_raw_data ;

List records

MemoReadFromFile (orderemail,"J:\dataease\_testmemo\folder4orders\smb.txt",0) .


because you can list a function or a derivation as a function is something that return something. Just executing a function in the middle of a DQL wouldn't make any sense (would now of course, with the manipulation functions, but as this is historic you need to follow the rules).

the best way to do it though it simply

define "retval" text .
for order_raw_data ;

Retval := MemoReadFromFile (orderemail,"J:\dataease\_testmemo\folder4orders\smb.txt",0) .

But then again this too wouldn't make any sense as what you do is to read the file into the memo(column) orderemail which we must assume is part of order_raw_data.

So what do you want to do with it.

You can now list it, or modify it or enter it etc.

BUTTON ON TABLE (does nothing)

Execute function/derivation

MemoReadFromFile (orderemail,"J:\dataease\_testmemo\folder4orders\smb.txt",0)+RefreshForm() .

Written by DataEase 11/03/15 at 12:12:11 Dataease [{8}]FIVE


Thank you.

I keep getting caught out by this 'column function not gui function'.  I'm used to dataease showing what i've done when i do it.  I understand why you're approaching it this way but i wish it was made clearer for people like me used to how it's always worked lol, at least in 'Returns/Result' say that this is a column function not gui function..

Just an observation but feel free to ignore the following, I just get confused by programmers talking about their internal engine as if it means something to me:

I've seen 'a prism function' said many times now but it doesn't really have any context to developers (or is that just me? lol), I use forms, tables, dql's, GUI's, but never prism.  Prism is the engine of dataease that makes everything work, it's the programmers inside world, so means nothing to me as a developer when it's mentioned, it's just the bit that makes dataease work and i can never see inside prism or edit it or recode it.

What I was trying to do with the dql:

One of our customers intends to email orders over in a fixed format.

I wanted to save this as a text file in a folder.

Then use dataease to import this file into a memo field (I could then pull out of it into other fields details like who ordered it, what they want etc).

On a button this works now i've included refresh (thank you), experiment successful :-D

We expect to get 40 - 50 emails per week, each from different people, ordering specific stock lines, so the next stage was to try 2 orders (2 files) in the folder.

Then using a DQL for loop import file 1 to memo field and save as new record 1, then import file 2 to memo field and save as new record 2 etc.

Each file is a fixed format so I hoped to store the file name to import in a field and use a for loop to update the next file name and import it into a new record until all files and contents had been imported.

As I can't use these new functions in DQLs  this is a no go and so i'll have a look at good old DQL and see if i can make import work in some way.

I'm confusing all these new functions with DQLs, i need to seperate these in my head and remember new functions can not be used in DQL's and only ever on buttons.

Written by Simon B 11/03/15 at 14:33:29 Dataease [{8}]FIVE


You can use all of these functions in DQL and anywhere in DataEase. That is the "point" of using the function format for new functionality.

Where commands can only be used in DQL, a function can be used in Derivation/Validation/DQL/OML i.e. everywhere where you can add code.

You only need to use it within the rules for using a function which is that when used in a Script i.e. OML/DQL you need to allocate it to something or use it as an argument/parameter in another function.

so you simply need to allocate it to a variable if you want to use it outside List Records in a DQL.

define "retval" text .

For etc...

retval := MemoReadFromFile(etc.

What you also need to remember is that Memo functions are manipulation functions so the Memo you use in the function need to be local to the function.

"Just an observation but feel free to ignore the following, I just get confused by programmers talking about their internal engine as if it means something to me:"

You are of course completely right but here you have to take into consideration that DataEase 8 started in the deep abyss of DFW 7 and is clawing its way back to humanity. The primary goal was to improve the functionality for existing users rather than aim all the way to the "holy grail" of DataEaseness - Ease!

I doubt that DE8 will ever become the next DataEase in the terms of a product that new users will embrace with gusto like DFD. It will be a tool for existing DataEase users and users with DataEase knowledge, but that doesn't mean that we can't make it more intuitive and lower the threshold for the users.

We will, and we are... ;-)

Written by DataEase 16/03/15 at 20:36:28 Dataease [{8}]FIVE

MemoWriteToFile(),MemoReadFromFile(),MemoStringFrom(), MemoStringBetween() sample

Download Sample

Seeing is believing, so please find attached a sample that showcase what you are looking for.

In this sample we write the content of a table with HTMLdocuments and strucured info to a document pr. record, then we read it back into another table and finally we process the memo and insert the results into a third table so it is exactly the same as the original.

Quite meaningless and a simple export/import would be much easier...but we are trying to show the flexibility and possibilities in combining all these functions.

Have a look and enjoy.

1. DocumentGenerator.

define "retval" text .

define "filename" text 200 .

for DocumentGenerator ;

filename := concat(GetCurrent("AppPath"),"\docs\",DocID,".txt") . -- generate filename

retval := WriteToFile(concat("DocID: ",DocID," /DocID"),filename,1) .-- write the value of DocID with enclosing tags.

retval := WriteToFile(concat("Date: ", Date," /Date"),filename,4) . -- same for date.

retval := WriteToFile(concat("CustomerName: ", CustomerName," /CustomerName"),filename,4) . etc..

retval := WriteToFile(concat("Heading: ", Heading,"/Heading"),filename,4) . etc.

retval := WriteToFile("Body: ",filename,4) .-- here we add the tag for body start.

retval := MemoWriteToFile(Body,filename,4) . --append body to file.


retval := ExecDQL("Delete records in DocumentReadback . delete records in DocumentProcessed. ") . -- just clean up the app.

retval := DocumentOpen("DocumentReadback") . -- open the next document in the chain.

2. Documentreadback

define "retval" text .

define "fileNr" numeric string 5 .

define "filename" text 200 .

fileNr := data-entry field1 .

while FileNr <=data-entry field2 do

filename := concat(GetCurrent("AppPath"),"\docs\",FileNr,".txt") .

if FileExists(FileName)=1 then -- check if the file exists, if it does we continue

enter a record in DocumentReadback -- create a new entry in DocumentReadback

dummy := MemoReadFromFile(Body,filename,1) . -- simpy reads the contents of the text file into the memo


FileNr := FileNr + 1 .


retval := RecordFirst() . -- show the first record we have read back.

3. Process the data we have read and insert them into DocumentProcessed

define "retval" text .

for DocumentReadBack with Processed = Not Processed ;

enter a record in DocumentProcessed

Dummy := MemoStringBetween(Body,DocumentReadBack Body,"DocID:","/DocID"); -- Read aut the string between DocID: and /DocID (case sensitive!!) Dummy is necessary to have a field to allocate to inside the Enter a Record (scope, could simply have used DocID but it would confuse you... any field would do)

DocID := Body ; -- copy the content of Body (memo) to DocID (only 255 will be copied, but that is all we need, MemoStringBetween is a memo function and will need a Destination Memo. We will change it to return 255 directly.)

Dummy := MemoStringBetween(Body,DocumentReadBack Body,"Date:","/Date") ; -- Same for date etc.

Date := Body ;

Dummy := MemoStringBetween(Body,DocumentReadBack Body,"Heading:","/Heading") ;

Heading := Body ;

Dummy := MemoStringBetween(Body,DocumentReadBack Body,"CustomerName:","/CustomerName") ;

CustomerName := Body ;

Dummy := MemoStringFrom(Body,DocumentReadBack Body,"Body:") . -- here we simply copy the remainder of the memo to Body.

modify records

Processed := Processed .


retval := DocumentOpen("DocumentProcessed") .


Written by DataEase 20/03/15 at 10:34:53 Dataease [{8}]FIVE

Re:MemoWriteToFile(),MemoReadFromFile(),MemoStringFrom(), MemoStringBetween() sample

Got some time to sit down to look at this example.  Can't say much more than wow! ... Simple small scripts doing some clever stuff here, ans showing how to use functions to do the type of thing I'm looking for.

Also showing off other things that i've read but not got to grips with yet, like running DQLs stored in labels, auto naming/importing files using a counter changing next file name, file paths being auto created etc.  

Rather taken back with this example, this for me is the best example i've seen and shows off a number of different new features and done very simply with little required and simple DQLs.

Thank you! :-)  This is a million miles away from 7.2, you've shut me up with this and I don't know what to say (yes I can hear you cheering lol).

Written by Simon B 23/03/15 at 12:13:11 Dataease [{8}]FIVE

Re:Re:MemoWriteToFile(),MemoReadFromFile(),MemoStringFrom(), MemoStringBetween() sample

We are glad that you are getting a glimpse  of the sunny side of the DE8 coin.

It is the biggest challenge for DE8 that it is deceptively similar to previous versions of DFW, when in reality it is a completely different beast altogether.


Written by DataEase 25/03/15 at 14:21:47 Dataease [{8}]FIVE