上一篇文章介绍了关于数据抓取的几个属性,这篇文章介绍一下当数据进入对应的FormDataSource对象后,如何遍历FormDataSource中的数据.
Axapta提供了两组遍历数据的函数,一组会影响界面Grid的显示,另外一组不会影响界面的显示.前者是可以覆盖的,后者是final类型的,不能覆盖.
第一组函数包含first,next,last,prev等,在通过键盘的向上和向下箭头或工具栏中的箭头操作Grid中的记录时都会调用next或者prev方法,如果通过代码调用这些方法,Grid的当前行也会随着方法的调用而变动,在例子中加入一个button,在点击button时调用如下代码可以看到效果.
void clicked()
{
FormDataSource fds;
CustTable custTmp;
int i ;
;
super();
fds = element.dataSource(1);
for(i=fds.first();i;i=fds.next())
{
print custTable.Name;
}
}
这组方法相对简单,个人感觉作用也不是很大,因为这些操作会由用户在界面上操作完成.{
FormDataSource fds;
CustTable custTmp;
int i ;
;
super();
fds = element.dataSource(1);
for(i=fds.first();i;i=fds.next())
{
print custTable.Name;
}
}
第二组方法更加吸引人些,第二组方法的原型如下:
public final Common getFirst( [int _mark = 0, boolean _fetchAhead = true] )
public final Common getNext()
public final int markRecord(Common _record [, int _mark = 0] )
当然这方法只提供了向后搜索的功能,向前搜索没有实现,不过感觉足够了,之所以说这些方法重要,是因为这些方法可以很方便地完成一些任务.
比如在Form的要通过MenuItem调用一个类实现某个功能,只需要将MunuItem的DataSource属性设成当前的DataSource,在被调用的类中就可以通过这些方法遍历该DataSource完成某些计算和操作而不影响用户的操作.
更加有趣的是,getFirst的第一个参数_mark,这个参数配合markRecord使用会蛮过瘾,Axapta提供了一种机制可以给FormDataSource中的记录添加个一个行标记,使用markRecord方法,这样就可以把Grid中的数据按某种规则分组,比如信用额度在某个范围内的分成一组,在另一个范围内的设成另一组等.另外,Axapta本身自己占用了两个数字0,1默认情况下,FormDataSource中所有行的标记都为0,如果在Grid中选中多行,则选中的行被标记为1.所以如果自己设标记的话,就不要跟这两个掺和了.
不过Axapta标准的代码里面,很少用到这个参数,即便用到了大多也直接用false或者true代替,boolean和int可以隐式转化,所以True的时候就代表只遍历Grid中被选中的多行,false则表示全部遍历,没发现将FormDataSource中的记录标记为2或者其他数字的情况,估计是这个场景用得不多的缘故.
到这里应该很清楚了getFirst得到FormDataSource被标记为某个数字的行的第一行,然后getNext遍历这些被标记特定数字的行,当然默认情况下是遍历所有行.
最后贴一段代码出来.
首先在某个button的clicked事件中,将特定的行做标记,然后再另一个button中读取被标记的行.
void clicked()
{
FormDataSource fds;
CustTable custTmp;
;
super();
fds = element.dataSource(1);
for(custTmp=fds.getFirst()?fds.getFirst():custTmp;
custTmp;
custTmp = fds.getNext())
{
if(custTmp.AccountNum == '4000'||
custTmp.AccountNum == '4007')
fds.markRecord(custTmp,2);
}
}
读取标记的行{
FormDataSource fds;
CustTable custTmp;
;
super();
fds = element.dataSource(1);
for(custTmp=fds.getFirst()?fds.getFirst():custTmp;
custTmp;
custTmp = fds.getNext())
{
if(custTmp.AccountNum == '4000'||
custTmp.AccountNum == '4007')
fds.markRecord(custTmp,2);
}
}
void clicked()
{
FormDataSource fds;
CustTable custTmp;
;
super();
fds = element.dataSource(1);
for(custTmp=fds.getFirst(2)?fds.getFirst(2):custTmp;
custTmp;
custTmp = fds.getNext())
{
info(custTmp.Name);
print custTable.Name;
}
}
这里有个问题就是在遍历的时候,Grid会把标记的行选中,做重点显示,暂时很没找到属性和方法让其设定标记但不影响界面的显示,改天再找找看有没有地方可以设定一下,这个功能在标准的Application中没用到,目前也没有找到用的需求.
{
FormDataSource fds;
CustTable custTmp;
;
super();
fds = element.dataSource(1);
for(custTmp=fds.getFirst(2)?fds.getFirst(2):custTmp;
custTmp;
custTmp = fds.getNext())
{
info(custTmp.Name);
print custTable.Name;
}
}