顯示具有 Reports 標籤的文章。 顯示所有文章
顯示具有 Reports 標籤的文章。 顯示所有文章

2025/03/14

程式碼轉換不再難:AI 助你精通 FastReport FastScript

 作者:吳祐賓

 

 


 

 

 

FastScript 是 FastReport VCL / FMX 超棒的產品之一,FastScript 功能非常豐富,七成需求都可以依賴它來完成,不一定要使用肥大的開發工具。

 

FastScript 限制

 

FastScript 也有其限制,例如它不支援以下兩種東西:

  • Class 建立。無法使用 record, class 等 object 來建立自己的物件
  • Set 集合。無法使用 [fsBold, ...]來設定集合

 

使用 AI,在 FastScript 上寫出一手好程式


還好現在有 AI 工具,把提示語給 AI 後,就可以快速寫出正確又有效率的工具出來,真是太棒了!

 

我使用提示語如下,提供給各位讀者參考:


使用 FastReport FastScript 的 JScript 語法建立一個腳本:[
  將 "Hello, World!" 顯示在 Memo1 元件中。(可以代換為你的需求)
]
Refer to the following FastScript JScript syntax rules:[
===
Classes
You cannot define a class inside the script, but you can use the external classes defined in add-in modules or your application.
===
Functions
There is a rich set of standard functions which can be used in a
script. To get an access to these functions, pass the fsGlobalUnit
reference to the TfsScript.Parent property.
===
About FastReport's FastScript:JScript syntax:
Program -> Statements
Statements -> Statement...
Block -> '{' Statements '}'
ImportStmt -> IMPORT (String/,)...
VarStmt -> VAR (VarDecl/',')...
VarDecl -> Ident [Array] [InitValue]Array -> '[' (ArrayDim/',')... ']'
ArrayDim -> Expression
InitValue -> '=' Expression
Expression -> SimpleExpression [RelOp SimpleExpression]...
SimpleExpression -> ['-'] Term [AddOp Term]...
Term -> Factor [MulOp Factor]...
Factor -> Designator
-> UnsignedNumber
-> String
-> '(' Expression ')'
-> '!' Factor
-> '[' SetConstructor ']'
-> NewOperator
-> '<' FRString '>'
SetConstructor -> SetNode/','...
SetNode -> Expression ['..' Expression]
NewOperator -> NEW Designator
RelOp -> '>'
-> '<'
-> '<='
-> '>='
-> '!='
-> '=='
-> IN
-> IS
AddOp -> '+'
-> '-'
-> '||'
-> '^'
MulOp -> '*'
-> '/'
-> '%'
-> '&&'
-> '<<'
-> '>>'
Designator -> ['&'] Ident ['.' Ident | '[' ExprList ']' | '(' [ExprList] ')']...
ExprList -> Expression/','...
Statement -> (AssignStmt | CallStmt | BreakStmt | ContinueStmt |
DeleteStmt | DoWhileStmt | ForStmt | FunctionStmt |
IfStmt | ImportStmt | ReturnStmt | SwitchStmt |
VarStmt | WhileStmt | WithStmt | Block) [';']
BreakStmt -> BREAK
ContinueStmt -> CONTINUE
DeleteStmt -> DELETE Designator
AssignStmt -> Designator ['+'|'-'|'*'|'/']'=' Expression
CallStmt -> Designator ['+''+'|'-''-']
ReturnStmt -> RETURN [Expression]
IfStmt -> IF '(' Expression ')' Statement [ELSE Statement]
SwitchStmt -> SWITCH '(' Expression ')' '{' (CaseSelector)... [DEFAULT ':' Statement] '}'
CaseSelector -> CASE SetConstructor ':' Statement
DoWhileStmt -> DO Statement [';'] WHILE '(' Expression ')' ';'
WhileStmt -> WHILE '(' Expression ')' Statement
ForStmt -> FOR '(' ForStmtItem ';' Expression ';' ForStmtItem ')' Statement
ForStmtItem -> AssignStmt-> CallStmt-> VarStmt-> Empty
TryStmt -> TRY CompoundStmt (FINALLY | EXCEPT) CompoundStmt
FunctionStmt -> FunctionHeading Block
FunctionHeading -> FUNCTION Ident FormalParameters
FormalParameters -> '(' [FormalParam/','...] ')'
FormalParam -> ['&'] Ident
WithStmt -> WITH '(' Designator ')' Statement
]
Specific usage of FastScript JScript: [
#language JScript // this is optional
import "unit1.js", "unit2.js"
Report.Memo1.Text = "HelloWorld"; // Sets the text of Memo1 through the Report object.
Memo1.Text = "HelloWorld";// Equivalent if Memo1 is in the main report scope (not within a sub-component like a Group or Band).
var mbSet = mbYes + mbNo;  // FastScript does not support sets directly; use addition for combining flags.
if (MessageDlg("Welcome to my JScript application. Exit now?", mtConfirmation, mbSet, 0) == mrYes)
{ ShowMessage("OK");}
// import section - must be before any other sections
var i, j = 0; // var section
function p1() // procedures and function
{//
}
// main procedure that will be executed.
p1();
// Dynamic array create. (var myarray = [] not support. Need use the FR TfrxArray Component)
var myarray = new TfrxArray();
myarray[0] = 1;
myarray[1] = 2;
for (i = 0; i < 1; i++) j = i + 1; myarray[i] = myarray[i] + j;
ShowMessage(IntToStr(myarray.Count)); // TfrxArray is not JScript array type.
// You can use the TStrings/TStringList. Same the Delphi TStrings/TStringList.
var myList = new TStringList();
myList.Add("message=HelloWorld");
ShowMessage(myList.Values("message"));
]
The following FastScript built-in functions are available:
function IntToStr(i: Integer): Stringfunction FloatToStr(e: Extended): Stringfunction DateToStr(e: Extended): Stringfunction TimeToStr(e: Extended): Stringfunction DateTimeToStr(e: Extended): Stringfunction VarToStr(v: Variant): Stringfunction StrToInt(s: String): Integerfunction StrToFloat(s: String): Extendedfunction StrToDate(s: String): Extendedfunction StrToTime(s: String): Extendedfunction StrToDateTime(s: String): Extendedfunction Format(Fmt: String; Args: array): Stringfunction FormatFloat(Fmt: String; Value: Extended): Stringfunction FormatDateTime(Fmt: String; DateTime: TDateTime): Stringfunction FormatMaskText(EditMask: string; Value: string): stringfunction EncodeDate(Year, Month, Day: Word): TDateTimeprocedure DecodeDate(Date: TDateTime; var Year, Month, Day: Word)function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTimeprocedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word)function Date: TDateTimefunction Time: TDateTimefunction Now: TDateTimefunction DayOfWeek(aDate: DateTime): Integerfunction IsLeapYear(Year: Word): Booleanfunction DaysInMonth(nYear, nMonth: Integer): Integerfunction Length(s: String): Integerfunction Copy(s: String; from, count: Integer): Stringfunction Pos(substr, s: String): Integerprocedure Delete(var s: String; from, count: Integer): Stringprocedure Insert(s: String; var s2: String; pos: Integer): Stringfunction Uppercase(s: String): Stringfunction Lowercase(s: String): Stringfunction Trim(s: String): Stringfunction NameCase(s: String): Stringfunction CompareText(s, s1: String): Integerfunction Chr(i: Integer): Charfunction Ord(ch: Char): Integerprocedure SetLength(var S: String; L: Integer)function Round(e: Extended): Integerfunction Trunc(e: Extended): Integerfunction Int(e: Extended): Integerfunction Frac(X: Extended): Extendedfunction Sqrt(e: Extended): Extendedfunction Abs(e: Extended): Extendedfunction Sin(e: Extended): Extendedfunction Cos(e: Extended): Extendedfunction ArcTan(X: Extended): Extendedfunction Tan(X: Extended): Extendedfunction Exp(X: Extended): Extendedfunction Ln(X: Extended): Extendedfunction Pi: Extendedprocedure Inc(var i: Integer; incr: Integer = 1)procedure Dec(var i: Integer; decr: Integer = 1)procedure RaiseException(Param: String)procedure ShowMessage(Msg: Variant)procedure Randomizefunction Random: Extendedfunction ValidInt(cInt: String): Booleanfunction ValidFloat(cFlt: String): Booleanfunction ValidDate(cDate: String): Booleanfunction CreateOleObject(ClassName: String): Variantfunction VarArrayCreate(Bounds: Array; Typ: Integer): Variant


前面的提示詞也可以使用:

 

將以下 C# 程式碼片段轉換為使用 JScript 語法的 FastReport FastScript。 該腳本應在 FastReport 環境中實現等效的功能。 請密切注意所提供的 FastScript JScript 語法規則和可用的內建函數。


總結

有了AI後,程式轉換上變得十分容易,從以前要求 Google 關鍵字力,現在要漸漸改為 AI 提示詞力。

 

如果有什麼想回饋的內容,歡迎在底下留言讓我知道。

2021/07/15

FastReport 報表檔 FR3 在 D7 升級 XE 前必須要了解的資訊

我家產品自從 D7 升級成 XE 後,在開發時,報表從零到有還蠻輕鬆的,FR (FastReport) 的報表產生器所產出的 fr3 報表定義檔會自動存為 UTF8 格式。上線後,才發現之前存在 D7 裡的 fr3 在 XE 中在中文的地方會出現亂碼。

D7 所設計的 fr3



XE 讀取 D7 設計的 fr3



沒有什麼比轉一半更令人揪心

在遇到問題時,如果這問題有一致性,就像文字轉碼一樣,全是亂碼的還容易處理:找到編碼,轉換,收工。

但現在的情況是 FR 轉出的 fr3 檔,有部分正常,有部分亂碼,這關最難解!

災難中的小確幸,確定是編碼問題

D7 只支援 Ansi,所以轉出來的 fr3 無庸至疑的是 Ansi,從圖片可知是採繁體中文大 5 碼  (Big5) 代碼頁 (CodePage=950)。

既然知道是 Ansi,現在就可以來猜亂碼的地方是什麼編碼。




我還是直接公佈答案好了:


沒錯,就是 Ansi 的 UTF8 代碼頁 (CodePage=65001)!


難解之處就在二選一

從上圖可以知道當切換代碼頁時,原本能顯示中文的地方會變成亂碼,反之亦然。哼哼,FastReport 真有你的,硬是不出升級工具。官方沒準備,只好自己硬上。

fr3 是 XML 格式,但


Delphi 的 XML Mapper 是很實用的 XML 解析工具,但無奈 fr3 是一個特規,它無法順利解析 fr3 的內容。

 

先說結論

經過在漫長的奮鬥之路後,總算是做出一個像樣的結果:


該顯示中文的地方能順利顯示中文,格式也採 UTF8,尤其是 XE 開始支援 Unicode 後,Ansi 文字處理變得相對麻煩,【System.AnsiStrings 單元】會是過這關的最佳利器!


和你分享 ❤

See also


2012/10/04

FastReport 的 Variables 和 Script Variables


Variables 可在 Design 上看到變數
Script Variables 則看不到

Design script裡面使用上
是直接使用,例如:

Script Variables :
========
Delphi:
frxReport.Script.Varialbes['XXX'] := 'XYZ';

FR Design
ShowMessage(XXX);  // 雖然看不到,但可以直接使用
========

 Variables:
========
Delphi:
frxReport.Varialbes['XXX'] := '''XYZ''';

FR Design
ShowMessage(<XXX>);  // 在Design Manager可以看到,但設定和呼叫上就比較麻煩
========

FastScript 若使用非 Pascal 語言來讀取變數時 (2024/05/28 更新)

 

若使用非 Pascal 語言時,以 JScript 為例,使用上不能採用快截符號讀取變數,會發生判斷式錯誤的例外。只能使用 Report 物件來讀取: 

 

Report.Variables["XXX"] or Report.Script.Variables["XXX"]



參考來源:

  • Script variables
  • FastReport 4 Programmer's manual







YA! 又過一關囉!

FastReport4.x 在 XE XE2 下編譯失敗的問題

如果是買FastReport正式版的使用者,可能會遇到FastReport 4.x的Source編譯失敗的情況

其實是因為XE2它為了與FireMonkey相容的關係

所以會把uses的位置做了一些修改