标准单据体插件
1 插件介绍
金蝶云苍穹,未提供单纯的表格控件,要实现多行多列数据的录入、显示,必须使用单据体。
设计时,单据体效果;
运行时,单据体效果;
可以在设计时,从工具栏中拖拽字段到单据体中,形成单据体的列;
暂时不能拖拽通用控件进单据体;
单据体与列字段,是包含关系,分别有对应的实体属性对象与控件编程模型;
用户添加、删除数据行,会触发单据体的行改变事件;而维护列字段的值,触发字段的值改变事件。
2 控件编程模型
2.1 控件编程模型定义
插件可以通过单据体控件编程模型实例,间接控制前端的单据体表格。
单据体的控件编程模型类为EntryGrid,派生自表格控件基类AbstractGrid:
package kd.bos.form.control; public class EntryGrid extends AbstractGrid implements ISupportInitialize {
插件可以通过如下语句,获取到单据体控件实例:
EntryGrid grid = this.getView().getControl(Key_EntryEntity);
2.2 控件方法清单
单据体控件EntryGrid,继承了表格控件基类的方法,并新增了如下公共方法:
方法 | 说明 |
---|---|
getEntryKey | 获取单据体标识 |
setEntryKey | 设置单据体标识 内部方法,插件勿调用 |
getSubEntryGrids | 获取子分录表格集合 |
setSubEntryGrids | 设置子分录表格集合 内部方法,插件勿调用 |
getRuleCount | 获取实体服务规则个数 |
setRuleCount | 设置实体服务规则个数 内部方法,插件勿调用 |
getFieldEdits | 获取列字段控件集合 |
getRowBindValue | 获取行绑定的值 内部方法,插件勿调用 |
getDataIndex | 生成列索引返回 绑定行数据时,会按照列索引绑定各单元格的值 |
updateColFmt | 刷新字段对应列的格式化信息 |
updateCellFmt | 刷新字段对应单元格的格式化信息 |
setNumFmtInfo | 基于单元格的数据,刷新单元格格式化信息 内部方法,插件勿调用 |
setFloatButtomData | 设置合计单元格的值 |
next | 翻页 内部方法,插件勿调用 |
getSelectRows | 获取选中行 |
beginInit | 序列化处理方法 内部方法,插件勿调用 |
endInit | 序列化处理方法 内部方法,插件勿调用 |
isInitialized | 序列化处理方法 内部方法,插件勿调用 |
3 数据模型
3.1 属性对象
保存单据设计时,系统会把单据体,转为单据主实体模型MainEntityType下的一个属性对象
EntryProp:
package kd.bos.entity.property; public class EntryProp extends DynamicCollectionProperty implements IValidatorHanlder {
EntryProp是集合型的属性,关联一个子实体模型 EntryType,包含单据体下的全部字段:
package kd.bos.entity; public class EntryType extends EntityType {
如下示例代码,演示如何获取到单据体对应的属性对象,以及子实体模型:
private EntryProp getEntryProp(){ // 单据体在主实体模型下的属性对象 MainEntityType mainType = this.getModel().getDataEntityType(); EntryProp entryProp = (EntryProp)mainType.getProperties().get(KEY_ENTRYENTITY1); // 单据体关联的子实体对象,其下包含了单据体全部字段 // EntryType entryType = (EntryType)entryProp.getItemType(); // DataEntityPropertyCollection props = entryType.getProperties(); return entryProp; }
3.2 属性值
在单据数据包中,单据体的数据是DynamicObjectCollection类型,单据体全部行的数据包集合。
单据体每行数据,又是DynamicObject类型,包含了单据体各字段值,以及子单据体数据包。
如下代码,分别演示了几种方法从数据模型中,获取单据体数据:
private DynamicObjectCollection getEntryRows(){ DynamicObjectCollection rows = null; // 方法一:利用DataModel提供的方法 rows = this.getModel().getEntryEntity(KEY_ENTRYENTITY1); // 方法二:自行从单据数据包中获取 DynamicObject billObj = this.getModel().getDataEntity(true); rows = billObj.getDynamicObjectCollection(KEY_ENTRYENTITY1); // 方法三:利用单据体属性对象EntryProp,从单据数据包中获取 EntryProp entryProp = (EntryProp)this.getModel().getDataEntityType().getProperties().get(KEY_ENTRYENTITY1); rows = (DynamicObjectCollection)entryProp.getValue(billObj); // 如下代码演示利用单据体属性对象,为单据体行增加新行 EntryType entryType = (EntryType) entryProp.getItemType(); DynamicObject row = new DynamicObject(entryType); rows.add(row); return rows; }
4 单据体数据操作接口
4.1 单据体数据操作接口定义
为方便代码快速访问单据体中的数据,系统特别封装了一个单据体数据操作接口IEntryOperate:
package kd.bos.entity.datamodel; public interface IEntryOperate {
动态表单数据模型接口IDataModel,继承了此接口。因此,插件可以直接通过表单数据模型,获取、设置单据体数据:
package kd.bos.entity.datamodel; public interface IDataModel extends ISupportInitialize, IEntryOperate, IDataProvider {
插件可以通过如下示例代码,获取到单据体数据模型接口实例:
private IEntryOperate getEntryDataModel(){ return this.getModel(); }
4.2 方法清单
单据体数据模型接口IEntryOperate,提供了如下方法:
方法 | 说明 |
---|---|
getEntryEntity | 获取全部行数据包集合; 有重载方法,可以指定行范围 |
getEntryRowEntity | 获取指定行的数据包 |
getEntryCurrentRowIndex | 获取焦点行索引 |
getEntryRowCount | 获取总行数 |
getEntryNextRowCount | 树表F7返回数据后,需要判断后面有没有足够同级行; 不够就appendEntryRow(不能insert,因为insert是插入下级行) |
getEntryNextRows | 获取树表当前节点后面的同级节点 |
createNewEntryRow | 新建行 |
batchCreateNewEntryRow | 批量新建行 |
insertEntryRow | 插入行 树表会给指定行,插入下级行 |
appendEntryRow | 批量追加分录行 树表F7返回数据时,使用此方法,在分录中间追加同级行 |
copyEntryRow | 复制行 |
deleteEntryRow | 删除行 |
deleteEntryRows | 批量删除行 |
deleteEntryData | 删除全部行 |
moveEntryRowUp | 行上移 |
moveEntryRowsUp | 批量行上移 |
moveEntryRowDown | 行下移 |
moveEntryRowsDown | 批量行下移 |
5 插件事件
单据体提供如下插件事件:
分类 | 事件 | 触发时机 |
---|---|---|
数据行改变 | beforeAddRow | 暂未触发 |
afterAddRow | 添加、插入、复制新行完毕,给新行填写了默认值之后触发 | |
beforeDeleteRow | 暂未触发 | |
afterDeleteRow | 删除行之后触发 | |
beforeDeleteEntry | 暂未触发 | |
afterDeleteEntry | 单据体数据被清空后触发 | |
afterMoveEntryUp | 单据体行往上移动后触发 | |
afterMoveEntryDown | 单据体行往下移动后触发 | |
用户点击 | cellClick | 单据体焦点行、焦点单元格切换时触发 |
entryRowClick | 单据体焦点行、焦点单元格切换时触发 | |
cellDoubleClick | 用户双击单据体中锁定的单元格时,触发此事件;如果单元格未锁定,双击不会触发此事件 | |
entryRowDoubleClick | 用户双击单据体中锁定的单元格时,触发此事件;如果单元格未锁定,双击不会触发此事件 | |
hyperLinkClick | 用户点击表格中超链接单元格时,触发此事件 |
响应单据体表格全部事件:
package kd.bos.plugin.sample.dynamicform.pcform.entrygrid.template; import java.util.EventObject; import kd.bos.entity.datamodel.events.AfterAddRowEventArgs; import kd.bos.entity.datamodel.events.AfterDeleteEntryEventArgs; import kd.bos.entity.datamodel.events.AfterDeleteRowEventArgs; import kd.bos.entity.datamodel.events.AfterMoveEntryEventArgs; import kd.bos.entity.datamodel.events.BeforeAddRowEventArgs; import kd.bos.entity.datamodel.events.BeforeDeleteEntryEventArgs; import kd.bos.entity.datamodel.events.BeforeDeleteRowEventArgs; import kd.bos.form.control.EntryGrid; import kd.bos.form.control.events.CellClickEvent; import kd.bos.form.control.events.CellClickListener; import kd.bos.form.control.events.RowClickEvent; import kd.bos.form.control.events.RowClickEventListener; import kd.bos.form.events.HyperLinkClickEvent; import kd.bos.form.events.HyperLinkClickListener; import kd.bos.form.plugin.AbstractFormPlugin; public class EntryGridAllEvents extends AbstractFormPlugin implements CellClickListener, RowClickEventListener, HyperLinkClickListener { private final static String KEY_ENTRYENTITY = "entryentity"; @Override public void registerListener(EventObject e) { super.registerListener(e); // 侦听单据体表格事件 EntryGrid entryGrid = this.getView().getControl(KEY_ENTRYENTITY); entryGrid.addCellClickListener(this); // 单元格点击 entryGrid.addRowClickListener(this); // 行点击 entryGrid.addHyperClickListener(this); // 点击超链接单元格 } /****************** 数据行变化触发的事件 **************************/ @Override public void beforeAddRow(BeforeAddRowEventArgs e) { // 此事件暂未触发 } @Override public void afterAddRow(AfterAddRowEventArgs e) { // 添加、插入、复制新行完毕,给新行填写了默认值之后,触发此事件; // 插件可以在此修改新行字段默认值,或者调整界面上控件的状态 // 实例:DataModelChangeListener捕获此事件,给前端单据体增加新行 } @Override public void beforeDeleteRow(BeforeDeleteRowEventArgs e) { // 此事件暂未触发 } @Override public void afterDeleteRow(AfterDeleteRowEventArgs e) { // 删除行之后,触发此事件; // 插件可以在此事件,进行删除行后的数据同步处理,如刷新合计 // 实例:DataModelChangeListener捕获此事件,通知前端单据体删除行及子单据体行 } @Override public void beforeDeleteEntry(BeforeDeleteEntryEventArgs e) { // 此事件暂未触发 } @Override public void afterDeleteEntry(AfterDeleteEntryEventArgs e) { // 单据体数据被清空后,触发此事件; // 插件可以在此事件进行数据同步处理; // 实例:DataModelChangeListener捕获此事件,给前端单据体增加新行 } @Override public void afterMoveEntryUp(AfterMoveEntryEventArgs e) { // 单据体行往上移动后,触发此事件; // 插件可以在此事件中,获知到被移动行的原始行号,进行数据同步处理; // 实例:DataModelChangeListener捕获此事件,给前端单据体表格下达行调整指令 } @Override public void afterMoveEntryDown(AfterMoveEntryEventArgs e) { // 单据体行往下移动后,触发此事件; // 插件可以在此事件中,获知到被移动行的原始行号,进行数据同步处理; // 实例:DataModelChangeListener捕获此事件,给前端单据体表格下达行调整指令 } /******************** 用户与单据体表格交互产生的事件 ***********************/ @Override public void cellClick(CellClickEvent arg0) { // 单据体焦点行、焦点单元格切换时,触发此事件: // 1. 通过点击鼠标,切换行、单元格时,触发事件; // 2. 按键盘上下左右键切换单元格,不触发事件,但是开始编辑单元格值,触发事件 // 插件可以在此事件,第一时间获取表格焦点单元格的变化,据此刷新界面控件状态; // 此事件与entryRowClick事件,先后触发,本事件在先; System.out.println(String.format("cellClick: row = %s; field = %s", arg0.getRow(), arg0.getFieldKey())); } @Override public void entryRowClick(RowClickEvent evt) { // 单据体焦点行、焦点单元格切换时,触发此事件: // 1. 通过点击鼠标,切换行、单元格时,触发事件; // 2. 按键盘上下左右键切换单元格,不触发事件,但是开始编辑单元格值,触发事件 // 插件可以在此事件,第一时间获取表格焦点行的变化,据此刷新界面控件状态; System.out.println(String.format("entryRowClick: row = %s", evt.getRow())); } @Override public void cellDoubleClick(CellClickEvent arg0) { // 用户双击单据体中锁定的单元格时,触发此事件;如果单元格未锁定,双击不会触发此事件 // 插件可以响应此事件,打开焦点单元格字段编辑子界面 // 插件在触发此事件时,会先触发cellClick事件 System.out.println(String.format("cellDoubleClick: row = %s; field = %s", arg0.getRow(), arg0.getFieldKey())); } @Override public void entryRowDoubleClick(RowClickEvent evt) { // 用户双击单据体中锁定的单元格时,触发此事件;如果单元格未锁定,双击不会触发此事件 // 插件可以响应此事件,打开子界面 // 插件在触发此事件时,会先触发entryRowClick事件 System.out.println(String.format("entryRowDoubleClick: row = %s", evt.getRow())); } @Override public void hyperLinkClick(HyperLinkClickEvent arg0) { // 用户点击表格中超链接单元格时,触发此事件; // 插件响应用户点击事件,打开链接页面 // 前提:单据体字段,需要勾选"显示为超链"选项,且锁定; System.out.println(String.format("hyperLinkClick: page = %s; row = %s; field = %s", arg0.getPageIndex(), arg0.getRowIndex(), arg0.getFieldName())); } }
标准单据体插件
本文2024-09-23 00:22:03发表“云苍穹知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-cangqiong-139015.html