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 ;-)