在Axapta中有一个基础类型Container,在某些场合下确实比较好用,axapta现有系统中用的也比较多,比如Runbase的pack()和unpack()方法就是用Container结合宏来实现的.
container可以看作是无类型的动态增长的数组,功能基本上等效于C#中的ArrayList.只不过container不能存放对象(Table对象还是可以存的),另外container可以作为数据库字段类型,在数据库中转化成img类型,可以看出container把数据序列化了.
另外由于Container存放的元素可以是Container,所以可以实现类似于二维数组的功能.今天遇到一个需求,做一张客户(供应商)对帐单,由于国内的财务需要按月汇总,而用户输入的查询时间可能是跨月的,并且不一定是从一号开始到月底结束的,比如用户输入如下时间段做查询
2006-03-13~~~2006-05-27
这样按照国内的财务需求,需要分解成如下的时间段:
1.2006-03-13~~~2006-03-31
2.2006-04-01~~~2006-04-40
3.2006-05-01~~~2006-05-27
分别统计上述三段时间的交易信息并分别汇总,这样就要求把任意一段时间,按月分解,当然这个有很多种做法,不过感觉用container实现这个小功能还是挺方便的,代码如下:
static
Container GetDatePeriod(TransDate fromDate,TransDate toDate)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
Container cPeriod,cPeriodForOneMonth;
int i;
int day;
TransDate transDate;
int gYearPart,gMonthPart;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//得到某一个月的天数
int GetDay(int yearPart,int monthPart)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
switch(monthPart)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
day = 31;
break;
}
case 4:
case 6:
case 9:
case 11:
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
day = 30;
break;
}
case 2:
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if(!(yearPart mod 4))
day = 29;
else
day = 28;
break;
}
default:
throw error("Error input month!");
break;
}
}
//得到一个完整月的开始和结束日期
Container GetPeriodForOneMonth(int yearPart,int monthPart)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
;
GetDay(yearPart,monthPart);
return [str2Date(int2str(yearPart)+"-"+int2Str(monthPart)+"-01",321),
str2Date(int2str(yearPart)+"-"+int2Str(monthPart)+"-"+int2Str(day),321)];
} ;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//插入开始和结束日期中间完整的月
for(i = mthofyr(fromDate)+1;i<mthofyr(toDate);i++)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
cPeriod = conins(cPeriod,conlen(cPeriod)+1,GetPeriodForOneMonth(year(toDate),i));
}
//插入开始月
GetDay(year(fromDate),mthofYr(fromDate));
gYearPart = year(fromDate);
gMonthPart = mthofYr(fromDate);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
transDate = str2Date(int2Str(gYearPart)+"-"+int2Str(gMonthPart)+"-"+int2Str(day),321);
cPeriod = conins(cPeriod,1,[fromDate,transDate]);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//插入结束月
if(mthofYr(fromDate)!=mthofYr(toDate))
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
gYearPart = year(toDate);
gMonthPart = mthofYr(toDate);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
transDate = str2Date(int2Str(gYearPart)+"-"+int2Str(gMonthPart)+"-01",321);
cPeriod = conins(cPeriod,conlen(cPeriod)+1,[transDate,toDate]);
}
return cPeriod;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
调用的代码如下:
static
void
Main(Args arg)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
Container c,cPeriod;
TransDate fromDate;
TransDate toDate;
int i;
;
fromDate = str2Date("2006-02-06",321);
toDate = str2Date("2006-09-30",321);
c = Class2::GetDatePeriod(fromDate,toDate);
for(i = 1 ;i<=conlen(c);i++)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
cPeriod = conpeek(c,i);
fromDate = conpeek(cPeriod,1);
toDate = conpeek(cPeriod,2);
print date2StrXpp(fromDate)+"---"+Date2StrXpp(toDate);
}
pause;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
当然由于对帐表要统计年结余额,所以用户输入的查询日期一般不允许跨年度,所以这个程序也就没有处理跨年度的情况了.