pceyes
尊榮會員
發表:70 回覆:657 積分:1140 註冊:2003-03-13
發送簡訊給我
|
對不起, 表達不清,致您 誤解, 以下是昨晚改的, 已可支援原先問題, 但第三層就不行了 [code delphi] (* 取得另一個資料表鍵值欄位資料*) // {margeMdbfield,,,,,} function TForm1.GetMargeMDBField(MargeString:widestring):string; var split_st : Tstringlist; mycn3,myRs3 : Variant; myconnstr3, sqltext : string; mdbfile,tablename,findfield,KeyValue,getfield:string; icnt : integer; begin log_st.add('GetMargeMDBField: ' MargeString); split_st := Tstringlist.create; try split_st.text := stringreplace(MargeString,',',#13,[rfReplaceAll]); if split_st.count < 6 then exit; // 若不合法, 直接離開 (* 遞迴 自己呼叫自己*) if split_st.count > 6 then begin log_st.add('GetMargeMDBField split_st.count > 6'); (*先解決 可執行的部分*) for icnt :=1 to split_st.count-1 do begin if funcode(split_st[icnt])<>'' then split_st[icnt]:= funcode(split_st[icnt]); end;(*先解決 可執行的部分*) // MARGEMDBFIELD if pos('MARGEMDBFIELD',split_st[4])>0 then begin split_st[4] := split_st[4] ',' split_st[5] ',' split_st[6] ',' split_st[7] ',' split_st[8] ',' split_st[9]; split_st[5] := split_st[10]; if Pos('{',split_st[4])>0 then split_st[4]:=funcode(split_st[4]); end; end;(* 遞迴 自己呼叫自己*) // 標準情形 mdbfile := split_st[1]; tablename := split_st[2]; findfield := split_st[3]; KeyValue := split_st[4]; //可以變動 log_st.add('GetMargeMDBField KeyValue: ' KeyValue); getfield := split_st[5]; if Pos('{',keyvalue)>0 then KeyValue := funcode(keyvalue); (*執行資料庫搜尋*) if fileexists(mdbfile) then begin //建立Connection物件 myCn3:=CreateOleObject('ADODB.Connection'); myconnstr3:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' mdbfile; myCn3.Open(myconnstr3); //建立RecordSet物件 myRs3:=CreateOleObject('ADODB.RecordSet'); sqltext := 'select ' getfield ' from ' tablename ' where ' findfield '="' KeyValue '"'; log_st.add('GetMargeMDBField: ' sqltext); myRs3.open(sqltext,myCn3,3,1); if myrs3.recordcount>0 then begin result := vartostr(myrs3.fields[getfield].value); end else begin result := 'Not_Found'; end; log_st.add('GetMargeMDBField Result: ' result); myRs3.close; mycn3.close; myRs3 := null; myCn3 := null; end;(*執行資料庫搜尋*) finally split_st.free; end; end;(* 取得另一個資料表鍵值欄位資料*)[/code]
新的問題如下: {MARGEMDBFIELD,cl.mdb,master,戶號,{MARGEMDBFIELD,cl.mdb,detail,個編,{MARGEMDBFIELD,cl.mdb,linchef,鄰別,{MARGEMDBFIELD,cl.mdb,linchef,鄰別,{ MARGEFIELD 鄰別 },個編},個編},戶號},電話1}
------ 努力會更接近成功
jow
尊榮會員
發表:66 回覆:751 積分:1253 註冊:2002-03-13
發送簡訊給我
|
(1)你的程式碼中, 這裡會產生Memory leaks, 物件產生後, 沒有Free掉. split_st := Tstringlist.create; try split_st.text := stringreplace(MargeString,',',#13,[rfReplaceAll]); if split_st.count < 6 then exit; // 若不合法, 直接離開 (2)程式碼中, 沒有看到處理 {MARGEFIELD, 鄰別} 的動作?! (3)新的問題描述有些怪怪的? 鄰別 call 了兩次 新的問題如下:
{MARGEMDBFIELD,cl.mdb,master,戶號, {MARGEMDBFIELD,cl.mdb,detail,個編, {MARGEMDBFIELD,cl.mdb,linchef,鄰別, {MARGEMDBFIELD,cl.mdb,linchef,鄰別, { MARGEFIELD 鄰別 }, 個編}, 個編}, 戶號}, 電話1}以下提供個人的一些想法和程式流程, 供你參考... [code delphi] unit fMain; interface uses Classes, Forms, StdCtrls, Mask, Controls; type TForm1 = class(TForm) private function Process(S: string): string; function FunctionID(S: string): Integer; function RemoveBraces(S: string): string; function MARGEFIELD(P: TStringList): string; function MARGEMDBFIELD(P: TStringList): string; public function Execute(S: string): string; end; var Form1: TForm1; implementation uses SysUtils; {$R *.dfm} { TForm1 } function TForm1.Execute(S: string): string; var I: Integer; Stack: TStringList; begin //(0)以TStringList來作為Stack, //(1)先找到指令字串的起頭點 '{' //(2)然後循序再找結尾點'}', 並送到 Process()去處理, //(3)回傳值與Stack中pop出來的字串結合, 繼續(2)的動作 //(4)當Stack.Count = 0 時, 完成Execute()動作, 並傳回最後結果 Stack := TStringList.Create; try Result := ''; for I := 1 to Length(S) do begin if S[I] = '{' then begin Stack.Insert(0, Result);//PUSH Result := S[I]; end else begin Result := Result S[I]; if S[I] = '}' then begin //完整指令字串 Result := Stack[0] Process(Result); Stack.Delete(0);//POP if Stack.Count = 0 then Break; end; end; end; finally FreeAndNil(Stack); end; end; function TForm1.RemoveBraces(S: string): string; begin S := Trim(S); if S[1] = '{' then S := Copy(S,2,Length(S)-1); if S[Length(S)] = '}' then S := Copy(S,1,Length(S)-1); Result := S; end; function TForm1.FunctionID(S: string): Integer; begin Result := -1; if S = 'MARGEFIELD' then Result := 0 else if S = 'MARGEMDBFIELD'then Result := 1; end; function TForm1.Process(S: string): string; var P: TStringList;//parameters begin Result := ''; P := TStringList.Create; try P.CommaText := RemoveBraces(S); case FunctionID(P[0]) of 0: Result := MARGEFIELD(P); 1: Result := MARGEMDBFIELD(P); end; finally FreeAndNil(P); end; end; function TForm1.MARGEFIELD(P: TStringList): string; begin Result := ''; if (P.Count = 2) and (P[0] = 'MARGEFIELD') then begin //模擬取得鄰別欄位值, 實際情況可能是從資料庫取得吧?! ^_^ if P[1] = '鄰別' then Result := '09'; end; end; //{margeMdbfield, ,,,,} function TForm1.MARGEMDBFIELD(P: TStringList): string; begin Result := ''; if (P.Count = 6) and (P[0] = 'MARGEMDBFIELD') then begin //各傳入的參數值 // = P[1] // = P[2] // = P[3] // = P[4] // = P[5] //在這裡從資料庫的資料表, 比對 //搜尋欄位的值, 若是等於, 則 //傳回欄位的值. end; end;
end. [/code]
pceyes
尊榮會員
發表:70 回覆:657 積分:1140 註冊:2003-03-13
發送簡訊給我
|
真不好意思, 誏您抓bug 您說得沒錯, memory 會出問題, 另外連問題也錯了 我只是要表現我的問題, 是要重複執行的行為
由於您的協助目前想的方法是先拆成以下陣列
{MARGEMDBFIELD,cl.mdb,master,戶號,X,電話1} 25234567 {MARGEMDBFIELD,cl.mdb,detail,個編,X,戶號} N1233211234567 {MARGEMDBFIELD,cl.mdb,linchef,鄰別,X,個編} L123459789 { MARGEFIELD 鄰別 } 16
然後再代入先前的 X 內 再以反迴圈取得值,再代回 X 您的程式寫得很棒, 我會仔細閱讀, 再次謝謝您!
------ 努力會更接近成功
編輯記錄
pceyes 重新編輯於 2008-12-22 16:38:52, 註解 無‧
|
pceyes
尊榮會員
發表:70 回覆:657 積分:1140 註冊:2003-03-13
發送簡訊給我
|
程式改好了, 有始有終, 做個完整交代.
[code delphi] // RPos(,,) -> position Value // is 0 return latest Position Value // If not found or Too Big Then Return -1 // So We Can Use RPos('{',Xstr,2)<>-1 // For Checking String Having Two Segement (Ex. {abc{1234}def}... ) function TForm1.Rpos(substr:widestring;str:widestring;num:integer):integer; var Num_st : Tstringlist; Pnum : integer; data_str ,head,tail: widestring; begin Num_st := Tstringlist.create; try data_str := str; while pos(substr,data_str)>0 do begin pnum := pos(substr,data_str); Num_st.Add(inttostr(Pnum)); head := copy(data_str,1,pnum-1); tail := copy(data_str,pnum 1,length(str)-length(head)-1); data_str :=head '龘' tail; end; if num=0 then begin // RAT result := strtoint(Num_st[Num_st.count-1]); end else begin // ? times Position if (Num_st.Count > 0)and(num <= Num_st.Count) then begin result := strtoint(Num_st[num-1]); end else begin // not found or Lower then Times result :=-1; end; end; finally Num_st.free; end; end;
(*多重 funcode*) // {MARGEMDBFIELD,CL.MDB,MASTER,戶號,{MARGEMDBFIELD,CL.MDB,DETAIL,個編,{MARGEMDBFIELD,CL.MDB,LINCHIEF,鄰別,{MARGEFIELD 鄰別},個編},戶號},電話1} function Tform1.Mfuncode(str:widestring):string; var Xstr ,head,tail: widestring; Splite_st : Tstringlist; icnt : integer; RepValue : string; begin log_st.add('Mfuncode: ' Str); Splite_st := Tstringlist.create; try Xstr := trim(str); while pos('{',Xstr)>0 do begin Xstr := DelSegeMent(Xstr);(*刪除前後{}*) // 取字串前段 head := copy(Xstr,1,pos('{',Xstr)-1); delete(Xstr,1,pos('{',Xstr)-1); // 取字串尾段 if rpos('}',xstr,2)<>-1 then begin // 表示 兩層以上 // {MARGEMDBFIELD,cl.mdb,detail,個編,{MARGEMDBFIELD,cl.mdb,linchef,鄰別,{MARGEFIELD鄰別},個編},姓名} tail := trim(copy(Xstr,rpos('}',Xstr,0) 1,length(str)-length(head))); delete(Xstr,rpos('}',Xstr,0) 1,length(str)-length(head)); end else begin // 表示 兩層以內 // {MARGEMDBFIELD,cl.mdb,linchef,鄰別,{MARGEFIELD鄰別},中文鄰別} tail := trim(copy(Xstr,rpos('}',Xstr,0) 1,length(str)-length(head))); end; if head <> '' then begin Splite_st.add('{' head FinishCode tail '}'); end; end;(*while*) delete(Xstr,rpos('}',Xstr,0),length(str)-length(head)); Splite_st.add('{' Xstr '}'); (*反向置換值*) // 先處理 {MARGEFIELD鄰別} // 再處理 {MARGEMDBFIELD,cl.mdb,linchef,鄰別,,個編} for icnt := splite_st.count-1 downto 0 do begin // 有 才處理 if pos(FinishCode ,splite_st[icnt])>0 then begin splite_st[icnt] := stringreplace(splite_st[icnt],FinishCode,RepValue,[rfReplaceAll]); end; RepValue := funCode(splite_st[icnt]); end;(*for 反向置換值*) result := RepValue; finally freeandnil(splite_st); end; end;(*多重 funcode*)
[/code]
------ 努力會更接近成功
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!
|
| |