EAS BOS 开发问题集锦

栏目:eas cloud知识作者:金蝶来源:金蝶云社区发布:2024-09-16浏览:1

EAS BOS 开发问题集锦

# EAS BOS 开发问题集锦

1:二次开发后,EAS的运行机制

(以下说明只适合于BOS6.1以后版本)


BOS视图目录说明:MMEAS:EAS解决方案目录


metadata:二次开发元数据存放目录


basemetas:标准产品元数据存放目录


在BOS开发平台中,当在basemetas目录下双击某一个元数据文件时,BOS会自动帮我们生成该元数据的一份拷贝到metadata目录下,二次开发如果需要修改元数据,就到metadata目录下修改。 EAS在运行时,会优先加载metadata目录下的元数据。(注:若删除metadata目录下修改过的元数据,EAS会自动加载basemetas目录下标准产品的元数据,因此在开发过程中,如果metadata目录下的元数据文件改乱了,可大胆将其删除)。


Java视图目录说明: 在BOS视图对元数据进行发布后,BOS平台会在Java视图生成相应的.java文件。此时,开发者可以通修改相关的java文件进行二次开发的工作。注意:二次开发所做的修改,要尽量避免与产品打补丁产生冲突。


2:UI类常用方法说明


方法:onLoad() 

说明:UI第一次加载时调用,通常用于单据第一次初始化时对单据进行相关属性的操作,注意,当在UI界面打开后,再点 “新增按钮”,此时是不执行此方法的。


方法:actionAddNew_actionPerformed(ActionEvent arg0) 

说明:点击单据上的“新增”按钮时触发的事件。


方法:verifyInput(ActionEvent e) 

说明:验证输入内容


方法:applyDefaultValue(IObjectValue iobjectvalue) 

说明:对表头的字段设置默认值时,重写此方法


方法:getSelectors() 

说明:


方法:*_dataChanged(DataChangeEvent e) 

说明:单据上某一字段的值改变时,触发此方法


方法:storeFields() 

说明:


方法:actionRec_actionPerformed(ActionEvent e) 

说明:


方法:applyDefaultValue(IObjectValue iobjectvalue) 

说明:


方法:public void verifyInput(ActionEvent actionevent) 

说明:验证



3:如何让表头的字段在单据提交后还能进行修改?

一般情况下,单据提交后,是不允许修改的。但是也存在一些特殊的情况,需要在工作流中,对单据中的某些字段进行修改,此时,一般是通过在自定义的UI扩展类中,重写onLoad()方法,然后在方法中调用控件的setEnabled()、setEditable()、setReadOnly()方法(这三个方法不一定需要全部调用,根据具体情况而定),如下代码:


@Override

public void onLoad() throws Exception {

super.onLoad();

//单据未生成凭证之前,"收款类型"为可编辑、“往来户”也可编辑

boolean hasFV = this.editData.isFiVouchered();

if(!hasFV){

//收款类型

f7RecBillType.setEnabled(true);

f7RecBillType.setEditable(true);

f7RecBillType.setReadOnly(false);

//往来户

prmtPayer.setEnabled(true);

prmtPayer.setEditable(true);

prmtPayer.setReadOnly(false);

}

}


4:如何修改F7字段所关联的基础档案

在一般情况下,在BIM视图对单据新增F7字段时,就可以关联到想要的基础档案或其它视图。但是,当需要关联一些不存在业务单元(即*.bizunit文件)的基础档案时(如:自定义核算项目)。此时就只能通过以下步骤来处理:


在BIM里加一个F7字段,关联物料或其他可以选到的基础资料。保存后先别发布


切换到BOS透视图,打到对应的.relation文件,修改supplierEntity,原来是指定物料的实体,改成自定义核算项目的实体


打开XXXEditUI.ui,修改F7字段的queryInfo,原来是指向物料的query,改成自定义核算项目的query


5:如何给F7控件设置过滤条件

当需要对F7控件所打个视图中的内容进行过滤时,可对F7控件设置过滤条件,使用方法如下:


    EntityViewInfo evi = new EntityViewInfo(); //创建实体视图

    FilterInfo f = new FilterInfo();//创建过滤对象

    FilterItemInfo filter1 = new FilterItemInfo("number", "SHFL001", CompareType.GREATER);//创建第一个过滤条件,第一个参数:所查询的实体的属性,第二个参数:属性的目标值,第三个参数:比较符

    FilterItemInfo filter2=  new FilterItemInfo("age", "20", CompareType.GREATER);//创建第二个过滤条件

    f.getFilterItems().add(filter1);//将过滤条件添加到过滤对象中

    f.getFilterItems().add(filter2);

    f.setMaskString("#0 or #1");//设置两个过滤条件之间的关系

    evi.setFilter(f);//设置实体视图的过滤器

    f7.setEntityViewInfo(evi);//将实体视图绑定到F7控件

    f7 .getQueryAgent().resetRuntimeEntityView();

6:如何通过IObjectPK pk获取实体对象

IObjectPK是一个表示实体对象id的对象,在日常开发工作中,经常需要通过它来获取实体对象。以下是通过IObjectPK获取实体对象代码的模版:


I*Info i*Info =  *Factory.getLocalInstance(ctx);

*Info info = i*Info.get*Info(pk);

//以下示例,通过IObjectPK获取成本对象实体:CostObjectInfo

ICostObject  iCostInfo = CostObjectFactory.getLocalInstance(ctx);

CostObjectInfo coi =  iCostInfo.getCostObjectInfo(pk);

7:如何通过实体对象的id获取实体对象

//如下代码,通过应收单的id号,获取应收单表体实体


String entityID ="dsfarlewkrjewrojafad";

//BOSUuid uid = BOSUuid.create(entityID);

IObjectPK opk = new ObjectUuidPK(entityID);

OtherBillentryInfo obi = OtherBillentryFactory.getRemoteInstance().getOtherBillentryInfo(opk);

8:BOTP自定义公式解决方案

注意:只适用于EASBOS530或以上版本


一、业务场景: 运行时BOTP的公式平台提供的函数较少,如果要实现比较复杂的逻辑,譬如通过物料编码从其他单据取出对应数量,运行时的公式平台就显得捉襟见肘了。对于客户开发的单据,可以通过写代码实现。但是对于标准产品的单据,如果反编译代码,则升级时相当麻烦。而自定义公式方案正是为了解决此难题而生。它可以通过写代码在BOTP公式平台挂上自定义的公式,公式内容由程序员自由决定,而不会受升级影响。


二、原理:(业务人员只需重点关注步骤3、4、5)


1.在BOS自定义一个类,实现com.kingdee.bos.service.formula.api.IFormulaFunctions接口。(该类必须位于com.kingdee.bos.service.formula.api此包下,因为要引用此包里的非公共类) 类的定义参考如下:


package com.kingdee.bos.service.formula.api;

import java.util.Iterator;

import java.util.List;

import java.util.Vector;

import com.kingdee.bos.kscript.KScriptException;

/**

 * BOTP自定义公式demo

 * @author Yang Yihao. Just call me House.

 * @date since 2007-9-6

 * @Email: dejavu.house@gmail.com

 */

public class CustomBTPFunctionDemo implements IFormulaFunctions

{

    //用于存放公式的变量

    private static Vector funcInfos;

    

    static

    {

        //加载类时定义自定义公式

        funcInfos = new Vector();

        //FuncInfo()的第一个参数是公式名,第二个参数是公式所在的分类(可随便取名),第三个参数是公式的描述信息(在BOTP公式平台显示)

        funcInfos.add(new FuncInfo("helloLiuXun", "HelloWorld", "Wish the 

Telecom project would complete soon.")); 

    }    

    /**

     * 运行时BOTP公式平台加载自定义公式时,就是从该返回值里取公式的名称的

     * @author Yang Yihao. Just call me House.

     * @date since 2007-9-6

     * @Email: dejavu.house@gmail.com

     * @return 所有自定义公式的名称

     */

    public String[] getAllFuncNames()

    {

        String as[] = new String[funcInfos.size()];

        for(int i = 0; i < funcInfos.size(); i++)

            as[i] = ((FuncInfo)funcInfos.get(i)).funcName;

        return as;

    }

    /**

     * 运行时BOTP公式平台加载自定义公式时,就是从该返回值里取公式的分类的(看运

行时的界面就很好理解)

     * @author Yang Yihao. Just call me House.

     * @date since 2007-9-6

     * @Email: dejavu.house@gmail.com

     * @param s

     * @return

     */

    public String getFuncCategory(String s)

    {

        if(s == null)

            return null;

        for(int i = 0; i < funcInfos.size(); i++)

            if(s.equals(((FuncInfo)funcInfos.get(i)).funcName))

                return ((FuncInfo)funcInfos.get(i)).funcCategory;

        return null;

    }

    /**

     * 获取公式的描述

     * @author Yang Yihao. Just call me House.

     * @date since 2007-9-6

     * @Email: dejavu.house@gmail.com

     * @param s

     * @return

     */

    public String getFuncDesc(String s)    {

        if(s == null)

            return null;

        for(int i = 0; i < funcInfos.size(); i++)

            if(s.equals(((FuncInfo)funcInfos.get(i)).funcName))

                return ((FuncInfo)funcInfos.get(i)).funcDesc;

        return null;

    }

    public boolean existFunction(String s)

    {

        if(s == null)

            return false;

        for(int i = 0; i < funcInfos.size(); i++)

            if(s.equals(((FuncInfo)funcInfos.get(i)).funcName))

                return true;

        return false;

    }

    /**

     * 运行公式时调用此方法,公式的具体逻辑就写在这里

     * @author Yang Yihao. Just call me House.

     * @date since 2007-9-6

     * @Email: dejavu.house@gmail.com

     * @param func 公式名称

     * @param paramList 公式的参数

     * @return 公式结果

     * @throws KScriptException

     */

    public Object evalFunction(String func, List paramList) throws 

KScriptException

    {

        //判断用户是选了哪个公式

        if(func != null && func.equals("helloLiuXun"))

        {

//这里可以写满足各式各样需求的代码

            if(paramList != null && paramList.size() > 0)

            {

                StringBuffer sb = new StringBuffer(10);

                for(Iterator iter = paramList.iterator(); iter.hasNext();)

                {

                    sb.append(iter.next()).append(",");

                }

                return sb.toString();           

 }

            else

                return "Congratulations";

        }

        return "TheEnd";

    }

}


2.在BOTP目标单据的实体(entity)上加上扩展属性“billFormulaClass”,属性值设为第1步创建的类的全名(含包名)。如下图:


(注意:此 扩展属性 要在 表头实体 的 基础信息 页签中添加,表体实体是不存在billFormulaClass这个扩展属性的)


3.运行时,在BOTP规则设置的“公式平台”->“公式元素”->“函数”页签里可以看到自定义的函数


 


helloLiuXun()就是自定义公式。


4.设置BOTP公式的格式如下:


 


参数用半角双引号括起来,可以传多参数,参数间用半角逗号隔开。 5.恭喜,令人兴奋的结果完全满足你个性化的需求!


9:在自定我Java类中,引用系统日志的方法

import org.apache.log4j.Logger;


// 获取写日志的对象

private static Logger logger =      Logger.getLogger("com.kingdee.eas.custom.gz.bd.app.BizTypeGZControllerBean");

//写日志

logger.info(e.getMessage());

10:EAS-BOS项目路径变更的方法

拷贝工作区的时候,会出现目录变更,在发布项目是,会出现启动ear失败情况,如下错误:


[apusic.service.J2EEDeployer] 启动应用 'eas.ear' 失败。

com.apusic.deploy.runtime.InvalidModuleException: 模块文件 'D:\zgh\Project\gz\eTianxia\workspace\EWorld\runtime\server\deploy\eas.ear' 不存在。

EAS-BOS项目路径变更的方法:


1. 修改:$ProjectPath$\runtime\server\profiles\server1\config\bosconfig.xml

<attribute key="MetaDataPath" value="D:\workspace\EWorld/metadata" />`

2. 修改$ProjectPath$\runtime\server\profiles\server1\config\licensefile.xml

<uri>D:\workspace\EWorld\runtime\server\profiles\server1\config\licenses\license</uri>

3. $ProjectPath$\runtime\server\profiles\server1\config\portalConfig\easWebConfig.xml

      <!--本地元数据加载路径-->

      <attribute key="metadatapath" value="D:\workspace\EWorld\metadata" />

4. 修改$ProjectPath$\EWorld\runtime\apusic\config\server.xml

<server>

    <application name="eas.ear" base="D:/workspace/EWorld/runtime/server/deploy/eas.ear" start="auto" />

</server>

11:部署时提示版本不一致的解决办法

从服务器的目录:如: D:\Kingdee\eas\server\propertiesCopy文件eascomponents.xml 到部署机的目录: 如:E:\workspace\mmeas(具体名称根据你的项目名而定)


12:如何获取当前用户

在UI扩展类中,获取当前用户可通过工具类SysContext 如:SysContext.getSysContext().getCurrentUserInfo()


在ControlerBean的扩展类中,获取当前用户可通过工具类ContextUtil 如:ContextUtil.getCurrentUserInfo(ctx)


关于SysContext和ContextUtil这两个工具类中方法的介绍: 这两个类是EAS的全局工具类,用于获取当前用户信息,当前组织单元信息、客户端IP、客户端名字等信息。SysContext用于客户端,如UI扩展类中;而ContextUtil用于服务端,如ControllerBean扩展类中。


13:如何增加F7界面上的过滤条件

找到F7界面所对应的Query后,选择字段页签,找对应的属性?扩展属性:增加“是否在通用过滤中显示”的扩展属性,并将其值设置为true。重新发布。


 


14:访问应用服务器[server1,127.0.0.1:6888]时,用户名[admin]认证失败!

请检查部署应用时配置的的用户名及密码是否能正常登录应用服务器的管理页面。


如果不能登录,请首先应用服务器的管理控制台创建用户;


或者重新部署应用,修改部署向导配置的用户名/密码为合法值。 异常堆栈:


com.kingdee.eas.tools.admin.domain.exception.AppServerLoginFailedException: Authentication denied,the user name and/or password is not valid!

 at com.kingdee.eas.tools.admin.domain.impl.EASServerServiceImpl.startApplicationServer(EASServerServiceImpl.java:913)

 at com.kingdee.eas.tools.admin.domain.impl.EASServerServiceImpl.startApplicationServer(EASServerServiceImpl.java:719)

上述提示的方案好像有点问题,我另找了一个解决办法: 进入%Apusic_home%\domains\server1\store,将users.db文件删除,重启应用服务器,即可恢复admin密码为初始密码。


15:如何获得BOSType

打开*.entity实体视图。切换到“源代码”标签,找到<bosType>48DA3A71</bosType>。这就是该实体所对应的BOSType了 或者java代码:


BOSObjectType objectType = objectValue.getBOSType();

16:如何添加第3方jar包

1、在项目中切换到 java视图 选择项目工程右键 >构建路径>配置构建路径 2、将jar包分别Copy到以下路径


用于BOS使用 \workspacewm\wmnew\lib\client\trd \workspacewm\wmnew\lib\server\trd


部署路径 /kingdee/eas/server/deploy/fileserver.ear/easWebClient/lib/client/trd /kingdee/eas/server/deploy/fileserver.ear/easWebClient/deploy/client /kingdee/eas/server/lib/server/trd /kingdee/eas/server/lib/client/trd


17:bos登陆客户端显示没有许可

原因:bos工具自带eas license没有对应模块许可导致。 解决方法:将eas7.0安装包中自带eas 的license文件替换到bos工具如下路径即可, \bim\eclipse\plugins\com.kingdee.bos.bim_template_6.1.0\templates\licenses PS:license文件名必修改成“license”字样才可 就把licenses PS:license文件放到相同路径。文件名为license


18:手动添加合计行

1. 代码方式处理

//添加合计栏

KDTFootManager footmgr = new KDTFootManager(kdtE2);

footmgr.addFootView();

kdtE2.setFootManager(footmgr);

kdtE2.addFootRow(0);

IRow row = footmgr.getFootRow(0);

row.getCell(0).setValue("合计:");


//设置合计字段(重视父类方法)

protected void setTableToSumField() {

setTableToSumField(kdtE1, new String[] { "ContractAmount" });

super.setTableToSumField();

}

完整代码


IRow row = tblMain.addRow();

row.getStyleAttributes().setBackground(new Color(236, 255, 255));

row.getCell(0).setValue("合 计 栏 :");

row.getStyleAttributes().setBold(true);

row.getStyleAttributes().setFontColor(Color.RED);

BigDecimal sum1 = new BigDecimal("0.00"),sum2 = new BigDecimal("0.00");

BigDecimal sum3 =new BigDecimal("0.00"),sum4=new BigDecimal("0.00");

for (int i=0;i<tblMain.getRowCount();i++) {

//合计最后俩栏

if (tblMain.getCell(i, 1).getValue()!=null && 

!tblMain.getCell(i, 1).getValue().equals("")) {

tblMain.getCell(i, 1).setValue(((BigDecimal)tblMain.getCell(i, 1).getValue()).setScale(2));

sum1 = sum1.add((BigDecimal)tblMain.getCell(i, 1).getValue());

}

if (tblMain.getCell(i, 2).getValue()!=null && 

!tblMain.getCell(i, 2).getValue().equals("")) {

tblMain.getCell(i, 2).setValue(((BigDecimal)tblMain.getCell(i, 2).getValue()).setScale(2));

sum2 = sum2.add((BigDecimal)tblMain.getCell(i, 2).getValue());

}

}

row.getCell(1).setValue(sum1.setScale(2));

row.getCell(2).setValue(sum2.setScale(2));


2. bim设计处理

ListUI所绑定的Query字段页签设置两个扩展属性


 


是否统计字段:true 统计字段按主键进行统计:设置为主键字段名,比如(id,entrys.id),如果不设置的话,统计的时候会按分录行统计,对非分录行统计出来的结果会不正确。


在ListUI.java中重写isFootVisible方法,将返回值设置为true。


@Override

protected boolean isFootVisible() {

   // TODO Auto-generated method stub

   return true;

}

19:bos保存后自动退出

我猜到可能是JVM内存的问题,于是找到exlipse.ini,修改为: Eclipse.ini 路径:D:\kingdee\EASStudio\bos\BOSModular\platform\eclipse -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M


20:屏蔽分录双击排序功能

this.kdtEntrys.removeKDTMouseListener(this.kdtEntrys.getSortMange());//所有列

tblMain.getColumn(i).setSortable(false); //单个

21:获取单元格显示的值

detailTable.getCellDisplayText(cell);

22:合并这两个EntityViewInfo

EntityViewInfo view1 = new EntityViewInfo(); 

EntityViewInfo view2 = new EntityViewInfo(); 

view1.getFilter().mergeFilter(view2.getFilter(), "and"); 

23:指定F7对字段排序

SorterItemCollection sorter = new SorterItemCollection();     

SorterItemInfo sortinfo = new SorterItemInfo();     

sortinfo.setPropertyName("属性名称");     

sortinfo.setSortType(SortType.DESCEND);           

EntityViewInfo entityInfo = new EntityViewInfo();     

entityInfo.setSorter(sorter);           

my_PromptBox.setEntityViewInfo(entityInfo); 

24:标准产品如何扩展类以便重写方法

对于客户端的UI类,无论是listUI,还是EditUI,都可以在通过追加后缀名CTEx的方式来扩展。如要重写标准产品采购订单的保存方法: com.kingdee.eas.scm.sm.pur.client.PurorderEditUI,在实际二次开发中,发布之后只会生成com.kingdee.eas.scm.sm.pur.client.AbstractPurorderEditUI,如果要重写保存的方法,则可以在com.kingdee.eas.scm.sm.pur.client包下新建PurorderEditUICTEx,此类继承PurorderEditUI类即可,然后在PurorderEditUICTEx重写保存方法。


服务端的扩展,主要是对bean的扩展,有两种方法 方法1. 1、在bim里面找到对应的业务单据XXX,打开“业务单元->功能”,新建一功能,然后发布。 2、切换到java视图,可以找到刚才的业务单据的XXXControllerBeanEx。 3、在XXXControllerBeanEx中覆盖对应的方法即可。 方法2. 新建一扩展类如:TestControllerBeanEx,然后在文本打开实体元数据,增加一扩展属性


<rs key="entityObject[com.kingdee.eas.custom.app.Test].extendedProperty.controllerBeanEx">  

<lang locale="en_US" value="com.kingdee.eas.custom.app.TestControllerBeanEx" />

<lang locale="zh_CN" value="com.kingdee.eas.custom.app.TestControllerBeanEx" />

<lang locale="zh_TW" value="com.kingdee.eas.custom.app.TestControllerBeanEx" />

</rs>

注意上面的写法[com.kingdee.eas.custom.app.Test]中的"Test"是TestControllerBeanEx的controllerBeanEx前面的Test,可以参考该实体文件的其他的属性 <rs ....> ... </rs>


备注 客户端的扩展针对行业版提供的是PIEx,为了不影响产品的后续维护,针对客户的客户端UI扩展务必使用后缀CTEx。


25:如何让编辑界面一打开就是最大化

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();  

this.setPreferredSize(screenSize);

26:去掉导出Excel右键菜单

public void addCommonMenusToTable(KDTable table) {

super.addCommonMenusToTable(table);

  PopupMenuManager mgr = getPopupMenuManager(table);

  mgr.removeMenuSection("export");

 }

27:设置是否在调入列表界面之前先出过滤框

protected boolean initDefaultFilter()  { 

return true; 

}

28:隐藏EditUI上面板上的添加行删除行的按钮

this.kdtPaymentInfoEntry_detailPanel.getAddNewLineButton().setVisible(false); this.kdtPaymentInfoEntry_detailPanel.getInsertLineButton().setVisible(false); this.kdtPaymentInfoEntry_detailPanel.getRemoveLinesButton().setVisible(false);

29:特殊数据授权开发

一, 首先需要单据支持特殊数据权限,具体开发步骤如下:


权限项绑定实体,。


权限项的是否支持数据权限为“是”


在${EAS_HOME}/server/profiles/server*/config/EAS_PermissionConfiguration.xml配置文件中增加单据实体,添加方式如下:


<special-data-permission> 

<name>com.kingdee.eas.fi.gl.app.Voucher</name> 

<type>2652E01E</type>

</special-data-permission>

发布,部署,重启服务,同步权限项。


在特殊数据权限界面找到单据勾选上拥有者有权和主管权限,此时单据只能由制单人和自己的上级主管查看。如果要其他人查看则在指定主管中选择相应的人员和要查看的部门


30:多页签切换事件

panel_componentShown //事件。当页签切换时间。调用这方法

this.kDTabbedPane1.setSelectedIndex(0);  //指定显示第一个页签

31:通过实体获取表名

MetaDataLoaderFactory.getRemoteMetaDataLoader().getEntity(info.getId().getType()).getTable();

32:table空白行也保存

kdtable.getRow(i).setChange(true);

33:组织切换(app下代码处理)

OrgSwitchFacadeFactory.getLocalInstance(ctx).orgSwitch(company.getId().toString());

34:禁用分录按钮(添加,删除,插入)

/**

* 禁用分录按钮

* @param table

*/

public static void disableHMDEntryButtons(KDTable table) {

if (table.getParent() == null || table.getParent().getParent() == null)

return;

// 隐藏按钮

Component c = table.getParent().getParent();

if (c instanceof DetailPanel) {

JPanel panel = (JPanel) c;

JPanel controlPanel = null;

// 获得controlPanel

Component[] components = panel.getComponents();

for (int i = 0; i < components.length; i++) {

Component component = components[i];

if ("controlPanel".equals(component.getName())) {

controlPanel = (KDPanel) component;

}

}

// 获得btn

if (controlPanel != null) {

components = controlPanel.getComponents();

for (int j = 0; j < components.length; j++) {

Component component = components[j];

if (component instanceof KDWorkButton) {

KDWorkButton workButton = (KDWorkButton) component;

workButton.setEnabled(false);

}

}

}

}

}

}




final KDTable kddetailTable=getDetailTable();


Container con =kddetailTable.getParent().getParent();


if (con instanceof DetailPanel) {

DetailPanel detail =(DetailPanel)con;


KDWorkButton btnadd= detail.getAddNewLineButton(); 


35:系统的组织隔离

FilterInfo otherFilter = com.kingdee.eas.framework.FrameWorkUtils.getF7FilterInfoByAuthorizedOrg(com.kingdee.eas.basedata.org.OrgType.getEnum("Admin"),"OrgUnit.id",true);

36:获取记账委托组织

IOrgUnitRelation iOrgUnitRelation = OrgUnitRelationFactory.getLocalInstance(ctx);

iOrgUnitRelation.getToUnit(storageOrgUnit1.getId().toString(), OrgType.STORAGE_VALUE, OrgType.COMPANY_VALUE);

37:F7多选并保存数据

设置F7开户多选功能,F7.setEnabledMultiSelection(true);


除了F7本身字段以外,再添加两个文本字段,F7Name(用于ListUI查询用),F7ID(用于保存多选值),F7自身是不保存数据值的


在F7_dataChanged方法里把F7多选到的值分别赋值到F7Name,F7ID中,例:


protected void f7_dataChanged(

com.kingdee.bos.ctrl.swing.event.DataChangeEvent e) {

      Object[] F7cols = (Object[]) e.getNewValue();

if (null == F7cols) {

txtF7Name.setText(null);

txtF7ID.setText(null);

SysUtil.abort();

}

StringBuilder f7id = new StringBuilder();

StringBuilder f7Name = new StringBuilder();

for (int i = 0; i < F7cols.length; i++) {

OperationTypeInfo info = (OperationTypeInfo) kOperationType[i];

String idString = info.getId().toString();// 业务类别

operationTypeid.append(idString).append(";");

operationTypeName.append(info.getNumber()).append("-").append(info.getName()).append(";");

}

String operationTypeidValue = operationTypeid.toString();

if (!StringUtils.isEmpty(operationTypeidValue)) {

operationTypeidValue = operationTypeidValue.substring(0,

operationTypeidValue.length() - 1);

txtF7ID.setText(operationTypeidValue);

}

String operationTypeNameValue = operationTypeName.toString();

if (!StringUtils.isEmpty(operationTypeNameValue)) {

operationTypeNameValue = operationTypeNameValue.substring(

0, operationTypeNameValue.length() - 1);

txtF7Name.setText(operationTypeNameValue);

}

}


在数据加载的时候,把数据通过ID再解析出来赋值给F7字段 一定要先super.loadFields,再设计f7字段为多选功能,否则这里保存出来的值是内存地址


public void loadFields() {

// 加载

super.loadFields();

f7.setEnabledMultiSelection(true);

String operationTypeID = editData.getOperationTypeID();


if (!StringUtils.isEmpty(operationTypeID)) {

String[] operationType = operationTypeID.split(";");

StringBuilder sbBuilder = new StringBuilder();

EntityViewInfo evi = new EntityViewInfo(); // 创建实体视图

FilterInfo f = new FilterInfo();// 创建过滤对象

for (int i = 0; i < operationType.length; i++) {

FilterItemInfo filter1 = new FilterItemInfo("id",

operationType[i], CompareType.EQUALS);

f.getFilterItems().add(filter1);// 将过滤条件添加到过滤对象中

sbBuilder.append("#").append(i).append(" ").append("or ");

}

String maskString = sbBuilder.toString();

if (!StringUtils.isEmpty(maskString)) {

maskString = maskString.substring(0, maskString.length() - 3);

f.setMaskString(maskString);

evi.setFilter(f);// 设置实体视图的过滤器

try {

IOperationType instance = OperationTypeFactory.getRemoteInstance();

OperationTypeCollection collection = instance.getOperationTypeCollection(evi);

int size = collection.size();

Object[] infoObjects=new Object[size];

for (int i = 0; i < size; i++) {

infoObjects[i]=collection.get(i);

}

f7.setData(infoObjects);

} catch (BOSException e) {

e.printStackTrace();

}

}

}


38:通过人员获取职位

PositionInfo getPositionByPerson(Context ctx,PersonInfo info)throws EASBizException, BOSException

{

EntityViewInfo view = new EntityViewInfo();

        SelectorItemCollection sic = new SelectorItemCollection();

        sic.add(new SelectorItemInfo("id"));

        sic.add(new SelectorItemInfo("person.id"));

        sic.add(new SelectorItemInfo("person.name"));

        sic.add(new SelectorItemInfo("person.number"));

        sic.add(new SelectorItemInfo("position.id"));

        sic.add(new SelectorItemInfo("position.number"));

        sic.add(new SelectorItemInfo("position.name"));

        sic.add(new SelectorItemInfo("position.job.id"));

        sic.add(new SelectorItemInfo("position.job.number"));

        sic.add(new SelectorItemInfo("position.job.name"));


        view.setSelector(sic);

        FilterInfo filter = new FilterInfo();

        filter.getFilterItems().add(new FilterItemInfo("person.id", info.getId() + ""));

        filter.getFilterItems().add(new FilterItemInfo("isPrimary", new Integer(1)));

        view.setFilter(filter);

        PositionMemberCollection col = PositionMemberFactory.getLocalInstance(ctx).getPositionMemberCollection(view);


        if ((col != null) && (col.size() > 0) && (col.get(0) != null)) {

        return col.get(0).getPosition();

        }

return null;

}

39:通过用户获取对应组织是否有对应名称权限

boolean flag=false;

BOSUuid userId=SysContext.getSysContext().getCurrentUserInfo().getId();  

BOSUuid orgId=SysContext.getSysContext().getCurrentOrgUnit().getId();  

ObjectUuidPK userPK = new ObjectUuidPK(userId);  

ObjectUuidPK orgPK = new ObjectUuidPK(orgId);  

com.kingdee.eas.base.permission.IPermission perm= null;

//获取权限

try {

    perm =PermissionFactory.getRemoteInstance();  

    flag=perm.hasFunctionPermission(userPK, orgPK, "权限名称"); 

} catch (Exception e1) {  

    e1.printStackTrace();  

}

40:在有分录的单据ListUI中,点击“关联生成”后,可不可以实现选中一条记录就生成包含所有分录的目标单据?

如果想根据单据头做botp转换,需要自己在单据的序时簿代码中添加 相关的代码设置,代码参考:


 public void actionCreateTo_actionPerformed(ActionEvent e) throws Exception 

setDAPTrans(true); 

super.actionCreateTo_actionPerformed(e); 

setDAPTrans(false); 

41:用业务建模工具新定义的单据如何跟权限管理集成起来?

新定义的单据,在没有做权限管理之前,是不受权限控制的。 将新单据跟权限管理集成起来,大致分为三个步骤:


【工具】>【权限管理】,在此界面定义单据所在的目录及给单据设置各种权限项(查看、新增、修改、删除、审核等)。如果没有新建某种权限项,则默认此种权限项不受控制,是可以在任何情况下 使用的。-----这只是加了权限项,但是并没有应用到单据中。


要应用到单据中,必须在主菜单管理中给业务单元加上相应的权限项,然 后发布,这是设计期要做的工作。


在运行期时,通过administrator登录,在“用户管理”里同步权限项?分配相应的权限即可


42:单据和基础资料是如何做组织隔离的及其他

假如BIM中定义了一个主业务组织是采购组织的单据,那么: 序时簿的过滤:


首先到用户的组织范围中查询用户有哪些组织的权限;


再找出用户的组织范围中的组织有哪些是采购组织; (例如用户的组织范围中可能有A、B、C三个组织,但是A是财务组织,B、C是采购组织,那么必 须把A给过滤掉);


功能权限的过滤,看看用户对当前单据有没有查看的权限


看看筛选出来的B和C这两个采购组织是不是实体,如果不是采购组织实体,那么也必须过滤掉; 编辑界面的过滤:


用户设置了单据的主业务组织是采购组织,则在单据的界面上应该动态加一个F7类型的字段“采购组 织”


该“采购组织”必须是必录的、可修改的


该"采购组织"的过滤条件参照序时簿的条件1、2、4


43:指定单据业务属性(即主业务组织)有什么意义?体现在哪里?##

指定当前单据的业务属性可以控制当前登录用户的访问权限,比如,单据Test的业务属性为库存组织,当前登录用户的组织范围有采购组织,财务组织,行政组织,由于此用户没有库存组织的权限,所以访问不到这个单据。


44:知道一个OrgUnitInfo,如何获取此info下面的子OrgUnitInfo?##

找OrgUnitInfo的长编码字段longNumber,他们是由!隔开的,这里可以找到所有ou的编码信息。


45:在程序中给F7增加过滤参数,发现有组织隔离的F7,比如养户档案,得到F7的Filter后增加一个FilterItemInfo条件,调试的时候没有看到我加的条件,只看到了框架做的组织隔离的条件?(适用于序时簿的过滤)##

重载方法:


protected FilterInfo getDefaultFilterForQuery() 

    FilterInfo info =super.getDefaultFilterForQuery(); 

    FilterInfo info1 = new FilterInfo(); 

    info.merge(info1,"AND"); 

}

45:做过组织隔离的F7进行再过滤在实现类构造函数里添加如下代码(适用于编辑界面)##

EntityViewInfo evInfo = new EntityViewInfo(); 

FilterInfo filter = new FilterInfo(); 

filter.getFilterItems.add("","");    // 加用户的过滤项 

evInfo.setFilter(filter); 

F7PromptControl.setEntityViewInfo(evInfo); 

46:getCurrentFIUnit()和getCurrentOrgUnit()之间的区别?##

如果我当前登录的组织是库存组织, getCurrentFIUnit()是不是就会找当前组织的上一级财务组织单元?其他的 getCurrentCtrlUnit(), getCurrentAdminUnit(), getCurrentCostUnit()等是否也是这个原理?


getCurrentFIUnit就是取当前财务组织,一般用于财务类型的单据; getCurrentOrgUnit是取当前的业务组织,适用于所有单据; getCurrentFIUnit()是指去当前登录用户所对应的财务组织; 同理:getCurrentCtrlUnit()、getCurrentAdminUnit()、getCurrentCostUnit()分别指当前用户所切换组织所对应的CU,行政组织,成本组织。


47:如何在BIM中添加图片##

在业务单元定义界面增加一个标签类型字段,如为:TestImage,则对应的标签控件名为:lblTestImage,再如业务单元名为:TestBill,则在TestBillEditUI.java中的的构造函数中的Super()语句下添加


public TestBillEditUI() throws Exception

{

        super();

        this.lblTestImage.setIcon(new javax.swing.ImageIcon("E:\Images\testimage.webp"));

}

下面为完整Demo


public class SingleEnrollEditUI extends AbstractSingleEnrollEditUI {

private static final long serialVersionUID = 1525974852523168246L;


private static final Logger logger = CoreUIObject

.getLogger(SingleEnrollEditUI.class);

        PhotoPanel pPanel = new PhotoPanel();

private boolean existPhoto;



        /**

* output class constructor

*/

public SingleBillEditUI() throws Exception {

super();

pPanel = new PhotoPanel();

existPhoto = false;

isSave = false;

}

      

        // 存储照片

private void storePhotoFile() throws Exception {

if ((pPanel.getSelectFile() != null && pPanel.getSelectImageBytes() != null)

|| pPanel.getSelectImage() != null) {

editData.setImageData(pPanel.getSelectImageBytes());

} else if (existPhoto) {

if (pPanel.getSelectImage() != null) {

editData.setImageData(pPanel.getSelectImageBytes());

} else {

editData.setImageData(null);

}

}

}


public void loadFields() {

super.loadFields();

pPanel.setOprtStat(getOprtState());

try {

this.loadImage();// 加载图片

} catch (Exception e) {

e.printStackTrace();

}

}


// 初始化图片显示区

private void initPhotoPanel() {

pPanel.setOprtStat("ADD");

pPanel.setBounds(627, 117, 169, 150);

photoPanel.add(pPanel);

}


// 在非新增状态下加载已经存储的图片

public void loadImage() throws IOException, BOSException {

ISingleBill irentVehicle = SingleBillFactory.getRemoteInstance();

SingleBillInfo rentVehicleInfo = null;

try {

rentVehicleInfo = irentVehicle

.getSingleBillInfo("select imageData where id =" + "'"

+ this.editData.getId() + "'");

if (!rentVehicleInfo.isEmpty()) {

if (rentVehicleInfo.getImageData() != null) {

byte[] byteArray = rentVehicleInfo.getImageData();

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(

byteArray);

BufferedImage bufferedImage = ImageIO

.read(byteArrayInputStream);

pPanel.setSelectImage(bufferedImage);

byteArrayInputStream.close();

pPanel.repaint();

}

}

} catch (ObjectNotFoundException e) {

MsgBox.showInfo("照片不存在");

SysUtil.abort();

} catch (EASBizException e) {

e.printStackTrace();

}

}


public void onShow() throws Exception {

// ((JFrame) getUIWindow()).setExtendedState(JFrame.MAXIMIZED_BOTH);

photoPanel.setLayout(null);

photoPanel.add(pPanel);

pPanel.setBounds(0, 0, 109, 152);

super.onShow();

}

}





byte[] bys = (byte[]) list.get(44);

BufferedImage image = ImageIO

.read(new ByteArrayInputStream(bys));

pPanel.setSelectImage(image);

pPanel.repaint();


48:获取当前窗口的工作状态(新增、修改或查看)##

getOprtState().equals(OprtState.ADDNEW);

49:在listui 中,有个小数字段,我在EDITUI中录入0时,保存后在LISTUI中显示为空,而不是0,请问怎么让他显示出来?##

请重载listui里的getQueryExecutor()方法,然后在语句“super.getQueryExecutor();”后面加上exec.option().isAutoIgnoreZero = false; 用来设置0不转换为空。


protected IQueryExecutor getQueryExecutor(IMetaDataPK queryPK, EntityViewInfo viewInfo) {

    IQueryExecutor executor= super.getQueryExecutor(queryPK, viewInfo);

    executor.option().isAutoIgnoreZero=false;

    return executor;

}

50:我想让一个EditUI的分录不能新增行,已经把新增行的按钮什么的都去掉了,但在分录的最后一列按回车,table还是会自动新增一行。请问怎么屏蔽掉?##

你在屏蔽“新增分录”那个按钮的同时, 调用屏蔽table的自动新增行语句disableAutoAddLine();使之不能自动新增行


51:多分录单据如何刷新editData?##

调用loadData();


52:如果我想通过代码取物料中的“多计量单位”的记录,请问怎么实现?##

String materialID = "";//物料ID 

EntityViewInfo view = new EntityViewInfo(); 

FilterInfo filter = new FilterInfo(); 

filter.getFilterItems().add(new FilterItemInfo("material.id",materialID)); 

view.setFilter(filter); 

MultiMeasureUnitCollection units = MultiMeasureUnitFactory.getRemoteInstance().getCollection(view); 

53:oracle 外键查询语句##

只需要把红色的文字换成相应的要查找的表名就可以了


select oc.name as "CONSTRAINT_NAME",

       o.name  as "TABLE_NAME",

       o1.name as "R_TABLE_NAME"

  from sys.con$  oc,

确认删除?
客服QQ
  • 客服QQ点击这里给我发消息