原文地址:如何动态创建table

需求:

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

但是创建tabel 都要绑定一个 具体的vo  而我需要一个动态的
如果用 select ... from dual 的话 字段的个数如何动态?

感谢答主sumury

方案0.1版本

//用以下的代码可以实现,但是有一点不足,就是当数据量比较多的时候,无法按照指定的行数进行分页显示。

//先在页面上创建一个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();
}
}
}
}

方案0.2版本

/*今天空下来,又研究了一下这个问题,有种比之前的方法更好些的方法。贴出来大家看看。
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数据。
目前还想不出怎么解决这个问题。*/

终极版1.0

/*通过一天的研究,解决了原来的代码中,无法对row进行insert和remove的处理。

原来的代码,对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中的数据进行insert、remove、update操作了。*/ 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};
}

感谢这些热爱思考且愿意分享代码的人们。

oaf 动态创建table vo (转)的更多相关文章

  1. js基础例子动态创建table实例

    <style> table{ width:500px; font-weight: bold; border: 1px solid #000; border-collapse:collaps ...

  2. 初探原生js根据json数据动态创建table

    初探原生js根据json数据动态创建table 小生以实习生的职位进入了一家非纯软件的公司做asp.net开发,大半个月下来发现公司里居然没有前端工程师,这令我很诧异,跟着公司做项目,发现前端后台没有 ...

  3. JS动态创建Table,Tr,Td并赋值

    JS动态创建Table,Tr,Td并赋值. 成果库修改: 要求主题列表随成果类型改变而改变 网上查询资料后开工,在成果类型下拉框添加change()事件触发Dwr,查询主题集合——动态创建/编辑Tab ...

  4. OAF 动态创建组件以及动态绑定属性

    在开发中,我们遇到以下一个需求. 一个表格左侧有5列是固定存在的,右侧有N列是动态生成的,并且该N列中第一列可输入,第二列是不可编辑的,但是是数字,如果小于0,那么就要显示为红色,重点标识出来. 首先 ...

  5. JS动态创建table

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. 动态创建table表格页面出现undefined原因以及修改

    源代码: var html: if(lists) { html += '<a href="https://www.4001149114.com/NLJJ/member/sharecel ...

  7. DOM – 7.动态创建DOM + 8.innerText innerHTML value

    7.动态创建DOM 8.innerText  innerHTML  value 7+8 练习:案例:点击按钮动态增加网站列表,分两列,第一列为网站的名字,第二列为带网站超链接的网站名.增加三行常见网站 ...

  8. JS,Jquery,ExtJs不同脚本动态创建DOM对象

    好久不来写东西了,这段时间太慢了,闲了下来看了几篇文章,觉得很好,同时也许咱们大家都能遇到,所以就把它记录下来... 简单使用JavaScript.JQuery.ExtJs进行DOM对象创建的测试,主 ...

  9. JS、JQuery和ExtJs动态创建DOM对象

    做了个简单使用JavaScript.JQuery.ExtJs进行DOM对象创建的测试,主要是使用JavaScript.JQuery.ExtJs动态创建Table对象.动态Table数据填充.多选控制. ...

随机推荐

  1. Python入门之字符编码

    一.字节编码的基础知识 一.计算机基础知识 #1 我们的程序都是运行在特定的操作系统内,例如window,linux,mac等等#2 运行应用程序,需要要操作系统发出请求,我们双击运行的时候会向操作系 ...

  2. c++编程和c在思想上最大的差别

    从正规的血统上来说,c++跟java一样是面向对象编程语言,而c是面向结构的编程语言.但是,在现实中,有大量的系统虽然用cpp编写,但是100%跟java一样,使用面向对象的几乎没有,绝大部分都是结合 ...

  3. 20145317彭垚《网络对抗》Exp6 信息搜集与漏洞扫描

    20145317彭垚<网络对抗>Exp6 信息搜集与漏洞扫描 问题回答 1.哪些组织负责DNS,IP的管理? DNS域名服务器:绝大多数在欧洲和北美洲,中国仅拥有镜像服务器. 全球一共有5 ...

  4. 20145328《网络对抗技术》Final

    系内选拔赛write-up 1 信息隐藏 第一题图片藏东西,后缀名改txt,没有发现,改rar,发现压缩包内存在key.txt,解压提示存在密码,尝试使用修复,得到key.txt,打开获取flag,S ...

  5. 写Java代码的一些小技巧

    写Java代码有三年多了,遇到过很多坑,也有一些小小的心得.特地分享出来供各位学习交流.这些技巧主要涉及谷歌Guava工具类的使用.Java 8新特性的使用.DSL风格开发.代码封装等技巧. 一.nu ...

  6. noip 2013 提高组 Day2 部分题解

    积木大赛: 之前没有仔细地想,然后就直接暴力一点(骗点分),去扫每一高度,连到一起的个数,于是2组超时 先把暴力程序贴上来(可以当对拍机) #include<iostream> #incl ...

  7. MariaDB学习记录

    MariaDB的学习 MariaDB的学习 关于MariaDB的历史,不再概述 下面是mariadb的官网:https://mariadb.com/ 同样的,MariaDB一样有连接java的jar包 ...

  8. Unity3D学习笔记(九):摄像机

    3D数学复习 using System.Collections; using System.Collections.Generic; using UnityEngine; public class w ...

  9. Intellij新建Spring项目引入用户目录下的Spring jar包

    首先,在IntelliJ IDEA中新建module,选择Spring应用:   在初次使用时,如果IDE检测到本地没有spring核心库,则会在新建过程中下载对应库文件,在使用spring框架时,可 ...

  10. Facebook广告API系列 3 Ads Management

    Facebook广告API系列 3 Facebook marketing API有三大组成部分: Audience Management Ads Management Ads Insights 本篇介 ...