QuickRep做報表換行問題。急需您的幫助! (100分)

其实还是用其它报表控件吧!!!!
 
我今天仔细搞了一下,实在是老火+++
可以实现高度不一致,但不是按自己的意思来的,设置了 detailband的 height,qrshape的height也跟它一致,可死活接不到一块。实在是烂啊——
procedure TForm2.DetailBand1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
var
s,y,i:integer;
begin
s:=currheight;
canvas.font.Name:='宋体';
canvas.font.size:=10;
maxlength:=canvas.textwidth(form1.table1.fields[1].asstring)+4;
if maxlength > currwidth then
begin
y:=maxlength mod currwidth;
if (y<>0) then
y:=maxlength div currwidth+1;
s:=y * currheight;
end;

Sender.Height:=s;
for i:=DetailBand1.ControlCount-1do
wnto 0do
if DetailBand1.Controls is TQRShape then
(DetailBand1.Controls as TQRShape).Height:=Sender.Height+5;
end;

procedure TForm2.QuickRep1NeedData(Sender: TObject;
var MoreData: Boolean);
begin
with form1do
begin
if not table1.eof then
begin
qrlabelbh.Caption:=table1.Fields[0].asstring;
qrlabelmc.Caption:=table1.Fields[1].asstring;
qrlabelsj.Caption:=table1.Fields[2].asstring;
qrlabeldw.Caption:=table1.Fields[3].asstring;
table1.next;
end;
MoreData:=not table1.eof ;
end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
maxheight:=canvas.textheight('Aa');
end;
 
初学帮顶。
 
在报表中使用QRRichText1 控件可以表达折行字段内容
在报表中加入QRRichText1 控件,设其属性:AutoStretch:True(回行为真),在控件所在条中的DetailBand1/BeforePrint:中写入代码:
QRRichText1.Lines.clear;
//清除
QRRichText1.Lines.Add(CustomerData.Query_zsmxdy_zsbhdy_zzfjb.fieldbyname('Xxdz').asstring);
可将CustomerData.Query_zsmxdy_zsbhdy_zzfjb.fieldbyname('Xxdz').asstring中内容显示出来,需要折行时自动折行。
*如果配合:测试字符串长度可形成:长则两行,短则一行显示
*在表格中一个位置放两个控件:QRRichText1和QRDBText3
*超过30字符QRDBText3为白字,不足30字符QRRichText1为白字
QRRichText1.Lines.Clear ;
if strlen(pchar(Query1.fieldbyname('gcmc').asstring))>=30 then
begin
QRRichText1.Lines.Text :=Query1.fieldbyname('gcmc').asstring ;
QRRichText1.Font.Color :=clWindowText;
QRDBText3.Font.Color :=clWindow;
end
else
begin
QRRichText1.Font.Color :=clWindow;
QRDBText3.Font.Color :=clWindowText;
end;
此例绝对可靠,用过不只一次了。
 
to tjlqp
你挺厉害的,有高见,麻烦您把你做的报表发给我一份好吗,你写的我看不太明白,谢谢您了,等待您的答复!
邮箱:lijw@mail.csoft.com.cn
 
tjlqp
3.09的QuickRep中的QRDBTEXT能夠自動換行(中文也可以自動換行),現在問題是要使qrsharp能跟著換行一起變化高度. 請問怎樣解決QRShape的高度隨著換行的高度變化而變化呢?
請email實例給我。weifang888@126.com 萬分感謝!
 
他那是换行吧——QRDBText就行了。
我有个例子实现了这个,但很不理想。跟我上面的有点相似
 
換行是很好解決的。問題是怎樣解決QRShape的高度隨著換行的高度變化而變化?
 
function AdjustQRDBText(Canvas:TCanvas;QRBand:TQRBand;QRDBText:TQRDBText;var BandHeight:Integer;var Value:string):string;
var
strValue,strTmp:Widestring;
i,intValue:integer;
iTextWidth,iQRDBTextWidth:integer;
iLines,iLineZiCount:Integer;
iSlgZI:Integer;
iTmpBandHeight,intPos:Integer;
begin
iSlgZI:=Canvas.TextHeight('我');
//得到单个字的宽度
strValue:=Trim(WideString(value));
intValue:=Length(strValue);
//得到输入文本的字数
iTextWidth:=Canvas.TextWidth(strValue);
//输入的文本宽度
iQRDBTextWidth:=QRDBText.Width;
//文本框的宽度,去除两边的宽度
iLineZiCount:=iQRDBTextWidth div iSlgZI;
//得到每一行的字数
iLines:=intValue div iLineZiCount+1;
//计算文本的行数
strTmp:='';
intPos:=1;
for I:=0 to iLines-1do
begin
//LineCount:=
if I<iLines-1 then
strTmp:=strTmp+Copy(strValue,intPos,iLineZiCount)+#10#13
else
strTmp:=strTmp+Copy(strValue,intPos,iLineZiCount);
intPos:=intPos+iLineZiCount;
end;
value:=strTmp;

QRDBText.top:=5;
QRDBText.Height:=iLines*iSlgZi;
//得到文本框的高度
iTmpBandHeight:=iSlgZi*(iLines+1);
//此处BAND的计算高度
if QRBand.Height<iTmpBandHeight then
QRBand.Height:=iTmpBandHeight;
for I:=0 to QRBand.ControlCount-1do
begin
if QRBand.Controls is TQRShape then
if TQRShape(QRBand.Controls).Shape=qrsVertLine then
begin
TQRShape(QRBand.Controls).Height:=QRBand.Height;
TQRShape(QRBand.Controls).Top:=0;
end;
end;
end;
 
//---------------------------------------------------------------------------
//控 件 包:Quickreport附加控件
//控件名称:QrText
//控件作者:along(阿龙)
//Eamil :longyunqiang@163.com;
longyunqiang@163.net
//发布类型:免费控件
//最后更新:2003.10.29
//---------------------------------------------------------------------------
// 主要功能:
// 改进了QRlabel的换行,可实现文字自动换行,且可设置行间距。
//---------------------------------------------------------------------------
//使用:使用方法与Quickreport的QRlabel相似。
//主要属性:
// text:要打印的文字内容。
// linespace:行间距(单位:点)。
//---------------------------------------------------------------------------
unit QRtext;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Graphics, QuickRpt;
type
TQRtext = class(tqrprintable)
private
Ftext: string;
//要显示的内容(内部用的变量)
Flinespace: integer;
//行间距(内部用的变量)
Fcount: integer;
//一行中的字数
procedure setftext(value: string);
//显示内容(将属性表的数据给内容变量)
procedure setFlinespace(value: integer);
//设置行间距(将属性表的数据给行间距变量)
function FormatLine(const oldLine: string;
const LineLength: integer): string;
//分行函数
{ Private declarations }
protected
procedure Paint;
override;
//显示数据
procedure Print(OfsX, OfsY: integer);
override;
//打印数据
{ Protected declarations }
public
constructor Create(AOwner: TComponent);
override;
destructor Destroy;
override;
{ Public declarations }
published
property text: string read Ftext write setftext;
//显示内容(将属性表的数据)
property linespace: integer read Flinespace write setFlinespace;
//设置行间距(将属性表的数据)
property font;
//设置字体
{ Published declarations }
end;

procedure Register;
implementation
procedure Register;
begin
RegisterComponents('QReport', [TQRtext]);
end;

{ TQRtext }
constructor TQRtext.Create(AOwner: TComponent);
begin
inherited;
width := 30;
height := 20;
Ftext := 'Text';
font.Name := '宋体';
font.Size := 10;
end;

destructor TQRtext.Destroy;
begin
inherited;
end;

procedure TQRtext.Paint;
var
list1, list2: Tstrings;
i, y, fontheight: integer;
begin
inherited;
//执行父类的动作。画边框
//清除显示
canvas.Brush.Style := bssolid;
canvas.Brush.Color := clwhite;
canvas.FillRect(canvas.ClipRect);
if length(Ftext) <= 0 then
exit;
//无字符要显示则退出
canvas.Font := font;
fontheight := canvas.TextHeight('字');
//求得每行高度
Fcount := width div canvas.TextWidth('字');
//求得每行字数
list1 := Tstringlist.create;
//用于分行
list2 := Tstringlist.create;
//用于显示
list1.Text := text;
//先处理手工分行的字符。
//然后再对每一行进行自动分行。
for i := 0 to list1.Count - 1do
list2.Text := list2.Text + formatline(list1.Strings, fcount * 2);
//处理显示
y := 0;
for i := 0 to list2.Count - 1do
begin
canvas.TextOut(0, y, list2.Strings);
//显示字符
y := y + fontheight + Flinespace;
//下一行的位置=上一行的位置+字高+行间距
end;
list1.Free;
list2.Free;
height := y;
end;

procedure TQRtext.print(OfsX, OfsY: integer);
var
list1, list2: Tstrings;
i, y, fontheight: integer;
begin
inherited;
//执行父类的动作。画边框
with qrprinterdo
begin
if length(Ftext) = 0 then
Ftext := ' ';
canvas.Font := font;
fontheight := canvas.TextHeight('字');
//求得每行高度
Fcount := width div canvas.TextWidth('字');
//求得每行字数
list1 := Tstringlist.create;
//用于分行
list2 := Tstringlist.create;
//用于显示
list1.Text := text;
//先处理手工分行的字符。
//然后再对每一行进行自动分行。
for i := 0 to list1.Count - 1do
list2.Text := list2.Text + formatline(list1.Strings, fcount * 2);
//处理显示
y := ypos(size.Top + ofsy);
for i := 0 to list2.Count - 1do
begin
canvas.TextOut(xpos(size.left + ofsx), y, list2.Strings);
//显示字符
y := y + fontheight + Flinespace;
//下一行的位置=上一行的位置+字高+行间距
end;
end;
list1.Free;
list2.Free;
end;

procedure TQRtext.setFlinespace(value: integer);
begin
Flinespace := value;
paint;
//值改变后重新显示数据
end;

procedure TQRtext.setftext(value: string);
begin
if Ftext <> value then
begin
Ftext := value;
paint;
//值改变后重新显示数据
end;
end;

function TQRtext.FormatLine(const oldLine: string;
const LineLength: integer): string;
var
Line: string;
NewLine, ReturnLine: string;
cnumber, number, theLength, j: integer;
begin
line := oldLine;
NewLine := '';
ReturnLine := '';
cnumber := 0;
number := 0;
theLength := Length(line);
j := 1;
while (j <= theLength)do
begin
if (LineLength <= number) then
//需要分行了
begin
if ((j > 1) and (line[j - 1] < #$80) and (line[j] < #$80)) then
//这个判断不适合big5码
begin
//前面一个与现在字符都不是中文字符
if (line[j - 1] = ' ') then
begin
if (line[j] <> ' ') then
begin
ReturnLine := ReturnLine + NewLine + #13#10;
NewLine := line[j];
number := 1;
cnumber := 0;
Inc(j);
continue;
end
else
begin
Inc(j);
continue;
end;
end
else
begin
//前面一个字符是英文,现在的字符也是英文或空格,不分段
NewLine := NewLine + line[j];
cnumber := 0;
Inc(j);
continue;
end;
end
else
if (0 = (cnumber mod 2)) then
//有个什么函数可以直接判断的来着
begin
ReturnLine := ReturnLine + NewLine + #13#10;
NewLine := line[j];
number := 1;
if (line[j] >= #$80) then
cnumber := 1;
Inc(j);
continue;
end
else
begin
//是中文字符的后半个字符
NewLine := NewLine + line[j];
cnumber := 0;
Inc(j);
continue;
end;
end
else
//长度小于等于LineLength
begin
NewLine := NewLine + line[j];
if (line[j] >= #$80) then
begin
Inc(cnumber);
Inc(number);
end
else
begin
Inc(number);
cnumber := 0;
if (j < theLength) and (line[j + 1] >= #$80) and (1 = number mod 2) then
begin
//如果下一个是中文,而现在为奇数,则补一个空格
NewLine := NewLine + ' ';
Inc(number);
end;
end;
Inc(j);
continue;
end;
end;
ReturnLine := ReturnLine + NewLine + #13#10;
Result := ReturnLine;
end;

end.

 
各位高手:
  我是要怎樣解決QRShape的高度隨著換行的高度變化而變化的問題?
 
我给你的控件已解决这个问题。
 
对qreport附件开发能能够解决。
 
lyq2276959
好的,請發我信箱:weifang888@126.com 謝謝!
 
已经在上面了啊——
 
hongxing_dl兄:
   這倆天倒霉,感冒啦,頭疼。不想動!請把lyq2276959高手的代碼做一份實例給我。非常感謝!
 
哦————————注意身体呀
我试过他的代码(qrtext控件,就将上面他的帖子全部复制到新建的 unit中,然后安装就可以了),跟qrlabel的效果也没什么区别(在delphi4下是这样的)
所以还是不能解决吧::::)
 
还在生病吗?
我已经搞好了,好了——————————————————
 
to hongxing_dl
我是菜鸟,你做好的,能给我一份吗,求求您了!
lijw@mail.csoft.com.cn
 
邮件已发出:))))
>sail_world:
呵呵——
hao a ---先记下,肯定会有你的——
 
顶部