壹佰网|ERP100 - 企业信息化知识门户

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3020|回复: 15

[OAF] 如何动态创建table

  [复制链接]
发表于 2011/7/17 08:53:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。如果您注册时有任何问题请联系客服QQ: 83569622  。

您需要 登录 才可以下载或查看,没有帐号?注册

x
应为系统中有几千个QA plan 但是不能手动创建几千个 质量收集页面
所有需要根据 不同的plan 动态创建对应的 质量收集页面。

但是创建tabel 都要绑定一个 具体的vo  而我需要一个动态的
如果用 select ... from dual 的话 字段的个数如何动态?
 楼主| 发表于 2011/7/17 15:47:49 | 显示全部楼层
自己顶个!
发表于 2011/7/18 10:00:55 | 显示全部楼层
说说看,为什么要动态创建table?
发表于 2011/7/18 10:53:21 | 显示全部楼层
应为系统中有几千个QA plan 但是不能手动创建几千个 质量收集页面
所有需要根据 不同的plan 动态创建对应的 质量收集页面。

但是创建tabel 都要绑定一个 具体的vo  而我需要一个动态的
如果用 select ... from dual 的话 字段的个数如何动态?
发表于 2011/7/18 13:54:33 | 显示全部楼层
用以下的代码可以实现,但是有一点不足,就是当数据量比较多的时候,无法按照指定的行数进行分页显示。

先在页面上创建一个advancedTable,名字叫“region5”,即可。

public void processRequest(OAPageContext pageContext, OAWebBean webBean)
  {
    super.processRequest(pageContext, webBean);

    final String CHILD_DATA_LIST = "childDataList";
    final String TEXT = "text";
    int COLUMN_COUNT = 0;

    // write your Personalization SQL in here.
    StringBuffer sbfSQL = new StringBuffer(200);
    // set title in the advancedTable
    sbfSQL.append("SELECT '名' user_name, 'ID' user_id, '開始日'  FROM dual  \r\n");
    sbfSQL.append("UNION ALL \r\n");
    sbfSQL.append("SELECT fu.user_name, to_char(fu.user_id), to_char(fu.start_date) FROM fnd_user fu");

    ResultSet rs = null;
    Statement s = null;
    Connection con = pageContext.getApplicationModule(webBean).getOADBTransaction().getJdbcConnection();

    try
    {
      s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
      rs = s.executeQuery(sbfSQL.toString());
      ResultSetMetaData rsmd = rs.getMetaData();
      COLUMN_COUNT = rsmd.getColumnCount();
      rs.last();
      int intRowCount = rs.getRow();
      rs.first();

      // find the advancedTable
      OAAdvancedTableBean tableBean = (OAAdvancedTableBean)webBean.findChildRecursive("region5");
      tableBean.setViewUsageName("");

      for (int i = 1; i <= COLUMN_COUNT; i++)
      {
        // create a column
        OAColumnBean cb = (OAColumnBean)createWebBean(pageContext, COLUMN_BEAN, null, null);
        tableBean.addIndexedChild(cb);

        // create MessageStyledText
        OAMessageStyledTextBean mst = (OAMessageStyledTextBean)createWebBean(pageContext, MESSAGE_STYLED_TEXT_BEAN, null, null);
        mst.setTextBinding(TEXT + i);
        cb.addIndexedChild(mst);

        // create title
        OASortableHeaderBean shb = (OASortableHeaderBean)createWebBean(pageContext, SORTABLE_HEADER_BEAN, null, null);
        shb.setPrompt(rs.getString(i));
        cb.setColumnHeader(shb);

        if (i != 1)
        {
          UINodeList colList = new DataObjectListNodeList(mst, new DataBoundValue(CHILD_DATA_LIST + i));
          cb.setIndexedNodeList(colList);
        }
      }

      // get row count;
      DictionaryData rowData[] = new DictionaryData[intRowCount - 1];
      int intRowLoop = 2;
      // loop row
      while (rs.next())
      {
        // setting 1 column cell value
        rowData[intRowLoop - 2] = new DictionaryData(TEXT + "1", rs.getString(1));

        // setting 2 to N column cell value
        DictionaryData otherColumn[] = new DictionaryData[COLUMN_COUNT];
        // loop column
        for (int j = 2; j <= COLUMN_COUNT; j++)
        {
          otherColumn[j - 2] = new DictionaryData(TEXT + j, rs.getString(j));
          rowData[intRowLoop - 2].put(CHILD_DATA_LIST + j , new ArrayDataSet(otherColumn));
        }
        intRowLoop++;
      }
      tableBean.setTableData(new ArrayDataSet(rowData));
    }
    catch (SQLException se)
    {
      se.printStackTrace();
    }
    finally
    {
      if (s != null)
      {
        try
        {
          s.close();
        }
        catch (SQLException se)
        {
          se.printStackTrace();
        }
      }

      if (rs != null)
      {
        try
        {
          rs.close();
        }
        catch (SQLException se)
        {
          se.printStackTrace();
        }
      }
    }
  }

发表于 2011/7/20 13:21:59 | 显示全部楼层
今天空下来,又研究了一下这个问题,有种比之前的方法更好些的方法。贴出来大家看看。
1、创建一个DynVO,里面不需要有SQL,而且只需要生成xml,就可以了
2、把DynVO加到AM中去。
3、在页面上创建advancedTable,取名region6,并且绑定DynVO1
4、在CO中追加以下代码:
  public void processRequest(OAPageContext pageContext, OAWebBean webBean)
  {
    super.processRequest(pageContext, webBean);
    OAApplicationModule am = pageContext.getApplicationModule(webBean);
    String[][] strTitleAndAttributeName = (String[][])am.invokeMethod("initDynVO");
    OAAdvancedTableBean tableBean = (OAAdvancedTableBean)webBean.findChildRecursive("region6");
    for (int i = 0; i < strTitleAndAttributeName[0].length; i++)
    {
      // create a column
      OAColumnBean cb = (OAColumnBean)createWebBean(pageContext, COLUMN_BEAN, null, null);
      tableBean.addIndexedChild(cb);
      // create MessageStyledText
      OAMessageStyledTextBean mst = (OAMessageStyledTextBean)createWebBean(pageContext, MESSAGE_STYLED_TEXT_BEAN, null, null);
      mst.setViewAttributeName(strTitleAndAttributeName[1][i]);
      cb.addIndexedChild(mst);
      // create title
      OASortableHeaderBean shb = (OASortableHeaderBean)createWebBean(pageContext, SORTABLE_HEADER_BEAN, null, null);
      shb.setPrompt(strTitleAndAttributeName[0][i]);
      cb.setColumnHeader(shb);
    }
  }
5、在AM中追加以下代码
  public String[][] initDynVO()
  {
    StringBuffer sbfSQLTitle = new StringBuffer(200);
    // set title in the advancedTable
    sbfSQLTitle.append("SELECT '名' user_name, 'ID' user_id, '開始日' start_date FROM dual");
    StringBuffer sbfSQLValue = new StringBuffer(200);
    sbfSQLValue.append("SELECT fu.user_name, to_char(fu.user_id), to_char(fu.start_date) FROM fnd_user fu");
   
    OAViewObjectImpl vo = getDynVO1();
    vo.setQuery(sbfSQLTitle.toString());
    vo.executeQuery();
    // set attribute to updateable
    Row row = vo.first();
    AttributeDefImpl[] ad = (AttributeDefImpl[])vo.getViewDefinition().getAttributeDefs();
    int intAttributeCount = ad.length;
    String[] strTitle = new String[intAttributeCount];
    for (int i = 0; i < intAttributeCount; i++)
    {
      ad[i].setUpdateableFlag(AttributeDefImpl.UPDATEABLE);
      // get title from SQL result.
      strTitle[i] = (String)row.getAttribute(i);
    }
    vo.setQuery(sbfSQLValue.toString());
    vo.executeQuery();
    return new String[][]{strTitle, row.getAttributeNames()};
  }
完毕。

残留问题:
虽然在AM的代码中写了ad[i].setUpdateableFlag(AttributeDefImpl.UPDATEABLE);
发现,对于VO中的数据,我们是可以更新了。
但是确不能insert和remove数据。
目前还想不出怎么解决这个问题。
发表于 2011/7/21 15:59:06 | 显示全部楼层
一天的研究,解决了原来的代中,无法rowinsertremove理。

原来的代码,对VO进行了2次查询,第一次检索出advancedTable的标题,第二次检索出实际数据。

但是比较好的做法是,使用UNION ALL,将两段查询合并,进行一次查询。

对于查询结果而言,第一行是标题,待我们提取出来以后,再删除它,剩下的就是要在advancedTable中显示的数据了。

然而,使用原来的代码,运行到row.remove()方法的时候,就是抛出错误消息Oracle.jbo.ReadOnlyViewObjectException: JBO-25016.

所以,我们需要跟踪row.remove()方法看看,到底哪里抛出了这个错误消息。

通过反编译 ViewRowImpl.class,发现
void doRemove(int i)
{
  ArrayList arraylist = null;
  try
  {
    useInner();
    if(mInner.mVO.isReadOnly())
      throw new ReadOnlyViewObjectException(mInner.mVO.getName());
......
}


然后再查看ViewObjectImpl.class 文件
public boolean isReadOnly()
{
  return mViewDef.isReadOnly() && getDynamicAttributeCount() == 0;
}


到这里发现一点苗头了,我们可以通过修改mViewDef.isReadOnly()getDynamicAttributeCount() == 0;中的任何一个值,来实现我们的目的。

通过进一步的调查发现很难修改mViewDef.isReadOnly()的值,所以,只能将重点放在修改getDynamicAttributeCount()上了。

通过读源代码发现,使用vo.addDynamicAttribute()方法,可以改变getDynamicAttributeCount()的返回值,于是就实验了一把。结果成功了。

以下是修改好的代码,可以对VO中的数据进行insertremoveupdate操作了。

   public String[][] initDynVO()
  {
    StringBuffer sbfSQL = new StringBuffer(200);
    // set title in the advancedTable
    sbfSQL.append("SELECT '
' user_name, 'ID' user_id, '開始日' start_date FROM dual ");
    sbfSQL.append("UNION ALL ");
    sbfSQL.append("SELECT fu.user_name, to_char(fu.user_id), to_char(fu.start_date) FROM fnd_user fu");
   
    OAViewObjectImpl vo = getDynVO1();
    vo.setQuery(sbfSQL.toString());
    vo.executeQuery();
    // set attribute to updateable
    Row row = vo.first();
    AttributeDefImpl[] ad = (AttributeDefImpl[])vo.getViewDefinition().getAttributeDefs();
    int intAttributeCount = ad.length;
    String[] strTitle = new String[intAttributeCount];
    String[] strAttributeNames = row.getAttributeNames();
    for (int i = 0; i < intAttributeCount; i++)
    {
      // for update the attribute
      ad.setUpdateableFlag(AttributeDefImpl.UPDATEABLE);
      
      // get title from SQL result.
      strTitle = (String)row.getAttribute(i);
    }
    // for insert and remove row.
    vo.addDynamicAttribute("DUMMY_ATTRIBUTE");
    row.remove();
    return new String[][]{strTitle, strAttributeNames};
  }


 楼主| 发表于 2011/7/23 17:28:54 | 显示全部楼层
sumury 发表于 2011/7/21 15:59
通过一天的研究,解决了原来的代码中,无法对row进行insert和remove的处理。

原来的代码,对VO进行了2次 ...

非常非常谢谢sumury 的回复
但是现在我遇到页面布局的问题 应为是代码生成的table 所以很有难度
现在我详细说一下需求:有一批SN item 要对他们进行质量数据收集(长宽高。室温 批次。)有些数据时共同数据只要输入一次剩下的item 对应的字段也会自动赋值  下面是我做的效果
但是现在有个问题 每个item要收集的字段有50-100个而且要item也不少 如果我的字段在页面上是横着那就需要不断的拖动滚动条很麻烦。如果能做出下面的效果最好:选择下一个item时 common data不变 unit data 清空让操作员重新输入

但是这样做觉得很有难度   不知道sumury有什么办法满足需求

在此先感谢了!!!!
发表于 2011/7/24 19:39:42 | 显示全部楼层
完全看不懂,你想表达的意思。
 楼主| 发表于 2011/7/25 12:49:23 | 显示全部楼层
简单的说就是如果有100列 页面排不下 需要一直拖滚动条  输入数据很麻烦
有什么办法
发表于 2011/8/12 10:48:46 | 显示全部楼层
{:soso_e179:}
发表于 2011/10/25 19:05:55 | 显示全部楼层
十万火急!!!!我看了楼主的代码后,照样做了一个动态的table出来!!可是楼主所说的删除操作和更新操作~~,代码呢???我搞了两天都不知到如何为动态table加多一列来专门删除记录的!!!急需代码!!跪求!!!
发表于 2011/11/8 22:29:23 | 显示全部楼层
你把你写好的不能执行更新删除的列的代码,贴出来看看呢。

代码不能指望人家帮你写好吧。

自己要动脑筋。
发表于 2011/11/8 23:16:35 | 显示全部楼层
好复杂啊!一时半会学不会。
发表于 2011/11/8 23:16:41 | 显示全部楼层
好复杂啊!一时半会学不会。
发表于 2011/11/17 16:49:56 | 显示全部楼层
OAF刚入门,但看这个代码还是一头雾水
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|手机版|壹佰网 ERP100 ( 京ICP备19053597号-2 )

Copyright © 2005-2012 北京海之大网络技术有限责任公司 服务器托管由互联互通
手机:13911575376
网站技术点击发送消息给对方83569622   广告&合作 点击发送消息给对方27675401   点击发送消息给对方634043306   咨询及人才点击发送消息给对方138011526

GMT+8, 2025/11/29 15:58 , Processed in 0.017979 second(s), 16 queries , File On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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