Btrieve API プログラミング
この章では、Btrieve API を直接呼び出して Pervasive PSQL アプリケーションの開発を開始する場合に役立つ情報を示します。最も一般的なプログラミング作業には、Visual Basic と Delphi のサンプル コードとサンプル構造体が付属しています。
この章では、以下の項目について説明します。
Btrieve API プログラミングの基礎
以下のフロー チャートは、レコードの挿入、更新および削除にアプリケーションでどの Btrieve オペレーションを使用したらよいかを示しています。Btrieve の詳細については、『Btrieve API Guide』を参照してください。
Btrieve API フロー チャート
レコードの挿入
1 OPEN(0)でファイルを開く
2 INSERT(2)でレコードを追加する(繰り返し)
3 CLOSE(1)でファイルを閉じる
4 STOP(25)でリソースを解放する
レコードの更新
1 OPEN(0)でファイルを開く
2 GET EQUAL(5)またはその他の単一レコード取得オペレーションを実行して既存のレコードを検索し物理カレンシーを設定する
3 レコードを変更する
4 UPDATE(3)で更新する
5 CLOSE(1)でファイルを閉じる
6 STOP(25)でリソースを解放する
レコードの削除
1 OPEN(0)でファイルを開く
2 GET EQUAL(5)またはその他の単一レコード取得オペレーションを実行して既存のレコードを検索し物理カレンシーを設定する
3 DELETE(4)でレコードを削除する
4 CLOSE(1)でファイルを閉じる
5 STOP(25)でリソースを解放する
Visual Basic に関する注記
以下に、Visual Basic で Pervasive PSQL アプリケーションを開発するときに注意が必要なことをいくつか示します。
•Visual Basic では、ユーザーが定義したデータ型にバイト配置の問題があることがわかっています。また、この問題に関する情報と PAln32.DLL、Pervasive Btrieve Alignment DLL の使用方法については、Btrieve API に関するセクション
Visual Basicを参照してください。
•結果のレコードのタイプごとにレコード クラスを作成すると、以下のステップに示すようなデータ アクセスが容易に行えます。
a. Record というクラスを作成します。
b. レコードのレイアウトを定義する構造体を作成します。
Type Byte2
field1 byte
field2 byte
End Type
Type Rec
Size As Byte2
Name As String*30 'SQL マスク = x30
Salary As String*10 'SQL マスク = zzzzzzz.99
End Type
c. iAsciiFlag = 1 と ispacing=0 を使用してデータを Rec のインスタンスへ読み込みます。
Dim instofRec As New Rec
d. ドット表記でデータにアクセスします。
instofRec.Name="Jeff"
e. レコード クラスを使用してすべての instofRec データ操作を行います。
Delphi に関する注記
以下に、Delphi で Pervasive PSQL アプリケーションを開発するときに考慮が必要なことを示します。
•Pascal の旧バージョンと違い、Delphi の長さ指定子のない文字列型は動的でヌル終端です。つまり、文字列バッファーに値を割り当てるまで、メモリが文字列バッファーに割り当てられている保証はありません。また、文字列型を使用する場合は、予想された結果を十分に保持できる大きさの文字列型を埋め込む必要があります。以下の例に示すように、StringOfChar()関数を使用して、Btrieve からの予想された戻り値を取り込める大きさの空白文字列を割り当てることができます。
CustKeyBuffer:string; // 長い文字列型
CustBufLen :word;
// BTRV() はキー長として常に 255 を渡すため、
// MAX_KEY_LEN は 255
CustKeyBuffer := StringOfChar(' ', MAX_KEY_LEN);
CustBufLen := SizeOf(CustRec);
Status := BTRV(B_GET_FIRST, CustPosBLock, CustRec, CustBufLen, CustKeyBuffer, 0);
{CustKeyBuffer にはキーの値が入っている}
{取得したレコード}
この章に示すすべての Delphi サンプルがエラー レポートを示しているわけではありません。しかし、すべての呼び出しの後の戻りコードを確認する必要があります。
•この章のサンプルを実行しようとする場合、INTERNAL_FORMAT スタイルを使用するフェッチについては、クエリ内のフィールドの順序はデータ レコードからフェッチするメンバーの順序に合っていなければなりません。FillGridHeaders()ルーチンを使用する場合、クエリがフィールドを一覧する順序と同じ順序でグリッドを詰める必要があります。
Pervasive PSQL アプリケーションの起動
Pervasive PSQL アプリケーションを開発する場合は、特定のプログラミング インターフェイスに対応するソース モジュールを組み入れる必要があります。
•BTRCONST と BTRAPI32 - Btrieve アプリケーションに必要なソース モジュール
Pervasive PSQL ソース モジュールの追加
アプリケーションを開発しているプログラミング インターフェイスに Btrieve ソース モジュールを組み込む必要があります。
►Visual Basic プロジェクトに Btrieve ソース モジュールを追加するには
1 Visual Basic で新しいプロジェクトを起動します。
2 既存の標準モジュールをプロジェクトに追加します。
3 Pervasive PSQL ソース モジュールを追加します。
►Delphi プロジェクトに Btrieve ソース モジュールを追加するには
1 Delphi で新しいプロジェクトを起動します。
2 [プロジェクト]メニューから[オプション]を選択します。
3 [ディレクトリ]タブをクリックします。
4 [検索パス]データ フィールドに「<パス>\INTF\DELPHI」を挿入します(パス部分は Pervasive PSQL SDK コンポーネントのインストール先です)。
5 USES 句にソース モジュールを組み入れます。
Btrieve API のコード サンプル
ここでは、Btrieve API で実行できる以下のタスクの Visual Basic、Delphi および C/C++ のコード サンプルを示します。
ファイルの作成
Create(14)オペレーションを使用して、アプリケーション内からファイルを作成することができます。ファイルを作成するには、新しい Btrieve ファイルの作成に必要な情報を含む構造体を作成する必要があります。
この API の詳細については、『Btrieve API Guide』を参照してください。
サンプル コード
以下のサンプル コードは、Create オペレーションでファイルを作成する方法を示しています。
Visual Basic(ファイルの作成)
以下のサブルーチンは、Orders というファイルを作成します。
Sub CreateOrdersFile(OrdFileLocation As String)
' 次の構文はファイル仕様を設定します
OrdFixedRecSize = Len(OrdRecBuf)
FileDefinitionBuffer.RecLen = OrdFixedRecSize
FileDefinitionBuffer.PageSize = 4096
FileDefinitionBuffer.IndxCnt = 2
FileDefinitionBuffer.FileFlags = VARIABLELENGTH
' キー 0、注文番号
FileDefinitionBuffer.KeyBuf0.KeyPos = 1
FileDefinitionBuffer.KeyBuf0.KeyLen = 4
FileDefinitionBuffer.KeyBuf0.KeyFlags = EXTTYPE + MODIFIABLE
FileDefinitionBuffer.KeyBuf0.KeyType = Chr$(BAUTOINC)
' キー 1、連絡先番号
FileDefinitionBuffer.KeyBuf1.KeyPos = 5
FileDefinitionBuffer.KeyBuf1.KeyLen = 4
FileDefinitionBuffer.KeyBuf1.KeyFlags = EXTTYPE + MODIFIABLE + DUP
FileDefinitionBuffer.KeyBuf1.KeyType = Chr$(BUNSGBIN)
BufLen = Len(FileDefinitionBuffer)
OrdFileLocation = OrdFileLocation & " "
KeyBufLen = Len(OrdFileLocation)
CopyMemory OrdKeyBuffer, OrdFileLocation, Len(OrdFileLocation)
giStatus = BTRCALL(BCREATE, OrdPosBlock, FileDefinitionBuffer, BufLen, ByValOrdFileLocation, KeyBufLen, 0)
End Sub
Delphi(ファイルの作成)
以下のルーチンは、Customer という可変長ファイルを作成します。
function CreateCustomerFile(FileName:String):SmallInt;
var
CustRec :CustomerRecordType; // ユーザー定義のレコード構造体
CustBufLen :word;
CustPosBlock :TPositionBlock; // [1..128] のバイト配列
CustFileLocation :String[255];
CustFixedRecSize :LongInt;
FileDefinitionBuffer :FileCreateBuffer; // ファイル作成用の構造体
FilebufLen :Word;
KeyNum :ShortInt;
begin
{ 次の構文はファイル仕様を定義します }
{ レコードの固定長部分のみのサイズを計算 }
CustFixedRecSize := SizeOf(CustRec) - SizeOf(CustRec.Notes);
FileDefinitionBuffer.fileSpec.recLen := CustFixedRecSize;
FileDefinitionBuffer.fileSpec.PageSize := 4096;
FileDefinitionBuffer.fileSpec.IndexCount:= 4;
FileDefinitionBuffer.fileSpec.FileFlags := VARIABLELENGTH;
{ キー仕様の定義、キー 0 連絡先番号 }
FileDefinitionBuffer.keyspecArray[0].Position := 1;
FileDefinitionBuffer.keyspecArray[0].Length := 4; {4 バイト整数}
FileDefinitionBuffer.keyspecArray[0].Flags := KFLG_EXTTYPE_KEY + KFLG_MODX;
FileDefinitionBuffer.keyspecArray[0].KeyType := AUTOINCREMENT_TYPE;
{キー 1、連絡先名 }
FileDefinitionBuffer.keyspecArray[1].Position := 5;
FileDefinitionBuffer.keyspecArray[1].Length := 30;
FileDefinitionBuffer.keyspecArray[1].Flags := KFLG_EXTTYPE_KEY +KFLG_MODX + KFLG_DUP;
FileDefinitionBuffer.keyspecArray[1].KeyType := STRING_TYPE;
{ キー 2、会社名 }
FileDefinitionBuffer.keyspecArray[2].Position := 35;
FileDefinitionBuffer.keyspecArray[2].Length := 60;
FileDefinitionBuffer.keyspecArray[2].Flags := KFLG_EXTTYPE_KEY + KFLG_MODX + KFLG_DUP;
FileDefinitionBuffer.keyspecArray[2].KeyType := STRING_TYPE;
{ キー 3、販売員、次回の連絡日 }
FileDefinitionBuffer.keyspecArray[3].Position := 220;
FileDefinitionBuffer.keyspecArray[3].Length := 4;
FileDefinitionBuffer.keyspecArray[3].Flags := KFLG_EXTTYPE_KEY + KFLG_MODX + KFLG_DUP + KFLG_SEG;
FileDefinitionBuffer.keyspecArray[3].KeyType := LSTRING_TYPE;
FileDefinitionBuffer.keyspecArray[4].Position := 223;
FileDefinitionBuffer.keyspecArray[4].Length := 4;
FileDefinitionBuffer.keyspecArray[4].Flags := KFLG_EXTTYPE_KEY + KFLG_MODX + KFLG_DUP;
FileDefinitionBuffer.keyspecArray[4].KeyType := DATE_TYPE;
CustFileLocation := FileName + #0; { 作成するファイルのパスおよびファイル名 }
FilebufLen := sizeof(FileDefinitionBuffer);
KeyNum := 0;
FillChar(CustPosBlock, SizeOf(CustPosBlock), #0);
Result := BTRV(B_CREATE, //OpCode 14
CustPosBLock, // ポジション ブロック("cursor" または "handle")
FileDefinitionBuffer, // 新規ファイルの定義
FileBufLen, // 定義の長さ
CustFileLocation[1], // パスとファイル名
keyNum); // 0(ゼロ)は既存のファイルを上書きする
end; {CreateCustomerFile}
C/C++(レコードの作成)
BTI_SINT CreateCustomerFile(LPCTSTR szCustomerFileName)
{
Customer_Record_Type CustRec; // ユーザー定義のレコード構造体
char CustPosBlock[POS_BLOCK_SIZE];
// customer ファイル内の "Cursor"
char CustFileLocation[255];
size_t CustFixedRecSize;
FileDescriptionType FileDefBuf; // ファイル作成用の構造体
BTI_WORD FilebufLen;
char KeyNum; // 1 バイトの符号
付き整数
BTI_SINT iStatus;
/* レコードの固定長部分のサイズを計算 */
CustFixedRecSize = sizeof(CustRec) - sizeof(CustRec.Notes);
FileDefBuf.RecLen = CustFixedRecSize;
FileDefBuf.PageSize = 4096;
FileDefBuf.IndxCnt = 4;
FileDefBuf.DupPointers = 4;
FileDefBuf.FileFlags = VAR_RECS | BALANCED_KEYS;
/* キー仕様の定義、キー 0 連絡先番号 */
FileDefBuf.KeyBuf[0].KeyPos = 1;
FileDefBuf.KeyBuf[0].KeyLen = 4;
FileDefBuf.KeyBuf[0].KeyFlags = EXTTYPE_KEY | MOD;
FileDefBuf.KeyBuf[0].KeyType = AUTOINCREMENT_TYPE;
/* キー 1 - 連絡先名 */
FileDefBuf.KeyBuf[1].KeyPos = 5;
FileDefBuf.KeyBuf[1].KeyLen = 30;
FileDefBuf.KeyBuf[1].KeyFlags = EXTTYPE_KEY | DUP | MOD;
FileDefBuf.KeyBuf[1].KeyType = STRING_TYPE;
/* キー 2 - 会社名 */
FileDefBuf.KeyBuf[2].KeyPos = 35;
FileDefBuf.KeyBuf[2].KeyLen = 60;
FileDefBuf.KeyBuf[2].KeyFlags = EXTTYPE_KEY | DUP | MOD;
FileDefBuf.KeyBuf[2].KeyType = STRING_TYPE;
/* キー 3 - 販売員、次回の連絡日 */
FileDefBuf.KeyBuf[3].KeyPos = 220;
FileDefBuf.KeyBuf[3].KeyLen = 3;
FileDefBuf.KeyBuf[3].KeyFlags = EXTTYPE_KEY | DUP | MOD | SEG;
FileDefBuf.KeyBuf[3].KeyType = STRING_TYPE;
FileDefBuf.KeyBuf[4].KeyPos = 223;
FileDefBuf.KeyBuf[4].KeyLen = 4;
FileDefBuf.KeyBuf[4].KeyFlags = EXTTYPE_KEY | DUP | MOD;
FileDefBuf.KeyBuf[4].KeyType = DATE_TYPE;
//
//------------------------------------------------------------------------
FilebufLen = sizeof(FileDefBuf);
KeyNum = 0; // 上書き処理
strcpy(CustFileLocation, szCustomerFileName);
iStatus = BTRV(B_CREATE,
CustPosBlock,
&FileDefBuf,
&FilebufLen,
CustFileLocation,
KeyNum);
return(iStatus);
} // CreateCustomerFile()
サンプル構造体(ファイルの作成)
以下のサンプル構造体はそれぞれ、前の Visual Basic、Delphi および C/C++ のコード サンプルで使用される構造体です。
Visual Basic(ファイルの作成)-サンプル構造体
Declare Function BTRCALL Lib "w3btrv7.dll" (ByVal OP, _
ByVal Pb$, Db As Any, DL As Long, Kb As Any, _
ByVal Kl, ByVal Kn) As Integer
Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" _
(hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Type OrderRecordBufferType
OrderNumberAs typ_byte4 ' 4 バイト unsigned
ContactNumber As typ_byte4 ' 4 バイト unsigned
OrderDateAs DateType
OrderTotal As typ_byte4 ' 4 バイト real
NotUsed As String * 64
End Type
Type OrderKeyBufferType
BufferValue(255) As Byte
OrderNumber As typ_byte4
CustNumber As typ_byte4
NotUsed As String * 64
End Type
Type FileSpec
RecLenAs Integer
PageSize As Integer
IndxCnt As Integer
NotUsedAs String * 4
FileFlags As Integer
Reserved As String * 2
Allocation As Integer
KeyBuf0 As KeySpec
KeyBuf1 As KeySpec
KeyBuf2 As KeySpec
KeyBuf3 As KeySpec
KeyBuf4 As KeySpec
KeyBuf5 As KeySpec
End Type
Global FileDefinitionBuffer As FileSpec
{以下は Order テーブル変数}
Global OrdPosBlock As Byte(0 to 127)
Global OrdRecPos As typ_byte4
Global OrdRecBuf As OrderRecordBufferType
Global OrdKeyBuffer As OrderKeyBufferType
Global OrdFixedRecSize As Long
Global OrdFileLocation As String
Delphi(ファイルの作成)-サンプル構造体
type
CustomerRecordType = packed record
必要に応じた処理
end; //CustomerRecordType
type
TPositionBlock = array[0..127] of byte;
type
BTI_KEY_DESC = packed record
Position :BTI_SINT;
Length :BTI_SINT;
KeyFlags :BTI_SINT;
NumUnique :BTI_LONG;
ExtKeyType:BTI_BYTE;
NullVal :BTI_BYTE;
Reserv :array [0..1] of BTI_CHAR;
KeyNumber :BTI_UBYTE;
ACSNumber :BTI_UBYTE;
end; {BTI_KEY_DESC}
BTI_KEY_ARRAY = array [0..MAX_KEY_SEG - 1] of BTI_KEY_DESC;
BTI_ACS = array [0..ACS_SIZE - 1] of BTI_CHAR;
type
FileCreateBuffer = packed record
RecLen :BTI_SINT;
PageSize :BTI_SINT;
NumKeys :BTI_SINT;
Reserved1 :BTI_LONG;
FileFlags :BTI_SINT;
DupPointers:BTI_BYTE;
Reserved2 :BTI_BYTE;
Alloc :BTI_SINT;
Keys :BTI_KEY_ARRAY;
ACS :BTI_ACS;
end; {BTI_FILE_DESC}
ここで留意すべき点は、定義を簡単にするために、オルタネート コレーティング シーケンス(ACS)をキー配列全体の後に置くということです。Btrieve は、最後のキー セグメントの直後に ACS が続くことを期待しているため、ACS を構造体内の該当位置まで移動させる必要があります。
C/C++(ファイルの作成)-サンプル構造体
struct CustRec
{
必要に応じた処理
} //CustRec
struct date_type
{
BTI_BYTE day;
BTI_BYTE month;
BTI_SINT year;
}; //date_type
struct KeySpec
{
BTI_SINT KeyPos;
BTI_SINT KeyLen;
BTI_SINT KeyFlags;
BTI_LONG KeyTot;
BTI_CHAR KeyType;
BTI_CHAR NulValue;
BTI_CHAR NotUsed[2];
BTI_BYTE KeyNumber;
BTI_BYTE ACSNum;
}; //KeySpec
struct FileDescriptionType
{
BTI_SINT RecLen;
BTI_SINT PageSize;
BTI_SINT IndxCnt;
BTI_LONG RecTot;
BTI_SINT FileFlags;
BTI_BYTE DupPointers;
BTI_BYTE NotUsed;
BTI_SINT Allocation;
KeySpec KeyBuf[119];
}; //FileDescriptionType
レコードの挿入
Insert(2)オペレーションは、ファイルにレコードを挿入します。この API への呼び出しを行うには以下の前提条件を満たす必要があります。
•対象となるファイルが開いていることが必要です。
•挿入するレコードは適切なレコード長を持つ必要があります。また、キー値は対象となるファイルで定義されているキーと一致していなければなりません。
データ バッファーに挿入する行を設定して BINSERT を呼び出すことにより、行を挿入できます。この API の詳細については、『Btrieve API Guide』を参照してください。以下のサンプル コードとサンプル構造体は、Visual Basic、Delphi、および C/C++ で Insert オペレーションを実行する方法を示しています。
サンプル コード
以下のサンプル コードは、Insert オペレーションでレコードを挿入する方法を示しています。
Visual Basic(レコードの挿入)
FillCustBufFromCustomerEdit
InsertCustomerRecord ' BtrCallModule プロシージャ
Sub FillCustBufFromCustomerEdit()
Dim tmplong As Long
Dim StrDay As String * 2
Dim StrMonth As String * 2
Dim StrYear As String * 4
tmplong = CLng(FormCustomerEdit.EdContactNumber.Text)
CustRecBuf.ContactNumber = ToType4(tmplong)
CustRecBuf.ContactName = FormCustomerEdit.EdContactName.Text
CustRecBuf.CompanyName = FormCustomerEdit.EdCompanyName.Text
CustRecBuf.Address1 = FormCustomerEdit.EdAddress1.Text
CustRecBuf.Address2 = FormCustomerEdit.EdAddress2.Text
CustRecBuf.City = FormCustomerEdit.EdCity.Text
CustRecBuf.State = FormCustomerEdit.EdState.Text
CustRecBuf.ZipCode = FormCustomerEdit.EdZip.Text
CustRecBuf.Country = FormCustomerEdit.EdCountry.Text
CustRecBuf.SalesRep = FormCustomerEdit.EdSalesRep.Text
StrDay = Mid$(FormCustomerEdit.EdContactDate.Text, 1, 2)
StrMonth = Mid$(FormCustomerEdit.EdContactDate.Text, 4, 2)
StrYear = Mid$(FormCustomerEdit.EdContactDate.Text, 7, 4)
CustRecBuf.NextContact.Day = CByte(StrDay)
CustRecBuf.NextContact.Month = CByte(StrMonth)
CustRecBuf.NextContact.Year = CInt(StrYear)
CustRecBuf.PhoneNumber = FormCustomerEdit.EdPhone.Text
CustRecBuf.Notes = Trim(FormCustomerEdit.EdNotes.Text) & Chr$(0)
FormCustomerEdit.EdRecLength = Str(CustBufLength)
End Sub
Sub InsertCustomerRecord()
Dim lCustBufLength As Long
Dim iKeyNum As Integer
Dim iKeyBufLen As Integer
lCustBufLength = Len(CustRecBuf) - MaxNoteFieldSize + Len(Trim(CustRecBuf.Notes))
' CustBufLength = 238
iKeyBufLen = KEY_BUF_LEN
iKeyNum = CustKeyBuffer.CurrentKeyNumber
giStatus = BTRCALL(BINSERT, CustPosBlock, CustRecBuf, lCustBufLength, CustKeyBuffer, iKeyBufLen, iKeyNum)
End Sub
Delphi(レコードの挿入)
function InsertCustomerRecord( var
CustPosBlock : TPositionBlock;
CustRec : CustomerRecordType) : SmallInt;
var
CustBufLen :Word;
KeyNum :ShortInt;
CustKeyBuffer:String[255];
begin
{ 可変長レコードの全体のサイズを計算 }
CustBufLen := SizeOf(CustRec) - SizeOf(CustRec.Notes) + Length(CustRec.Notes);
KeyNum := -1; { 挿入時の "カレンシー変更なし" を指定 }
FillChar(CustKeyBuffer, SizeOf(CustKeyBuffer), #0); {not needed going in}
Result := BTRV(B_INSERT, //OpCode 2
CustPosBLock, // 既に開いているポジション ブロック
CustRec, // 挿入するレコード
CustBufLen, // 新規レコードの長さ
CustKeyBuffer[1], // NCC insert には不要
KeyNum);
end; {InsertCustomerRecord}
C/C++(レコードの挿入)
BTI_SINT InsertCustomerRecord(
char CustPosBlock[POS_BLOCK_SIZE],
Customer_Record_Type CustRec)
{
BTI_WORD CustBufLen;
char KeyNum; // 1 バイトの符号付きバイト
char CustKeyBuffer[255];
BTI_SINT iStatus;
/* 可変長レコードの全体のサイズを計算 */
CustBufLen = sizeof(CustRec) - sizeof(CustRec.Notes) + strlen(CustRec.Notes);
KeyNum = -1; // insert 中の "カレンシー変更なし" を指定
memset(CustKeyBuffer, sizeof(CustKeyBuffer), 0);
//not needed going in
iStatus = BTRV(B_INSERT, //OpCode 2
CustPosBlock, // 既に開いているポジション ブロック
&CustRec, // 挿入するレコード
&CustBufLen, // 新規レコードの長さ
CustKeyBuffer, // NCC insert には不要
KeyNum);
PrintStatus("B_INSERT:status = %d", iStatus);
return(iStatus);
} // InsertCustomerRecord()
サンプル構造体(レコードの挿入)
以下のサンプル構造体はそれぞれ、前の Visual Basic、Delphi および C/C++ のコード サンプルで使用される構造体です。
Visual Basic(レコードの挿入)-サンプル構造体
Global Const BINSERT = 2
' 以下は Customer テーブルのデータ構造
Type CustomerRecordBufferType
ContactNumber As typ_byte4
ContactNameAs String * 30
CompanyName As String * 60
Address1 As String * 30
Address2 As String * 30
City As String * 30
StateAs String * 2
ZipCodeAs String * 10
CountryAs String * 3
PhoneNumberAs String * 20
SalesRepAs String * 3
NextContactAs DateType
NotUsedAs String * 12
Notes As String * MaxNoteFieldSize
End Type
' 以下は Customer ファイルの変数
Global CustPosBlockAs Byte(0 to 127)
Global CustRecBuf As CustomerRecordBufferType
Global CustKeyBufferAs CustomerKeyBufferType
Global CustFixedRecSize As Long
Global CustFileLocationAs String
Global CustPositionAs typ_byte4
Global CustPosPercent As typ_byte4
Function ToInt(vValue As typ_byte4) As Long
Dim iInt As Long
CopyMemory iInt, vValue, 4
ToInt = iInt
End Function
Function ToType4(vValue As Long) As typ_byte4
Dim tmpTyp4 As typ_byte4
CopyMemory tmpTyp4, vValue, 4
ToType4 = tmpTyp4
End Function
Delphi(レコードの挿入)-サンプル構造体
type
CustomerRecordType = packed record
必要に応じた処理
end; //CustomerRecordType
C/C++(レコードの挿入)-サンプル構造体
struct CustRec
{
必要に応じた処理
} //CustRec
レコードの更新
Update(3)オペレーションは、既存のレコード内の情報を変更します。この Btrieve 呼び出しを行うには、ファイルが開いており、物理カレンシーが確立していなければなりません。トランザクション内でレコードを更新する場合は、レコードの取得もトランザクション内で行う必要があります。
この API の詳細については、『Btrieve API Guide』を参照してください。以下のサンプル コードとサンプル構造体は、Visual Basic、Delphi、および C/C++ で Update オペレーションを実行する方法を示しています。
サンプル コード
以下のサンプル コードは、Update オペレーションでファイルを変更する方法を示しています。
Visual Basic(レコードの更新)
FillCustBufFromCustomerEdit
UpdateCustomerRecord 'BtrCallModule プロシージャ
Sub FillCustBufFromCustomerEdit()
Dim tmplong As Long
Dim StrDay As String * 2
Dim StrMonth As String * 2
Dim StrYear As String * 4
tmplong = CLng(FormCustomerEdit.EdContactNumber.Text)
CustRecBuf.ContactNumber = ToType4(tmplong)
CustRecBuf.ContactName = FormCustomerEdit.EdContactName.Text
CustRecBuf.CompanyName = FormCustomerEdit.EdCompanyName.Text
CustRecBuf.Address1 = FormCustomerEdit.EdAddress1.Text
CustRecBuf.Address2 = FormCustomerEdit.EdAddress2.Text
CustRecBuf.City = FormCustomerEdit.EdCity.Text
CustRecBuf.State = FormCustomerEdit.EdState.Text
CustRecBuf.ZipCode = FormCustomerEdit.EdZip.Text
CustRecBuf.Country = FormCustomerEdit.EdCountry.Text
CustRecBuf.SalesRep = FormCustomerEdit.EdSalesRep.Text
StrDay = Mid$(FormCustomerEdit.EdContactDate.Text, 1, 2)
StrMonth = Mid$(FormCustomerEdit.EdContactDate.Text, 4, 2)
StrYear = Mid$(FormCustomerEdit.EdContactDate.Text, 7, 4)
CustRecBuf.NextContact.Day = CByte(StrDay)
CustRecBuf.NextContact.Month = CByte(StrMonth)
CustRecBuf.NextContact.Year = CInt(StrYear)
CustRecBuf.PhoneNumber = FormCustomerEdit.EdPhone.Text
CustRecBuf.Notes = Trim(FormCustomerEdit.EdNotes.Text) & Chr$(0)
FormCustomerEdit.EdRecLength = Str(CustBufLength)
End Sub
Sub UpdateCustomerRecord()
Dim lCustBufLength As Long
Dim iKeyBufLen As Integer
Dim iKeyNum As Integer
' 次の構文は customer レコードを更新します
lCustBufLength = Len(CustRecBuf) - MaxNoteFieldSize + _
Len(Trim(CustRecBuf.Notes))
iKeyBufLen = KEY_BUF_LEN
iKeyNum = CustKeyBuffer.CurrentKeyNumber
giStatus = BTRCALL(bUpdate, CustPosBlock, CustRecBuf, lCustBufLength, CustKeyBuffer, iKeyBufLen, iKeyNum)
End Sub
Delphi(レコードの更新)
function UpdateCustomerRecord( var
CustPosBlock:TPositionBlock;
CustRec :CustomerRecordType) : SmallInt;
var
CustBufLen :Word;
KeyNum :ShortInt;
CustKeyBuffer :String[255];
begin
{ 可変長レコードの全体のサイズを計算 } }
CustBufLen := SizeOf(CustRec) - SizeOf(CustRec.Notes) + Length(CustRec.Notes);
KeyNum := -1; { 更新時の "カレンシー変更なし" を指定 }
FillChar(CustKeyBuffer, SizeOf(CustKeyBuffer), #0); {not needed going in}
Result := BTRV(B_UPDATE, //OpCode 3
CustPosBLock, // 既に開いているポジション ブロック
CustRec, // 新規レコード
CustBufLen, // 新規レコードの長さ
CustKeyBuffer[1], // NCC update には不要
KeyNum);
end; {UpdateCustomerRecord}
C/C++(レコードの更新)
BTI_SINT UpdateCustomerRecord(
char CustPosBlock[POS_BLOCK_SIZE],
Customer_Record_Type CustRec)
{
BTI_WORD CustBufLen;
char KeyNum; // 1 バイトの符号付きバイト
char CustKeyBuffer[255];
BTI_SINT iStatus;
/* 可変長レコードの全体のサイズを計算 */
CustBufLen = sizeof(CustRec) - sizeof(CustRec.Notes) + strlen(CustRec.Notes);
KeyNum = -1; // 更新時の "カレンシー変更なし" を指定
memset(CustKeyBuffer, sizeof(CustKeyBuffer), 0);
//not needed going in
iStatus = BTRV(B_UPDATE, //OpCode 3
CustPosBlock, // 既に開いているポジション ブロック
&CustRec, // 挿入するレコード
&CustBufLen, // 新規レコードの長さ
CustKeyBuffer, // NCC insert には不要
KeyNum);
PrintStatus("B_UPDATE:status = %d", iStatus);
return(iStatus);
} //UpdateCustomerRecord()
サンプル構造体(レコードの更新)
以下のサンプル構造体はそれぞれ、前の Visual Basic、Delphi および C/C++ のコード サンプルで使用される構造体です。
Visual Basic(レコードの更新)-サンプル構造体
Global Const bUpdate = 3
Insert オペレーションについては、
サンプル構造体(レコードの挿入)を参照してください。
Delphi(レコードの更新)-サンプル構造体
type
CustomerRecordType = packed record
必要に応じた処理
end; //CustomerRecordType
C/C++(レコードの更新)-サンプル構造体
struct CustRec
{
必要に応じた処理
} //CustRec
Step オペレーションの実行
Step オペレーション(Step First、Step Next、Step Last、Step Previous)では、レコードを取得してデータ バッファーに入れることができます。レコードを取得するためにキー パスは使用されません。これらの API の詳細については、『Btrieve API Guide』を参照してください。
以下のサンプル コードとサンプル構造体は、Delphi と C/C++ で Step オペレーションを実行する方法を示しています。
メモ: レコードが返される順序に決して依存しないでください。MicroKernel は、いつでもファイル内のレコードを移動できます。特定の順序でレコードを必要とする場合は、Get オペレーションを使用してください。
サンプル コード
以下のサンプル コードは、Step オペレーションでレコードを取得する方法を示しています。
Delphi(Step オペレーション)
以下のコード例は、ファイル内の最初の物理位置を返します。
{ ファイルから最初の物理レコードを取得 }
CustBufLen := SizeOf(CustRec); // データ レコードの最大サイズ
Status := BTRV(B_STEP_FIRST, //OpCode 33
CustPosBLock, // 既に開いているポジション ブロック
CustRec, // レコードが返されるバッファー
CustBufLen, // 返される最大長
CustKeyBuffer[1], // Step では不要
CustKeyNumber); // Step では不要
{ ファイルから 2 番目のレコードを取得(順序は保証されない)}
CustBufLen := SizeOf(CustRec); // リセット - 前の Step によって変更されている
Status := BTRV(B_STEP_NEXT, //OpCode 24
CustPosBLock,
CustRec,
CustBufLen,
CustKeyBuffer[1]
CustKeyNumber);
{ 先頭レコードに戻る }
CustBufLen := SizeOf(CustRec); // リセット - 前の Step によって変更されている
Status := BTRV(B_STEP_PREV, //OpCode 35
CustPosBLock,
CustRec,
CustBufLen,
CustKeyBuffer[1],
CustKeyNumber);
C/C++(Step オペレーション)
/* ファイルから最初の物理レコードを取得 */
CustBufLen = sizeof(CustRec); // データ レコードの最大サイズ
iStatus = BTRV(B_STEP_FIRST, //OpCode 33
CustPosBLock, // 既に開いているポジション ブロック
&CustRec, // レコードが返されるバッファー
&CustBufLen, // 返される最大長
CustKeyBuffer, // Step では不要
KeyNum); // Step では不要
/* ファイルから 2 番目のレコードを取得(順序は保証されない) */
CustBufLen = sizeof(CustRec); // リセット - 前の Step によって変更されている
iStatus = BTRV(B_STEP_NEXT, //OpCode 24
CustPosBLock,
&CustRec,
&CustBufLen,
CustKeyBuffer,
KeyNum);
/* 先頭レコードに戻る */
CustBufLen = sizeof(CustRec); // リセット - 前の Step によって変更されている
iStatus = BTRV(B_STEP_PREVIOUS, //OpCode 35
CustPosBLock,
&CustRec,
&CustBufLen,
CustKeyBuffer,
KeyNum);
サンプル構造体
以下のサンプル構造体はそれぞれ、前の Delphi および C/C++ のコード サンプルで使用される構造体です。
Delphi(Step オペレーション)-サンプル構造体
type
CustomerRecordType = packed record
必要に応じた処理
end; //CustomerRecordType
C/C++(Step オペレーション)-サンプル構造体
struct CustRec
{
必要に応じた処理
} //CustRec
Get オペレーションの実行
Get オペレーションでは、レコードを取得できます。これらのオペレーションは、どの行を返すかを指定するためにキー バッファー パラメーターを必要とします。これらの API の詳細については、『Btrieve API Guide』を参照してください。
以下のサンプル コードとサンプル構造体は、Visual Basic、Delphi、および C/C++ でいくつかの Get オペレーションを実行する方法を示しています。
サンプル コード
以下のサンプル コードは、Get オペレーションでファイルを取得する方法を示しています。
Visual Basic(Get オペレーション)
Sub LoadContactBox(RecPosition As typ_byte4)
FormBrowseCustomers.lstContact.Clear
GetDirectCustomerRecord ' BtrCallModule プロシージャ
If giStatus = 0 Then
' 次の構文は contact リスト ボックス文字列を作成します
FormatContListBoxString
If giStatus = 0 Then
PosIndex = 0
PosArray(PosIndex) = RecPosition
FirstRecPosition = RecPosition
End If
Else
FormBrowseCustomers.lblMsg.Caption = "didn't get record"
End If
' 次の構文はリスト ボックスの残りを埋めます
While giStatus = 0 And PosIndex < CustMaxNumRows - 1
GetNextCustomerRecord ' BtrCallModule プロシージャ
If giStatus = 0 Then
' contact リスト ボックス文字列を作成
FormatContListBoxString
' 次の構文はレコード位置を返します
GetPositionCustomerRecord ' BtrCallModule プロシージャ
If giStatus = 0 Then
PosIndex = PosIndex + 1
PosArray(PosIndex) = RecPosition
' 次の構文はレコード位置配列へのポインターを構築します
Select Case PosIndex
Case 1
SecondRecPosition = RecPosition
Case 10
SecToLastRecPosition = RecPosition
Case 11
LastRecPosition = RecPosition
End Select
End If
End If
Wend
If FormBrowseCustomers.lstContact.ListCount <> 0 Then
FormBrowseCustomers.lstContact.ListIndex = 0
End If
End Sub
Sub GetDirectCustomerRecord()
Dim iKeyBufLen As Integer
Dim iKeyNum As Integer
' 次の構文はレコード位置によって直接レコードを取得します
BufLen = Len(CustRecBuf)
iKeyBufLen = MaxKeyBufLen
iKeyNum = CustKeyBuffer.CurrentKeyNumber
' 次の構文はデータ バッファーにアドレスを設定します
CustRecBuf.Notes = "" ' 取得の前に可変長領域をクリア
LSet CustRecBuf = RecPosition
giStatus = BTRCALL(BGETDIRECT, CustPosBlock, _
CustRecBuf, BufLen, CustKeyBuffer, iKeyBufLen, _
iKeyNum)
DBLen = BufLen
End Sub
Sub GetNextCustomerRecord()
Dim iKeyNum As Integer
Dim iKeyBufLen As Integer
' 次の構文は次の customer レコードを返します
BufLen = Len(CustRecBuf)
iKeyBufLen = KEY_BUF_LEN
iKeyNum = CustKeyBuffer.CurrentKeyNumber
giStatus = BTRCALL(BGETNEXT, CustPosBlock, _
CustRecBuf, BufLen, CustKeyBuffer, iKeyBufLen, _
iKeyNum)
End Sub
Sub GetPositionCustomerRecord()
Dim iKeyBufLen As Integer
Dim iKeyNum As Integer
' 次の構文はレコード位置を返します
BufLen = MaxDataBufLen
iKeyBufLen = KEY_BUF_LEN
iKeyNum = CustKeyBuffer.CurrentKeyNumber
giStatus = BTRCALL(BGETPOS, CustPosBlock, _
RecPosition, BufLen, CustKeyBuffer, iKeyBufLen, _
iKeyNum)
End Sub
Delphi(Get オペレーション)
var
CustKeyBuffer:LongInt;
begin
CustBufLen := SizeOf(CustRec);
CustKeyNumber := 0; {In order by Contact ID}
{ 次の構文は指定したソート順を使用して、ファイルから }
{ 最初のレコードを返します }
CustBufLen := SizeOf(CustRec); // データ レコードの最大サイズ
Status := BTRV(B_GET_FIRST, //OpCode 12
CustPosBLock, // 既に開いているポジション ブロック
CustRec, // レコードが返されるバッファー
CustBufLen, // 返される最大長
CustKeyBuffer, // レコードから抽出したキー値を返す
CustKeyNumber); // 取得時に使用するインデックス順
{ 次の構文は指定したソート順でファイル内の次のレコードを }
{ 返します }
CustBufLen := SizeOf(CustRec); // リセット - 前の Get によって変更されている
Status := BTRV(B_GET_NEXT, //OpCode 6
CustPosBLock,
CustRec,
CustBufLen,
CustKeyBuffer[1],
CustKeyNumber);
{ 次の構文はファイル内の前のレコードを返します }
CustBufLen := SizeOf(CustRec); // リセット - 前の Step によって変更されている
Status := BTRV(B_GET_PREV, //OpCode 7
CustPosBLock,
CustRec,
CustBufLen,
CustKeyBuffer[1],
CustKeyNumber);
C/C++(Get オペレーション)
/* ファイルから最初の論理レコードを取得 */
CustBufLen = sizeof(CustRec); // データ レコードの最大サイズ
iStatus = BTRV(B_GET_FIRST, //OpCode 12
CustPosBLock, // 既に開いているポジション ブロック
&CustRec, // レコードが返されるバッファー
&CustBufLen, // 返される最大長
CustKeyBuffer, // レコードから抽出したキー値を返す
CustKeyNumber); // 取得時に使用するインデックス順
/* ファイルから 2 番目のレコードを取得選択したキー順 */
CustBufLen = sizeof(CustRec); // リセット - 前の Get によって変更されている
iStatus = BTRV(B_GET_NEXT, //OpCode 6
CustPosBLock,
&CustRec,
&CustBufLen,
CustKeyBuffer,
CustKeyNumber);
/* 先頭レコードに戻る */
CustBufLen = sizeof(CustRec); // リセット - 前の Get によって変更されている
iStatus = BTRV(B_GET_PREVIOUS, //OpCode 7
CustPosBLock,
&CustRec,
&CustBufLen,
CustKeyBuffer,
CustKeyNumber);
サンプル構造体(Get オペレーション)
以下のサンプル構造体はそれぞれ、前の Visual Basic、Delphi および C/C++ のコード サンプルで使用される構造体です。
Visual Basic(Get オペレーション)-サンプル構造体
Global Const BGETNEXT = 6
Global Const BGETDIRECT = 23
Global Const BGETPOS = 22
Delphi(Get オペレーション)-サンプル構造体
type
CustomerRecordType = packed record
必要に応じた処理
end; //CustomerRecordType
C/C++(Get オペレーション)-サンプル構造体
struct CustRec
{
必要に応じた処理
} //CustRec
チャンク、BLOB、および可変長レコード
Btrieve のチャンク オペレーションを使用すると、可変長レコード部分および BLOB 部分の読み書きが行えます。最大レコード長は 64 GB ですが、固定レコード長の最大は 64 KB(65,535 バイト)です。最初の 65,535 バイトを越えた先にあるレコードの各部分にアクセスしたいときに、チャンクを使用します。
サンプル コード
以下のサンプル コードは、チャンク、バイナリ ラージ オブジェクト(BLOB)および可変長レコードを処理する方法を示しています。
Visual Basic(チャンク/BLOB/可変長レコード)
Private Sub LoadImageFromBtrieve()
' 次の構文は、Btrieve に格納されているイメージを
' 出力イメージ テキスト ボックスで指定したファイルに返します
Dim lBytes As Long
Dim lBytesread As Long
Dim sLine As String
Dim lBytesToRead As Long
Dim iKey As Integer
Dim lAddressMode As Long
Dim lNumberOfChunks As Long
Dim lChunkOffset As Long
Dim lChunkAddress As Long
Dim lChunkLength As Long
Dim iNumChunksRead As Integer
GetEqualGraphicRecord ' レコードと BLOB の一部を取得
On Error GoTo FileNotFound
FormCustomerGraphic.MousePointer = 11
lNumberOfChunks = 0
On Error GoTo BMPOpenError
Open txtOutputImage.Text For Binary Access Write As #1
lBytesread = (BufLen - 68)
'読み取ったバイト数から Btrieve API グラフィック
'レコードの固定長を差し引いた値を保存する
'グラフィック レコードの最初のチャンクの固定長は
'68 です(上の GetEqualGraphicRecord)
sLine = Right(ChunkReadBuffer.ChunkArray, lBytesread)
Put #1, , sLine '最初のチャンクを bmp ファイルに書き出す
iNumChunksRead = 1
If giStatus = 22 And (BufLen = MaxChunkSize) Then
GetPositionGraphicRecord
'チャンクを取得する前に、
'現在のレコードの位置を取得する必要がある
Do
lNumberOfChunks = 1
lChunkOffset = 0
lChunkAddress = 0
lChunkLength = MaxChunkSize
iNumChunksRead = iNumChunksRead + 1
ChunkGetBuffer.RecordAddress = GrphPosition
'H80000000(ランダム チャンクの取得)
'H40000000(ネクスト イン レコード バイアス)はレコード内カレンシーを使用させる
ChunkGetBuffer.AddressMode = ToType4((&H80000000 + &H40000000))
ChunkGetBuffer.NumberOfChunks = ToType4(lNumberOfChunks)
ChunkGetBuffer.ChunkOffset = ToType4(lChunkOffset)
ChunkGetBuffer.ChunkAddress = ToType4(lChunkAddress)
ChunkGetBuffer.ChunkLength = ToType4(lChunkLength)
' 前の構文は読み取りバッファーを使用します。
' 最初のチャンクの取得 GetEqualGraphicRecord で
' レコードの固定長が読み取られているため、以降の
' チャンクの取得ではバッファー全体を使用します。
' 次の構文は読み取りバッファーと取得バッファーを読み込みます
CopyMemory ChunkReadBuffer, ChunkGetBuffer, Len(ChunkGetBuffer)
GetGraphicChunk
If giStatus = 0 Then 'レコードの終わりを越えて読むと 103 が返される
If MaxChunkSize <> BufLen Then
sLine = Left(ChunkReadBuffer.ChunkArray, BufLen)
lBytesread = lBytesread + (BufLen)
Else
sLine = ChunkReadBuffer.ChunkArray
Bytesread = lBytesread + MaxChunkSize
End If
If Len(sLine) > 0 Then
Put #1, , sLine
End If
End If
Loop While (giStatus = 0)
End If
Close #1
On Error Resume Next
Set Image1.Picture = LoadPicture(txtOutputImage.Text)
FormCustomerGraphic.MousePointer = 0
NumChunks.Text = iNumChunksRead
NumBytes.Text = lBytesread
LastStatus.Text = giStatus
On Error GoTo 0
Exit Sub
'InvalidPicture:
MsgBox Err.Number & ":" & Err.Description & vbCrLf & "Load from disk and save", vbOKOnly, "Invalid Picture in Graphic file"
Resume Next
FileNotFound:
MsgBox Err.Number & ":" & Err.Description, vbOKOnly, "Graphic Load Error"
FormCustomerGraphic.MousePointer = 0
On Error GoTo 0
BMPOpenError:
MsgBox "Directory for temporary imaging work does not exist." & vbCrLf & _
"Please select a valid directory for image out.", vbOKOnly, "User path error"
Screen.MousePointer = vbDefault
On Error GoTo 0
End Sub
Sub GetGraphicChunk()
Dim sKeyBuffer As String
Dim iKeyBufLen As Integer
BufLen = Len(ChunkReadBuffer)
sKeyBuffer = Space$(KEY_BUF_LEN)
iKeyBufLen = KEY_BUF_LEN
{次の構文では、キー番号にチャンク モードの -2 を設定する必要があります}
giStatus = BTRCALL(BGETDIRECT, GrphPosBlock, _
ChunkReadBuffer, BufLen, ByVal sKeyBuffer, _
iKeyBufLen, -2)
End Sub
サンプル構造体(チャンク/BLOB/可変長レコード)
次のサンプル構造体は、前の Visual Basic のコード サンプルで使用される構造体です。
Visual Basic(チャンク/BLOB/可変長レコード)-サンプル構造体
TypeType GraphicRecordBufferType
ContactNumber As typ_byte4
NotUsed As String * 64
End Type
Type GraphicKeyBufferType
BufferValue(255) As Byte
CurrentKeyNumberAs Integer
ContactNumber As typ_byte4
NotUsed As String * 64
End Type
Type ChunkReadDescriptorNext
ChunkArray As String * MaxChunkSize
End Type
Type ChunkGetDescriptor
RecordAddressAs typ_byte4
AddressModeAs typ_byte4
NumberOfChunks As typ_byte4
ChunkOffsetAs typ_byte4
ChunkLengthAs typ_byte4
ChunkAddress As typ_byte4
End Type
Global ChunkGetBuffer As ChunkGetDescriptor
Global ChunkReadBuffer As ChunkReadDescriptorNext
' グラフィック テーブル変数
Global GrphPosBlock As Byte(0 to 127)
Global GrphRecBuf As GraphicRecordBufferType
Global GrphKeyBuffer As GraphicKeyBufferType
Global GrphFixedRecSize As Long
Global GrphFileLocation As String
Global GrphKeyNumber As Integer
Global GrphPosition As typ_byte4
セグメント化されたインデックスの処理
以下のサンプル コードは、セグメント化されたインデックスを処理する方法を示しています。
サンプル コード
Visual Basic(セグメント化されたインデックス)
Sub CreateCustomerFile(CustFileLocation As String)
' 次の構文は customer ファイルを作成し、
' ファイル仕様を設定します
CustFixedRecSize = Len(CustRecBuf) - Len(CustRecBuf.Notes)
FileDefinitionBuffer.RecLen = CustFixedRecSize
FileDefinitionBuffer.PageSize = 4096
FileDefinitionBuffer.IndxCnt = 4
FileDefinitionBuffer.FileFlags = VARIABLELENGTH
' 以下はキー仕様を定義する
' キー 0、連絡先番号
FileDefinitionBuffer.KeyBuf0.KeyPos = 1
FileDefinitionBuffer.KeyBuf0.KeyLen = 4
FileDefinitionBuffer.KeyBuf0.KeyFlags = EXTTYPE + MODIFIABLE
FileDefinitionBuffer.KeyBuf0.KeyType = Chr$(BAUTOINC)
' キー 1, 連絡先名
FileDefinitionBuffer.KeyBuf1.KeyPos = 5
FileDefinitionBuffer.KeyBuf1.KeyLen = 30
FileDefinitionBuffer.KeyBuf1.KeyFlags = EXTTYPE + MODIFIABLE + DUP
FileDefinitionBuffer.KeyBuf1.KeyType = Chr$(BSTRING)
' キー 2, 連絡先名
FileDefinitionBuffer.KeyBuf2.KeyPos = 35
FileDefinitionBuffer.KeyBuf2.KeyLen = 60
FileDefinitionBuffer.KeyBuf2.KeyFlags = EXTTYPE + MODIFIABLE + DUP
FileDefinitionBuffer.KeyBuf2.KeyType = Chr$(BSTRING)
' キー 3, 販売員、次回の連絡日
' これはセグメント キー
FileDefinitionBuffer.KeyBuf3.KeyPos = 220
FileDefinitionBuffer.KeyBuf3.KeyLen = 3
FileDefinitionBuffer.KeyBuf3.KeyFlags = EXTTYPE + _ MODIFIABLE + DUP + SEGMENT
FileDefinitionBuffer.KeyBuf3.KeyType = Chr$(BSTRING)
FileDefinitionBuffer.KeyBuf4.KeyPos = 223
FileDefinitionBuffer.KeyBuf4.KeyLen = 4
FileDefinitionBuffer.KeyBuf4.KeyFlags = EXTTYPE + MODIFIABLE + DUP
FileDefinitionBuffer.KeyBuf4.KeyType = Chr$(BDATE)
BufLen = Len(FileDefinitionBuffer)
CustFileLocation = CustFileLocation & " "
KeyBufLen = Len(CustFileLocation)
giStatus = BTRCALL(BCREATE, CustPosBlock, _
FileDefinitionBuffer, BufLen, _
ByVal CustFileLocation, KeyBufLen, 0)
End Sub
Delphi(セグメント化されたインデックス)
セグメント化されたインデックスの作成に関するコードを参照するには、
Delphi(ファイルの作成)コード サンプルの「キー 3」を参照してください。
var
CustKeyBuffer :record // セグメント キー バッファー
SalesRep :array[0..2] of Char;
NextContact :DateType; //Btrieve データ構造
end;
CustBufLen :Word;
CustKeyNumber:ShortInt;
begin
CustKeyNumber := 3; //SalesRep/Date 順
CustKeyBuffer.SalesRep := 'TO'; //イニシャル TO の人物を検索
CustKeyBuffer.NextContact.Day := 9; //NextContact が 9/9/98
CustKeyBuffer.NextContact.Month := 9;
CustKeyBuffer.NextContact.Year := 1998;
CustBufLen := SizeOf(CustRec);
{次の構文は指定したソート順(キー番号)を使用して最初のレコードを返します}
Status := BTRV(B_GET_EQUAL, //OpCode 5
CustPosBLock, // 既に開いているポジション ブロック
CustRec, // レコードが返されるバッファー
CustBufLen, // 返される最大長
CustKeyBuffer, // レコードから抽出したキー値を返す
CustKeyNumber); // 取得時に使用するインデックス順
C/C++(セグメント化されたインデックス)
struct // セグメント化されたキー バッファー
{
char SalesRep[3];
date_type NextContact; //Btrieve データ構造
} CustKeyBuffer;
BTI_WORD CustBufLen;
char CustKeyNumber;
CustKeyNumber = 3; // SalesRep/Date 順
CustKeyBuffer.SalesRep = "TO"; // イニシャル TO の人物を検索
CustKeyBuffer.NextContact.Day = 9; // NextContact が 9/9/98
CustKeyBuffer.NextContact.Month = 9;
CustKeyBuffer.NextContact.Year = 1998;
CustBufLen = sizeof(CustRec);
/* 指定したソート順(KeyNum)でファイルから先頭レコードを取得する */
iStatus = BTRV(B_GET_EQUAL, //OpCode 5
CustPosBLock, // 既に開いているポジション ブロック
&CustRec, // レコードが返されるバッファー
&CustBufLen, // 返される最大長
CustKeyBuffer, // 検索するレコードを指定
CustKeyNumber); // 取得時に使用するインデックス順
Visual Basic のための Btrieve API 関数の宣言
以下に、Visual Basic のための Btrieve API 関数の宣言を示します。
Declare Function BTRCALL Lib "w3btrv7.dll" (ByVal OP, ByVal Pb$, Db As Any, DL As Long, Kb As Any, ByVal Kl, ByVal Kn) As Integer
Declare Function BTRCALLID Lib "w3btrv7.dll" (ByVal OP, ByVal Pb$, Db As Any, DL As Long, Kb As Any, ByVal Kl, ByVal Kn, ByVal ID) As Integer
Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)