Auto increment primary id when handcoding

I am testing how to add records to a table using handcoding.

Adding a record with the add command works fine. But it seems I have to handcode the autoincrement id field for the primary key.

What is the best way of doing this?
Is it driver dependent?

At the moment I am working with tps files.

Werner

Is this hand code inside an APP or a CwProj?
If APP is it ABC or Legacy?
if ABC do you want to use ABC classes or just Clarion?
What File Driver?

1 Like

This is what I do for a TPS file, not threaded, open for the lifetime of an ABC app with true threading. It logs OutputDebugStringA based on a command line string.

Global Embeds: Program Setup

IF CLF:LogToDebugOutput

    IF NOT Exists(GFP:DebugOutputFile)
        Create(DebugOutput)
        IF ErrorCode()
            Halt(0,'Exit Code : ' & ErrorCode() )
        End
    End

    Open(DebugOutput,12H)
    IF ErrorCode()
        Message('ErrorCode 12:' & ErrorCode() )
    End

    Stream(DebugOutput)
    Set(DebugOutput)
    Previous(DebugOutput)

    Glo:DebugOutputID = DbgO:RecordID

End

Global Embeds: Program End

IF CLF:LogToDebugOutput

    Flush(DebugOutput)
    Close(DebugOutput)

End

DebugView procedure

    IF CLF:LogToDebugOutput

        GLO:DebugOutputID  += 1
        DbgO:RecordID       = GLO:DebugOutputID
        DbgO:Date           = Today()
        DbgO:Time           = Clock()
        DbgO:DebugString    = pCstring
        Add(DebugOutput)

    End

TPS File def.

DebugOutput          FILE,DRIVER('TOPSPEED'),NAME(GFP:DebugOutputFile),PRE(DbgO),CREATE,BINDABLE
RecordIDPK               KEY(DbgO:RecordID),NOCASE,OPT,PRIMARY
Record                   RECORD,PRE()
RecordID                    ULONG
Date                        LONG
Time                        LONG
DebugString                 CSTRING(2048)
                         END
                     END                       

I needed this to be as streamlined and efficient as possible to not slow up the app and I dont think I’ll get it any more streamlined, but this shows how autoincrementing is done on the primary key.

When the app is called with the /DebugOutput command line flag, the above code kicks in.

assuming tps (if SQL you probably will get the backend to allocate the key value).

if using ABC then the insert() method does it all for you.

if using a straight Clarion add() then set/previous to get current max value and then add one to get the next id in the sequence. If multiple sessions are adding at the same time you may need to do this code in a loop in case you get duplicate key error on the add.

I haven’t looked in years but the Clarion legacy templates insert a “place holder” record that is then updated when the user saves the new record (or is deleted if the user cancels).

When you say “hand code” I assume you mean you want to add a record using hand code in an app that uses the templates?

If you’re using the ABC templates then there are built-in functions that allow you to do it, priming and not priming other fields and cancelling the auto-in if you want.

Have a look in the help for PrimeRecord, Filemanager class, it has a good example. Note PrimeRecord also does the Auto-inc, so you don’t need to use the PrimeAutoInc method.

I guess calling it handcoding is not quite correct in this context. What I did was to create a very simple application with a dictionary with only one table for testing purposes.

As you can see I made a test button and put in some code in the accepted embed point . I had not included the file manager class in the project, but with your suggestions and a little help from copilot I ended with the following code which works quite well:

=============================================

Access:Navn.PrimeRecord
Access:Navn.PrimeAutoInc

! Navn.Id is the primary field with autoincrement

Navn.Fornavn='Werner'
Navn.Etternavn='Lekven'
Navn.Email='[email protected]'
Navn.Mobil=90677627

Access:Navn.Insert()
    If ERRORCODE()
      Message('Error when adding record : ' & error()) 
      else | 
      Message('New record added with  id: ' & Navn.id)
   end

===================================================

Thanks for your help!

PS. I do not know why my last part of this post in is in bold and bigger font :wink:

[Edit: Werner I have now applied Clarion code formatting. cheers Geoff R]

IF NOT Access:MyFilename.Insert() = Level:Benign
MyError = Access:MyFilename.GetError()
End

ErrorCode() wont always return the right error, you need to use GetError() to get the Errorcode().

Hi Werner

re formatting Clarion code in your messages here, see:

Separately, with ABC code like insert() it is better to avoid checking errorcode() but instead say something like:

if Access:Navn.Insert() <> level:benign
  <error handling>
end

or you could use Access:Navn.TryInsert() if you want more control of the error messages etc.

cheers again

Geoff R

[Edit: I see Rich beat me to it re Level:Benign]

1 Like

Thanks to both of you.

I posted the code to see if I could get some further insights, so thanks very much.

:slightly_smiling_face:

1 Like