線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2304
推到 Plurk!
推到 Facebook!

請教下關於數值賦值的問題.

答題得分者是:P.D.
guyuelang
一般會員


發表:6
回覆:13
積分:3
註冊:2008-12-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-12-26 17:12:01 IP:222.242.xxx.xxx 訂閱
我在一個stringgrid中的3列和4列中輸入了來自表中的數值,帶一位小數
我想把3列和4列相加和2列比大小,
StrToInt(stringgrid1.Cells[2,x])>StrToInt(stringgrid1.Cells[3,x]) StrToInt(stringgrid1.cells[4,x])
我這么能比較,不加strtoint的時候也能比較但數據前加0就比較不出了
如果列2大 就賦空值再輸入
輸入完后 我再加入一行的時候 這個時候就提示出錯了 提示 '' is not a valid intrger value
請教各位大大,我該怎么辦,是那裡做錯了呢?謝謝!
herbert2
尊榮會員


發表:58
回覆:640
積分:894
註冊:2004-04-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-12-26 20:20:57 IP:211.72.xxx.xxx 訂閱

===================引 用 guyuelang 文 章===================
我在一個stringgrid中的3列和4列中輸入了來自表中的數值,帶一位小數
我想把3列和4列相加和2列比大小,
StrToInt(stringgrid1.Cells[2,x])>StrToInt(stringgrid1.Cells[3,x]) StrToInt(stringgrid1.cells[4,x])
我這么能比較,不加strtoint的時候也能比較但數據前加0就比較不出了
疑惑: 既然帶一位小數, 為何用 StrToInt() 做比較?

如果列2大 就賦空值再輸入
輸入完后 我再加入一行的時候 這個時候就提示出錯了 提示 '' is not a valid intrger value
疑惑: 輸入完後是否有 OnExit Event ? 『再加入一行』指 Row 還是 Column ? 是否此時才觸發 OnExit ?

請教各位大大,我該怎么辦,是那裡做錯了呢?謝謝!
建議: 敘述明確, 附簡要的 Code, 版友們才好幫忙!

P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-12-26 23:46:14 IP:61.67.xxx.xxx 未訂閱

===================引 用 guyuelang 文 章===================
我在一個stringgrid中的3列和4列中輸入了來自表中的數值,帶一位小數
我想把3列和4列相加和2列比大小,
StrToInt(stringgrid1.Cells[2,x])>StrToInt(stringgrid1.Cells[3,x]) StrToInt(stringgrid1.cells[4,x])
樓上已經指出一個問題, 小數是什麼型態, 先搞清楚!
還有使用strtoint()有很大風險, 如果cell中有非數值字串就引發錯誤了, 你應該使用 strtointdef(), 查一下help就知道用法
我這么能比較,不加strtoint的時候也能比較但數據前加0就比較不出了
把字串的定義再翻書仔細看過!
字串如何比對, 原則上逐字, 有結果就結束, so, 你猜猜看 '2' 與 '099' 那一個大

如果列2大 就賦空值再輸入
輸入完后 我再加入一行的時候 這個時候就提示出錯了 提示 '' is not a valid intrger value
加入一行, 這是什麼東東?
請教各位大大,我該怎么辦,是那裡做錯了呢?謝謝!
你錯的是對基本型態的定義完全不熟, 必須要再加強! 不用客氣了!
guyuelang
一般會員


發表:6
回覆:13
積分:3
註冊:2008-12-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-12-30 10:59:50 IP:222.242.xxx.xxx 訂閱
出差去了 抱歉 回覆晚了
看完二位的回覆 臉馬上紅了
說得太對了 我是初學的 沒有把基本功好好的學好
厚著臉皮再請教下 那裡有比較好的學習函數的
估計還有很多不好的習慣在裡面
把源碼弱弱貼出 占用各位寶貴的時間 請發狠的教訓我吧 ~~~~(>_<)~~~~

[code delphi]
unit wpff;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DBGrids, ExtCtrls, RzPanel, DB, StdCtrls, Buttons, Grids;

type
TFwpff = class(TForm)
StringGrid1: TStringGrid;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
Label1: TLabel;
Label2: TLabel;
ComboBox1: TComboBox;
DataSource1: TDataSource;
RzPanel1: TRzPanel;
DBGrid1: TDBGrid;
Label3: TLabel;
Edit1: TEdit;
procedure FormShow(Sender: TObject);
Function JCxmlb: Boolean;
Function IsNull: Boolean;
procedure ComboBox1Select(Sender: TObject);
procedure StringGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure BitBtn1Click(Sender: TObject);
procedure StringGrid1KeyPress(Sender: TObject; var Key: Char);
procedure DBGrid1DblClick(Sender: TObject);
procedure DBGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: string);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Fwpff: TFwpff;
x,y: Integer;
Ss:Boolean = False ;//判断当焦点在StringGrid1上时是否按回车键
s1: Boolean = False;//在StringGrid1的OnSetEditText事件中是否执行相关代码,其作用是防止连续出现对话框
s2: Boolean = False; //在StringGrid1的OnSetEditText事件中是否执行相关代码,其作用是防止删除行时,统计的数量金额错误

implementation
uses date,m1;

{$R *.dfm}
procedure TFwpff.BitBtn1Click(Sender: TObject);
var
m: Integer;
begin
if (JCxmlb = True)then
begin
datam1.ADOConnection1.BeginTrans;
Try
For m := 1 to StringGrid1.RowCount-1 do
begin
with datam1.ADOtree2 do
begin
Close;
SQL.Clear;
SQL.Add('insert wupingfachu Values(:a,:b,:c,:d,:e)');
Parameters.ParamByName('a').Value := Trim(StringGrid1.Cells[0,m]);
Parameters.ParamByName('b').Value := Trim(StringGrid1.Cells[1,m]);
Parameters.ParamByName('c').Value := Strtoint(StringGrid1.Cells[2,m]);
Parameters.ParamByName('d').Value := Trim(StringGrid1.Cells[5,m]);
Parameters.ParamByName('e').Value := now;
ExecSQL;
end;
end;
datam1.ADOConnection1.CommitTrans;
Application.MessageBox('發出數據成功。','提示',64);
Except
datam1.ADOConnection1.RollbackTrans;
Application.MessageBox('系統出錯。','提示',64);
Close;
end;
end
else
Application.MessageBox('項目列表有錯誤,請查看是否有空項。','提示',64);
end;


procedure TFwpff.ComboBox1Select(Sender: TObject);
begin
StringGrid1.SetFocus;
StringGrid1.Col := 2;
end;
procedure TFwpff.DBGrid1DblClick(Sender: TObject);
begin
with datam1.ADOgongdi1 do
begin
Close;
SQL.Clear;
SQL.Add('select id,sum(shuliang) as caigou from wupingfachu where id=:a');
sql.add('group by id');
Parameters.ParamByName('a').Value := Trim(datam1.ADOtree1.FieldByName('id').Value);
Open;
end;
StringGrid1.Cells[0,StringGrid1.RowCount-1] := datam1.ADOtree1.FieldByName('id').Value;
StringGrid1.Cells[1,StringGrid1.RowCount-1] := datam1.ADOtree1.FieldByName('name').Value;
StringGrid1.Cells[3,StringGrid1.RowCount-1] := datam1.ADOgongdi1.FieldByName('caigou').Value;
StringGrid1.Cells[4,StringGrid1.RowCount-1] := datam1.ADOtree1.FieldByName('shuliang').Value;
StringGrid1.Cells[5,StringGrid1.RowCount-1] := datam1.ADOtree1.FieldByName('didian').Value;
StringGrid1.Cells[6,StringGrid1.RowCount-1] := formatdatetime('yyyy/mm/dd',now);
DataSource1.DataSet := nil;
DBGrid1.Visible := False;
StringGrid1.SetFocus;
StringGrid1.Col := 2;
end;
procedure TFwpff.DBGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_ReTurn then
DBGrid1.OnDblClick(Sender);
end;
procedure TFwpff.FormShow(Sender: TObject);
begin
edit1.Text:=formatdatetime('yyyy/mm/dd',now);
StringGrid1.Cells[0,0]:=' 編號';
StringGrid1.Cells[1,0]:=' 名稱';
StringGrid1.Cells[2,0]:=' 數量';
stringgrid1.cells[3,0]:=' 采購數量';
stringgrid1.Cells[4,0]:=' 庫存數量';
StringGrid1.Cells[5,0]:=' 地點';
StringGrid1.Cells[6,0]:=' 日期';
with datam1.ADOwuping do
begin
close;
sql.Clear;
sql.Add('select distinct didianm from diming');
open;
end;
while Not Datam1.ADOwuping.Eof do
begin
ComboBox1.Items.Add(Datam1.ADOwuping.FieldByName('didianm').Value);
combobox1.ItemIndex:=0;
Datam1.ADOwuping.Next;
end;
end;
procedure TFwpff.StringGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
R,L: Integer;
begin
S1 := False;
s2 := False;
ss := False;
if key = VK_Delete then
begin
if StringGrid1.RowCount>2 then
begin
If Application.MessageBox('確實要刪除這個記錄嗎?','提示',MB_YESNO )= ID_Yes then
begin
if IsNull = False then
if x <> StringGrid1.RowCount-1 then
begin
For r := x 1 to StringGrid1.RowCount-1 do
For l := 0 to StringGrid1.ColCount-1 do
StringGrid1.Cells[l,r-1]:= StringGrid1.Cells[l,r];
end;
StringGrid1.RowCount := StringGrid1.RowCount-1;
s2 := True;
Exit;
end;
end
else if StringGrid1.RowCount = 2 then
begin
If Application.MessageBox('確實要刪除這個記錄嗎?','提示',MB_YESNO )= ID_Yes then
begin
StringGrid1.Cells[0,x]:= '';
StringGrid1.Cells[1,x]:= '';
StringGrid1.Cells[2,x]:= '';
StringGrid1.Cells[3,x]:= '';
StringGrid1.Cells[4,x]:= '';
StringGrid1.Cells[5,x]:= '';
StringGrid1.Cells[6,x]:= '';
StringGrid1.SetFocus;
StringGrid1.Col := 2;
end;
end;
end;
if (key = Vk_Next)and(DBGrid1.Visible = True)then
begin
DBGrid1.SetFocus;
Exit;
end;
if (Key = VK_Down)and(IsNull = False)and(x = StringGrid1.RowCount-1) then
begin
StringGrid1.RowCount := StringGrid1.RowCount 1;
// StringGrid1.Cells[0,StringGrid1.RowCount-1]:= StringGrid1.Cells[0,StringGrid1.RowCount-2];
StringGrid1.Col := 2;
Exit;
end;
if Key = Vk_ReTurn then
begin
Ss := True;
DataSource1.DataSet := Nil;
DBGrid1.Visible := False;
with datam1.ADOtree1 do
begin
Close;
SQL.Clear;
SQL.Add('select * from wupingshuju where didian = :a');
Parameters.ParamByName('a').Value := Trim(combobox1.Text);
Open;
end;
if datam1.ADOtree1.RecordCount>0 then
if datam1.ADOtree1.RecordCount>1 then
begin
DataSource1.DataSet := datam1.ADOtree1;
DBGrid1.Visible := True;
dbGrid1.SetFocus;
end
else
begin
Application.MessageBox('選擇的地方沒有數據!','提示',64);
{ StringGrid1.Cells[0,x]:= '';
StringGrid1.Cells[1,x]:= '';
StringGrid1.Cells[2,x]:= '';
StringGrid1.Cells[3,x]:= '';
StringGrid1.Cells[4,x]:= '';
StringGrid1.Cells[5,x]:= ''; }
StringGrid1.SetFocus;
end;
end;
if (Key = VK_Shift)and(JCxmlb = True) then
BitBtn1.SetFocus;
end;
procedure TFwpff.StringGrid1KeyPress(Sender: TObject; var Key: Char);
var
mm: Boolean;
begin
if y = 2 then
begin
mm := (Key <#8)or(Key >#8)and(Key<#48)or(Key>#57);
if mm then
Key := #0;
end;
end;
function TFwpff.JCxmlb: Boolean;
var
a,b: integer;
begin
ReSult := True;
for a := 1 to StringGrid1.RowCount-1 do
For b := 0 to StringGrid1.ColCount-1 do
if Trim(StringGrid1.Cells[b,a]) = '' then
begin
Jcxmlb := False;
break;
end ;
end;
function TFwpff.IsNull: Boolean;
var
b: integer;
begin
isNull := False;
For b := 0 to StringGrid1.ColCount-1 do
begin
if StringGrid1.Cells[b,x]='' then
begin
Isnull := True;
break;
end;
end;
end;
procedure TFwpff.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
begin
y := ACol;
x := ARow;
if ACol = 2 then
StringGrid1.Options := StringGrid1.Options [goEditing]
else
StringGrid1.Options := StringGrid1.Options -[goEditing];
end;
procedure TFwpff.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: string);
begin
if strtointdef(stringgrid1.Cells[2,x])>strtointdef(stringgrid1.Cells[3,x]) strtointdef(stringgrid1.cells[4,x]) then
begin
Application.MessageBox('輸入的數大於庫存的數。','提示',64);
StringGrid1.Cells[2,x]:='';
StringGrid1.Col := 2;
end;
end;
end.

[/code]

P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-12-30 12:56:12 IP:61.67.xxx.xxx 未訂閱

嗯! 還有得救啦!
至於要看那本函數, 說真的還沒有呢? 現在的Delphi只能靠經驗傳承, 市面上要找到書可以說zero了, 所以多問, 多被罵就是經驗, 也不用怕害羞, 反正我也看不到你啊!
但你貼上全部的code, 我們實在沒有太多時間去一一品味, 往後最好只把重點貼出來, 如果要整個程式碼, 可以用上傳方式壓縮你的程式上傳到kiop, 有興趣的人會去解開來看
guyuelang
一般會員


發表:6
回覆:13
積分:3
註冊:2008-12-26

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-12-30 15:06:46 IP:222.242.xxx.xxx 訂閱
多謝D大大的耐心回覆 
我覺得問題還是出在procedure TFwpff.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: string);
begin
if StrTofloat(stringgrid1.Cells[2,x])>StrToFloat(stringgrid1.Cells[3,x]) StrToFloat(stringgrid1.cells[4,x]) then
begin
StringGrid1.Cells[2,x]:=FloatToStr(0);
StringGrid1.Col := 2;
end;
end;
這裡我明明輸入了單步運行時候發現value還是等於‘’
寧外還請教下herbert2 爲什麽還要OnExit Event 我沒有用啊
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-12-30 23:13:48 IP:61.67.xxx.xxx 未訂閱

===================引 用 guyuelang 文 章===================
多謝D大大的耐心回覆
我覺得問題還是出在procedure TFwpff.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;
const Value: string);
begin
if StrTofloat(stringgrid1.Cells[2,x])>StrToFloat(stringgrid1.Cells[3,x]) StrToFloat(stringgrid1.cells[4,x]) then
Strtofloat() 的函數在這個地方使用十分不恰當, 因為一但cells值不為float時, 會引發錯誤
例如:Strtofloat('2. 33') -->有看出錯誤嗎?
或者 StrtoFloat('2.O1')
一般我會宣告一個變數, 然後利用這樣的寫法 a1: string;
這種做法還是會引發錯誤, 但卻不會中斷程式的執行, 讓使用者不覺得程式有問題
try
a1:=floattostr(Strtofloat(string.....));
except
a1:= ''; 這裡可以使用任何你識別的字串
end;
begin
StringGrid1.Cells[2,x]:=FloatToStr(0);
StringGrid1.Cells[2,x]:='0' -->這樣不就好了, 為什麼要多一個floattostr()造成引發錯誤的可能性?
這是脫褲子放屁的想法
StringGrid1.Col := 2;
end;
end;
這裡我明明輸入了單步運行時候發現value還是等於‘’
單步運行要看你tracer的位置, 一般我都會使用showmessage()做為除錯, 放在結果執行之後, 這是最安全的做法
至於你把這件事放在setEditText上是否恰當, stringgrid 有很多事件可用, 不妨一個個試試看, 總可以找出一個適合放這段的位置(我並沒有說放在setEditText是錯的哦, 不要誤解我的意思, 只希望你對event的觸發動機可以自己去發掘, 這才是你自己的經驗)
寧外還請教下herbert2 爲什麽還要OnExit Event 我沒有用啊
編輯記錄
P.D. 重新編輯於 2008-12-30 23:15:49, 註解 無‧
P.D. 重新編輯於 2008-12-30 23:19:37, 註解 無‧
guyuelang
一般會員


發表:6
回覆:13
積分:3
註冊:2008-12-26

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-12-31 09:20:58 IP:222.242.xxx.xxx 訂閱
經驗啊 這個就是要長久中鍛煉出來的 謝一個先 經驗直徑傳功給我了
D大大的經驗說得對 先宣告為妙

a1:=floattostr(Strtofloat(string.....));
請問這句是先float過來又float過去?這有什麽好處呢?

:-P 我本來是這么些的StringGrid1.Cells[2,x]:='0'
後來想是先float了就再把它float進去看看對不 結果不對

D大大說得對 showmessage()做為除錯, 放在結果執行之後, 這是最安全的做法

我還試了KeyDown結果一樣 估計不是這個的問題
我想其實就是cell的值比較的問題 直接比較也可以 就是怎么改成數值比較 怎么改安全點
我估計是沒有使用對函數

P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-12-31 10:54:14 IP:61.67.xxx.xxx 未訂閱
a1:=floattostr(Strtofloat(string.....));
請問這句是先float過來又float過去?這有什麽好處呢?


>>因為 a1 宣告為 sring
先strtofloat() 是把 cell值轉為 float, 如果沒有錯誤的話, 再floattostr()轉回string給 a1
如果有錯, 則引發 except 的程式
為什麼要轉, 如果程式是這麼寫
var a1: float;
try
a1:= strtofloat(stringgrid1.cell[2,x]);
except
a1:= 0;
end;

你認為這段程式有什麼瑕疵, 想想看
guyuelang
一般會員


發表:6
回覆:13
積分:3
註冊:2008-12-26

發送簡訊給我
#10 引用回覆 回覆 發表時間:2009-01-05 17:19:14 IP:222.242.xxx.xxx 訂閱

var a1: float;
try
a1:= strtofloat(stringgrid1.cell[2,x]);
except
a1:= 0;
end;

你認為這段程式有什麼瑕疵, 想想看

抱歉 抱歉 又出去了
我看來好像是很對的 沒有什麽錯誤啊
我想我那個能不能用 FormatFloat('#0.00',stringgrid1.Cells[2,x],AsFloat);
看來還是不用stringgrid的好

還有請問 我這個貼是不是要馬上結案?
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#11 引用回覆 回覆 發表時間:2009-01-06 00:40:27 IP:61.67.xxx.xxx 未訂閱
1.我並沒有說這樣寫法有錯(事實上沒錯), 我說的是瑕疵
2.其實說了那麼多, 發現你還是無法看到事實的重點
3.之所以會這麼做, 主要是STRTOFLOAT()的轉換, 如果內容值不為標準的數值型態, 就會引發錯誤, 例如STRTOFLOAT('A')或STRTOFLOAT(' '), 而偏偏STRINGGRID 又是STRING型態, 所以為了避免使用者在STRINGGRID輸入非數字的內容, 才會有這樣的判斷式出現, 而這支的瑕疵在那? 如果 TRY 以下轉換到A1有問題(如上面所言的操作), 會觸發 A1:=0, 但如果程式是如此呢!
stringgrid1.cell[2,x]為'0'時, 這樣的是否會觸發except呢? 答案是應該不會吧! 這樣 a1值也是為0, 那你如何來判斷轉換當中有錯誤呢
所以回到最上面的回覆, 我會設定 a1 為字串, 這樣在觸發except時, 我可以指定 a1:= 'error', 然後在後面程式段就可以判斷
if a1='error' then showmessage('wrong value')的訊息, 希望你看得懂!

至於這段寫法
FormatFloat('#0.00',stringgrid1.Cells[2,x],AsFloat);
我覺得很怪, 那邊抄來的, 你run看看可以執行嗎? 還是我個人孤陋寡聞, 有這種寫法
你是不是要再查一下help
===================引 用 guyuelang 文 章===================

var a1: float;
try
a1:= strtofloat(stringgrid1.cell[2,x]);
except
a1:= 0;
end;

你認為這段程式有什麼瑕疵, 想想看

抱歉 抱歉 又出去了
我看來好像是很對的 沒有什麽錯誤啊
我想我那個能不能用 FormatFloat('#0.00',stringgrid1.Cells[2,x],AsFloat);
看來還是不用stringgrid的好

還有請問 我這個貼是不是要馬上結案?
guyuelang
一般會員


發表:6
回覆:13
積分:3
註冊:2008-12-26

發送簡訊給我
#12 引用回覆 回覆 發表時間:2009-01-06 12:34:46 IP:222.242.xxx.xxx 訂閱
我還是用的STRTOFLOAT()轉換的 我在KeyPress加入了判斷(key <#8)or(Key>#8)and(key < #46)or(key>#46)and(key <#48)or(key > #57)
限制了輸入 應該用STRROFLOAT()就可以了
應該是艱難的看懂了 唉 基礎太差
麻煩大大這么細心的解釋了
至於這段寫法
FormatFloat('#0.00',stringgrid1.Cells[2,x],AsFloat);
我覺得很怪, 那邊抄來的, 你run看看可以執行嗎? 還是我個人孤陋寡聞, 有這種寫法
大大火眼啊 是在GOOGLE上找來的 我看函數里有FORMAT能格式化字段 想試下

D大大 估計是夜行者這么晚了還在回 呵呵
我發現我現在很春蟲蟲了 問題解決了
提示是提示 '' is not a valid intrger
我就在前面加個 if trim(stringgrid1.Cells[2,x])<>'' then 就可以 唉 越來越小白了
覺得比較還是放在SetEditText好些吧
系統時間:2024-04-29 15:44:52
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!