简易报告字段编辑方法

要在检验报告显示一段内容,常见的实现方法有插入文本对象、使用数据库字段、使用公式字段三种方法

文本对象

使用文本对象方法的方法如下:

  1. 报告内单击鼠标右键,选择插入文本对象
  2. 待鼠标变成十字型后框出文本区域
    ![](Pasted image 20240809135612.png)
  3. 在框选的区域内输入想要数据的文本即可
    ![](Pasted image 20240809135759.png)
  4. 我们可以在预览界面看到最终的效果
    ![](Pasted image 20240809135905.png)
    使用文本对象呈现内容有操作简单,逻辑清晰等优点,在呈现的效果上为输入内容就是最终显示内容。当在呈现报告的内容需要由一点规则决定,则文本对象无法实现。这时候需要根据具体规则选择下面两种方式进行实现。

    数据库字段

    在进行数据库字段的具体使用之前需要先了解一些前置内容。![](Pasted image 20240809141656.png)如上图,检验报告的内容中批次信息、检验项目信息两部分内容是主要构成内容,而它们在后台实际存储方式可能与一般想法是不一样的。位于报告上半部的信息主要存储在一张名为T_PH_COA的表中,它不是与批号一一对应,而是每当我们打开LIMS的报表功能时,会将打开时的批次信息存入该表中,并赋予一个新的报表编号。所以上图中批号4639在左侧有“3454、3469”两个编号,它们在后台存储内容如图 ![](Pasted image 20240809143239.png)
    同样的,报表显示的检验项目信息存储在T_PH_COA_ROW中,当T_PH_COA新增一条记录时,T_PH_COA_ROW也会对应新增检验项目信息,并且将对应报表编号进行存储。下图为两个表对应数据示例。![](Pasted image 20240809145010.png)
    检验报告中除上面已经提到的T_PH_COAT_PH_COA_ROW表,还用到了LIMS_HTML_NOTESLOTT_PH_COA_ADDRESST_PH_COA_SETUPT_REPORT_TEXT,这几个表之间的关系加下图。它们存储的内容可以参考文件“不完全对照表”,里面列出了这些表中目前已知的字段。
erDiagram
    T_PH_COA ||--o{ T_PH_COA_ROW : "LEFT OUTER JOIN
(REPORT_NUMBER)" T_PH_COA }|--|| T_PH_COA_SETUP : "INNER JOIN
(COA_SETUP, VERSION)" T_PH_COA }|--|| T_REPORT_TEXT : "INNER JOIN
(STATUS≠NAME)" T_PH_COA_SETUP }|--o{ T_PH_COA_ADDRESS : "LEFT OUTER JOIN
(COMPANY_NAME=NAME)" T_PH_COA_SETUP }|--o{ LIMS_HTML_NOTES : "LEFT OUTER JOIN
(LONG_TEXT=NOTE_ID)"

基于以上内容,我们已经知道了检验报告内可以直接从数据库中获取到那些信息。那么使用时直接找到对应表的字段,拖到报告中即可。具体步骤如下:

  1. 视图中打开字段资源管理器![](Pasted image 20240809150444.png)
  2. 打开数据库字段、数据表,找到要插入的字段,选中要插入的字段![](Pasted image 20240809150729.png)
  3. 单击鼠标右键,选择“插入到报表中”,鼠标到报告内要显示的位置单击左键即可![](Pasted image 20240809151213.png)
  4. 最终效果如图
    ![](Pasted image 20240809151350.png)

    公式字段

    前面文本对象解决了在报告中显示不变内容的需求,数据库字段解决根据不同批次显示内容的需求。有些时候后台拿来的无法直接使用,例如需要将后台保存的委托方名称变成“委托方为”+委托方名称的形式,又例如复核人位置的需要显示复核人和复核时间的信息,其中年月日之间需要使用“.”隔开…诸如此类,就需要使用公式对存储的数据进行之后才能进行展示。

    不完全数据类型

    要实现上面提到的【“备注:委托方为”+委托方名称+“。”】。是可以使用下面公式实现。
    1
    "备注:委托方为" & {LOT.LOT_COMMENT}&"。"
    公式中双引号所包裹的内容属于字符串类型,这样写的作用时告诉电脑这是一段文字。电脑除了认识字符串类型之外,还认识数字类型、时间日期类型、布尔值类型。关于字符串,可以和另一个字符串拼接(如上,三个字符串进行拼接)、计算字符串长度,截取其中一部分等操作;关于数字,可以进行加减乘除运算、四舍五入、获取一个随机数等操作;关于日期,可以获取日期中的年月信息、计算星期几,计算两个日期之间的间隔天数等操作;布尔值类型与if结构关系紧密,留到后面讲解。
    由于字符串类的数据处理显示的内容容易理解,所以一般将数字类型、时间日期类型转换为字符串进行显示。将其它类型的数据转换为字符串类型,一般使用totext()函数处理。下面两个例子分别为对日期和数字进行转换的公式。
    1
    2
    totext({T_PH_COA.C_RQST_DATE},"yyyy-MM-dd")
    totext({T_PH_COA.C_BATCH_SIZE},1)
    第一个公式为将后台的T_PH_COA.C_RQST_DATE值转换为用短横线将年月日分隔开字符串进行显示。日期时间的更多显示形式见下图:![](Pasted image 20240809163906.png)
    第二个公式为将后台T_PH_COA.C_BATCH_SIZE的数值转为字符串并四舍五入后保留一位小数。关于数值的更多显示形式下面图:![](Pasted image 20240809164743.png)![](Pasted image 20240809164533.png)

    条件显示

    上面关于委托方信息的公式直接使用也是有问题的,因为有部分产品是没有委托方的,那么这部分产品在录入系统的时候就肯定不会填写委托方信息。如果不加判断直接使用公式,最终报告救护显示错误信息。所以正确的公式应该这样:
    1
    2
    3
    4
    if  (not isnull({LOT.LOT_COMMENT})) then
    "备注:委托方为" & {LOT.LOT_COMMENT}&"。"
    else
    ""
    这个公式出现了notisnull()if ... then ... else ...三个新东西。首先isnull({LOT.LOT_COMMENT})的作用是判断传入的LOT.LOT_COMMENT是不是空的(LIMS端有没有写委托公司),返回一个布尔类型的判断段值(True或者False)。其中传入字段为空则返回True,反之则返回False。not是布尔类型数据的一种运算,表示对后面的布尔值取反(True变False,False变True)。布尔运算另外两个常见的运行(或运算、与运算)规则见下图表:
x 的值 y 的值 x And y x Or y
True True True True
True False False True
False True False True
False False False False
有了上面的内容,现在来理解if ... then ... else ...结构,它实际就是根据不同的条件进行不同的操作。比如上面公式,电脑首先not isnull({LOT.LOT_COMMENT})的值是否为True,如果是就执行then后面的内容(对三个字符串进行拼接),如果为False就跳过then的内容进行下一次if判断,直到Else,执行""。现在来看一个稍微复制些的公式
1
2
3
4
5
6
7
8
9
10
if {T_PH_COA.COA_SETUP} = "FP_ZH" OR {T_PH_COA.COA_SETUP} = "BJ_FP_ZH"   then
totext({T_PH_COA.C_BATCH_SIZE},0) & {UNITS.DISPLAY_STRING}
else if {T_PH_COA.COA_SETUP} = "RM_ZH" OR {T_PH_COA.COA_SETUP} = "BJ_RM_ZH" then
{T_PH_COA.C_BATCH_SIZE} & {UNITS.DISPLAY_STRING} & "/" &{T_PH_COA.C_NUM_CNTNR} & {T_PH_COA.C_UNIT_CNTNR}
else if {T_PH_COA.COA_SETUP} = "INT_ZH" OR {T_PH_COA.COA_SETUP} = "BJ_INT_ZH" then
if {T_PH_COA.C_BATCH_SIZE} >= 100 then
totext({T_PH_COA.C_BATCH_SIZE},1) & {UNITS.DISPLAY_STRING}
else if {T_PH_COA.C_BATCH_SIZE} < 100 then
totext({T_PH_COA.C_BATCH_SIZE},2) & {UNITS.DISPLAY_STRING}

上面有两个if结构判断,若外面IF结构第三层判断符合条件,则进行内层if判断,下面为详细解释:

  1. 第一层条件判断
    • if {T_PH_COA.COA_SETUP} = "FP_ZH" OR {T_PH_COA.COA_SETUP} = "BJ_FP_ZH" then
      • 这行代码检查变量COA_SETUP的值是否等于”FP_ZH”或者”BJ_FP_ZH”。
      • 如果条件为真,则执行以下操作:
        • totext({T_PH_COA.C_BATCH_SIZE},0) & {UNITS.DISPLAY_STRING}
  2. 第二层条件判断
    • else if {T_PH_COA.COA_SETUP} = "RM_ZH" OR {T_PH_COA.COA_SETUP} = "BJ_RM_ZH" then
      • 如果第一层条件不满足,代码会检查COA_SETUP是否等于”RM_ZH”或者”BJ_RM_ZH”。
      • 如果条件为真,则执行以下操作:
        • {T_PH_COA.C_BATCH_SIZE} & {UNITS.DISPLAY_STRING} & "/" &{T_PH_COA.C_NUM_CNTNR} & {T_PH_COA.C_UNIT_CNTNR}
  3. 第三层条件判断
    • else if {T_PH_COA.COA_SETUP} = "INT_ZH" OR {T_PH_COA.COA_SETUP} = "BJ_INT_ZH" then
      • 如果前两个条件都不满足,代码会检查COA_SETUP是否等于”INT_ZH”或者”BJ_INT_ZH”。
      • 如果条件为真,则进入内部的嵌套条件判断:
        • if {T_PH_COA.C_BATCH_SIZE} >= 100 then
          • 如果C_BATCH_SIZE大于或等于100,则执行:
            • totext({T_PH_COA.C_BATCH_SIZE},1) & {UNITS.DISPLAY_STRING}
        • else if {T_PH_COA.C_BATCH_SIZE} < 100 then
          • 如果C_BATCH_SIZE小于100,则执行:
            • totext({T_PH_COA.C_BATCH_SIZE},2) & {UNITS.DISPLAY_STRING}
              • 这里保留两位小数。