Farseer

MRPII学习中......

2010年1月4日 #

Dynamics AX EnterPrise Portal Tools

安装Dynamics AX EnterPrise Portal Tools后,打开VS2008,报错说,Dynamics AX EnterPrise Portal这个add-in发生了非预期的错误,让重启VS,点确定后,报一个非法参数的代号为80070075的错误,问是否把add-in去掉,点否后正常进入VS2008.通过工具->外接程序管理器,启用Dynamics AX Enterprise Portal Tools这个Add-in的时候会重现前面提到的错误。
这个Add-in是AX的开发环境AOT和VS2008两个开发环境沟通的桥梁,如果不启用这add-in,VS2008和AOT的联系就没那么方便了,AX的web userControl不能直接导入到AOT相应的节点下,也不能直接把AOT里的User Control导入到VS中修改.

解决方案是:安装VS2008的SP1.

搞不懂为什么不装SP1会出这个问题,只要求安装VS2008也没要求必须装VS2008 SP1,看来微软能装的补丁乖乖地装上还是没错的。

posted @ 2010-01-04 21:58 佛西亚 阅读(129) | 评论(0) |  编辑

2009年11月22日 #

查看字段的EDT类型列表

在项目初始化的时候,可能需要修改某些字段的长度,这样就需要知道该字段对应的EDT类型,由于字符的长度只能从最上层的EDT类型修改,所以需要找到这个类型,如果EDT类型的继承层次很多的话,一个个找下去是一件很累的事情,如果能根据表名和字段名找到对应的EDT类型列表可能会减轻一些工作,写这段代码也很简单,类似于如下代码:
Code

posted @ 2009-11-22 23:44 佛西亚 阅读(109) | 评论(0) |  编辑

关于数量和金额的小数位数

在AX中数量和金额的EDT类型的基类型都是Real,虽然创建EDT类型的时候,选择的是real,其实叫做Decimal更符合实际情况,因为这种类型的EDT类型在SQL Server里都翻译成numbric类型,因为处理数量和金额的时候要使用精确的计算方式,而不能采用float和real之类的近似数据类型。MSDN关于这些类型的可以参照如下链接:

http://msdn.microsoft.com/zh-cn/library/ms187912.aspx

关于数量和金额在AX的处理主要是基于三个基础EDT类型,数量是RealBase,金额是Money和MoneyMST。其中RealBase我们可以在AOT树中找到,Money和MoneyMST就找不到了,不过它们两个的直接下线Amount和AmountMST在AOT中可以找到。

在界面中显示多少位小数是通过EDT类型的NoOfDecimals来定义的,这个属性跟基类型是string的EDT类型的StringSize不同,NoOfDecimals这个属性只是用来定义在用户的界面上显示多少位小数的,而不会影响SQL Server数据库里使用该EDT类型的字段的小数位数,看了一下SQL Server里对应的数量和金额的字段类型都是Numbric(28,12),我在AX里也没找到更改这个长度的地方,OK,我们可以设想数据存储层最多只能存储12位小数,那么在表现层即使把值定义成可以显示多于12位也没太大意义,实际的ERP应用中也不需要精确到这么大的精度,当然如果这个字段不是直接存储到数据库里,而是做为中间变量值去做运算,在一定程度上倒是可以提高运算的精度,测试了一下,NoOfDecimals可以设定成任意整数值,但是实际上大于16位的值时,它已经当作默认值2去处理了,比如AmoutMST这个EDT类型,NoOfDecimals的值被设置成了20,实际上拖到界面上后,只显示两位小数。
到这里我们可以的出一个结论,NoOfDecimals只是用于限定界面显示的,如果在程序中用EDT类型去定义一个变量,可以赋值为任意长度的小数位数(当然Decimal最大也就(38,20)),在把计算结果存储到SQL Server里时会舍为为12位小数。

 这样,数据层和表现层小数位数的限定就清楚了,数据层的小数位数固定为12位(当然可能有地方可以修改这个设定,只是我没找到而已),表现层通过EDT类型的NoOfDecimals去限定。实际上,程序的设计应该在业务逻辑层根据业务的需要在业务层去做一些限定,不能根据数据层和表现层这哥俩一商量就完事了。AX在业务逻辑层对小数的位数也有规定。
联系到业务层面,我们提到数量,当然要跟单位联系起来,要不然只说一个数字,没任何意义,五吨和五千克显然没什么可比性,提到金额,一定要跟币种联系起来,发5W日元和5W美元给你的感觉铁定不一样。AX也是根据这个思路来做的,对数量的小数位数的限定体现在单位上,而对金额的舍入位数的限定写在了币种上。

先来看看数量,我们以销售订单的销售数量为例说明,该字段对应的扩展数据类型是SalesOrderedQty,一路追上去,最终可以追到最顶层的EDT类型是我们前面提到的RealBase,看实际的需求情况了,如果要求所有的数量的显示位数都改成4位或者更高的位数(默认为2位),就直接修改RealBase,这样大家就都继承了,如果只想修改销售数量,可以只修改SalesOrderQty,我们这里只以修改SalesOrderedQty这个EDT类型为例说明,将EDT类型的NoOfDecimals的值设置为4

从上图可以看出数量确实显示为4位了,但是如果输入值就知道了,单位Kg的小数位数我设置为了1位,如下图所示:

无论输入1.2345,还是其他的什么值,都会给你舍到1.2或者1.3(四舍五入),如果想真的能够输入四位值,需要把物料对应的单位的值也设置成4位,这样表现层和业务上也就一致了,如果不设置单位的小数位数,数量字段显示一串零,也没什么意义,单位最多可以设置8位小数,一般情况下足够了,当然可以去修改代码,把这个限定放开,但最多也就12位吧,数据层限定了,还没遇到需要保存这么多位的需求。
再看看金额,还是以销售订单为例吧,EDT类型的SalesLineAmount的最顶级的父类型是Amount,与AmoutnMST相对应,表示的是用原币表示的金额,而AmountMST表示的是用本位币表示的金额。我们知道,在系统管理->设置->系统->修改数据类型的界面有一个修改金额这个数据类型的选项,翻了一下代码,这个地方的设置只会影响AmoutMST这个EDT类型,所以继承自AmountMST的EDT类型会受到影响,但是像销售金额这种用原币表示的金额都是继承自Amount的,所以在这里的修改并不会影响销售订单的行金额显示位数,这里修改EDT类型SalesLineAmount为4位,修改后得到如下值:

从图中可以看出,值虽然显示为了四位小数,但是数量和价格的乘积应该是34.991728,如果舍入到四位应该是34.9917。在币种设置了化整处理,在总账->设置->汇率->化整(选项卡),如下图所示:

可以看到上面一共有四个关于金额的设置,其中第一个是用于常规化整的,我们上面的销售订单行的LineAmount就是受这个字段控制的,其余三个,其中两个订单化整实在开发票的时候把金额取整,而舍入价格是针对价格的舍入设定,不过很让我纳闷的是,这个常规设置只有三种选择,不设置,0.1和0.01,如果这里不设置,AX也会取默认值0.01,所以相当于这里只能是设置为取一位小数0.1,如果想保留三位小数,或者更多,就没办法设置了,这确实是挺奇怪的事情,或许有地方设置我没有找到吧,我翻了半天也没找到在哪里可以设置为更多小数位数。。。我能想到的解决方案也只有把常规化整这个字段对应的EDT类型的NoOfDecimals的长度改得长一些,这其实是我不想采用的方法,因为这样业务人员根本没办法做到,总不能要求业务人员跑到AOT里面去修改这东西,所以我觉得把这个EDT类型暴露在管理里面的修改数据类型里面是不是更合理?或者干脆发布的时候就把这个EDT类型的NoOfDecimals弄得长一些?或者MS认为金额就应该最多保留2位?我暂时把常规化整对应的EDT类型RoundOff的属性NoOfDecimals改成4,然后把常规化整改为0.0001,然后再看销售订单的行金额,如下图所示:

另外采购销售价格之类价格的也是继承自Amount这个基础类型的,所以通过系统管理里修改数据类型的功能并不会更改价格的小数显示位数,只能去AOT里找到相应的EDT类型做修改了,另外价格不像数量和金额,有业务逻辑层的控制,只修改相应的EDT类型就可以,但是价格实际上是跟货币相关的,所以这样处理给人一种不是很统一的感觉。

OK,就说这么多了,由于没看到正式的文档,所有的内容都来自于我自己的测试和猜测,所以不见得正确,还望高手指点。

posted @ 2009-11-22 22:18 佛西亚 阅读(211) | 评论(0) |  编辑

2009年11月19日 #

关于我的收藏夹的迁移

AX从4.0开始增加了一个我的收藏夹的功能,这个功能跟IE的收藏夹功能类似,可以把自己喜欢的东西拖到收藏夹里,IE的收藏夹可以通过拷贝My Favorite文件夹的方式实现,AX的收藏夹想转移怎么办那?
AX收藏夹的数据都序列化到了表SysPersonalization的字段Buffer里,可以通过这个表的字段实现备份恢复收藏夹的目的:

Code

在这里记录一下,免得以后想用的时候忘记了。

posted @ 2009-11-19 21:42 佛西亚 阅读(97) | 评论(0) |  编辑

2009年11月18日 #

文件传输(三)---关于计时器

文件传输设计成在后台执行的Windows Services,在配置文件中定义执行数据上传下载的时间,这样就需要定义个Timer来检查指定的时间是否到达,以便执行相应的操作,在.NET中有几个类库中有Timer的定义,具体的内容可以查看MSDN。

我使用了空间System.Timers里的Timer,Timer可以设置时间间隔,每隔一定的时间执行由ElapsedEventHandler定义的事件,由于网络不稳定,所以断线的情况时有发生,所以我们要定义一个时间段,在这个时间段内,每隔一定的时间去检查一下是否有文件需要上传,但是由于网络传输的不确定性,隔多长时间去检查就是个问题了,由于System.Timers的Timer是多线程的,所以如果不加以处理会产生资源竞争的情况,比如定义了Timer的Interval是360000,即每隔6分钟去检查一下是否有文件需要上传或下载,如果上一个Timer所触发的ElapsedEventHandler事件还没处理完,又再次触发ElapsedEventHandler时间,就会出问题了,需要加把锁,通过System.Threading中的Interlocked去实现。
定义变量locaVar的值为0时执行事件处理程序对应的代码,在代码开始执行时

if (0 == Interlocked.Exchange(ref lockVar, 1))

执行完毕后,重置lockVar的值

//释放锁
                    Interlocked.Exchange(ref lockVar, 0);

 

posted @ 2009-11-18 21:13 佛西亚 阅读(102) | 评论(0) |  编辑