好吧,我想通了,所以誰運行到這個位置是我的解決辦法的人。
第一關I的從數據庫中讀取數據時將創建兩個陣列和保持只有一個記錄中的每個ID和日期的拷貝的「公式字段」一節中作了式。然後,對於具有相同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
一些經驗教訓一路上了解到...
水晶報表確實以一種不可思議的方式全局變量。我花了幾個小時與他們混在一起,發現只要在你用Global [vartype]「name」語法放入它們的每個部分中聲明它們,你就可以基本在報告中的任何地方使用它們。儘管每次Crystal不刪除它的值或重置它或任何東西時,都會重新聲明它。
此運算符 「:=」 比 「=」 不同。 「:=」運算符用於設置變量的值,而「=」似乎只用於比較。
Crystal Reports是與它的設計很奇怪。如果你確實希望你的公式字段返回一個特定的變量或者你只需輸入那個變量名而不用「;」之後。任何沒有「;」的東西之後它被認爲是公式的結尾。所以,如果你得到這個愚蠢的「哦,這段代碼看起來像它不是公式的一部分」錯誤,那麼這是因爲你沒有把「;」之後,Crystal會假設你的函數在該位置結束。但是如果你不把一個變量放在沒有「;」的地方之後它只是返回「假」默認情況下你的公式。所以在我的公式中,我有// idTest // Ubound(idArray) // expDateTest 我所要做的就是取消註釋我想要返回的變量,公式將這樣做。
哦,我也忘了說這個。您需要將該idArray公式字段拖到某個地方的報告中,否則將永遠不會被調用。我只是將公式返回給一個空白的StringVar,並將該字段拖到某個位置。 – ChumpStick