普通宏-动态表名
报表样例
通过本示例,可以了解普通宏在报表中的应用。
制作如下图所示的报表:
报表特点:
- 用户可以在查看报表时,可以输入要查看数据的表名后缀
- 报表根据用户输入的表名后缀可以动态地查询出不同数据表的数据进行展现
报表数据来自复杂sql数据集,sql语句中应用了普通宏来动态控制需查询的数据表名,数据集sql语法如下:
制作方法
定义复杂sql数据集时,在sql语句from关键字后面的表名部分,于“demo_”后设置宏“${tableName}”,作用是通过宏的值来与前面的“demo_”动态地拼接成要查询数据表的完整表名:
在数据集定义界面的“宏配置”Tab页下,将自动获取刚才sql语句中设置的宏,默认类型即为普通宏,为该宏设置默认值,表示数据集默认要查询的数据表:
绘制报表格式,并设置各单元格表达式,注意B1单元格设置为向右扩展:
- A3:=ds1.select(#0)
- B1:=to(1,ds1.colCount())
- B2:=ds1.fieldName(B1)
- B3:=ds1.field(B2)
设置第一列、第一行的单元格均为隐藏:
进入通用查询,将宏tableName添加为查询条件即可完成该示例报表的制作:
详细了解复杂sql数据集的建立,请参考:复杂sql。
详细了解宏在通用查询中的使用,请参考:通用查询 -> 使用参数和宏。
功能点说明
宏与普通宏
宏是一个没有数据类型的字符串标识。宏有宏名和宏值:宏名用于唯一标识宏,便于对宏进行引用;宏值即为赋给宏的一串字符值。在表达式中可以引用宏,引用方式为${宏名},例如上面示例sql语句表达式中的${tableName}。
在报表运算之前,系统会全面搜索整张报表的表达式定义,将所有的引用宏名的地方替换成宏值。
宏有普通宏、动态宏、条件宏多种类型。其中,普通宏直接将值作为宏值传到报表中进行计算。
例如在上面的示例报表中,数据集sql语句定义为:select * from demo_${tableName}。当查看报表时传入的宏值为“product”时,系统会首先用宏值替换sql语句中的宏,即sql语句变为:select * from demo_product,所以数据集将从demo_product表取数。同理,当传入的宏值为“customers”时,sql语句变为:select * from demo_customers,数据集将从customers表取数。
数据集中定义的宏会被自动添加为报表宏,并且宏可以添加到通用查询中作为查询条件。例如上面示例报表中,就将宏tableName设为了查询条件,从而实现了可以根据用户输入的表名后缀,在sql语句中动态地拼接成要查询的完整数据表名,进行动态地表数据获取。
利用宏可以为报表的设计带来极大的灵活性,实现动态地表达式替换,根据用户传入的不同宏值,在报表中计算出不同的表达式结果,从而得到不同的报表信息或进行灵活的控制,减少报表制作的数量与工作量。例如假设某企业对销售订单数据的存储是以销售区域的划分存储在表名为“order_地区”的数据表中,当不同销售区域的员工都需要对订单数据进行查询时,不必制作多张报表,而是可以只设计制作一张统一的报表模板,在报表中利用宏实现数据集的动态表名计算。比如将数据集sql设置为:select * from order_${area}。
详细了解宏的应用,请参考:宏。
to()函数
示例报表中,B1单元格的表达式为:=to(1,ds1.colCount()) 。它的结果是生成以1为开始,表达式ds1.colCount()的值为结束,步长为1的N个连续整数。例如=to(1,5) 返回的结果是:1,2,3,4,5 。
由于数据集sql语句查询的表名并不固定,并且是查询全部字段,因此查询不同表时数据集中的数据列数也不固定。为了让报表在展现时,可以计算并展现出与数据集相同的列数,这里使用了to函数让单元格横向扩展出对应个数的格子。其中,ds1.colCount()的结果是返回数据集的数据列数。
详细了解to()函数,请参考:to()。
关于colCount()函数请继续阅读下面内容。
数据集函数colcount()、fieldName()、field()
B1单元格的表达式=to(1,ds1.colCount()) 中应用了数据集函数colcount()。该函数的作用是可以获得数据集的列数,语法为:数据集名称.colcount()。例如当示例报表数据集查询demo_product表数据时,该表共有10个字段,因此ds1.colCount()的结果是10。这样表达式=to(1,10) 就会返回从1到10的十个整数。由于B1单元格向右扩展,从而就扩展出了十个单元格,在报表中形成十列。
B2单元格的表达式为:=ds1.fieldName(B1)。它的结果是返回列号为B1单元格的值的数据集列名。例如=ds1.fieldName(2)返回数据集第二列的列名。表达式应用了数据集函数fieldName(),该函数的作用是可以根据列号取数据集的列名,语法为:数据集名称.fieldName()。由于B2为B1的子格,将跟随B1向右扩展,因此通过表达式=ds1.fieldName(B1) ,B2单元格最终就显示出了数据集各列的列名。
B3单元格的表达式为:=ds1.field(B2)。它的结果是返回数据集当前行中B2列的数据。例如:=ds1.field("产品ID")将返回数据集当前行中的产品ID。field()是数据集函数,它的作用是获得数据集当前行或者当前组中第一行中指定列的数据,语法为:数据集名称.field()。B3左侧A3单元格的表达式为:=ds1.select(#0)。它的结果是返回数据集所有数据行的行号,因此A3单元格默认按照数据集的行数向下扩展出多个单元格。由于B3是A3的子格,同时也是B2的子格,B3将同时向下、向右进行交叉扩展,从而最终显示出数据集中各行、各列的数据。
详细了解以上函数,请参考:colcount()、fieldName()、field()。
详细了解单元格的扩展,请参考:扩展。
单元格的隐藏
报表中B1单元格的作用是向右扩展出与数据集相同的列数,A3单元格的作用是向下扩展出与数据集相同的行数。这两个单元格没有实际业务含义,无需在报表中显示,因此可以将B1所在行、A3所在列的单元格设置为隐藏,从而让报表只显示出需要查看的业务数据。
详细了解单元格的隐藏属性,请参考:显示。