NetTalk Central

Author Topic: A different way to capture a new record  (Read 11964 times)

terryd

  • Hero Member
  • *****
  • Posts: 759
    • View Profile
    • Davcomm
    • Email
A different way to capture a new record
« on: June 29, 2013, 03:47:46 AM »
Most of us have run into the problem of part captured records caused by users cancelling a record which  was auto incremented or moving off a capture screen whilst in the middle of entering a record or browsing to another website, or many other reasons.
I am sure that some other developers are doing what I am going to suggest but it may help those, like myself who have been previously using a standard capture of displaying the table values on the screen and capturing direct to the table.
What I suggest is capturing to a memory form
So from the menu I call the netwebform directly, something like Create a new Policy.
On the Netwebform setting I set the form source to Memory and the URL on Save and on Cancel to 'index'htm' On the layout field I check Include Save/Close Button and Include Cancel button.

I add the table I am going to update and tables I am going  use as lookups to Data/Tables Other files
In local data I create a group eg. LocalPolicy with a prefix of LOCPOL (you choose your own obviously)
I then Insert all the fields from the table I am going to finally populate that I will need to capture to. I don't need fields like autonumber or primary ids since I will set them later.
I can leave out any field which is not a direct capture (i.e. capture date, captured by et.al.)
I then populate the tabs and fields that I require. I have found that if my capture fields can be grouped by function that using the wizard form style works well since the user can only save once on the last tab.

NOTE: Remember by default a memory form is in change mode, not insert. It's not a problem here and it can be amended but keep this in mind when selecting embed points.


When all the fields are complete
I put code in the following embed points
I create a Procedure routine called ClearLocalPolicy. In it for each of my local variables in the LocalPolicyGroup I zero the values
ClearLocalPolicy ROUTINE
    CLEAR(LocalPolicy)
     p_web.SetSessionValue('LOC:PolicyNumber',LOC:PolicyNumber)
     or
     p_web.SetSessionValue('LOC:PolicyNumber','')
Exit    

I do this because the LocalVariables will persist. If I come into this procedure again all the values I previously entered will redisplay.

In Routines\CancelForm\1 Start I add DO ClearLocalPolicy
In Routines\PostUpdate\1 Start
access:policy.Open() !because at this point the Policy file is closed
access:policy.Usefile()
CLEAR(Policy) !not necessary but i'm old fashioned
I then put each of the fields in the file in the embed
e.g.
POL:SalesType = p_web.GSV('LOC:SalesType') !this is a value captured in the procedure
POL:CaptureDate = today()                  !this is a date which I don't capture but calculate now
I have converted to Bruce's suggestion of created my own guids so:-
POL:PolicyID = ''
LOOP x# = 1 TO 16
   POL:PolicyID = CLIP(POL:PolicyID) & chr(random(97,122)) ! creates a 16 lower case alphabetic guid
END

Or If you are auto incrementing  use access:policy.Insert() at he end of placing a value against each field in the file
If you are not autoincrementing you can either
add(policy)
or
access:policy.Insert()
DO ClearLocalPolicy - Clears the variables so when this users add a new policy the fields are all blank
Remember to then close the file
access:policy.Close()

And that's it.
This has taken a lot of pain out of having to periodically go through tables clearing out partially captured records which may have autoincremented numbers where you have to explain to a client (as I do) why records 1,2 3 and 5 are in the table but not 4

NOTE:
I first tried to find a place where I could call the ClearLocalPolicy routine at the beginning of the procedure before doing anything but almost every embed is called more than once. My eureka moment was to think that as long as I cleared the values when leaving the form then the next time I came in the values would be blank. Please note my eureka moments are not as earthshaking as Archimedes but they're mine.

To quote someone familiar to all of us' This ain't rocket sceince'

Any comments, suggestions or improvements on this process would be appreciated.
But be gentle ;-)
« Last Edit: June 30, 2013, 07:22:31 AM by terryd »
Terry Davidson
Windows 10 64 bit/Windows7 64bit
Clarion 9.1.11529/Clarion10 12567
Nettalk 913
Nettalk 1015
StringTheory267/Winevent515/XFiles298/MessageBox239/Cryptonite186

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: A different way to capture a new record
« Reply #1 on: July 01, 2013, 07:54:17 AM »
that's a big block of code, so I'm only looking at it in pieces, but this bit caught my eye;

POL:PolicyID = ''
LOOP x# = 1 TO 16
   POL:PolicyID = CLIP(POL:PolicyID) & chr(random(97,122)) ! creates a 16 lower case alphabetic guid
END


I'd change this to

POL:PolicyID = st.Random(16,st:Lower + st:Number)

It's shorter, and also uses a bigger alphabet.

Actually what I do in my apps is make a very simple, Clarion Source procedure called GetGuid() which returns the above line. Then I can call that from anywhere in the app (including global file manager embed points.) I _think_ (but have not yet tested) that you can even then prime the value in the Dictionary. And the bonus is that if I decide to change how the guid is made, I only have to do it in one place.

Cheers
Bruce

Rene Simons

  • Hero Member
  • *****
  • Posts: 650
    • View Profile
Re: A different way to capture a new record
« Reply #2 on: July 01, 2013, 11:00:56 PM »
Hi,

Priming in the dictionary as Bruce describes works fine.

Some additional info:
I have added a parameter to my  GetGuid()  procedure which passes the length of the random string I want. The default is set to 16 when I pass no parameter.
When I do pass a value it can be from 1 up to 48 .

I also have added the st.upper to the second parameter. it gives me 47672401706823533450263330816 different outcomes ;D when I ask for 16 characters .

Rene
Rene Simons
NT14.14

terryd

  • Hero Member
  • *****
  • Posts: 759
    • View Profile
    • Davcomm
    • Email
Re: A different way to capture a new record
« Reply #3 on: July 02, 2013, 01:36:07 AM »
Thanks Bruce and Rene.
Bruce yep much better system I'll convert my apps to use that.
I actually took my code from a thread between you and CaseyR.
Interesting Rene. Not sure if I'll ever need a variable size as large as that but something for me to keep in mind.

I have also found that in the ClearLocalPolicy routine I have had to add this since if the form is saved (not cancelled) the values come back restored from the GetValue rather than the GetSessionValue

ClearLocalPolicy ROUTINE
    CLEAR(LocalPolicy) ! my Local variables Group
     p_web.SetSessionValue('LOC:PolicyNumber',LOC:PolicyNumber)
     p_web.SetValue('LOC:PolicyNumber',LOC:PolicyNumber)
     or
     p_web.SetSessionValue('LOC:PolicyNumber','')
    p_web.SetValue('LOC:PolicyNumber','')
Exit   
Terry Davidson
Windows 10 64 bit/Windows7 64bit
Clarion 9.1.11529/Clarion10 12567
Nettalk 913
Nettalk 1015
StringTheory267/Winevent515/XFiles298/MessageBox239/Cryptonite186

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: A different way to capture a new record
« Reply #4 on: July 02, 2013, 01:41:25 AM »
>> I also have added the st.upper to the second parameter.

This bring case-sensitivity into play though. In other words;
abcde <> ABCDE.

Now of course as long as the key is marked as "case sensitive" then this is no problem. But when you move to SQL case sensitivity is one of those "grey areas" - and it's not always something you have control over. So I use just the upper, or lower case characters, plus the digits.
That allows for 36 ^ 16 possible combinations.
that's 7 958 661 109 946 400 884 391 936
ie 7 958 661 109 946 trillion.
(and remember they only actually have to be unique with a single table.)

cheers
Bruce

Rene Simons

  • Hero Member
  • *****
  • Posts: 650
    • View Profile
Re: A different way to capture a new record
« Reply #5 on: July 02, 2013, 02:36:22 AM »
Hi,

@Bruce : The SQL "grey area" is a good point you make here.
Luckily I only have to change the code in one place now <g>.
And almost 8 gazillion is also an awfull lot.

Rene
Rene Simons
NT14.14

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: A different way to capture a new record
« Reply #6 on: July 02, 2013, 10:16:00 PM »
>> And almost 8 gazillion is also an awfull lot.

yeah I think we're safe, especially for that list of departments with like 5 records in it.... :)

Cheers
Bruce

terryd

  • Hero Member
  • *****
  • Posts: 759
    • View Profile
    • Davcomm
    • Email
Re: A different way to capture a new record
« Reply #7 on: July 03, 2013, 01:29:37 AM »
Nettalk 710 String Theory 189

Bruce I added a local string theory object to the procedure called st and get the following error message

Cannot call procedure as function - C:\ins\Data\cwprog\Clarion8NT7\Finrite\EdconDirect\EdconDirect016.clw:7168,28

referring to this line
  POL:PolicyID = st.Random(16,st:Lower + st:Number)
Terry Davidson
Windows 10 64 bit/Windows7 64bit
Clarion 9.1.11529/Clarion10 12567
Nettalk 913
Nettalk 1015
StringTheory267/Winevent515/XFiles298/MessageBox239/Cryptonite186

peterH

  • Sr. Member
  • ****
  • Posts: 413
    • View Profile
Re: A different way to capture a new record
« Reply #8 on: July 03, 2013, 01:52:43 AM »
Do this instead:

st.Random(16,st:Lower + st:Number)
POL:PolicyID = st.GetValue()

Peter

Update: hmm, seems like i completely missed the point  :-\
« Last Edit: July 03, 2013, 11:59:44 PM by peterH »

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: A different way to capture a new record
« Reply #9 on: July 03, 2013, 08:49:31 AM »
>> String Theory 1.89

need I say more?

terryd

  • Hero Member
  • *****
  • Posts: 759
    • View Profile
    • Davcomm
    • Email
Re: A different way to capture a new record
« Reply #10 on: July 03, 2013, 10:13:20 PM »
I am suitably chastened.
As far as the guid creation is concerned I have done the following. Could you please critique.

I have created a source procedure called CreateGUID
parameters (String p_Blank), String
and declare globally

Inside the procedure I have added the stringtheory local local object with object name st

Created a local variable NewGUID string(16)

Inside processed code
  NewGUID = st.Random(16,st:Lower + st:Number)
  RETURN NewGUID

I use this from the priming tab on the calling netwebform
e.g
setfield: POLHIST:PolicyHistoryID
as: CreateGUID('')
From a usage point of view
1. I only have to change my GUID creation code in one place
2. I don't have to add the StringTheory local object to every procedure where I want to create a guid 
Terry Davidson
Windows 10 64 bit/Windows7 64bit
Clarion 9.1.11529/Clarion10 12567
Nettalk 913
Nettalk 1015
StringTheory267/Winevent515/XFiles298/MessageBox239/Cryptonite186

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: A different way to capture a new record
« Reply #11 on: July 03, 2013, 11:12:23 PM »
>> From a usage point of view
>> 1. I only have to change my GUID creation code in one place
>> 2. I don't have to add the StringTheory local object to every procedure where I want to create a guid 

Absolutely - 100%.

2 comments on the function ;

a) what's the incoming parameter used for?

b) you don't need the newGuid variable. The one-line in the function need only be;

Return st.Random(16,st:Lower + st:Number)

(aside: It makes me think that a simple p_web method might actually be useful here - that would have the benefit of being "universally available" - but of course would only apply to web apps. Your function can be called in windows apps as well, which means it's much more of an all-round solution. )

Cheers
Bruce

terryd

  • Hero Member
  • *****
  • Posts: 759
    • View Profile
    • Davcomm
    • Email
Re: A different way to capture a new record
« Reply #12 on: July 04, 2013, 01:39:55 AM »
Changed
Sure is nice to do this in one place.
Terry Davidson
Windows 10 64 bit/Windows7 64bit
Clarion 9.1.11529/Clarion10 12567
Nettalk 913
Nettalk 1015
StringTheory267/Winevent515/XFiles298/MessageBox239/Cryptonite186