📄 total.cpp
字号:
SetDateFix((FIX_TDATETIME *)pRowFix,nDate1,nDate2,nMode,nRow);
SetRoadwayFix((FIX_DWORD *)pColFix,pHead,nCol,ROADTYPE_IN);
pReport->pRowFix = pRowFix;//报表固定行
pReport->pColFix = pColFix;
pReport->pTotal = pTotal;
pReport->nRow=nRow; pReport->nCol=nCol; //行数,列数
//行比较的字段名
lstrcpyn(pReport->szRowField,pszRowField,sizeof(pReport->szRowField));
//列比较的字段名
lstrcpyn(pReport->szColField,pszColField,sizeof(pReport->szColField));
//报表标题
lstrcpyn(pReport->szTitle,pszTitle,sizeof(pReport->szTitle));
//报表条件
GetTotalText(pReport->szCondition);
//固定行列交叉处标题
lstrcpyn(pReport->szTextTitle,pszTextTitle,sizeof(pReport->szTextTitle));
pReport->nRowType = ftDate; //日期类型
pReport->nRowStatus = TOTALDATA_INC; //数值递增
pReport->nColType = ftInteger; //整数类型
pReport->nRowStatus = TOTALDATA_EQUAL; //数值相等
pReport->nTotalType = ftInteger; //整数类型
return(TRUE);
}
//设置日期固定行
int SetDateFix(FIX_TDATETIME *pFix,DWORD nDate1,DWORD nDate2,
int nMode,int nRow)
{
int i,n,nYear,nMonth,nDay;
TDateTime t;
if(nMode==TOTAL_DAY || nMode==TOTAL_MONTH){
t = DWORDToTDate(nDate1);
for(i=0;i<nRow;i++){
n = TDateToDWORD(t);
DWORDToDateStr(pFix[i].szTitle,n); //行列标题
pFix[i].tDivision=t; //分界值
t += 1;
}
}
else if(nMode==TOTAL_QUARTER || nMode==TOTAL_YEAR){
GetDateOnDWORD(nDate1,&nYear,&nMonth,&nDay);
for(i=0;i<nRow;i++){
wsprintf(pFix[i].szTitle,"%04d年%02d月",nYear,nMonth); //行列标题
pFix[i].tDivision=TDateTime(nYear,nMonth,1);//分界值
nMonth++;
if(nMonth>12){nYear++; nMonth=1;}
}
}
return(TRUE);
}
//设置车道固定行
int SetRoadwayFix(FIX_DWORD *pFix,void *pHead,int nRow,int nType)
{
int i,j;
void *pCur;
ROADWAY *pRoad;
for(i=j=0;i<nRow;i++){
while(1){
pCur = GetDotOnTList(pHead,j++);
if(pCur==NULL)break;
pRoad = LookRoadway(pCur);
if((int)pRoad->nType==nType)break;//车道类型:进入、外出、混合
}
if(pCur==NULL)break;
if(pRoad->szName[0]!=0) //描述
lstrcpyn(pFix[i].szTitle,pRoad->szName,sizeof(pFix[0].szTitle)); //行列标题
else wsprintf(pFix[i].szTitle,"<%d>",pRoad->nNo);
pFix[i].nDivision=pRoad->nNo; //分界值
}
return(TRUE);
}
//设置用户类型固定行
int SetPriceFix(FIX_DWORD *pFix,void *pHead,int nRow)
{
int i,j;
void *pCur;
PRICEDATA *pPrice;
for(i=j=0;i<nRow;i++){
pCur = GetDotOnTList(pHead,j++);
if(pCur==NULL)break;
pPrice = LookPrice(pCur);
if(pPrice->szUserType[0]!=0) //描述
lstrcpyn(pFix[i].szTitle,pPrice->szUserType,sizeof(pFix[0].szTitle)); //行列标题
else wsprintf(pFix[i].szTitle,"<%d>",pPrice->nID);
pFix[i].nDivision=pPrice->nID; //分界值
}
return(TRUE);
}
//获取类型nType车道数量
int GetRoadNumWithType(void *pHead,int nType)
{
int i,n;
void *pCur;
ROADWAY *pRoad;
for(i=n=0;;i++){
pCur = GetDotOnTList(pHead,i);
if(pCur==NULL)break;
pRoad = LookRoadway(pCur);
if((int)pRoad->nType==nType)n++;//车道类型:进入、外出、混合
}
return(n);
}
//统计一个报表
int TotalOneReport(TDataSet *pQuery,TOTALREPORT *pReport)
{
int rc;
int x,y,nCount;
int nCol,nRow;
void *pTotal,*pColFix,*pRowFix;
char *pszRowField; //行比较的字段名
char *pszColField; //列比较的字段名
char *pszTotalField; //统计内容的字段名(szTotalField[0]=0 =>统计数量)
int nRowType; //行数据类型
int nRowStatus; //行数据比较
int nColType; //列数据类型
int nColStatus; //列数据比较
int nTotalType; //统计表数据类型
nCol = pReport->nCol;
nRow = pReport->nRow;
pColFix = pReport->pColFix;
pRowFix = pReport->pRowFix;
pTotal = pReport->pTotal;
pszColField = pReport->szColField;
pszRowField = pReport->szRowField;
pszTotalField = pReport->szTotalField;
nRowType=pReport->nRowType; //行数据类型
nRowStatus=pReport->nRowStatus; //行数据比较
nColType=pReport->nColType; //列数据类型
nColStatus=pReport->nColStatus; //列数据比较
nTotalType=pReport->nTotalType; //统计表数据类型
nCount=0;
SetCurDataSet(pQuery);
rc = FirstCurTable();
while(rc){
x = GetTotalXY(pColFix,nCol,pszColField,nColType,nColStatus);
y = GetTotalXY(pRowFix,nRow,pszRowField,nRowType,nRowStatus);
AddTotalData(pTotal,pszTotalField,nTotalType,nCol,nRow,x,y);
rc=NextCurTable();
nCount++;
}
return(nCount);
}
//获取统计位置
int GetTotalXY(void *pFix,int nFix,char *pszField,int nDataType,int nDataStatus)
{
FIX_DWORD *pDFix;
FIX_TDATETIME *pTFix;
FIX_STRING *pSFix;
DWORD nData;
TDateTime tData;
char szData[30];
int i;
if(nDataType==ftInteger){//整数类型
nData = GetFieldInt(pszField);
pDFix = (FIX_DWORD *)pFix;
if(nDataStatus==TOTALDATA_INC){//递增
for(i=0;i<nFix;i++)
if(nData<=pDFix[i].nDivision)break;
}
else if(nDataStatus==TOTALDATA_DEC){//递减
for(i=0;i<nFix;i++)
if(nData>=pDFix[i].nDivision)break;
}
else {//相等
for(i=0;i<nFix;i++)
if(nData==pDFix[i].nDivision)break;
}
}
//日期类型
else if(nDataType==ftDate || nDataType==ftTime || nDataType==ftDateTime){
tData = GetFieldDouble(pszField);
if(nDataType==ftDate)tData = int(tData);
pTFix = (FIX_TDATETIME *)pFix;
if(nDataStatus==TOTALDATA_INC){//递增
for(i=0;i<nFix;i++)
if(tData<=pTFix[i].tDivision)break;
}
else if(nDataStatus==TOTALDATA_DEC){//递减
for(i=0;i<nFix;i++)
if(tData>=pTFix[i].tDivision)break;
}
else { //相等
for(i=0;i<nFix;i++)
if(tData==pTFix[i].tDivision)break;
}
}
else if(nDataType==ftString){//字符串类型
GetFieldText(pszField,szData,sizeof(szData));
pSFix = (FIX_STRING *)pFix;
if(nDataStatus==TOTALDATA_INC){//递增
for(i=0;i<nFix;i++)
if(lstrcmpi(szData,pSFix[i].szDivision)<=0)break;
}
else if(nDataStatus==TOTALDATA_DEC){//递减
for(i=0;i<nFix;i++)
if(lstrcmpi(szData,pSFix[i].szDivision)>=0)break;
}
else { //相等
for(i=0;i<nFix;i++)
if(lstrcmpi(szData,pSFix[i].szDivision)==0)break;
}
}
else i=-1; //无法处理类型
return(i);
}
//统计数据
int AddTotalData(void *pTotal,char *pszField,int nDataType,
int nCol,int nRow,int x,int y)
{
int nData;
float fData;
int rc;
//统计数值
if(x<=0 || x>=nCol && y<0 && y>=nRow)return(FALSE);
nData=0; fData=0.0f;
if(pszField[0]==0)//统计数量
nData =1;
else {
if(nDataType == ftInteger)
nData = GetFieldInt(pszField);
else if(nDataType==ftFloat)
fData = GetFieldDouble(pszField);
}
rc=TRUE;
if(nDataType == ftInteger)
((int *)pTotal)[y*nCol+x] += nData;
else if(nDataType==ftFloat)
((float *)pTotal)[y*nCol+x] += fData;
else rc=FALSE;
return(rc);
}
//显示一个报表
void ShowOneReport(TTotalFrame *pFrame,TOTALREPORT *pReport)
{
static char pszSum[]="合计";
TStringGrid *pGrid;
void *pTotal,*pColFix,*pRowFix;
int nCol,nRow;
int nColType,nRowType,nTotalType;
int i,j;
char szBuf[50],*p;
pFrame->m_TitlePanel->SetTextBuf(pReport->szTitle);
pFrame->m_ConditionPanel->SetTextBuf(pReport->szCondition);
nCol = pReport->nCol;
nRow = pReport->nRow;
pColFix = pReport->pColFix;
pRowFix = pReport->pRowFix;
pTotal = pReport->pTotal;
nRowType=pReport->nRowType; //行数据类型
nColType=pReport->nColType; //列数据类型
nTotalType=pReport->nTotalType; //统计表数据类型
pGrid = pFrame->m_TextGrid;
pGrid->ColCount=nCol+2;
pGrid->RowCount=nRow+2;
for(i=0;i<nCol;i++){ //列标题
p = GetFixTitle(pColFix,nColType,i);
SetGridCellText(pGrid,p,i+1,0);
}
for(i=0;i<nRow;i++){ //行标题
p = GetFixTitle(pRowFix,nRowType,i);
SetGridCellText(pGrid,p,0,i+1);
}
SetGridCellText(pGrid,pReport->szTextTitle,0,0);//固定行列交叉处标题
SetGridCellText(pGrid,pszSum,nCol+1,0); //合计标题
SetGridCellText(pGrid,pszSum,0,nRow+1); //合计标题
for(i=0;i<nRow;i++){//行
for(j=0;j<nCol;j++){//列
GetTotalText(pTotal,nTotalType,nCol,nRow,j,i,szBuf);
SetGridCellText(pGrid,szBuf,j+1,i+1);
}
}
for(i=0;i<nRow;i++){//行合计
GetTotalRowSumText(pTotal,nTotalType,nCol,nRow,i,szBuf);
SetGridCellText(pGrid,szBuf,nCol+1,i+1);
}
for(i=0;i<nCol;i++){//列合计
GetTotalColSumText(pTotal,nTotalType,nCol,nRow,i,szBuf);
SetGridCellText(pGrid,szBuf,i+1,nRow+1);
}
GetTotalSumText(pTotal,nTotalType,nCol,nRow,szBuf);//总计
SetGridCellText(pGrid,szBuf,nCol+1,nRow+1);
SetGridWidth(pGrid);//设置格栅单元宽度
}
//设置格栅单元内容
void SetGridCellText(TStringGrid *pGrid,char *pszText,int nCol,int nRow)
{
char szBuf[5];
if(pszText!=NULL)
pGrid->Cells[nCol][nRow]=pszText;
else{
szBuf[0]=0;
pGrid->Cells[nCol][nRow]=szBuf;
}
}
//设置格栅单元宽度
void SetGridWidth(TStringGrid *pGrid)
{
int i,n,nWidth;
n = pGrid->ColCount;
if(n<=0)n=1;
//等宽度
nWidth = pGrid->ClientRect.Width();
nWidth = (nWidth -n)/n;
for(i=0;i<n;i++) pGrid->ColWidths[i]=nWidth;
}
//获取固定行标题
char *GetFixTitle(void *pFix,int nDataType,int nIndex)
{
char *p;
if(nDataType==ftInteger)//整数类型
p = ((FIX_DWORD *)pFix)[nIndex].szTitle;
//日期类型
else if(nDataType==ftDate || nDataType==ftTime || nDataType==ftDateTime)
p = ((FIX_TDATETIME *)pFix)[nIndex].szTitle;
else if(nDataType==ftString)//字符串类型
p = ((FIX_STRING *)pFix)[nIndex].szTitle;
else p=NULL; //无法处理
return(p);
}
//获取统计单元内容
char *GetTotalText(void *pTotal,int nDataType,int nCol,int nRow,
int x,int y, char *pszText)
{
int nPos,nData;
float fData;
nPos = y*nCol+x;
if(nDataType == ftInteger){//整数类型
nData = ((int *)pTotal)[nPos];
sprintf(pszText,"%d",nData);
}
else if(nDataType==ftFloat){//浮点数
fData = ((float *)pTotal)[nPos];
sprintf(pszText,"%5.2f",fData);
}
else pszText[0]=FALSE;
return(pszText);
}
//获取行合计内容
char *GetTotalRowSumText(void *pTotal,int nDataType,
int nCol,int nRow, int y,char *pszText)
{
int i,nPos;
int nData;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -