bestlong 怕失憶論壇's Archiver

bestlong 發表於 2010-3-30 16:53

TQRDBText 中文不會自動換行

設計 QuickReport 的報表

已將 QRDBText 元件的屬性設定如下:

AutoSize := False;
AutoStretch := True;
WordWrap := True;

在英文資料時會換行,但在中文資料時就沒有換行

bestlong 發表於 2010-3-30 17:01

只好手動處理[code]
procedure AutoWrapRow(wide: integer; var value: string);
var
   tempArr: Array of string;
   wideLen, i, j: integer;
   s: WideString;
begin
   j := 1;
   s := value;
   widelen := length(s);
   SetLength(tempArr, j);
   tempArr[0] := '';
   for i := 1 to wideLen do
      begin
         if Length(tempArr[j-1]) + Length(s[i]) > wide then
            begin
               j := j + 1;
               setlength(tempArr, j);
               tempArr[j-1] := s[i];
            end
         else
            begin
                tempArr[j-1]:= tempArr[j-1] + s[i];
            end;
      end;
   s := '';
   for i := 0 to Length(tempArr)-2 do
       s := s + tempArr[i] + chr(13);
   value := s + tempArr[Length(tempArr)-1];
   tempArr := nil;
end;
[/code]請在 QRDBText 的 OnPrint 事件中呼叫 AutoWrapRow() 來處理換行,中文不會亂碼[code]
procedure TForm1.QRDBText9Print(sender: TObject; var Value: String);
begin
  AutoWrapRow(24, Value); // 24 為一行的字數
end;
[/code]其他的 Quick Report 元件 QRLabel, QRMemo, QRDBMemo...等等也都適用,不過就是要自行量測可以列印的字數寬度。

bestlong 發表於 2010-3-30 17:17

看到另一個辦法就是放一個 TMemo 元件來幫忙負責換行,把換好行後的 Lines 再 Assign 回來即可。[code]
procedure TqrWeekQA.QRDBTxtInTimePrint(sender: TObject; var Value: String);
var  I: Integer;
begin
  with Sender as TQRDBText do
  begin
    meCutWord.Font.Assign(Font); //指定字型
    meCutWord.Width := Width;    //指定寬度
    meCutWord.Lines.Clear;       //清除上一次的東西
    meCutWord.Lines.Text := Value; //把 value assign 進去
    Value := meCutWord.Lines.Strings[0];
    for I := 1 to meCutWord.Lines.Count - 1 do
    begin
      Value := Value + #13 + meCutWord.Lines.Strings; //逐行取出再塞回去
    end;
  end;
end;
[/code]參考來源
[url]http://vclxx.org/forum/index.php?topic=22428.0[/url]

bestlong 發表於 2010-3-30 20:35

一個更簡單的方法:
1. 加一個 TQRRichText
2. 在該 TQRRichText 的 band 的 BeforePrint 事件中,加入以下以下程式碼[code]
procedure TForm1.QRBand1BeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean);
begin
  QRRichText1.Lines.Clear;
  QRRichText1.Lines.Add(Query1.FieldByName(欄位名稱).AsString);
end;
[/code]參考來源
[url]http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=41104[/url]
[url]http://delphi.ktop.com.tw/board.php?cid=30&fid=100&tid=44298[/url]

bestlong 發表於 2010-3-30 20:47

QuickReport里TQRText对中文居然不能正确换行,即使设置了WordWarp属性为True。QuickReport就是Bug多多,现在Delphi已经改带Rave,QuickReport已经被抛弃了,估计它的开发工作也快停止了。可是有时候遇到历史遗留问题,还是不得不面对它的。为了这个不能换行的问题郁闷了好久。有人采用直接改正QuickReport源代码里的AddWord方法,似乎一劳永逸啊,可是改起来还是有点难度的。当多人合作的时候,其他人也得改。在网上看到一个利用TMemo的自动换行功能来解决问题的方法,感觉不错。我也想过相似的思路,不过我想的是TRichEdit。不过发现一个bug,TRichEdit里不能显示字符“°”(度数 ),TQRRichText也一样,会出现“RichEdit line insert error”。恰好我做的报表包括字符“°”,恰好撞上,所以我的方法失败了。估计这是Borland在实现TRichEdit时的Bug。而TMemo就可以显示“°”。
具体说一下利用TMemo的解决方法:
1.在报表所在的Form上放一个TMemo控件Memo1,一个就够,由它来负责解决换行问题
2.在需要显示换行的字段的地方用TQRMemo替代TQRDBText,并调整好TQRMemo的长度和宽度(显示字段的最大范围);
3.在TQRMemo所在的band的BeforePrint事件中调用PrepareQRMemo[code]
procedure TForm1.DetailBand1BeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean);
begin
...
PrepareQRMemo(qrmmBZ, '备注');
...
end;

procedure TForm1.PrepareQRMemo(aQRMemo: TQRMemo; FieldName: string);
begin
  Memo1.Lines.Clear;
  Memo1.Width := aQRMemo.Width;
  Memo1.Lines.Text := ds.FieldByName(FieldName).AsString;
  aQRMemo.Lines.Assign(Memo1.Lines);
end;
[/code]參考來源 [url]http://arming.ycool.com/post.610253.html[/url]
頁: [1] 2

Powered by Discuz! X1.5 Archiver   © 2001-2010 Comsenz Inc.