Btrieve API プログラミング
 
このページをシェアする                  
Btrieve API プログラミング
この章では、Btrieve API を直接呼び出して PSQL アプリケーションの開発を開始する場合に役立つ情報を示します。最も一般的なプログラミング作業には、Visual Basic と Delphi のサンプル コードとサンプル構造体が付属しています。
以下の項目について説明します。
Btrieve API プログラミングの基礎
Visual Basic に関する注記
Delphi に関する注記
PSQL アプリケーションの起動
Btrieve API のコード サンプル
Visual Basic のための Btrieve API 関数の宣言
Btrieve API プログラミングの基礎
以下のフロー チャートは、レコードの挿入、更新および削除にアプリケーションでどの Btrieve オペレーションを使用したらよいかを示しています。API の詳細については、『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 で PSQL アプリケーションを開発する際、次のことに注意してください。
Visual Basic では、ユーザー定義データ型に関するバイト アライメントの問題があることがわかっています。また、この問題に関する情報と PAln32.DLL、Btrieve Alignment DLL の使用方法については、Btrieve API に関するセクション Visual Basic を参照してください。
結果のレコードの種類ごとにレコード クラスを作成すると、以下の手順に示すようなデータ アクセスが容易に行えます。
1 Record というクラスを作成します。
2 レコードのレイアウトを定義する構造体を作成します。
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
3 iAsciiFlag = 1 と ispacing=0 を使用してデータを Rec のインスタンスへ読み込みます。
Dim instofRec As New Rec
4 ドット表記でデータにアクセスします。
instofRec.Name="Jeff"
5 レコード クラスを使用してすべての instofRec データ操作を行います。
Delphi に関する注記
以下に、Delphi で 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()ルーチンを使用する場合、クエリがフィールドを一覧する順序と同じ順序でグリッドを詰める必要があります。
PSQL アプリケーションの起動
PSQL アプリケーションを開発する場合は、特定のプログラミング インターフェイスに対応するソース モジュールを組み入れる必要があります。
BTRCONST と BTRAPI32 – Btrieve アプリケーションに必要なソース モジュール
PSQL ソース モジュールの追加
アプリケーションを開発しているプログラミング インターフェイスに Btrieve ソース モジュールを組み込む必要があります。
Visual Basic プロジェクトに Btrieve ソース モジュールを追加するには
1 Visual Basic で新しいプロジェクトを起動します。
2 既存の標準モジュールをプロジェクトに追加します。
3 PSQL ソース モジュールを追加します。
Delphi プロジェクトに Btrieve ソース モジュールを追加するには
1 Delphi で新しいプロジェクトを起動します。
2 プロジェクト]メニューから[オプション]を選択します。
3 ディレクトリ]タブをクリックします。
4 検索パス]データ フィールドに「<パス>\INTF\DELPHI」を挿入します(パス部分は PSQL SDK コンポーネントのインストール先です)。
5 USES 句にソース モジュールを組み入れます。
Btrieve API のコード サンプル
ここでは、Btrieve API で実行できる以下のタスクの Visual Basic、Delphi および C/C++ のコード サンプルを示します。
ファイルの作成
レコードの挿入
レコードの更新
Step オペレーションの実行
Get オペレーションの実行
チャンク、BLOB、および可変長レコード
セグメント化されたインデックスの処理
ファイルの作成
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;           //array[1..128] of byte
  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(レコードの挿入)
Delphi(レコードの挿入)
C/C++(レコードの挿入)
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); {実行は不要}
 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;   //挿入時の "カレンシー変更なし" を指定
  memset(CustKeyBuffer, sizeof(CustKeyBuffer), 0);   //実行は不要
  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(レコードの更新)
Delphi(レコードの更新)
C/C++(レコードの更新)
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); {実行は不要}
 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);   //実行は不要
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);     //Reset - リセット - 前の 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; {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 のコード サンプルで使用される構造体です。
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)    '読み取ったバイト数からグラフィック レコードの
                                '固定長を差し引いた値を保存する
                                'グラフィック レコードの最初のチャンクの固定長は
                                '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/可変長レコード)-サンプル構造体
 
Type 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);
 
    {次の構文は、指定したソート順(KeyNum)を使用してファイルから先頭レコードを取得します}
  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)