人力资源管理软件
  报表工具功能介绍  
九大模型
柔性化加工算法
对象实例化及其衍生技术
数据微引擎技术和数据库
动态指令技术
多数据源的集成与控制
图形报表
OLAP报表模型
项目化架构及其意义
无代码发布

对象实例化及其衍生技术


  实现这张报表需要用到工具的一个数据运算功能:数据微引擎。所谓数据微引擎,是在工具的脚本中,嵌入了SQL运算的机制,在工具中虚拟了一个SQL运算引擎,从而满足更为灵活的报表运算请求。(注意:这里的"SQL运算",和"SQL数据源"完全不同。前者的运算是在工具内部完成,偏重于对已获取的原始数据进行动态的、灵活的报表运算处理;后者则是将SQL提交数据库,由数据库进行SQL处理,更偏重于原始数据的获取。)
  针对上表的处理,实质上是在工具中对获取的原始数据进行了多次SQL聚类运算,比如,对年龄段"24岁到40岁"的运算类似于: SELECT 分公司, 部门, SUM(员工ID) AS 员工数量 WHERE 年龄>= 24 AND 年龄< 40 GROUP BY 分公司, 部门 。
  当然,使用某些特定的函数,也可以实现这些功能。然而,毕竟函数的功能有限而且单一,不能适用于各种变化的需求。相对而言,采用脚本形式,在脚本中模拟SQL机制进行运算,不仅可以保证强大的可扩展性以适应各种变化需求,并且有效地降低了用户的学习负担,相信对于专业人员来说,SQL语句应该是再熟悉不过的工具了吧。
工具将报表在创建过程中的所有可输出部分创建为对象实例,并且这个对象实例的生命周期与报表表现同步,就是说,从报表局部输出开始,直至这张报表最终被浏览完毕并且在浏览端关闭,在此期间这个实例对象会一直存在。换而言之,在此期间任意事件,我们可以通过某些事件或者条件的触发,去动态改变某个指定实例的属性,如数据值、显示格式等。

1、对象实例化:
  工具以控件方式设计报表,报表控件根据摆放区域的不同,可以做单次实例输出和多次实例输出。比如,在报表标题、主数据头、分组头等区域的控件,一般为单次输出,即在报表中仅创建一个实例;在主数据、细项数据等区域的控件,一般为多次输出,即设计时在设计界面上摆放的某一个控件,在实际报表创建的时候,根据需要显示的数据量,自动创建出多个实例对象。
  这些实例对象,无论是单次输出,还是多次输出的,都具有自己独有的实例命名。比如,在主数据上放置一个文本框控件,命名为A,对应的数据有10条记录,那么就会在实际产生的报表中创建分别命名为A1、A2、A3、A4、A5、A6、A7、A8、A9、A10的10个实际对象实例。这些实例除了命名不同以外,在填充数值、显示风格等方面,都可以做独立的控制,相互之间没有影响。


2、实例对象可用方法:
  针对每一个实例对象,可以对该对象的任意属性进行修改,比如:对文本显示内容(Text)、值(Value)、显示字体颜色(Font.Color)等等。使用"控件名.RealName"可以获取当前控件对象的实例命名,使用"maxReport.FindViewObject"可以获得指定命名的实例对象。使用"实例对象名称.属性"就可以修改指定对象的某个属性。
  此外,每一个实例有自己的几个触发事件:OnAfterData(获得数据之后)、OnBeforePrint(显示输出之前)、OnAfterPrint(显示输出之后)、OnPreviewClick(显示后,浏览用户使用鼠标单击该对象的时候)。不同的触发事件可以指定不同的函数脚本,在函数脚本中可以对已创建的任意实例对象,或者是数据源数据进行运算,并根据运算结果或逻辑结果,对已创建的实例对象(包括自身和其他实例对象)的属性进行丢改、调整。

3、 应用范例1:复运算报表:
  对象实例化技术的一个典型应用:在报表生成后的用户浏览过程中,通过用户鼠标点击事件的触发,获取报表部分实例对象的存在值,然后根据逻辑进行再次运算,并根据运算结果改变报表某些数据的显示。

4、 应用范例2:为报表创建可点击跳转页面的目录:
  范例1仅仅是对象实例化的一个典型应用,我们下面来看另外一个例子,这个例子表现的是如何通过对象实例化,去建立一个特殊要求的报表的:


4.1 报表设计需求:

报表是一个典型的分组报表,需要将销售订单数据按销售地区进行分组显示。特殊之处在于,由于数据量比较大,浏览者希望能像Word文档一样在报表封面上加上一个目录,并且能够在浏览的时候,鼠标点击目录,则报表自动跳转到该目录对应的内容页面。



4.2 实现方法及技巧
首先:在第一页上提取分组头数据建立目录,目录中使用一个空文本框用于在后续报表页面创建过程中,动态填充具体页数。
其次:新建报表页,在新报表页中放置内容数据。因为涉及目录跳转,并且在本案例中中是以分组形式建立数据内容的,故而把脚本写在分组头的OnBeforePrint事件中。脚本主要目的是逆向刷新对应的目录中显示"第N页"的文本框,将当前分组头所在页数填入文本框中。
定义变量:
  定义两个变量,一个是RealName,字符串类型,用于保存对应目录控件的实例名称;另一个是view,实例类型,用于保存指定名称的文本框实例对象。
  建立脚本:
  首先,建立一个跳转标记,这个标记的作用是为了鼠标点击目录时,可以跳转到指定内容位置。标记的命名规则为固定以'URL'开始,加上当前行数。
  maxReport.AddAnchor('URL' + IntToStr(<Line>));
  然后,获得对应目录的文本控件实例名称,在Max@X中,一个控件的实例名称规则为:控件名(假  设名称可以确定为"MemoXR_N"再加上当前分组行号。
  realName := 'MemoXR_N' + IntToStr(<Line>);
  第三步就是根据实例名称获取实例对象。
  view := TmaxMemoView(maxReport.findViewObject(realName));
  第四步为获得内容分组头当前所在页,将这个页数刷新到指定目录实例对象的Text中。
  view.Text := VarToStr(maxReport.GetAnchorPage('URL' + IntToStr(<Line>)));
  五步局部刷新报表对象。
  maxReport.RefreshViewer(view, True);
  最后:报表目录已经创建成功,然后还有一个问题,就是如何做到点击目录时,报表自动跳转到相应的内容页面:我们之前在脚本的的一行已经创建了一个跳转标记,那么,只要在目录文本的控件属性中指定这个标记就可以了。具体方法为:选定目录上的文本控件,设定其基本属性中的"URL地址"属性值为:#URL[<Line>]。其中#是固定用法,后面所跟随的是我们在脚本的一行中创建的标记,URL加上当前行数。需要注意的是,这种用法的前提是目录行数和内容分组行数实际上是一一对应的,所以在内容上用内容的当前分组行数来建立标记,在目录上通过目录的当前行数来对应到内容的标记位置。