?? threadp.pas
字號:
//說明:
//1、字段的統一定義(都是代碼的定義):
// 地市 CITYCODE
// 局向 OFF_NO_HOME
// 星級 DJDM
// 時間 SJ
// 性質 XZDM
// 品牌 PP
// 數量 SL
// 性別 COLNAME
// 喜好 JHDM
// 狀態 ZTDM
// 業務 YWDM
// 行業 HYDM
{****************曾慶順改動*******************
1、線程的總體思路是錯的,數據庫的安全訪問的問題
2、在線程執行時一直占用主線程,調用VCL。要實現線程安全
3、刪除一些沒有必要的東西,改掉了recorecount取值的方法
//2002。09。16
4、加了互斥(臨界區),防止多線程共同申請資源時出現死鎖
2002、08、27
待處理的問題
1、執行函數里有個locate
2、執行函數的加詳細數值的循環有問題
3、線程初始化時有問題,沒必要重復做,
還有就是自增變量會超過長度,不能用靜態數組
**********************************************}
Unit ThreadP;
Interface
Uses
Windows,Classes, Messages, SysUtils, Graphics, ExtCtrls, Db, DBTables, XLGrids, XLCells, forms,
Chart, Series, Dialogs, ComObj, main ;
Type
TQXSql = Record
QXSumSql, QXSeriesSql, QXTotalSumSql: String;
End;
Type
TDrawThread = Class(TThread)
Private
Sheet: TXLSheet;
Querytj, Querytj2, Querytj3: Tquery;
cityname: Array[0..20] Of String;
offname: Array[0..20] Of Array[0..20] Of String;
starname: Array[0..20] Of String;
ppname: Array[0..255] Of String;
lbname: Array[0..20] Of String;
xbname: Array[0..5] Of String;
TypeName: Array[0..99] Of String;
onecity: integer;
tital: integer;
querytjCount,querytj3Count :integer;
DataBase: String;
//全局變量
P_i,P_j,P_Bz,P_FieldCount :integer;
P_value,P_cityname :string;
//標志是否加合計底下的
P_add,P_INDISEQBz :boolean;
//
P_count :integer;
//
P_str :string;
//異常
P_Exception :Exception;
temp: Array[0..49] Of Variant;
//初始化
Procedure initialize;
//得到幾個轉換的名稱
Function GetName(s: String): String;
//
Procedure GetTotal(i, j, k: integer);
//用來調用vcl函數等,實現線程同步
Procedure RunUpdate;
//修復增加統計詳細項目信息時把該合成的加在一起
Procedure RunModify;
//異常處理過程
Procedure ShowError;
procedure inisheet;
Protected
Procedure Execute; Override;
Public
P_Result :boolean;
Constructor Create(XLSheet: TXLSheet; QueryGroup, QueryAll, QueryCol: Tquery; count1,Count2 :integer;DataBaseName: String; OneCityName: integer = 0; title: integer = 0);
End;
//執行為true表示成功
Function RunThead(XLSheet: TXLSheet; QueryGroup, QueryAll, QueryCol: Tquery;count1,Count2 :integer; DataBaseName: String; OneCityName: integer = 0; title: integer = 0):TDrawThread;
Function To_CityNo(pCityNo:String):Integer;
Implementation
Constructor TDrawThread.Create(XLSheet: TXLSheet; QueryGroup, QueryAll, QueryCol: Tquery;count1,Count2 :integer; DataBaseName: String; OneCityName: integer = 0; title: integer = 0);
Begin
Inherited Create(true);
Sheet := xlsheet;
P_Result :=true;
P_add :=true;
P_INDISEQBz :=false;
//存的是統計類型的詳細的項目
querytj := querygroup;
//具體的統計數值合計
querytj2 := queryall;
//統計的類型
Querytj3 := querycol;
onecity := onecityname;
querytjCount :=count1;
querytj3Count :=Count2;
database := databasename;
tital := title;
FreeOnTerminate := True;
Resume;
End;
//外部調用線程,返回為真就是成功
Function RunThead(XLSheet: TXLSheet; QueryGroup, QueryAll, QueryCol: Tquery;count1,Count2 :integer; DataBaseName: String; OneCityName: integer = 0; title: integer = 0):TDrawThread;
var
draw1 :TDrawThread;
begin
result :=nil;
draw1 :=nil;
try
draw1 :=TDrawThread.Create(XLSheet,QueryGroup, QueryAll, QueryCol,count1,Count2,DataBaseName,OneCityName, title);
result :=draw1;
finally
//draw1.DoTerminate;
//draw.Suspend;
//draw.Free;
//draw1.Resume;
end;
end;
Procedure TDrawThread.Execute;
Var
i, j, temp1,li,lj,lSum: integer;
temps,str: String;
Begin
FreeOnTerminate:=true;
//OnTerminate:=self.OnTerminate;
if WaitForSingleObject(ZqsMutex,INFINITE)=WAIT_OBJECT_0 then
begin
Try
initialize;
lj :=0;
synchronize(inisheet);//陳振劍改:修正BUG
if querytj3.Fields.Fields[0].DisplayName = 'INDISEQ' then//喜好比較特別
P_INDISEQBz :=true;
if P_INDISEQBz then
Sheet.RowCount :=querytjCount + 4
else
Sheet.RowCount :=querytjCount + 3;
//如果有0表示不屬于那個城市,畫網格的列數
If tital = 0 Then
Sheet.ColCount := querytj3Count + querytj.Fields.Count+1
Else
Sheet.ColCount := querytj3Count + querytj.Fields.Count+2;
P_FieldCount :=querytj.Fields.Count;
Sheet.ColWidths[-1] := 0;
Sheet.RowHeights[-1] := 0;
If Terminated Then Exit;
//0----clBtnShadow,1------clGrayText,2-------clBtnFace
//畫統計的類型,比如行業等
P_i :=P_FieldCount - 1;
P_j :=0;
P_bz :=0;
P_value :=getname(querytj3.Fields.Fields[0].DisplayName);
Synchronize(RunUpdate);
If Terminated Then Exit;
//畫統計的詳細項目,第一列第二行開始的幾行統計的詳細項目
For i := 0 To P_FieldCount - 2 Do
Begin
//線程同步調用
P_i :=i;
P_j :=1;//第一列
P_bz :=1;
P_value :=getname(querytj.Fields.Fields[i].DisplayName);
Synchronize(RunUpdate);
//讓統計的詳細項目變成兩行
if P_INDISEQBz then
begin
P_str :='INDISEQBZ';
Synchronize(RunModify);
end;
If Terminated Then Exit;
End;
li :=P_FieldCount -1;
//畫統計類型的詳細,比如行業詳細名稱的企業等
If querytj2.SQL.Text <> '' Then
Begin
if querytj3.Fields.Fields[0].DisplayName = 'INDISEQ' then//喜好比較特別
begin
//
querytj3.First;
For j := 0 To querytj3Count - 1 Do
Begin
//線程同步調用
//加上大類
P_i :=li +j;
P_j :=1;
P_bz :=2;
P_value :=querytj3.Fields.Fields[1].AsString;
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
If Terminated Then Exit;
//當前的大類名稱和同行的前一個比較,相同加在一起
P_str :='INDISEQ';
Synchronize(RunModify);
If Terminated Then Exit;
//加上小類
P_i :=li +j;
P_j :=2;
P_bz :=2;
P_value :=querytj3.Fields.Fields[3].AsString;
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
lj :=j;
If Terminated Then Exit;
querytj3.Next;
End;
end
else
begin
querytj3.First;
For j := 0 To querytj3Count - 1 Do
Begin
//線程同步調用
P_i :=li +j;
P_j :=1;
P_bz :=2;
P_value :=querytj3.Fields.Fields[1].AsString;
Synchronize(RunUpdate);
lj :=j;
If Terminated Then Exit;
querytj3.Next;
End;
end;
End;
//最后一列畫上其他與合計
If tital = 0 Then
Begin
P_i :=li + lj +1;
P_j :=1;
P_bz :=1;
P_value :='其他';
Synchronize(RunUpdate);
//讓統計的詳細項目變成兩行
if P_INDISEQBz then
begin
P_str :='INDISEQBZ';
Synchronize(RunModify);
end;
If Terminated Then Exit;
P_i :=li +lj+2;
P_j :=1;
P_bz :=1;
P_value :='合計';
Synchronize(RunUpdate);
//讓統計的詳細項目變成兩行
if P_INDISEQBz then
begin
P_str :='INDISEQBZ';
Synchronize(RunModify);
end;
If Terminated Then Exit;
End;
//
if P_INDISEQBz then
lj := 3
else
lj := 2;
//清空數組
//畫上,第3行開始的對應的統計詳細項目的數值
querytj.First;
While Not querytj.eof Do
Begin
For i := 0 To P_FieldCount - 2 Do
Begin
//設置高度把相同的合并
temp[i]:= querytj.Fields.Fields[i].Text;
// sheet.Cells [1,2].Free ;
//以下判斷是哪個統計詳細項目的數值
If (querytj.Fields.Fields[i].DisplayName <> '') and (temp[i] <> '') Then//?
Begin
If UPPERcase(querytj.Fields.Fields[i].DisplayName) = uppercase('CityNo') Then
begin
//線程同步調用
P_i :=i;
P_j :=lj;
P_bz :=2;
P_value :=cityname[strtoint(Copy(temp[i],3,1))];
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
//當前的城市名稱和同列的前一個比較,相同加在一起
P_str :='city';
Synchronize(RunModify);
If Terminated Then Exit;
end;
If UPPERcase(querytj.Fields.Fields[i].DisplayName) = uppercase('off_no_home') Then
Begin
If onecity = 0 Then
begin
//線程同步調用
P_i :=i;
P_j :=lj;
P_bz :=2;
P_value :=offname[strtoint(Copy(temp[i - 1],3,1)), strtoint(temp[i])];
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
If Terminated Then Exit;
end
Else
begin
//線程同步調用
P_i :=i;
P_j :=lj;
P_bz :=2;
P_value :=offname[onecity, strtoint(temp[i])];
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
If Terminated Then Exit;
end;
if i>0 then
begin
P_CityName :=cityname[strtoint(Copy(querytj.Fields.Fields[i -1].text,3,1))];
//當前的城市名稱和前1列的城市同,再看同列前一行是否同,相同加在一起
P_str :='off_no_home';
Synchronize(RunModify);
end
else
begin
//單個城市時
P_str :='city';//直接調用城市的做法就可以了
Synchronize(RunModify);
end;
End;
If UPPERcase(querytj.Fields.Fields[i].DisplayName) = uppercase('GradeNo') Then
begin
//線程同步調用
P_i :=i;
P_j :=lj;
P_bz :=2;
P_value :=starname[strtoint(temp[i])];
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
If Terminated Then Exit;
end;
If UPPERcase(querytj.Fields.Fields[i].DisplayName) = uppercase('Custatt') Then
begin
//線程同步調用
P_i :=i;
P_j :=lj;
P_bz :=2;
P_value :=lbname[strtoint(temp[i])];
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
If Terminated Then Exit;
end;
If UPPERcase(querytj.Fields.Fields[i].DisplayName) = uppercase('sex') Then
Begin
If UpperCase(Temp[i])=UpperCase('F') Then
begin
//線程同步調用
P_i :=i;
P_j :=lj;
P_bz :=2;
P_value :=xbname[0];
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
If Terminated Then Exit;
end;
If UpperCase(Temp[i])=UpperCase('M') Then
begin
//線程同步調用
P_i :=i;
P_j :=lj;
P_bz :=2;
P_value :=xbname[1];
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
If Terminated Then Exit;
end;
If UpperCase(Temp[i])=UpperCase('O') Then
begin
//線程同步調用
P_i :=i;
P_j :=lj;
P_bz :=2;
P_value :=xbname[2];
if P_value='' then
P_value :='無法分類';
Synchronize(RunUpdate);
If Terminated Then Exit;
end;
End;
If UPPERcase(querytj.Fields.Fields[i].DisplayName) = uppercase('ProductNo') Then
Begin
temps := temp[i];
temp1 := ord(temps[1]);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -