在项目中遇到这么个情况:
一个页面左边是链接列表,右边嵌套一个Ifram。如果页面长时间没动,点击左边列表,右边的Ifram会跳转到设定的页面(登录页面)。但是左边的不变。
如果想整个页面跳转过去,只在登录页面Default.aspx上加一小段代码即可!
<script language="javascript" type="text/javascript">
if (top != self) {
if (top.location != self.location)
top.location = self.location;
}
</script>
库存模型组:在AX中库存模型组是非常重要的,是计算库存成本的重要组成部分,决定了将物料过账到总帐的方式。
库存模型组包含确定如何控制和处理物料收货和发货的设置。
在新建物料的时候,库存模型组也是一个必填字段。下面来看看代码是怎么创建库存模型组的。
系统库存模型组关联的表:inventModelGroup
一般表都会有一个find方法,用来查找主键对应的记录,找到则返回行记录,update参数则表示返回的记录是否可以修改,返回false的话就表示是自读的。和find方法相类似的有一个exist方法,它的功能就是查找主键是否存在,存在则返回true。这两个方法属于典型的静态方法,不属于表和行记录,属于整个表的方法。
在新建记录时候,系统最先调用的是initValue方法,新建库存模型组记录的时候会有几个默认值。允许财务负库存,
过账实际库存和过账财务库存是默认勾选的,还有库存模型类型是先进先出(FIFO)。都是写在initValue方法里面。
validateField方法,这个方法在字段的值改变,且字段失去焦点的时候触发,主要用于字段的值是否符合规范,此表的validateField方法:
public boolean validateField(fieldId _fieldIdToCheck)
{
boolean ret;
InventTable inventTable;
ret = super(_fieldIdToCheck);
switch(_fieldIdToCheck)
{
case fieldnum(InventModelGroup, NegativePhysical):
if (this.RecId && !this.NegativePhysical && this.NegativePhysical != this.orig
().NegativePhysical)
{
startLengthyOperation();
while select inventTable
where inventTable.ModelGroupId == this.ModelGroupId
{
ret = this.inventModelType().checkNotNegativeOnHand(inventTable, true);
if (!ret)
return ret;
}
}
break;
case fieldnum(InventModelGroup, InventModel):
if (InventModelType::newInventModel(this.InventModel).stdCostBased() && !
InventParameters::find().MultiSiteActivated)
{
ret = checkFailed("@SYP1642");
}
if (InventModelGroup::isModelGroupUsedInStdCostConv(this.ModelGroupId))
{
ret = checkFailed(strfmt("@SYS126546", this.ModelGroupId));
}
break;
}
return ret;
}
它检查了传进来的字段是否是(允许财务负库存字段)如果是修改了这个字段的话。就执行里面方法,值得一提的是,this.orig这个方法返回的是最后一次提交到数据库的记录。startLengthyOperation()这个方法是系统了global的方法,就是一般复杂操作的代码会把鼠标编程不可操作的,现在还不知道是神马意思。这里面还涉及到跟这表相关的类
inventModelType类,表方法inventModelType就是返回这个类,并且把当前的库存模型类型传进去实例化,它每一种库存模型类型都对应了一个类,一般实例化的就是类InventModelType_FIFO,一般修改库存模型组改为标准成本会进入方法。
validateWrite方法,在保存数据时,触发此方法判断是否满足保存的条件,此方法的父类方法主要检查必填字段的合法性,弱此字段返回false,则保存将被阻止,返回true,则触发Insert或者Update方法。而此表的validateWrite方法直接调用类inventModelType的方法validateWriteInventModelGroup
如果修改的是库存模型类型,checkFailed返回一个假值,然后info一些信息给用户。
关于库存物料这一块:
在新建物料的时候会有5个必输字段:物料编号,物料组,物料类型,库存模型组,维度组。
下面研究一下新建物料组时相关问题:必须得创建一个物料组,这就是创建物料的前提条件。
在新建物料组的时候,看上去蛮简单,一般我们需要填写的就两个,物料组和名称字段。
物料组的主表是inventItemGroup但是会发现在窗体上很多字段都没在表字段里面,都是在表edit方法中得到的,在AX系统中会有两个比较特殊的方法,display方法和edit方法,一般是用来得到不能直接从数据源字段中得到的数据。
在一般窗体数据源中都会出现creat,insert这样方法,但奇怪的是这个窗体中没得。更奇怪的是在把断点放在表方法中的setLedgerAccount中,在点击新建按钮时候不会触发,但是在切换tabpage时候就会跳到这里面断点中来。
这里面给各种科目赋值涉及到的表和方法:
在表inventItemGroup中有一个公用的方法setLedgerAccount,给不同的会计科目类型赋值(InventAccountType)
他在这个方法里面直接调用表inventPosting(库存,分类账日记账表)里面的方法item,不知道为什么直接跳到这个表来了。两个表有如下关系:InventPosting.ItemCode == 1 && InventPosting.ItemRelation == InventItemGroup.ItemGroupId .......InventPosting表中的ItemCode扩展子自枚举类型
TableGroupAll,TableGroupAll::GroupId == 1,也就是ItemCode为组!
InventItemGroup.ItemGroupId也就是该表的名称字段。
在item方法中又涉及一个表InventPostingParameters(库存交易记录组合表)!这个表只有一条记录,分别判断里面的“表,组,所有”的物料关系是否启动。再做相应的判断!
在item方法里面三个参数(InventAccountType,ItemId,ItemGroupId)第一个科目类型,第二个物料编号此时调用物料编号都是空的,第三个编号组也就是当前的物料名称)
在setLedgerAccount里面调用也就是把当前科目类型,物料编号为空,当前物料组名称传进去。
在item方法里面,往inventPosting中循环找到相应的科目编号!
一般第一次创建的时候tableGroup为All,然后找到相应的科目编号。
新建物料组后还没有在表inventPosting里面创建记录。待考察。。。。