本文介绍了在前端页面上新增标准单据体分录并填充数据的需求、思路与实现过程。首先,通过新建单据页面和编写单据插件来响应事件,实现页面加载和点击工具栏按钮时自动填充数据。提供了三种实现方案:方案一通过接口新建或批量新建行并赋值,适用于数据量小;方案二通过表格设置器批量增加分录行,性能较优;方案三通过设置表单数据包实现批量填充,同样性能较优。还提醒了开发环境和注意事项,如点击后定位问题、缺省行数设置、循环赋值时的行号问题等,并给出了参考资料。
关键词:单据体
一、需求
标准单据体控件在前端页面上新增分录并填充数据。
二、思路与方案
在 控件使用指南——标准单据体 中,明确指出单据体是用来在界面上显示、录入多行多列数据。其控件编程模型类为kd.bos.form.control.EntryGrid,派生自表格控件基类kd.bos.form.control.AbstractGrid,并提供了诸多方法和事件。
三、实现过程
1. 新建单据页面,其中,单据体分页展示,每页5条。其设计器界面如下图所示。
注意:
单据体控件的业务属性“缺省行数”设置为0。
2. 编写单据插件,响应事件 afterCreateNewData(EventObject) 以实现页面加载时自动为标准单据体填充数据,响应事件 itemClick(ItemClickEvent) 以实现点击工具栏按钮时为标准单据体填充数据。
@Override public void afterCreateNewData(EventObject e) { // 方案一 // this.entryentitySetVal1(); // 方案二 // this.entryentitySetVal2(); // 方案三 this.entryentitySetVal3(); super.afterCreateNewData(e); } @Override public void itemClick(ItemClickEvent evt) { String itemKey = evt.getItemKey(); if (StringUtils.equalsIgnoreCase("kdec_bartest", itemKey)) { // 方案一 // this.entryentitySetVal1(); // 方案二 // this.entryentitySetVal2(); // 方案三 // this.entryentitySetVal3(); } super.itemClick(evt); }
3.1 方案一
1. 通过以下接口实现
① this.getModel().createNewEntryRow("entryentity");//新建行
② this.getModel().batchCreateNewEntryRow("entryentity", size);//批量新建行
其中,entryentity为单据体标识,size为新增分录的行数。
接口中还有其他同名增行api可调用,请自行查阅。
2. 完整代码
/** * 方案一 * 适用于数据量小的业务场景 */ private void entryentitySetVal1() { StringBuffer logBuffer = new StringBuffer("单据体赋值: \r\n"); // 待新增分录的行数 int size = 6; IDataModel dataModel = this.getModel(); int currRowCnt = dataModel.getEntryRowCount(KEY_ENTRYENTITY); dataModel.batchCreateNewEntryRow(KEY_ENTRYENTITY, size); for (int i = currRowCnt; i < (currRowCnt + size); i++) { // 第 1 个参数(propName): 单据体列字段的字段标识 // 第 2 个参数(value):对应列字段待填充的值 // 第 3 个参数(rowIndex):行号, 从0开始计 dataModel.setValue(KEY_ENTRYFIELD[0], "文本-" + (i + 1), i); dataModel.setValue(KEY_ENTRYFIELD[1], 8.88, i); dataModel.setValue(KEY_ENTRYFIELD[2], (i+1), i); dataModel.setValue(KEY_ENTRYFIELD[3], 1.23, i); logBuffer.append(String.format("第 %1$s 行数据: %2$s, %3$s, %4$s, %5$s\r\n", (i + 1), String.format("文本-%s", (i + 1)), 8.88, (i + 1), 1.23)); } logger.info(logBuffer.toString()); this.getView().showTipNotification(logBuffer.toString()); }
3.2 方案二
1. 通过表格设置器实现
步骤:先开启事务,然后设置 表格值设置器 表格所包含的列,接着向表格值设置器填充数据,再用表格设置器批量增加分录行,最后关闭事务,更新分录。
2. 完整代码
/** * 方案二 * 该方案适用于批量数据赋值, 性能较优 */ private void entryentitySetVal2() { StringBuffer logBuffer = new StringBuffer("单据体赋值: \r\n"); int size = 7; AbstractFormDataModel model = (AbstractFormDataModel) this.getModel(); // 开启事务 // 为表格设置一行数据后,微服务会向前端发送数据,并重新渲染表格。如果设置多行数据则会渲染多次。 // 事务的作用是将多次修改的数据作为整体向前端发送,将多次渲染合并为一次,避免多次渲染造成的卡顿等性能问题。 model.beginInit(); // 设置表格值设置器表格所包含的列 TableValueSetter setter = new TableValueSetter(); setter.addField(KEY_ENTRYFIELD[0]); setter.addField(KEY_ENTRYFIELD[1]); setter.addField(KEY_ENTRYFIELD[2]); setter.addField(KEY_ENTRYFIELD[3]); // 向表格设置器填充数据 for (int i = 0; i < size; i++) { setter.addRow("文本-" + (i + 1), 5.55, (i+1), 6.66); logBuffer.append(String.format("第 %1$s 行数据: %2$s, %3$s, %4$s, %5$s\r\n", (i + 1), String.format("文本-%s", (i + 1)), 5.55, (i + 1), 6.66)); } // 用表格设置器批量添加行 model.batchCreateNewEntryRow(KEY_ENTRYENTITY, setter); // 关闭事务 model.endInit(); // 更新分录 this.getView().updateView(KEY_ENTRYENTITY); logger.info(logBuffer.toString()); this.getView().showTipNotification(logBuffer.toString()); }
3.3 方案三
1. 通过设置表单数据包来实现批量填充标准单据体数据
2. 完整代码
/** * 方案三 * 该方案适用于批量数据赋值, 性能较优 */ private void entryentitySetVal3() { StringBuffer logBuffer = new StringBuffer("单据体赋值: \r\n"); DynamicObjectType entryType = this.getModel().getEntryEntity(KEY_ENTRYENTITY).getDynamicObjectType(); DynamicObjectCollection entryColl = this.getModel().getEntryEntity(KEY_ENTRYENTITY); // 待新增分录的行数 int size = 8; for (int i = 0; i < size; i++) { DynamicObject entryObj = new DynamicObject(entryType); entryObj.set(KEY_ENTRYFIELD[0], String.format("文本-%s", (i + 1))); entryObj.set(KEY_ENTRYFIELD[1], 13.14); entryObj.set(KEY_ENTRYFIELD[2], BusinessDataServiceHelper.loadSingle((i + 1), "bd_currency")); entryObj.set(KEY_ENTRYFIELD[3], 13.14); logBuffer.append(String.format("第 %1$s 行数据: %2$s, %3$s, %4$s, %5$s\r\n", (i + 1), String.format("文本-%s", (i + 1)), 13.14, (i + 1), 13.14)); entryColl.add(entryObj); } // 点击事件, 存在苍穹缓存不同步的问题, 需代码处理 this.getModel().updateEntryCache(entryColl); this.getView().updateView(KEY_ENTRYENTITY); logger.info(logBuffer.toString()); this.getView().showTipNotification(logBuffer.toString()); }
四、效果图
五、开发环境版本
不限
六、注意事项
1. 点击工具栏按钮为标准单据体填充数据后,采用方案一会自动定位到最后一页。
2. 本样例中,注意将单据体控件的业务属性“缺省行数”设置为0。否则,默认会按该配置多出空行。
3. 方案一适用于数据量小的业务场景,方案二、方案三适用于批量数据赋值,性能较优,重点推荐方案二、三。
4. 注意方案一 & 方案二循环赋值时的行起始号!若单据体已存在有数据行,则方案一需从后一行开始赋值,而方案二始终是从第 0 行开始赋值。
5. 标准单据体默认是支持分页功能的。当数据量大于5000时,会从数据库取下一页数据。
6. 本样例附件中仅含样例源码,页面较简单,请自行新建,然后注册插件,重启服务即可复现样例效果。
七、参考资料
如何在界面上给单据体创建分录行并赋值.zip(10.87KB)
推荐阅读