0

I have a crystal report I need to modify to leave out duplicate rows by "name". So in Section Expert I am putting in a formula in Suppress and I cannot figure out how to compare the current name field being added to all the previous names that are in the group already. I was trying to use the Filter() function, but for the String array parameters I don't know what to enter that would be all of the other names previously added to the group. I need to compare the current name being added and see if it is already in the group so I can then compare another field called "date" and if the date of the field being added is more recent then the date of the duplicate name it will over write the row and only show the row with the most recent date.

Basically the question is how do I create an array with all the current fields already in the group(or does one exist already) so that I may use the Filter() function to see if the current name being added is already in that array of names added?

4

1 回答 1

0

好吧,我想通了,因此对于遇到此问题的任何人来说,这都是我的解决方案。

首先,我在“公式字段”部分创建了一个公式,该公式在从数据库中读取数据时创建了两个数组,并且在记录中只保留了每个 id 和 date 的副本。然后对于具有相同 id 的任何其他记录,它将将该记录的日期与数组中具有相同名称的记录进行比较,如果日期更大(稍后),那么它将用当前读取的日期替换日期。我将此公式字段命名为 idArray。

Global StringVar Array idArray;
Global DateVar Array expArray;
BooleanVar addName;
NumberVar x;
StringVar idTest;
StringVar expDateTest;

whilereadingrecords;
(
    addName := true;
    for x := 1 to Ubound(idArray) step 1 do
    (
        if({hrpersnl.p_empno} = idArray[x]) then
        (   
            addName := false;
            if(Date({nemphist.enddate}) > expArray[x]) then
                expArray[x] := Date({nemphist.enddate});
        )
    );

    if(addName = true) then
    (
        reDim Preserve idArray[Ubound(idArray) + 1];
        reDim Preserve expArray[Ubound(expArray) + 1];

        idArray[Ubound(idArray)] := {hrpersnl.p_empno};
        expArray[Ubound(expArray)] := Date({nemphist.enddate});
        //idTest := idTest + ' ' + {hrpersnl.p_empno};
        //expDateTest := expDateTest + ' ' + toText(Date({nemphist.enddate}));
    );

   //idTest
   //Ubound(idArray)
   //expDateTest
)

注释掉的行是我用来测试以查看数组是如何构建的。我把它们留在那里只是作为如何调试水晶报告的一个例子,因为它没有附带调试器。

下一步是创建一个记录抑制公式。在“报告”菜单中,我转到“部分专家”,在我组的“详细信息”部分中,单击“抑制(无向下钻取)”选项旁边的小 x-2 按钮。然后我插入了这段代码,它查看当前记录的 id 和日期,如果 id 在第一个数组中,它将占据它的位置并使用它从第二个数组中检索日期,如果当前记录的日期小于日期我们现在知道是最大值,那么它将抑制记录。

Global StringVar Array idArray;
Global DateVar Array expArray;

NumberVar x;
BooleanVar suppress := false;

for x := 1 to Ubound(idArray) do
(
    if({hrpersnl.p_empno} = idArray[x]) then
        if(Date({nemphist.enddate}) < expArray[x]) then
            suppress := true;
);

if(suppress = true) then
    true
else
    false

一路上学到的一些教训……

  1. Crystal Reports 以一种奇怪的方式处理全局变量。我花了几个小时的时间来研究它们,你基本上可以在报告中的任何地方使用它们,只要你在使用 Global [vartype] "name" 语法放入它们的每个部分中声明它们。即使您每次都重新声明它,Crystal 不会删除它的值或重置它或任何东西。

  2. 此运算符“:=”与“=”不同。“:=”运算符用于设置变量的值,而“=”似乎仅用于比较。

  3. 水晶报表的设计真的很奇怪。如果您确实希望您的公式字段返回特定变量或您只需键入该变量名称而不使用“;”的内容 在它之后。任何没有“;”的东西 在它被认为是公式的结尾之后。所以如果你得到这个愚蠢的“哦,这段代码看起来不是公式的一部分”错误,那是因为你没有放一个“;” 在某事之后,Crystal 假设您的功能在该位置结束。但是如果你不放一个没有“;”的变量 在它之后你的公式默认返回“false”。所以在我的公式中,我有 //idTest //Ubound(idArray) //expDateTest 我所要做的就是取消注释我想要返回的变量,公式就会这样做。

于 2015-04-27T13:22:42.057 回答