通過(guò)在腳本屬性中編寫(xiě) JScript 代碼實(shí)現(xiàn)對(duì)報(bào)表生成與行為進(jìn)行自定義控制。報(bào)表腳本編程可以在報(bào)表模板中直接實(shí)現(xiàn)對(duì)報(bào)表的自定義控制,通過(guò)修改報(bào)表模板而不是修改源程序達(dá)到對(duì)報(bào)表運(yùn)行行為的維護(hù)修改。
報(bào)表腳本屬性的名稱為對(duì)應(yīng)事件的名稱再加上“Script”。如果事件由某個(gè)報(bào)表子對(duì)象的相關(guān)行為觸發(fā),則對(duì)應(yīng)報(bào)表腳本屬性定義在此子對(duì)象上;反之,其它的事件腳本屬性定義在報(bào)表主對(duì)象上。
在所有的事件腳本中,都有一個(gè)內(nèi)建變量 Report 可以使用,其是對(duì)報(bào)表主對(duì)象的引用。如果事件有一個(gè)觸發(fā)子對(duì)象與之關(guān)聯(lián),則有一個(gè)內(nèi)建變量 Sender 可以使用,它是對(duì)觸發(fā)事件的子對(duì)象的引用。
報(bào)表腳本都有一個(gè)觸發(fā)報(bào)表對(duì)象,一般這個(gè)觸發(fā)報(bào)表對(duì)象對(duì)應(yīng)腳本中的內(nèi)建 Sender 變量。下面就根據(jù)觸發(fā)報(bào)表對(duì)象分類(lèi)列出各個(gè)報(bào)表腳本屬性并進(jìn)行簡(jiǎn)要說(shuō)明。
報(bào)表腳本概述
報(bào)表主對(duì)象上的腳本屬性
- 初始化腳本(InitializeScript): 在報(bào)表生成開(kāi)始時(shí)執(zhí)行本腳本。報(bào)表開(kāi)發(fā)者可以對(duì)報(bào)表模板定義進(jìn)行修改調(diào)整。例如用戶要從所有可選的列中選擇一部分列顯示,就可以在此事件中以編程方式動(dòng)態(tài)定義列。
- 導(dǎo)出前腳本(ExportBeginScript): 在報(bào)表導(dǎo)出數(shù)據(jù)執(zhí)行之前觸發(fā),可以在本腳本中改變導(dǎo)出選項(xiàng)參數(shù),自定義報(bào)表的默認(rèn)導(dǎo)出行為。本腳本對(duì)應(yīng)的 Sender 變量為 IGRExportOption 接口引用,根據(jù)導(dǎo)出數(shù)據(jù)類(lèi)型,可以把 Sender 對(duì)象轉(zhuǎn)換為具體的導(dǎo)出類(lèi)型對(duì)象,具體請(qǐng)參考 IGRExportOption 接口的編程參考幫助。
- 開(kāi)始處理腳本(ProcessBeginScript): 當(dāng)報(bào)表準(zhǔn)備對(duì)填入的數(shù)據(jù)進(jìn)行分析處理之前觸發(fā),可以在此腳本中對(duì)已填入的數(shù)據(jù)進(jìn)行一些修改與補(bǔ)充,例如根據(jù)需要在記錄集的后面追加一些空白記錄。
- 結(jié)束處理腳本(ProcessEndScript): 當(dāng)報(bào)表對(duì)填入的數(shù)據(jù)進(jìn)行分析處理完成之后觸發(fā)。
- 排序前腳本(BeforeSortScript): 當(dāng)要對(duì)記錄集中的記錄進(jìn)行重新排序之前觸發(fā)本。如果設(shè)置了記錄集的排序字段(SortFields)屬性,在每次生成報(bào)表時(shí),在 BeginPeocessRecord 事件之前會(huì)觸發(fā) BeforeSort 事件。另當(dāng)查詢顯示器設(shè)定為可排序時(shí),點(diǎn)擊明細(xì)網(wǎng)格的列標(biāo)題會(huì)按點(diǎn)擊的列對(duì)記錄進(jìn)行重新排序,此時(shí)也會(huì)觸發(fā)BeforeSort事件。
- 頁(yè)開(kāi)始腳本(PageStartScript): 在開(kāi)始生成一個(gè)打印頁(yè)面時(shí)觸發(fā)。
- 頁(yè)結(jié)束腳本(PageEndScript): 在完成一個(gè)打印頁(yè)面生成時(shí)觸發(fā)。
- 預(yù)覽前腳本(ShowPreviewWndScript): 在顯示默認(rèn)打印預(yù)覽窗口時(shí)觸發(fā)。本腳本對(duì)應(yīng)的 Sender 變量為 IGRPrintViewer 接口引用,在本腳本中通過(guò) Sender 變量改變打印顯示控件的屬性,從而達(dá)到定制打印預(yù)覽窗口的目的,如隱藏工具欄上的某些按鈕等。
記錄集上的腳本屬性
- 處理記錄腳本(ProcessRecordScript): 當(dāng)報(bào)表生成時(shí),會(huì)按順序遍歷每一條記錄,每當(dāng)遍歷一條記錄時(shí)觸發(fā)執(zhí)行本腳本。在此腳本中,可以取記錄的各個(gè)字段的值。報(bào)表開(kāi)發(fā)者可以在此腳本中對(duì)數(shù)據(jù)進(jìn)行一些自定義的分析統(tǒng)計(jì)。
- 取記錄腳本(FetchRecordScript): 在報(bào)表生成時(shí),報(bào)表主對(duì)象請(qǐng)求數(shù)據(jù)時(shí)觸發(fā)。
- 提交記錄前腳本(BeforePostRecordScript): 在向報(bào)表記錄集中填入記錄數(shù)據(jù)的過(guò)程中,每當(dāng)提交一條記錄之前觸發(fā)件。在此腳本中,我們可以對(duì)當(dāng)前記錄的各個(gè)字段值進(jìn)行重新設(shè)置。譬如可以設(shè)置需要由其它字段通過(guò)計(jì)算得來(lái)的字段值。
- 頁(yè)處理記錄腳本(PageProcessRecordScript): 當(dāng)報(bào)表在生成打印頁(yè)面數(shù)據(jù)時(shí),會(huì)再次按順序遍歷每一條記錄,此遍歷果城中每當(dāng)遍歷一條記錄時(shí)觸發(fā)。
分組上的腳本屬性
- 分組開(kāi)始腳本(GroupBeginScript): 在生成報(bào)表時(shí),開(kāi)始一個(gè)新分組項(xiàng)時(shí)觸發(fā)。
- 分組結(jié)束腳本(GroupEndScript): 在生成報(bào)表時(shí),一個(gè)新分組項(xiàng)結(jié)束時(shí)觸發(fā)。
字段上的腳本屬性
- 取顯示文字腳本(GetDisplayTextScript): 當(dāng)準(zhǔn)備獲取字段對(duì)象的顯示文字時(shí)觸發(fā)。在此腳本中可以改寫(xiě)子段的顯示文字,通過(guò)設(shè)置子段的 DisplayText 屬性改變其顯示文字。例如可以將一個(gè)整數(shù)字段的顯示文字改為任意的非數(shù)字文字。
報(bào)表節(jié)上的腳本屬性
- 格式化腳本(FormatScript): 當(dāng)報(bào)表節(jié)在輸出之前觸發(fā)。包括查詢顯示與打印生成顯示。一般在本腳本中改變節(jié)及節(jié)中的部件框或單元格的顯示外觀屬性,達(dá)到某些突出顯示的效果。也可以改變節(jié)及節(jié)中的部件框或單元格的 Visible 屬性,實(shí)現(xiàn)按條件動(dòng)態(tài)顯示或隱藏報(bào)表內(nèi)容。本腳本會(huì)頻繁執(zhí)行到,應(yīng)注意腳本的運(yùn)行性能。
部件框上的腳本屬性
- 自繪腳本(CustomDrawScript): 報(bào)表部件框自繪腳本。當(dāng)部件框?yàn)樽岳L部件框時(shí)(部件框的“自繪”屬性設(shè)置為“是”),部件框在輸出顯示時(shí)會(huì)觸發(fā)本事件,報(bào)表開(kāi)發(fā)者應(yīng)該在本事件中實(shí)現(xiàn)部件框的顯示輸出。
文字部件框上的腳本屬性
- 取顯示文字腳本(GetDisplayTextScript): 當(dāng)準(zhǔn)備獲取文字框的顯示文字時(shí)觸發(fā)。在此腳本中可以改寫(xiě)文字框的顯示文字,通過(guò)設(shè)置文字框的 DisplayText 屬性改變其顯示文字。文字框包括靜態(tài)框、字段框、統(tǒng)計(jì)框、系統(tǒng)變量框與綜合文本框。
編寫(xiě)報(bào)表腳本代碼
腳本語(yǔ)言類(lèi)型可以為 JScript 或 VBScript,新建報(bào)表默認(rèn)為 JScript。如果要使用 VBScript 腳本語(yǔ)言,通過(guò)報(bào)表主對(duì)象的“腳本類(lèi)別(ScriptType)”屬性指定為 VBScript。
首先選中要編寫(xiě)報(bào)表腳本的報(bào)表對(duì)象,然后在屬性編輯窗口選中對(duì)應(yīng)腳本屬性,執(zhí)行腳本屬性行右邊的“...”按鈕可以打開(kāi)腳本編輯窗口,在此窗口中輸入腳本代碼。下圖為腳本編輯窗口界面:

在所有的事件腳本中,都有兩個(gè)內(nèi)建變量 Report 與 Sender 可以使用,Report 變量是對(duì)報(bào)表主對(duì)象的引用。如果事件腳本有一個(gè)觸發(fā)報(bào)表子對(duì)象與之關(guān)聯(lián),內(nèi)建變量 Sender 是對(duì)觸發(fā)事件的報(bào)表子對(duì)象的引用;反之 Sender 與 Report 都是對(duì)報(bào)表主對(duì)象的引用;如 FieldGetDisplayTextScript 腳本中,Sender 表示觸發(fā)此事件的字段對(duì)象(IGRField)。通過(guò) Report 與 Sender 變量就可以獲取或設(shè)置報(bào)表對(duì)象的屬性,調(diào)用報(bào)表對(duì)象的方法,請(qǐng)借助本幫助中編程參考部分應(yīng)用對(duì)象的屬性與方法。
在上面的腳本編輯窗口中,為字段的“取顯示文字腳本”屬性上的報(bào)表腳本。其中的 Sender 表示字段對(duì)象,當(dāng)其值為空時(shí),將字段的顯示文本屬性設(shè)為“待定”;當(dāng)其布爾值為真時(shí),將字段的顯示文本屬性設(shè)為“熱賣(mài)中”,反之設(shè)為另外的“停止銷(xiāo)售”。
瀏覽報(bào)表腳本 - 開(kāi)發(fā)指南
整個(gè)報(bào)表腳本代碼瀏覽功能就是在一個(gè)窗口中集中查看整個(gè)報(bào)表中的全部腳本代碼,這樣可以方便了解整個(gè)報(bào)表中的腳本定義情況,以及各個(gè)腳本之間的關(guān)聯(lián)關(guān)系。
執(zhí)行報(bào)表主對(duì)象上的“瀏覽報(bào)表腳本”屬性命令可以打開(kāi)整個(gè)報(bào)表腳本代碼瀏覽窗口,如下圖。

在腳本代碼瀏覽窗口中不能編輯腳本,從列表中選擇對(duì)應(yīng)的腳本并執(zhí)行“編輯腳本...”按鈕,或雙擊下面編輯框中的腳本代碼可以打開(kāi)對(duì)應(yīng)的腳本編輯窗口。
瀏覽報(bào)表腳本代碼
報(bào)表參數(shù)可以用來(lái)存儲(chǔ)腳本運(yùn)行得到的計(jì)算值,以供腳本下一次運(yùn)行使用,或在另一個(gè)腳本中應(yīng)用。如果某個(gè)腳本在報(bào)表的一次運(yùn)行過(guò)程中會(huì)多次執(zhí)行到,且一次運(yùn)行需要用到上一次運(yùn)行的結(jié)果值,這樣的方式就需要借助報(bào)表參數(shù)來(lái)存儲(chǔ)上一次運(yùn)行的結(jié)果值。如果要實(shí)現(xiàn)某項(xiàng)功能需要編寫(xiě)多個(gè)報(bào)表腳本才能達(dá)到,且不同腳本之間需要傳遞計(jì)算值,也需要借助報(bào)表參數(shù)。
例子1:用報(bào)表腳本實(shí)現(xiàn)收發(fā)存功能
實(shí)現(xiàn)一個(gè)庫(kù)存收發(fā)存報(bào)表,庫(kù)存有一個(gè)期初數(shù),列出每筆庫(kù)存變動(dòng)記錄,并計(jì)算出變動(dòng)后的結(jié)余庫(kù)存數(shù)。用一個(gè)報(bào)表參數(shù)存儲(chǔ)期初數(shù),在記錄集的“提交記錄前腳本”中計(jì)算出余額值。
//余額字段的值由上一筆的余額值加上本筆入庫(kù)數(shù)量減去本筆出庫(kù)數(shù)量
Report.FieldByName("Balance").AsFloat = Report.ParameterByName("Balance").AsFloat +
Report.FieldByName("IncQty").AsFloat - Report.FieldByName("DecQty").AsFloat
//更新參數(shù)的值為本筆的余額,以供下筆計(jì)算使用
Report.ParameterByName("Balance").AsFloat = Report.FieldByName("Balance").AsFloat;
例子2:實(shí)現(xiàn)自定義統(tǒng)計(jì)計(jì)算
實(shí)現(xiàn)分組統(tǒng)計(jì)自定義計(jì)算,要求統(tǒng)計(jì)金額大于1000以上的數(shù)據(jù)的合計(jì)值。實(shí)現(xiàn)這樣需要定義一個(gè)報(bào)表參數(shù)存儲(chǔ)中間運(yùn)算值,在分組的“分組開(kāi)始腳本”中設(shè)置報(bào)表參數(shù)的值為0,在記錄集的“處理記錄腳本”中按條件累加報(bào)表參數(shù)的值,在分組的“分組結(jié)束腳本”中將報(bào)表參數(shù)的值傳遞給要展現(xiàn)這個(gè)統(tǒng)計(jì)值的統(tǒng)計(jì)框。
分組開(kāi)始腳本如下:
//初始統(tǒng)計(jì)值設(shè)為0
Report.ParameterByName("SumAmt").AsFloat = 0;
處理記錄腳本如下:
//按條件累加報(bào)表參數(shù)的值
var AmtField = Report.FieldlByName("Amt");
if (AmtField.AsFloat >= 1000)
{
var AmtParam = Report.ParameterByName("SumAmt");
AmtParam.AsFloat= AmtParam.AsFloat + AmtField.AsFloat;
}
分組結(jié)束腳本如下:
//將報(bào)表參數(shù)的值傳遞給要展現(xiàn)這個(gè)統(tǒng)計(jì)值的統(tǒng)計(jì)框
Report.ControlByName("SumBox").Value = Report.ParameterByName("SumAmt").AsFloat;
調(diào)試報(bào)表腳本
報(bào)表主對(duì)象的初始化腳本實(shí)現(xiàn)根據(jù)報(bào)表參數(shù)動(dòng)態(tài)確定列的可見(jiàn)性
說(shuō)明:根據(jù)參數(shù)值確定某個(gè)列實(shí)現(xiàn)顯式出來(lái)
Report.ColumnByName("Column1").Visible = Report.ParameterByName("ShowColumn1").AsBoolean;
Report.ColumnByName("Column2").Visible = Report.ParameterByName("ShowColumn2").AsBoolean;
報(bào)表主對(duì)象的開(kāi)始處理腳本實(shí)現(xiàn)追加空白記錄
描述:報(bào)表中有金額線列,每頁(yè)打印固定行數(shù),最后一頁(yè)用空白行補(bǔ)齊,讓空白行也顯示出金額線列。直接用明細(xì)網(wǎng)格的追加空白行不能達(dá)到金額線列也顯示出金額線,而是應(yīng)該通過(guò)追加空白記錄的方式來(lái)實(shí)現(xiàn)。
//假設(shè)每頁(yè)要顯示20 行,求出最后要補(bǔ)充的行數(shù)
var AppendRows = 20 - (Report.DetailGrid.Recordset.RecordCount % 20);
if (AppendRows == 20)
AppendRows = 0;
for (i=0; i<AppendRows; ++i)
{
Report.DetailGrid.Recordset.Append();
Report.DetailGrid.Recordset.Post();
}
報(bào)表主對(duì)象的預(yù)覽前腳本實(shí)現(xiàn)隱藏打印顯示器的工具欄上的部分按鈕
//隱藏發(fā)送電子郵件按鈕與保存報(bào)表文檔菜單相
Sender.RemoveToolbarControl(6); //grtctMail
Sender.RemoveToolbarControl(7); //grtctSaveDocument
//顯示出導(dǎo)航窗口,以單頁(yè)模式查看報(bào)表
Sender.ShowBookmark = true; //顯示出導(dǎo)航窗口
Sender.ViewMode = 2; //grpvmSinglePage 按單頁(yè)模式查看。
記錄集的提交記錄前腳本實(shí)現(xiàn)計(jì)算字段
//字段值根據(jù)其它子段計(jì)算得來(lái)
Report.FieldByName("CalcAmount").AsFloat = Report.FieldByName("Quantity").AsFloat * Report.FieldByName("Unitprice").AsFloat;
字段的取顯示文字腳本實(shí)現(xiàn)字段顯示文字的改變
//將一個(gè)整數(shù)字段根據(jù)不同的值顯示不同的文字
if (Sender.AsInteger == 5)
Sender.DisplayText = "優(yōu)秀";
else if (Sender.AsInteger == 4)
Sender.DisplayText = "良好";
else if (Sender.AsInteger == 3)
Sender.DisplayText = "達(dá)標(biāo)";
else
Sender.DisplayText = "不及格";
報(bào)表節(jié)的格式化腳本實(shí)現(xiàn)突出顯示
//這是一個(gè)寫(xiě)在內(nèi)容行上的腳本,通過(guò)改變外觀屬性實(shí)現(xiàn)以不同方式顯示不同類(lèi)別的內(nèi)容
//當(dāng)Amount字段的值大于等于5000時(shí),將Amount顯示為粗體,綠色,背景色為白色
//當(dāng)Amount字段的值大于等于1000時(shí),將Amount顯示為正常體,黃色,背景色為藍(lán)色
//當(dāng)Amount字段的值小于1000時(shí),將Amount顯示為正常體,紅色,背景色為白色
var AmountContentCell = Sender.ContentCells.Item("Amount");
var AmountField = Report.FieldByName("Amount");
var FontBold;
var FontItalic;
var TextColor;
var BackColor;
if (AmountField.AsFloat >= 5000)
{
FontBold = true;
FontItalic = false;
TextColor = GetColorValue(0, 255, 0);
BackColor = GetColorValue(255, 255, 255);
}
else if (AmountField.AsFloat >= 1000)
{
FontBold = false;
FontItalic = false;
TextColor = GetColorValue(255, 255, 0);
BackColor = GetColorValue(0, 0, 255);
}
else
{
FontBold = false;
FontItalic = true;
TextColor = GetColorValue(255, 0, 0);
BackColor = GetColorValue(255, 255, 255);
}
//當(dāng)為打印輸出狀態(tài)時(shí),文字顏色始終為黑色,背景色始終為白色
//if (Report.DisplayMode == grrdmPrintGenerate)
if (Report.DisplayMode == 2)
{
TextColor = GetColorValue(0, 0, 0);
BackColor = GetColorValue(255, 255, 255);
}
AmountContentCell.Font.Bold = FontBold;
AmountContentCell.Font.Italic = FontItalic;
AmountContentCell.ForeColor = TextColor;
AmountContentCell.BackColor = BackColor;
function GetColorValue(r,g,b)
{
return r + g*256 + b*256*256;
}
報(bào)表節(jié)的格式化腳本實(shí)現(xiàn)分組尾按條件隱藏
//這是一個(gè)寫(xiě)在分組尾上的腳本,根據(jù)條件動(dòng)態(tài)設(shè)置 Visible 屬性
Sender.Visible = (Report.FieldByName("Type").AsInteger == 0);
報(bào)表節(jié)的格式化腳本根據(jù)頁(yè)號(hào)顯示或隱藏報(bào)表節(jié)或部件框
//只在第一頁(yè)顯示當(dāng)前報(bào)表節(jié)
Sender.Visible = (Report.SystemVarValue(3) == 1);
//如果是第一頁(yè)不顯示一個(gè)部件框
Report.ControlByName("MemoBox1").Visible = (Report.SystemVarValue(3) != 1);
控制某個(gè)部件框在最后一頁(yè)顯示
Report.ControlByName("MemoBox1").Visible = (Report.SystemVarValue(3) == Report.SystemVarValue(2));
部件框的自繪腳本實(shí)現(xiàn)自定義圖形與文字繪出
function GetColorValue(r,g,b)
{
return r + g*256 + b*256*256;
}
var Graphics = Report.Graphics;
var x = Graphics.Left;
var y = Graphics.Top;
var width = Graphics.Width;
var height = Graphics.Height;
var PartSize = height/3;
var DrawLeft = x + (width - PartSize)/2;
var DrawRight = DrawLeft + PartSize;
var DrawXCenter = (DrawLeft + DrawRight)/2;
var DrawTop = y;
var DrawBottom = y + height;
//設(shè)定繪出線型
Graphics.SelectPen(2, GetColorValue(255, 0, 0), 0/*grpsSolid*/);
//設(shè)定填充色
Graphics.SelectFillColor( GetColorValue(0, 255, 255) );
//畫(huà)箭頭兩邊斜線
Graphics.MoveTo(DrawLeft, DrawTop+PartSize);
Graphics.LineTo(DrawXCenter, DrawTop);
Graphics.LineTo(DrawRight, DrawTop+PartSize);
//畫(huà)箭頭豎線
Graphics.MoveTo(DrawXCenter, DrawTop);
Graphics.LineTo(DrawXCenter, DrawTop+PartSize*2);
//畫(huà)出圓圈
Graphics.Ellipse(DrawLeft, DrawTop+PartSize*2, PartSize, PartSize, true);
//恢復(fù)填充色設(shè)定,SelectFillColor調(diào)用之后,必須對(duì)應(yīng)調(diào)用RestoreFillColor
Graphics.RestoreFillColor();
//恢復(fù)繪出線型設(shè)定,SelectPen調(diào)用之后,必須對(duì)應(yīng)調(diào)用RestorePen
Graphics.RestorePen();