請教下關於數值賦值的問題. |
答題得分者是:P.D.
|
guyuelang
一般會員 發表:6 回覆:13 積分:3 註冊:2008-12-26 發送簡訊給我 |
我在一個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 發送簡訊給我 |
===================引 用 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 發送簡訊給我 |
===================引 用 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 發送簡訊給我 |
出差去了 抱歉 回覆晚了
看完二位的回覆 臉馬上紅了 說得太對了 我是初學的 沒有把基本功好好的學好 厚著臉皮再請教下 那裡有比較好的學習函數的 估計還有很多不好的習慣在裡面 把源碼弱弱貼出 占用各位寶貴的時間 請發狠的教訓我吧 ~~~~(>_<)~~~~ [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 發送簡訊給我 |
|
guyuelang
一般會員 發表:6 回覆:13 積分:3 註冊:2008-12-26 發送簡訊給我 |
多謝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 發送簡訊給我 |
===================引 用 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 我沒有用啊 |
guyuelang
一般會員 發表:6 回覆:13 積分:3 註冊:2008-12-26 發送簡訊給我 |
經驗啊 這個就是要長久中鍛煉出來的 謝一個先 經驗直徑傳功給我了
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 發送簡訊給我 |
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 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
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 發送簡訊給我 |
我還是用的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好些吧 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |