在Oracle APEX Interactive Report中更新与过滤器相关的页面项

时间:2015-04-13 20:00:36

标签: javascript jquery oracle-apex

我最近在Oracle APEX应用程序中开始使用Interactive Reports。以前,应用程序中的所有页面都使用经典报表。我的新页面中的交互式报表工作得很好,但是,现在,我想在同一页面上的交互式报表上方添加一个摘要框/表格,以显示交互式报表中某些列的总和值。换句话说,如果我的交互式报表显示3个不同的经理名称,2个不同的办公地点和5个不同的员工,我的摘要框将包含一行和三列,分别带有数字3,2和5。

到目前为止,我已经通过创建摘要框作为经典报告来完成此工作,该报告计算交互式报告从中提取的同一表中每列的不同值。当我尝试过滤交互式报告时出现问题。显然,经典报告不会根据交互式报告过滤器进行刷新,但我不知道如何将两者联系起来,以便经典报告响应交互式报告中的过滤器。根据我的研究,有一些方法可以使用javascript / jquery在交互式报告的搜索框中引用该值。如果可能,我希望使用javascript或jquery从交互式表格的过滤器中引用该值,以便每次应用新过滤器时刷新摘要框。有谁知道怎么做?

1 个答案:

答案 0 :(得分:3)

不要在过滤器上进行javascript解析。这是一个坏主意 - 想想你将如何实现这一点?有大量的编码要做,还有很多ajax。随着apex 5即将到来,当API和标记即将发生巨大变化时,它会在哪里离开?


不要只是屈服于要求。首先要确保技术上的可行性。如果不是,请确保您清楚地了解时间消耗的含义。拥有这些不同的价值计数会带来什么真正的价值?也许有另一种方法来实现他们想要的东西?也许这只不过是一个尝试的解决方案,而不是真正问题的核心。想想的东西......


话虽如此,这里有两个选择:

第一种方法:在交互式报告上计算不同聚合

interactive report with count distinct aggregates applied

您可以通过“操作”按钮将这些添加到IR。 aggregate location under the actions button

aggregate definition

请注意,这个聚合将是最后一行!在我发布的示例中,将每页行数减少到5会将聚合行推送到分页集3! / p>


第二种方法:APEX_IR和DBMS_SQL

您可以使用apex_ir API检索IR的查询,然后使用它进行计数。
(Apex 4.2) APEX_IR.GET_REPORT
(Apex 5.0) APEX_IR.GET_REPORT

一些指示: 通过查询apex_application_page_regions

来检索区域ID

确保您的源查询不会包含#...#替换字符串。 (例如#OWNER#。)

然后获取报告SQL,重写它并执行它。例如:

DECLARE
   l_report apex_ir.t_report;
   l_query varchar2(32767);

  l_statement varchar2(32000);
  l_cursor integer;
  l_rows number;
  l_deptno number;
  l_mgr number;
BEGIN 
    l_report := APEX_IR.GET_REPORT (
                    p_page_id => 30,
                    p_region_id => 63612660707108658284,
                    p_report_id => null);
    l_query := l_report.sql_query;
    sys.htp.prn('Statement = '||l_report.sql_query);
    for i in 1..l_report.binds.count
    loop
        sys.htp.prn(i||'. '||l_report.binds(i).name||' = '||l_report.binds(i).value);
    end loop;

    l_statement := 'select count (distinct deptno), count(distinct mgr) from ('||l_report.sql_query||')';

    sys.htp.prn('statement rewrite: '||l_statement);

 l_cursor := dbms_sql.open_cursor;
    dbms_sql.parse(l_cursor, l_statement, dbms_sql.native);

    for i in 1..l_report.binds.count
    loop
      dbms_sql.bind_variable(l_cursor, l_report.binds(i).name, l_report.binds(i).value);
    end loop;

    dbms_sql.define_column(l_cursor, 1, l_deptno);
    dbms_sql.define_column(l_cursor, 2, l_mgr);

    l_rows := dbms_sql.execute_and_fetch(l_cursor);

    dbms_sql.column_value(l_cursor, 1, l_deptno);
    dbms_sql.column_value(l_cursor, 2, l_mgr);

    dbms_sql.close_cursor(l_cursor);

    sys.htp.prn('Distinct deptno: '||l_deptno);
    sys.htp.prn('Distinct mgr: '||l_mgr);
  EXCEPTION WHEN OTHERS THEN
    IF DBMS_SQL.IS_OPEN(l_cursor) THEN
      DBMS_SQL.CLOSE_CURSOR(l_cursor);
    END IF;
    RAISE;
END;

我将来自apex_ir.get_report和dbms_sql的示例代码汇总在一起 Oracle 11gR2 DBMS_SQL reference

但有一些严重的警告:列列表很棘手。如果用户可以控制所有列并且可以删除某些列,则这些列将从选择列表中消失。例如,在我的示例中,让用户隐藏DEPTNO列会使整个代码崩溃,因为即使它将从内部查询中消失,我仍然会对此列进行计数。你可以通过不让用户控制它,或者首先解析语句等来阻止这个......


祝你好运。