お世話になります。
たまです。
[Windows2000,Delphi5,Oracle]
DBGridに表示させるカラム:Column1が「NUMBER(13,4)」なのですが
グリッド上で10桁以上入力するとエラーとなります。
そこでLength関数よりチェックを行おうと思っているのですが
Column1_Length := Length(Column1_Value);
if Column1_Length > 9 then
begin
Showmessage('桁数オーバー');
end;
を、どのタイミング(イベント?)ですればよいのかわかりません。
お分かりになる方がいましたらよろしくお願い致します。
(13,4)ということは、整数部9桁の小数部4桁だったと思いますが、違いましたっけ?
< (13,4)ということは、整数部9桁の小数部4桁だったと思いますが、違いましたっけ?
はい、その通りです。
いろいろとやってみたのですが(初心者レベルですが(^^; )
グリッドに入力された値(整数部9桁・小数部4桁まで)を変数に格納する場合に
型は、Double型?Extended型?その他? どれが適切なのでしょうか?
それと
小数部は、小数点以下5桁以上は自動的に切り上げになります。
整数部は、10桁以上入力した場合にエラーが発生します。
この時の対象法としてはどのようなものがあるでしょうか?
よろしくお願いいたします。
http://www.borland.co.jp/qanda/delphi/d0002955.html
が参考になると思います。
はい、参考になりました。
「変数に格納する」という問題はフォーマット関数を使いクリアできました。
ありがとうございます。
なのですが
整数部に10桁以上入力した場合の問題がクリアできません。
入力してEnterなりをたたいた後に
「変換エラー。値が範囲外です。」
となってしまいます。
これもフォーマット関数で解決できるのでしょうか?
整数部が10桁以上入力されたことを知ることが出来ればよいのですが(!?)
よろしくお願いします。
こんばんは、たまさん
TField にデータ検証をする為の OnValidate イベントがあります。
以下が例です。
procedure FloatFieldValidate(Sender: TField);
var
Len: Integer;
begin
Len:= Length(Sender.AsString);
if (Len > 9) and (AnsiPos('.', Sender.AsString) > 10) then
raise Exception.Create('整数部の有効桁数を超えています');
end;
上記はイレギュラーな入力を考慮していない為、不完全ですが、
同じくTField のValidChar プロパティで入力制限をかけてやれば、
イレギュラー処理も幾分楽になると思います。
Basserさん、ありがとうございます。
イベントについて初歩的な質問なのですが
> procedure FloatFieldValidate(Sender: TField);
とは、
『Table1コンポーネントをダブルクリックして「項目の追加」を行う画面でカラム:Column1 の OnValidate を設定する』
ということなのでしょうか?
もしあっているならば、こちら↓の手続きで(TTableではなくTQueryですが)
procedure TDM.Query1COLUMN1Validate(Sender: TField);
var
Q_Length: Integer;
Q_Value: String;
begin
Q_Value := Form1.DBGrid1.SelectedField.Text;
Q_Length := Length(Sender.AsString);
if Q_Value > '999999999' then //小数点以下は無視
begin
showmessage('最大値オーバー');
DM.Query1.Cancel;
Abort;
end
else
begin
//(小数点ナシ整数部10桁以上)or(小数点アリで位置が10桁目以上)の場合
if ((Q_Length > 9) and (AnsiPos('.', Sender.AsString) = 0)) or (AnsiPos('.', Sender.AsString) > 10) then
begin
showmessage('入力桁数オーバー');
DM.Query1.Cancel;
Abort;
end;
end;
end;
うまく動作させることができました。
Basserさん、ありがとうございます m(_"_)m
"AnsiPos"の使い方を知りませんでした。
それと
> TField のValidChar プロパティで入力制限をかけて
というのは
Form1.DBGrid1.Fields[3].ValidChars := [#0..#9];
では違いますよね?!
よろしくお願いします。
こんばんは、たまさん
OnValidate イベントの設定方法ですが、
DMQueryが DBGrid にリンクされていると思うので
DMQuery の AfterOpenイベントで
※ フィールド名がわからないので 'Column1'としています
With DMQuery do
If Assigned(FieldByName('Column1')) then
begin
FieldByName('Column1').OnValidate:= TDMQuery1COLUMN1Validate;
// '-', '.', '0'〜'9' のみ入力可
FieldByName('Column1').ValidChars:= [#45,#46,#48..#57];
end
とすれば、別に「項目の追加」をしなくても結構です。
「項目の追加」をした場合は、TFieldの下位クラスの
TFloatFieldが生成されると思うので、
制限によってはValidCharsはいらない場合があると思います。
(TFloatFieldで設定済)
現在、自宅にDelphiの環境が無いので、はっきり答えられないので
申し訳ありません。
Basserさん、ご回答ありがとうございます。
私も現在、自宅にDelphiの環境がないので
年明けにやってみようと思います m(_._)m
お世話になります。
入力制限を…ということでやってみたところうまく動作できました。
Basserさん、ありがとうございます。m(_~_)m
入力できるのは'.'と'0'〜'9'としました。
そこで、'.'を複数個入力された場合にエラー表示をさせようと
OnKeyDownイベントやOnKeyPressイベントで試みてみたのですが、、
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = Char(VK_BACK) then //これはテストでBackSpaceを。。
showmessage('BackSpace');
end;
『.』のキーコードが分からずできませんでした。(;_;)
VK_DECIMALは違うのでしょうか。。?
どうぞよろしくお願いします。
OnKeyPress イベントの引数である Key は
文字型なので
if Key = '.' then
begin
Key:= #0;
Beep;
end;
でいいと思います。
> OnKeyPress イベントの引数である Key は文字型なので
(Sender: TObject; var Key: Char); ← このことですね!?
Basserさん、ありがとうございます。
また質問なのですが (^-^;
入力を行っている時に編集しているセルの値を取得することは可能でしょうか?
例えば、('100'を'101'にする)
1. 編集する前の値が'100'。
2. BackSpaceで'0'をひとつ消して'10'になった時に'10'を取得する。
3. '1'を入力して'101'にした時に'101'を取得する。
このような流れはできますか?
よろしくお願いします。
TDBGrid の機能だけでは無理のような気がします。
自作コンポーネントで TCustomDBGrid.SetEditText を継承したクラスを
作成するのがいいかと思います。
Basserさん、いろいろとご教示ありがとうございます m(_'_)m
そうですか、
TDBGridではできない処理なのですね o(;_;)o
(また質問なのですが)
自作コンポーネントの作成とはこのような感じでよいのでしょうか?
type
TMyDBGrid = class(TDBGrid) //クラスの宣言はこんな感じですか?
//"TCustomDBGrid"?
……………
procedure TMyDBGrid(?); //"?"部は特に書かなくてもよい?
begin
{…処理…}
end;
> TCustomDBGrid.SetEditText を継承したクラスを
SetEditTextはどのように書けばよいのでしょうか?
すみません、基本的な質問で (^-^;
よろしくお願い致します。
私はイベントで取得できるようするのがいいかと思います
以下を例としてあげておきます
type
TGetEditTextEvent = procedure(Sender: TObject; const EditText: String) of object;
TMyDBGrid = class(TDBGrid)
private
FOnGetEditText: TGetEditTextEvent;
protected
procedure SetEditText(ACol, ARow: Longint; const Value: string); override;
public
// public で宣言してますが、コンポーネントととして登録するのなら,
// published で宣言した方がいいかも
property OnGetEditText: TGetEditTextEvent read FOnGetEditText write FOnGetEditText;
end;
implementation
{ TMyDBGrid }
procedure TMyDBGrid.SetEditText(ACol, ARow: Integer; const Value: string);
begin
// 上位クラスのSetEditTextを呼び出し
inherited SetEditText(ACol, ARow, Value);
// イベントが設定されていれば、OnGetEditText イベントを発生させています
if Assigned(FOnGetEditText) then FOnGetEditText(Self, Value);
end;
Basserさん、いつもありがとうございます。
Basserさんのサンプルコードを貼り付けてみました。
"クラスの宣言"と"procedure TMyDBGrid.SetEditText"はうまくできました。
でも OnGetEditTextイベントの設定の仕方がわかりません。。
(TStringGridにはこのイベントがあったのですが…)
自作の関数を作るということなのでしょうか?
public
procedure OnGetEditText; //宣言
procedure FOnGetEditText(???); //?'const Value: string'?
begin
{…処理…}
end;
こんな感じでは…ないですよね?!
「グリッドに入力された値を取得して、その中に'.'が含まれているかをチェックする」
これをしようとする場合、、
『(OnKeyPressイベントは使わずに(FOnGetEditTextイベントより値を取得しチェックする』
ということですよね?
それと、、(Helpを見てみたのですが)
"FOnGetEditText(Self, Value)"の'Self'には'ACol'と'ARow'が入るのでしょうか?
初歩的な質問ばかりですいません。。(^-^;
よろしくお願い致します。
こんばんは、たまさん
>『(OnKeyPressイベントは使わずに(FOnGetEditTextイベントより値を取得しチェックする』
> ということですよね?
いいえ、チェックはOnKeyPressイベントで行う方法でいいと思います。
あくまでイベントは値を取得する為のものです。
Public部に変数を宣言し、そこに格納してもよかったのですが
TCustomDBGridの内部に同じ値が Private で存在している為、
同じ値を格納するのもどうかとゆうことでイベントにしただけです。
>それと、、(Helpを見てみたのですが)
>"FOnGetEditText(Self, Value)"の'Self'には'ACol'と'ARow'が入るのでしょうか?
上記に関しては、ヘルプで Self を見てもらえばわかると思います。
最後にイベントの設定方法ですが
下記のような感じです。
※必要以上のものは省いています
Type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FEditText: String;
FMyGrid : TMyDBGrid;
procedure MyGetEditText(Sender: TObject; const EditText: String);
end;
var
Form1: TForm1;
implementation
procedure TForm1.MyGetEditText(Sender: TObject; const EditText: String);
begin
FEditText:= Value;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FMyGrid:= TMyDBGrid.Create(Self);
FMyGrid.Parent:= Self;
FMyGrid.OnGetEditText:= MyGetEditText;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FMyGrid.Free;
end;
後は、MyGetEditTextで取得したFEditTextの値をOnKeyPressイベントで参照するだけです。
ツイート | ![]() |