2026年3月23日 星期一

Delphi FireDAC

 FDManager

var sParams:TStringList;

sParams.Add('Server=xx.xx.xx.xx');
sParams.Add('User_Name=xxxxx');
sParams.Add('Password=xxxxx');
sParams.Add('Database=xxxxx');
sParams.Add('DriverID=MSSQL');
sParams.Add('Pooled=True');
          sParams.Add('ExtendedMetadata=True');  //可以用來取得欄位屬性歸屬
FDManager1.AddConnectionDef('MSSQL_Pool', 'MSSQL', sParams);

FDConnection (與FDManager搭配使用,可以理解是DB Session)

FDConnection1.ConnectionDefName := 'MSSQL_Pool';
FDConnection1.Connected := True;

FDQuery / FDUpdateSQL

with FDQuery1 do
begin
  Connection := FDConnection1;
  CachedUpdates := True;
  UpdateOptions.UpdateTableName := 'Table1';
  UpdateOptions.KeyFields := 'Field1,Field2';
  UpdateOptions.UpdateMode := upWhereKeyOnly;
 
            UpdateObject := Self.FDUpdateSQL1;

  Close;
  SQL.Text :=
    ' select a.*, b.Fiedl5 '+
    ' from Table1 a '+
    ' left join Table2 b on b.field1=a.field1 '+
    ' where ... ';
  Open;
end;

ApplyUpdates

FDQuery1.CheckBrowseMode;
FDQuery1.FetchNext;  //抓資料到本地快取, 確保快取內容有提供回寫的資料
FDQuery1.ApplyUpdates(-1);


取得別名欄位的表格屬性及原欄名稱,需設定連線參數 ExtendedMetadata=True
var column:TFDDatSColumn;
column := FDQuery1.GetFieldColumn(Field);
column.ActualOriginTabName // Field歸屬的Table
column.ActualOriginColName // Field實體表格中的Column Name


FDConnection -> FDQuery,當FDQuery資料是分批讀取還沒完全將資料載入時,FDConnection沒辦法被其他FDQuery操作使用,會出現以下的錯誤訊息。


FDQuery.SourceEOF; //可以知道資料是否已完全載入

提供的建議做法是放二個FDConnection,一個做 Select...,另一個做Update/Insert/Delete/Exec ...
如果沒有閒置的 FDConnection, 就要Create一個FDConnection提供給FDQuery使用。





2026年3月19日 星期四

美元 為何又稱美金

 「美元」之所以在華語世界常被稱為「美金」,主要與歷史上的貨幣制度以及黃金的關聯性有關。這可以追溯到 19 世紀到 20 世紀中葉的全球金融背景:

1. 金本位制度(Gold Standard)

在 19 世紀後半葉至 20 世紀初,世界主要經濟體實行「金本位制」。當時的美元與黃金是直接掛鉤的,面額可以隨時向銀行兌換成等值的實體黃金。

實質等同: 由於美元在當時代表著特定重量的黃金,民眾習慣將這種具有黃金價值的貨幣稱為「美金」。

2. 布列頓森林體系(Bretton Woods System)

二戰結束後(1944 年),全球建立了布列頓森林體系。該體系確立了美元與黃金掛鉤(每 35 美元兌換 1 盎司黃金),而其他國家的貨幣再與美元掛鉤。

國際儲備: 美元成為全球最主要的儲備貨幣,地位如同黃金般穩固。這進一步加深了「美元即黃金」的社會認知,「美金」這個稱呼也因此在兩岸三地及海外華人圈廣為流傳。

3. 文化與習慣

雖然 1971 年尼克森衝擊(Nixon Shock)宣告美元正式脫離金本位,美元不再能兌換黃金,但「美金」這個詞彙已經深植於語言習慣中:

辨識度: 在華語口語中,「美金」聽起來比「美元」更具備財富的象徵意義。

區分需求: 在早期外匯管制較嚴格的時期,民間習慣用「美金」來區分本地貨幣與這種強勢的國際貨幣。

補充小知識:

儘管現在美元本質上是「法定貨幣」(Fiat Money)而非金幣,但這種稱呼已成為一種文化印記。在正式的金融公文或新聞報導中,通常會使用「美元」;而在日常生活中,「美金」依然是極為普遍的用法。


Gemini

 

2026年2月25日 星期三

修正 Quick Report 預覽/列印的顯示比例

 當調整了電腦螢幕的縮放比例後,操作程式裡的報表QuickReport,發現報表預覽的資料內容沒有隨著顯示縮放比跟著做調整,但不影響實際列印輸出的結果。



參考網上的作法,修正 QuickReport 需 QRPrntr.pas 排除縮放比的問題。

我採用網友提供的方法1來處理。

File Name : QRPrntr.pas

Procedure Name : CreateMetafileCanvas


QRPrntr.pas 修正後,重新編譯QR506RunDXE10.bpl,

預覽結果就會以符合系統縮放比做調整了。


【參考連結】

老森常譚 IT Help 《Delphi》修正 Quick Report 預覽列印的比例問題


2025年12月25日 星期四

QuickReport - 載入 Qrp 報表文件時,會預先使用預設印表機的紙張格式套用在文件上,與設計的報表格式不符...

 var 
  repReport:TQuickRep;
  iPageHeightPixel, iPageWidthPixel:Integer;
  Meta: TMetafile;
begin
  inherited;
  repReport := TQuickRep.Create(nil);
  repReport.PrevInitialZoom := qrZoomToWidth;   //頁寬
  repReport.PrevShowThumbs := False;            //不顯示簡視欄
  repReport.PrevShowSearch := False;            //不顯示搜尋欄
  repReport.PreviewInitialState := wsMaximized; //最大化
  repReport.ShowProgress := True;
  repReport.PreviewDefaultSaveType := stQRP;

  repReport.Prepare;
  repReport.QRPrinter.Load('Report.qrp');    //載入檔案

  Meta := repReport.QRPrinter.GetPage(1);
  iPageWidthPixel := Meta.Width;    //取得文件記錄中的尺寸 Pixel
  iPageHeightPixel := Meta.Height;  //取得文件記錄中的尺寸 Pixel

  repReport.Page.Orientation := repReport.QRPrinter.Orientation; //報表直/橫向
  repReport.Page.PaperSize := TQRPaperSize.Custom; //報表紙張格式
  repReport.Units := TQRUnit.Pixels;
  repReport.Page.Length := iPageHeightPixel; //設定報表長度
  repReport.Page.Width := iPageWidthPixel;   //設定報表寬度

  repReport.PrinterSettings.PaperSize := TQRPaperSize.Custom;  //報表紙張格式
  repReport.PrinterSettings.PrinterIndex := 1;      //指定印表機
  repReport.PrinterSettings.ApplySettings(repReport.QRPrinter);

  repReport.QRPrinter.PrinterIndex := 1;            //指定印表機
  repReport.QRPrinter.aPrinterSettings.ApplySettings;
  repReport.QRPrinter.PreviewModal;      //預覽文件
end;

2025年12月18日 星期四

QuickReport Prepare / Preview / Print Event觸發的差異




 

面對風險、機遇和挑戰,你為什麽總是賺小虧大?


 

高智商問題:100名囚犯如何用數學拯救自己?

 


透過詢問專業建議,更能具體掌握需要改進細節

 


#CharGPT

在參與考試或競賽後,建立回饋機制對個人成長至關重要。不論最終的成績表現如何,主動向評分委員請益都是提升自我的關鍵步驟。透過詢問專業建議,參賽者能具體掌握需要改進的空間或加強的細節。這種積極的學習態度有助於發現盲點,進而在未來的挑戰中展現更優異的實力。總結而言,將賽後的檢討視為持續進步的契機,是追求卓越不可或缺的過程。

2025年6月11日 星期三

QuickReport 調整 QRShape 配合 DetailBand 展延

 


procedure TForm1.DetailBand1BeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean);
var h:extended;
begin
  DetailBand1.ExpandedHeight(h);
  QRShape1.Size.Height := h - QRShape1.Size.Top - 1;
end;



2025年5月21日 星期三

藍寶石

 藍寶石

「藍寶石」雖然名字有「藍」字,但實際上藍寶石的顏色不只藍色,這是因為它的命名來自於寶石的礦物成分,而不是顏色。

✅ 原因說明:
1. 藍寶石是「剛玉」(Corundum)的一種
  • 剛玉的化學成分是氧化鋁(Al₂O₃)。
  • 純淨的剛玉其實是無色透明的。
  • 當剛玉中含有不同的微量元素時,會呈現不同的顏色。

2. 顏色來源是微量元素
微量元素 顏色
鐵、鈦         藍色
                紅色 → 就是「紅寶石」
                黃色
鉻 + 鐵         粉紅色
                綠色

3. 命名方式
所有不是紅寶石的剛玉(即使不是藍色),在寶石學上都歸類為「藍寶石」的一種。

  • 比如:黃色叫「黃寶石」實際上是「黃色藍寶石」。
  • 粉色叫「粉紅藍寶石」、綠色叫「綠色藍寶石」。

❗那為什麼紅色的剛玉叫「紅寶石」?
這是因為紅寶石的價值和歷史地位非常特殊,因此被單獨劃分出來。它和藍寶石其實是同一種礦物(剛玉),但名稱上有所區分。

🔍 總結
「藍寶石」是礦物名稱,不代表一定是藍色。
各種顏色的剛玉都可以叫「藍寶石」,除了紅色那種叫「紅寶石」。
因此你會看到粉色、黃色甚至無色的「藍寶石」。

ChatGPT



2025年5月19日 星期一

常用函數

String

System

function Copy(S: String; Index: Integer; Count: Integer): string;

 

System.SysUtils

function StringReplace(const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string;
function FormatDateTime(const Format: string; DateTime: TDateTime): string;
function FormatFloat(const Format: string; Value: Extended): string;
function FormatCurr(const Format: string; Value: Currency): string;
function Trim(const S: string): string; 
function TrimLeft(const S: string): string; overload;
function TrimRight(const S: string): string; overload;
function QuotedStr(const S: string): string; overload;

 比對字串 (不區分大小寫)
function CompareText(const S1, S2: string): Integer; 
 
function UpperCase(const S: string): string; 
function UpperCase(const S: string; LocaleOptions: TLocaleOptions): string;
function LowerCase(const S: string): string; overload;
function LowerCase(const S: string; LocaleOptions: TLocaleOptions): string;
function Languages: TLanguages;


System.StrUtils

 回傳Text存在於Array裡的索引值 (區分大小寫)
function IndexStr(const AText: string; const AValues: array of string): Integer;

回傳Text存在於Array裡的索引值 (不區分大小寫)
function IndexText(const AText: string; const AValues: array of string): Integer; 
 
function LeftStr(const AText: string; const ACount: Integer): string; overload;
function RightStr(const AText: string; const ACount: Integer): string; overload;
function MidStr(const AText: string; const AStart, ACount: Integer): string; overload;
function ReverseString(const AText: string): string;
function SplitString(const S, Delimiters: string): TStringDynArray;
 
function IfThen(AValue: Boolean; const ATrue: string; AFalse: string = ''): string; overload;  

Integer / Float

System

是否為奇數
function Odd(X: Integer): Boolean;
 
procedure Inc(var X: Integer); 
procedure Inc(var X: Integer; N: Integer);

 

System.SysUtils

function StrToIntDef(const S: string; const Default: Extended): Extended;
function StrToFloatDef(const S: string; const Default: Extended): Extended;
function TryStrToFloat(const S: string; out Value: Extended): Boolean;
function TryStrToCurr(const S: string; out Value: Currency): Boolean;
function TryStrToInt(const S: string; out Value: Integer): Boolean; overload;

 

System.Math

平方
function Power(const Base, Exponent: Double): Double;
 
將變數向上捨入至正無窮大。
function Ceil(const X: Double): Integer; 
 
將變數向負無窮方向舍入。
function Floor(const X: Double): Integer;  
 
Form.Width / 2 回傳浮點數
Form.Width div 2 回傳整數值 (不計小數)

function Max(const A, B: Integer): Integer; overload;
function MaxValue(const Data: array of Double): Double; overload;
function MaxIntValue(const Data: array of Integer): Integer;
function Min(const A, B: Integer): Integer; overload;
function MinValue(const Data: array of Double): Double; overload;
function MinIntValue(const Data: array of Integer): Integer;
function InRange(const AValue, AMin, AMax: Int64): Boolean; overload;

取整數
function Int(const X: Extended): Extended;

取小數
function Frac(const X: Extended): Extended;

判斷正/負號
function Sign(const AValue: Integer): TValueSign; 

Array中的平均值
function Mean(const Data: array of Single): Single;

function IfThen(AValue: Boolean; const ATrue: Integer; const AFalse: Integer = 0): Integer; overload;


Datetime

System.DateUtils

function IsPM(const AValue: TDateTime): Boolean; 
function IsAM(const AValue: TDateTime): Boolean;
function IsValidDate(const AYear, AMonth, ADay: Word): Boolean;
 
傳回指定 TDateTime 值所在年份的週數。
function WeeksInYear(const AValue: TDateTime): Word;
 
傳回指定年份的週數。
function WeeksInAYear(const AYear: Word): Word;       
 
傳回指定 TDateTime 值所在年份的天數。
function DaysInYear(const AValue: TDateTime): Word; 
 
傳回指定年份的天數。
function DaysInAYear(const AYear: Word): Word; 
 
傳回指定月份的天數。
function DaysInMonth(const AValue: TDateTime): Word;
 
傳回指定年份的指定月份的天數。
function DaysInAMonth(const AYear, AMonth: Word): Word;
 
function Today: TDateTime;
function Yesterday: TDateTime;
function Tomorrow: TDateTime;
 
function YearOf(const AValue: TDateTime): Word;
function MonthOf(const AValue: TDateTime): Word;
function WeekOf(const AValue: TDateTime): Word;           
function DayOf(const AValue: TDateTime): Word;
function HourOf(const AValue: TDateTime): Word;
function MinuteOf(const AValue: TDateTime): Word;
function SecondOf(const AValue: TDateTime): Word;
function MilliSecondOf(const AValue: TDateTime): Word;
function StartOfTheMonth(const AValue: TDateTime): TDateTime;
function EndOfTheMonth(const AValue: TDateTime): TDateTime;
function StartOfAMonth(const AYear, AMonth: Word): TDateTime;
function EndOfAMonth(const AYear, AMonth: Word): TDateTime;
function StartOfTheWeek(const AValue: TDateTime): TDateTime; 
function EndOfTheWeek(const AValue: TDateTime): TDateTime;  
function StartOfAWeek(const AYear, AWeekOfYear: Word;const ADayOfWeek: Word = 1): TDateTime;
function EndOfAWeek(const AYear, AWeekOfYear: Word;const ADayOfWeek: Word = 7): TDateTime;
 
function YearsBetween(const ANow, AThen: TDateTime): Integer;
function MonthsBetween(const ANow, AThen: TDateTime): Integer;
function WeeksBetween(const ANow, AThen: TDateTime): Integer;
function DaysBetween(const ANow, AThen: TDateTime): Integer;
function HoursBetween(const ANow, AThen: TDateTime): Int64;
function MinutesBetween(const ANow, AThen: TDateTime): Int64;
function SecondsBetween(const ANow, AThen: TDateTime): Int64;
function MilliSecondsBetween(const ANow, AThen: TDateTime): Int64;
 
function IncYear(const AValue: TDateTime; const ANumberOfYears: Integer = 1): TDateTime; inline;
function IncWeek(const AValue: TDateTime;const ANumberOfWeeks: Integer = 1): TDateTime; inline;

指定天數偏移的日期 
function IncDay(const AValue: TDateTime; const ANumberOfDays: Integer = 1): TDateTime; inline;
 
function IncHour(const AValue: TDateTime; const ANumberOfHours: Int64 = 1): TDateTime; inline;
function IncMinute(const AValue: TDateTime; const ANumberOfMinutes: Int64 = 1): TDateTime; 
function IncSecond(const AValue: TDateTime; const ANumberOfSeconds: Int64 = 1): TDateTime;
function IncMilliSecond(const AValue: TDateTime; const ANumberOfMilliSeconds:Int64 = 1): TDateTime;


File/Fold

System.SysUtil

資料夾是否存在.
function DirectoryExists(const Directory: string; FollowLink: Boolean = True): Boolean;

檔案是否存在
function FileExists(const FileName: string; FollowLink: Boolean = True): Boolean;

檔案放置的資料夾
function ExtractFileDir(const FileName: string): string;

檔案放置的路徑
function ExtractFilePath(const FileName: string): string;

檔案放置的磁碟代號
function ExtractFileDrive(const FileName: string): string;

檔案名稱
function ExtractFileName(const FileName: string): string;

變更副檔名
function ChangeFileExt(const FileName, Extension: string): string;

檔案是否唯讀
function FileIsReadOnly(const FileName: string): Boolean;

檔案設定唯讀
function FileSetReadOnly(const FileName: string; ReadOnly: Boolean): Boolean;

刪除檔案
function DeleteFile(const FileName: string): Boolean;

檔案名稱更名
function RenameFile(const OldName, NewName: string): Boolean;

檔案搜尋
function FileSearch(const Name, DirList: string): string;

目前的使用路徑
function GetCurrentDir: string;

設定目前的使用路徑
function SetCurrentDir(const Dir: string): Boolean;

建立資料夾(樹狀)
function ForceDirectories(Dir: string): Boolean;

建立資料夾
function CreateDir(const Dir: string): Boolean;

移除資料夾
function RemoveDir(const Dir: string): Boolean;