☆BDE Table.Locateで・・・。

ずいぶん昔に作ったBDEを使ったプログラムをDelphi2007で再コンパイルして仕事をしていたところ、 「この操作は行えません」というエラーメッセージが頻繁に表示されるようになりました。

そこでシンプルなサンプルを作って、原因を探したところ、Locateメソッドの検索文字がフィールドサイズより長い場合にエラーになっていました。(そんな仕様だっけ?)

又、この問題とは別に、TEditのMaxLengthがランタイムテーマの影響を受けることが確認できました。 検索文字入力用Editには、元々MaxLengthをフィールド長さで設定してあり、今まで検索文字がフィールドサイズを超えることがなかったのですが、ランタイムテーマの影響で、バイト数から文字数扱いになってしまい、エラーが起こったようです。

今回は、文字長さをバイト数で計算して、フィールド長さ以下であることを確認の上、Locateメソッドに渡すことにより、この問題を解決しました。

※テスト用プログラムです。データベースは、DBDEMOSのemployee.dbを使っています。
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables;

type
  TForm1 = class(TForm)
    Table1: TTable;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  S1, S2: String;
begin
  S1 := Edit1.Text;
  S2 := Edit2.Text;
  Table1.Locate('LastName;FirstName',VarArrayOf([S1, S2]), [loPartialKey]);
end;

end.

Locate

|

☆DBGridでのBeginDrag

DBGridのOnMouseDownは、セルのある場所では動きません。OnMouserDownでの処理を行いたい場合には、通常コンポーネントにしてMouseDownをoverrideし、そこで処理をさせています。 ただ、Drag開始のためだけにコンポーネントを作るのも面倒なので、何か方法がないかいろいろと試し、次のようにOnMouseMoveを使えばうまくいきました。
// BDEでTableにDEMOSのanimals.dbfを設定して試しました。
// Memo1とTable1-DataSource1-DBGrid1を配置しています。

var
  FieldIndex: Integer;

procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  Cell: TGridCoord;
begin
  // BeginDrag
  if (csLButtonDown in DBGrid1.ControlState) then
  begin
    Cell := DBGrid1.MouseCoord(X, Y);
    FieldIndex := Cell.X - 1;
    DBGrid1.BeginDrag(False);
  end;
end;
Memo1のDrag&Dropの設定を行います。
procedure TForm1.Memo1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := True;
end;


procedure TForm1.Memo1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  Memo1.Lines.Add(Table1.Fields[FieldIndex].AsString);
end;
一番簡単なのは、DragModeをdmAutomaticにすることですが、常にDrag&Drop処理だけで使うわけではないので除外ですね。

※Delphi Users' Forumへコメントしたものです(^^;

|

■BDEのエリアスが消えた!?

Delphi2005をアップデートしてから、BDEのエリアスが消えていました。他に原因が思い当たらないことから、Update1のインストール作業によるものではないかと思っています。Delphi2005のアンインストールによって、エリアスが消えることはコメントされていますが、インストールで消えるというコメントはありません。でも念のため、アップデートされる前にidapi32.cfgをバックアップされる方がいいかも知れませんね。

Delphi 2005 に関するQ&A

以前のバージョンのDelphiまたはC++Builderがインストールされている場合のDelphi 2005のアンインストールに関する既知の問題

|