起步软件技术论坛
搜索
 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2178|回复: 9

[结贴] 多主表单个从表如何实现

  [复制链接]

9

主题

45

帖子

188

积分

初级会员

Rank: 2

积分
188
QQ
发表于 2014-4-30 19:02:22 | 显示全部楼层 |阅读模式
版本: 小版本号:
数据库: 服务器操作系统: 应用服务器:
客户端操作系统: 浏览器:
AB为主从表,A为主表,B为从表;CB也为主从表,C表中一个关系是A的主键,现在希望通过该主键构成CB主从表。
实际应用:A表为销售申请主表,B为销售商品明细表,C为发票申请主表;C只能对A中的记录发起业务流程即开票申请,而财务人员根据B的内容来开票。
简单实现方法是:AC合并,但因为关系太多可能降低性能。
请问如何实现?有没有好而高效的实现方法?谢谢!

9

主题

45

帖子

188

积分

初级会员

Rank: 2

积分
188
QQ
 楼主| 发表于 2014-4-30 20:21:06 | 显示全部楼层
是否可在从表中增加一个逆向字段来指向C主库?这样做也没有问题?
回复 支持 反对

使用道具 举报

17

主题

355

帖子

772

积分

高级会员

Rank: 4

积分
772
QQ
发表于 2014-4-30 22:44:40 | 显示全部楼层
"实际应用:A表为销售申请主表,B为销售商品明细表,C为发票申请主表;C只能对A中的记录发起业务流程即开票申请,而财务人员根据B的内容来开票。"
首先你这个表结构设计的没有问题,挺清晰的,不要合并,合并会造成很多麻烦的。
C是针对A来进行开票申请的,这个开票申请和B直接开票应该不是一回事吧。
首先你A销售订单进行开票申请形成C,开发票是通过B明细来进行的,我认为你这个发票申请和财务人员开发票是有关系的,你从这个角度去分析。
只有开票申请的订单才可以进行财务的出具发票,假如有一个发票的表,你这个发票表的来源就是从C表中A订单的B明细行项,简单的说就是B明细表开发票。
不知道你明白没有。。。

评分

参与人数 1 +3 收起 理由
jishuang + 3 赞一个!

查看全部评分

一步一步走向那迦南地......
回复 支持 反对

使用道具 举报

17

主题

355

帖子

772

积分

高级会员

Rank: 4

积分
772
QQ
发表于 2014-4-30 22:45:20 | 显示全部楼层
对这个挺感兴趣的,有机会再一起讨论,明天放假回家了,要几天不在,见谅了!!
一步一步走向那迦南地......
回复 支持 反对

使用道具 举报

45

主题

4492

帖子

3960

积分

论坛元老

Rank: 8Rank: 8

积分
3960
QQ
发表于 2014-5-1 11:30:32 | 显示全部楼层
gzprof 发表于 2014-4-30 20:21
是否可在从表中增加一个逆向字段来指向C主库?这样做也没有问题?

除了楼上所说,你还有一个需求没有说明白,也就是说 一个发票 是否可以对应多个 销售单;
我们在做实现的销售时,很有可能一个发票对应该多个销售单的;

所以说,你表结构可以改动一个,也就是说C 通过 A 来找到B中的明细,而不是C 直接对应 B,
C 直接对应 B,有可能B中的明细查询不到。

评分

参与人数 1 +3 收起 理由
jishuang + 3 赞一个!

查看全部评分

向前进,向前进,我们……
回复 支持 反对

使用道具 举报

9

主题

45

帖子

188

积分

初级会员

Rank: 2

积分
188
QQ
 楼主| 发表于 2014-5-1 22:46:38 | 显示全部楼层
我说过AC可以合并,只是因为字段太多而分开。你们都没有仔细看我的需求。这里是一张发票申请单,不是一张发票。
这张发票申请单,只对应一个业务申请。实际上,所有流程的源头是业务申请;每一张业务申请单,对应一个客户,一张业务发票申请,对应多条销售商品明细(名称 单位 价格 。。。)。一张发票申请单,财务人员可能开一张发票,也可能开多张发票,这里就不管了。
回复 支持 反对

使用道具 举报

45

主题

4492

帖子

3960

积分

论坛元老

Rank: 8Rank: 8

积分
3960
QQ
发表于 2014-5-2 09:18:44 | 显示全部楼层
gzprof 发表于 2014-5-1 22:46
我说过AC可以合并,只是因为字段太多而分开。你们都没有仔细看我的需求。这里是一张发票申请单,不是一张发 ...

楼主,不是没有细看你的需求,而是在你的业务需求的基础上,进行拓展了一下,
我所说的情况,是在实际情况中现实存在的,不知道你的业务需求有没有这一块。
如:
李四一个业务单 0001,另一个业务 0002,
在发票申请的时候,一起进行申请;

还有一个种情况就是, 李四的业务单部分商品开发票,一部分商品不开发票。
你这些情况都应该考虑。

向前进,向前进,我们……
回复 支持 反对

使用道具 举报

17

主题

355

帖子

772

积分

高级会员

Rank: 4

积分
772
QQ
发表于 2014-5-3 19:31:53 | 显示全部楼层
gzprof 发表于 2014-5-1 22:46
我说过AC可以合并,只是因为字段太多而分开。你们都没有仔细看我的需求。这里是一张发票申请单,不是一张发 ...

我回来了,问题解决没,没解决继续讨论!
一步一步走向那迦南地......
回复 支持 反对

使用道具 举报

91

主题

13万

帖子

3万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
35942
发表于 2014-5-4 09:40:18 | 显示全部楼层
gzprof 发表于 2014-5-1 22:46
我说过AC可以合并,只是因为字段太多而分开。你们都没有仔细看我的需求。这里是一张发票申请单,不是一张发 ...

如果只是要展现B和C的数据

AB是主从,那么B中也有A的主键值

C的数据有了,根据这个主键值去过滤B的数据
远程的联系方法QQ1392416607,添加好友时,需在备注里注明其论坛名字及ID,公司等信息
发远程时同时也发一下帖子地址,方便了解要解决的问题  WeX5教程  WeX5下载



如按照该方法解决,请及时跟帖,便于版主结贴
回复 支持 反对

使用道具 举报

9

主题

45

帖子

188

积分

初级会员

Rank: 2

积分
188
QQ
 楼主| 发表于 2014-5-6 01:08:21 | 显示全部楼层
已经实现。现在贴出来分享,希望高手指教提出更好的解决方法。

1、概念设置
首先,将AB概念按教学方法设置主从库。其次,B增加一个关系fCid,类型为概念C,并且在映射设置中增加一个字段为fCid(这样,B就有了2个分别指向A和C的映射字段)。然后,进行概念C的设置:C中设一个单值关系Aid,String类型,以便将来通过A来访问B;再增加一个多值关系Bids,类型为概念B,互逆中设置B的关系fCid。
由于我这里的业务逻辑是:AB为逻辑源头,有AB才有C;A删除则B中相关数据必须删除,C没有AB则继续存在。故在A的互逆关系中设置了级联删除(composition),而C的互逆关系则不设置级联删除(在高级中不配置,其缺省为aggregation)。

2、界面模型
有关AB的应用,直接使用教学里面的主从界面。
而CB的应用,首先按教学方法使用主从界面,C为主B为从。C界面中的数据操作不变,但从概念B的界面中则不能有新建和删除操作,只能查询和修改(前面已经解释了原因)。那么如何把C的数据连接到B呢?
我这里是这样做的(比较复杂,牵涉到有关windowDialog与主界面的数据互传):
在C界面中增加一个trigger,点击事件为打开一个windowDialog,并传入一个参数idFPSQ:C的当前数据行的主键值。另外,在该弹出窗口的receive事件中,要处理器回送数据;这里仅仅是刷新数据,将关联的从数据B显示出来。
这个弹出窗口做2件事情:
(1)选择C对应的A数据行,并将有关A的数据读出来并传回C中。故要按传统使用方法建立数据映射,特别是C的关系Aid一定要映射好(对应到弹出窗口数据的rowID)。
(2)将A中选中的1条主记录所对应的B中从记录关联到C来,就是对B中的这些数据记录的fCid赋值为参数idFPSQ。增加一个trigger来执行此事件。原界面的“确定”“取消”可以保留,作用不一样;只有增加的这个按钮才能进行主从关联。由于弹出窗口向导中没有主从表界面,故只有自己加入一个从表(增加dataDetail数据组件和对应的grid组件;grid一定要有否则会报错,dataDetail要设置dataMaster和主从关系)。

参考代码
BC主从界面的js文件:
  1. var mainActivity = {};

  2. mainActivity.trigger1Click = function(event){
  3.         var mainData = justep.xbl('dataMaster');
  4.         var idFPSQ = mainData.getCurrentID();
  5.         justep.xbl("selectSaleWindowDialog").open({
  6.                 "idFPSQ" : idFPSQ
  7.                 });        // 传入本发票申请记录的主键,以便弹出窗口对选中的业务申请明细记录赋值。
  8. };

  9. /**
  10.         name:windowDialog#onReceive}
  11.         @param {function} onInit 初始化事件,参见{@link UI.windowDialog#onInit}
  12.         @param {function} onOpen 对话框打开事件,参见{@link UI.windowDialog#onOpen}
  13.         @param {function} onClose 对话框关闭事件,参见{@link UI.windowDialog#onClose}
  14. description: 构造函数
  15.         @example
  16.         //动态创建
  17.         var dialog = new justep.WindowDialog(id, url, title);
  18. */
  19. mainActivity.selectSaleWindowDialogReceive = function(event){
  20.         var detailData = justep.xbl('dataDetail');       
  21.         detailData.refreshData();
  22.         // 弹出窗口选定了对应的业务申请单,且对相关业务申请明细记录填入了本发票申请记录的主键值;
  23.         // 这样,这里只要刷新数据就会自动将其作为从表刷出来。
  24. };
复制代码
弹出窗口界面的js文件:
  1. var selectOneSale = {};


  2. /**
  3.         name:windowReceiver#onReceive
  4.         @event
  5. description: <b>[回调型事件]</b> window接收调用者传入的数据
  6.         @param event
  7.         <br/><b>格式说明:</b>
  8.         <xmp>
  9.         {
  10.                 "source" : 组件的js对象,
  11.                 "data" : 传入的数据
  12.         }
  13.         </xmp>
  14.         @example
  15.         //接受传入的rowid,组成filter刷新data
  16.         1、data组件上定义filter1 = DEMO_TABLE1 = :rowid
  17.         2、接管onReceive
  18.         windowReceiverReceive = function(event){
  19.                 if(event.data && event.data.rowid){
  20.                         var data = justep.xbl('mainData');
  21.                         //给变参:rowid赋值
  22.                         data.filters.setStringVar('rowid', event.data.rowid);
  23.                         data.refreshData();
  24.                 }
  25.         }
  26. */
  27. var        idFPSQ;
  28. selectOneSale.windowReceiverReceive = function(event){
  29.         idFPSQ = event.data.idFPSQ;
  30.         //alert(idFPSQ);
  31. };

  32. /*function justep.SingleList.windowOK(event){
  33.         var        dataMain = justep.xbl("main");
  34.         var        dataSQMX = justep.xbl("dataSQMX");
  35.         dataSQMX.refreshData();        // Load detail about YWSQ
  36.         for (var i = 0; i < dataSQMX.getCount(); i++) {
  37.                 var id = dataSQMX.getID(i);
  38.                 data.setValue('fFPSQZKID', idFPSQ, id);
  39.         }
  40.         data.saveData();       
  41. };*/

  42. selectOneSale.trigger1_11Click = function(event){
  43.         var        dataMain = justep.xbl("main");
  44.         var        dataSQMX = justep.xbl("dataSQMX");
  45.         dataSQMX.refreshData();        // Load detail about YWSQ
  46.         for (var i = 0; i < dataSQMX.getCount(); i++) {
  47.                 var id = dataSQMX.getID(i);
  48.                 dataSQMX.setValue('fFPSQZKID', idFPSQ, id);
  49.         }
  50.         dataSQMX.saveData();
  51.         justep.SingleList.windowOK();       
  52. };
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|X3技术论坛|Justep Inc.    

GMT+8, 2024-5-16 11:36 , Processed in 0.064862 second(s), 30 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表