View RSS Feed

Development Team Blog

The secret NewRecord command

Rate this Entry
A well known old trick in DataFlex is the Move 0 to Recnum trick. It's been used with character mode DataFlex and Visual DataFlex for so long that nobody probably remembers where it came from, and I'm not sure it was ever really a documented or intended feature in the beginning. Nonetheless it became a fully supported technique at some point.

Basically, if you ever wanted to create a new record loosely based on data from an existing record, you could use this trick to simplify code and save temporary variables. To create a new record you typically do a Clear MyTable, but by doing so you'll of course lose the existing values in the buffer (it's clearing the buffer). So instead of doing a Clear, you can simply Move 0 to Recnum, which clears out the reference to the existing record, so it effectively has to create a new record when saving, while leaving the rest of the buffer intact. Voila!

This technique turned out to be so common that even the SQL/CK drivers had to implement special code to support it in such a way that it worked the same as with the DataFlex database. Although use of DF_FILE_STATUS was considered the better approach for the SQL drivers.

Later on when RowID and non-recnum tables were introduced, this old technique could no longer be used. If you have a non-recnum table, there's no Recnum, and without that it's obviously a bit of a challenge to Move 0 to Recnum... Quickly it was suggested that you could use the DF_FILE_STATUS attribute instead, as it would work with non-recnum tables. It usually works with the SQL drivers and recnum-enabled tables as well.

The gotcha there was that setting DF_FILE_STATUS didn't always work as a proper replacement for the Move 0 to Recnum trick with the DataFlex database. You see, the DataFlex database has an old optimization strategy where it defers fetching all the fields after an indexed Find. Only the data present in the specified index is available in memory immediately after a Find. If you then touch the buffer, it fetches the whole record. So if you Move 0 to Recnum, it will first make sure the whole record is in memory. As you might guess, setting DF_FILE_STATUS doesn't do this extra check to fetch the whole record, so when you later saved, you ended up with missing data for parts of the record, which was not very good. Of course, you can still use Move 0 to Recnum with the DataFlex database, as it's always recnum-enabled. But if you need generic code that works across different databases and with non-recnum tables, that's not an ideal solution.

At first it was suggested that DF_FILE_STATUS should be changed to load the whole record in memory. As you might guess, DF_FILE_STATUS is also used in many other situations that have very little to do with the Move 0 to Recnum trick. And as often happens when changing existing generic code that's used in many different situations, to better suit a very specific situation, it wreaked havoc and we got all sorts of weird problem reports. Luckily this got caught very early on, and was never formally released.

So the solution then was to step back and formalize the whole Move 0 to Recnum trick into a new command. This new command now clearly separates the specific clone-record technique from any unrelated use of DF_FILE_STATUS, and also removes any confusion and sense of bad trick with the old Move 0 to Recnum technique.

This new command is aptly named, NewRecord, and it simply prepares for saving a new record, just like Clear, except it doesn't actually clear the record buffer. If you find it confusing, you can think of Clear as performing two separate operations. First preparing the buffer so that a subsequent SaveRecord will create a new record instead of modifying an existing one, and then clearing all columns in the record buffer. The NewRecord command essentially does the first part, but skips the second part. Obviously the NewRecord command also makes sure the whole record is in memory first, which it can safely do since its dedicated and exclusive use is for the clone-record technique (no compatibility issues with existing code).

You use it directly in place of Move 0 to Recnum, which means it's a straightforward and simple code change. The command was first introduced in Visual DataFlex 12.0, and it's the official replacement for the Move 0 to Recnum trick. It works with both recnum tables and non-recnum tables, with the DataFlex database and any other CK drivers.

Code:
...
//Move 0 to MyTable.Recnum
NewRecord MyTable
...
SaveRecord MyTable
You'll notice that you get proper syntax highlighting in the Studio for NewRecord, and it even assists with CodeSense and everything. The only trouble is, while it was carefully designed and implemented in VDF 12.0, it was apparently never documented... Well, if nothing else, it gave me a reason to write up this article.
Categories
Uncategorized

Comments

  1. Jakob Kruse's Avatar
    Keeping the good stuff secret eh? ;-) Well it's nice to have it out in the open!
  2. Gregg Finney's Avatar
    I believe that John 2E came up this around the 2.3 or 3.0 days. If I remember correctly he have a command called "Inactivate" or something like that. It was in one his 2E packages.

    Gregg Finney
    http://www.VisualDataFlexDeveloper.org
  3. Mark Rutherford's Avatar
    Committed to memory... now I will use that instead.
    Thanks!
  4. Garret Mott's Avatar
    Thanks for this!

    If I read you correctly, this is purely procedural & will therefore not use any DD validation. Is there a recommended way to do that? Write my own method?

    Inquiring minds...
  5. Clive Richmond's Avatar
    If anyone is looking to create a new record loosely based on the data from an existing local record buffer then this post has a couple of solutions.
  6. TBear's Avatar
    The method of using "Move 0 to "File".Recnum has in actually fact been around since the old procedural 2.2 days, perhaps even 2.1. I should know because I use to use it in the early 1980s. John 2E had nothing to do with it. Having said this, I was not told of this great little trick from anyone, but it was something I found quite by accident when trying to replicate already existing records and thinking that there must be a better/quicker way than clearing the buffer and then putting a whole lot of Move "data" to "File"."Field" lines in my programme. I can remember talking about this to another DataFlex programmer about 6 months or so later and he said he had been using it as well, but wasn't sure where he got the information from. He even showed me a programme of his to prove the point. So, in summary, it has been used by "enlightened" programmers since way back when and as far as I am able to tell, the reason how they found out about it was either by simple logic (that's how I found that it worked) or by word of mouth.