If you have TPS files and you want to change the values in a defined set of records to something that can be determined from the record you are using, then you can use a process procedure. Select the ProcessWizard as the type of procedure, tell it what file you want to process, and in the TakeRecord method, put the code you want, like
if fil:ordertotal = 0 then fil:ordertotal = fil:pieces * fil:price.
That embed will be under the ProcessManger in local objects, and looks like this:
Having said that, your statement “Since Clarion 8 is TPS based, I assume I cannot run direct SQL” is not correct. A clarion8 program could be running against data stored in an any SQL database, or possibly a bunch of ISAM formats other than TPS. And if the data is in a SQL database, you can certainly use SQL.
If you have a lot of rows to process, then adding a STREAM before you start looping, and FLUSH afterwards will help with speed. LOGOUT/COMMIT (with a commit very few hundred rows) would too.
If you are using the Process template, then the template will handle the looping for you.
If you look at the code you will see something like:
ThisProcess.TakeRecord PROCEDURE
ReturnValue BYTE,AUTO
CODE
IF MCH:Units <= 0 then MCH:Units = 1.
ReturnValue = PARENT.TakeRecord()
PUT(Process:View)
IF ERRORCODE()
GlobalErrors.ThrowFile(Msg:PutFailed,'Process:View')
ThisWindow.Response = RequestCompleted
ReturnValue = Level:Fatal
END
RETURN ReturnValue
which will do what you want. Note that, if you don’t want to waste time writing back records that have not changed, you would use the ValidateRecord embed to filter out records that were fine. So in your simple case you would put in ValidateRecord
if mch:units <= 0 then return record:filtered.
and in the TakeRecord you would just have
MCH:units = 1
because you would only be getting the mch:units<= 0 at that point.
Also, when using Process template: If you add filter to the process, you should take into account that if you change a field that you have in your filter, the behavior is unpredictable.
I.e.
If filter says mch:units=0, changing mch:units=1 and then save may move the pointer outside the view.
So better use validaterecord in such cases.
No, Incorrect. You just need to select the ODBC driver in the dct and supply the appropriate connection string.
Then you can issue a {prop:SQL}=‘Update blah where blah’
This assumes your data in in an SQL server somewhere of course. If your data is in fact in a TPS file then all the above answers apply.
The IF ERRORCODE() THEN BREAK. should not be there. If any error or problem occurs Access:UBmch.Next() will return <> 0 and end the Loop, the ErrorCode() may not be set.
A Process Template will not Update unless you do as JonW showed and select that in the “Action for Process”. I prefer Not to do that. I would rather do as you suggested and use the ABC method to Update so it goes thru the same update code as a Form. In TakeRecord you would have your code:
!-- Take Record Embed
IF MCH:Units <= 0 THEN
MCH:Units = 1
Access:UBmch.Update() !or IF .TryUpdate()
END