Steve のソリューションは非常に優れており、特にデータベース コンテナとルールの割り当てを利用していますが、明らかに (ある程度) 状況に行き詰まっています。レコードを追加しようとしていて、独自の自動インクリメントを作成する必要がある場合は、プロシージャ コールだけでそれを実行して割り当てる必要がある場合があります。これはほんの一例ですが、参考になるかもしれません。
FUNCTION AddMyNewRecord()
*/ localized variable so you don't accidentally mangle some otherwise
*/ coincidental variable somewhere else. Preserve work area at start
local lnSelect, llSaveOk, lnAttempts, lnNewPKID
lnSelect = select()
llSaveOk = .f.
select YourAddressTable
if NOT FLOCK()
lnAttempts = 0
do while lnAttempts < 10 AND NOT FLOCK()
wait window "Attempting lock for address table..." timeout 1
enddo
endif
if NOT FLOCK()
messagebox( "Unable to lock file to add next record primary key." )
else
*/ We have a lock, now try to detect both the highest and lowest
*/ EXISTING key for the table
use in select( "C_TryNextKey" )
select MIN( YAT.PK ) as MinKey,;
MAX( YAT.PK ) as MaxKey ;
from ;
YourAddressTable YAT;
into ;
cursor C_TryNextKey readwrite
*/ Determine if you need higher or lower key sequence
if CriteriaForPositiveKey
lnNewPKID = C_TryNextKey.MaxKey +1
else
*/ must be getting next LOWER sequence
lnNewPKID = C_TryNextKey.MinKey -1
endif
*/ close temp cursor from getting respective high / low key
use in select( "C_TryNextKey" )
*/ NOW, we can add the new record
Select YourAddressTable
APPEND BLANK
*/ replace PK and all the other fields you need to do too
Replace PK with lnNewPKID,;
Address1 with lcSomeVariableYouHaveForAddress1,;
Address2 with lcSomeVariableForAddress2,;
AnyOtherFields with lcOtherFieldsToBeSet
*/ Unlock the address table
UNLOCK
*/ set flag so we know it worked vs not.
llSaveOk = .t.
endif
*/ Return back where it started
select( lnSelect )
*/ Return if the save was ok or not.
return llSaveOk
endproc
これにより、既存のデータベースもテーブル構造も変更されません。ただし、新しいレコード コンテンツを挿入する前に、テーブルをロックしようとします。次に、最小 ID と最大 ID を確認します。データを分析して、一部が負と正である理由を見つけ、上記のコードに入れられた「プレースホルダー」の条件を更新する必要があります。最後に、テーブルのロックを解除します。
これが理にかなっている場合は、素晴らしいです。調整が必要な場合は、私に知らせてください。さらにガイドできるようにします.