QRShapeの動的生成

解決


take  2006-05-16 07:09:06  No: 21546

QuickReportで非DBの単一情報の印刷をするためにQRLabelやQRShapeの動的生成&配置を試してますが、QRShapeの方が上手く表示されません。
環境上、プリントアウトの実験はできてないんですが、よろしく御願いします。

procedure TForm1.Button1Click(Sender: TObject);
var
  CreateLabel:TQRLabel;
  Rect: Trect;
  CreateShape:TQRShape;
begin
  CreateLabel := TQRLabel.Create(Unit2.QuickReport2);
  CreateLabel.Parent := unit2.QuickReport2;
  Rect.Left := 0;
  Rect.Right:= 0;
  Rect.Top  := 10;
  Rect.Bottom:=10;
  CreateLabel.BoundsRect := Rect;
  CreateLabel.Caption := 'TEST';
  CreateLabel.Name := 'LABELX1';
  //成功!

  CreateShape := TQRShape.Create(Unit2.QuickReport2.TitleBand1);
  CreateLabel.Parent := unit2.QuickReport2.TitleBand1;
  Rect.Top := 50;
  Rect.Left:= 50;
  Rect.Right:=100;
  Rect.Bottom:=100;
  CreateShape.BoundsRect := Rect;
  CreateShape.Name := 'SHAPEX';
  //失敗!
  QuickReport2.Preview;
end;

環境Win2000+Delphi7


igy  2006-05-17 02:52:43  No: 21547

>  CreateShape := TQRShape.Create(Unit2.QuickReport2.TitleBand1);
>  CreateLabel.Parent := unit2.QuickReport2.TitleBand1;

×:CreateLabel.Parent := unit2.QuickReport2.TitleBand1;
○:CreateShape.Parent := unit2.QuickReport2.TitleBand1;

ですか?


take  2006-05-17 06:41:06  No: 21548

失礼しました!
お恥ずかしい超恥ずかしいミスです。
ありがとうございます。

恥ずかしいついでに聞いていいですか?
OnNeedDataイベントはなぜ2周するんでしょうか?
できればここにCreate文を挿入したいんですが、2周繰り返してダブってしまいます。文末にMoreData := False;にしても今度はレポートが生成されなくなるし。


igy  2006-05-17 09:04:31  No: 21549

>2周繰り返してダブってしまいます。
他のイベントでCreateするのでは、だめですか?


take  2006-05-17 18:32:35  No: 21550

やってみましたが、新たな問題があります。
サイズの変更に際して、動的に位置決めをしたいので、アプリ起動時にCreateしたものをPrint&Preview前に再度呼び出してプロパティを設定したいのです。
が、以下のコードだとメモリーエラーになります。
ログを探しているのですが、自分に理解できる内容のモノがみつかりません。

//起動時(Form2にQuickReportを配置)
procedure TForm2.FormCreate(Sender:TObject);
var
  CreateLabel: TQRLabel;
begin
  CreateLabel := TQRLabel.Create(QuickRep);
  CreateLabel.Parent := QuickRep;
  CreateLabel.Name := 'QLabelX';
end;

//印刷前
//procedure TForm2.BeforePrint(Sender: TCustomQuickRep;var PrintReport: Boolean);
begin
  TQRLabel('QLabelX').Caption := '出力文字';
  TQRLabel(FindComponent('QLabelX')).Caption := '出力文字';
end;

procedure TForm1.PreviewButton(Sender:TObject);
begin
  QucikRep.Preview;
end;

自分でも「FindComponent」や「動的生成」などで探してはいるんですが…
f(^_^;)


スコープ?  2006-05-17 18:56:44  No: 21551

詳細に考えませんでしたが、なんとなく、各クラスのインスタンス・ポインタ(つまり変数)のスコープが変なような気が・・・。。

>procedure TForm2.FormCreate(Sender:TObject);
>var
>  CreateLabel: TQRLabel;

これはこうでなかのかなぁ.....?

var
  CreateLabel: TQRLabel;
procedure TForm2.FormCreate(Sender:TObject);

クリエートしてメソッド完了とともに破棄(つまりnilスタック)になってる....そんな気がしてなりません。はずしてたらすみません。


igy  2006-05-17 19:00:35  No: 21552

>procedure TForm2.FormCreate(Sender:TObject);
>var
>  CreateLabel: TQRLabel;

の CreateLabel: TQRLabel; を

 TForm2 = class(TForm)
    ..
  private
    { Private 宣言 }
    CreateLabel: TQRLabel;  // <== ここ
    ..
  end;

のように移動し、

>//procedure TForm2.BeforePrint(Sender: TCustomQuickRep;var PrintReport: Boolean);
>begin
>  TQRLabel('QLabelX').Caption := '出力文字';
>  TQRLabel(FindComponent('QLabelX')).Caption := '出力文字';
>end;

の部分を

//procedure TForm2.BeforePrint(Sender: TCustomQuickRep;var PrintReport: Boolean);
var
        cp: TComponent;
begin
        cp := FindComponent('CreateLabel');
        if cp <> Nil then
        begin
                TQRLabel(cp).Caption := '出力文字';
        end;
end;

にしてはどうでしょう?


take  2006-05-17 19:20:06  No: 21553

一度破棄してしまうとそれを拾い出すことってできないんですか?
ちなみに、LOOPでvar CreateLabel:TQRLabel;
を使い回して生成してるんですが、それだとすべて破棄していることになるんですね?


igy  2006-05-17 20:01:41  No: 21554

さきほど
>cp := FindComponent('CreateLabel');
としていたのは
cp := FindComponent('QLabelX');
でした。すみません。

で、
>procedure TForm2.FormCreate(Sender:TObject);
>var
>  CreateLabel: TQRLabel;
>begin
>  CreateLabel := TQRLabel.Create(QuickRep);
>  CreateLabel.Parent := QuickRep;
>  CreateLabel.Name := 'QLabelX';
>end;

procedure TForm2.FormCreate(Sender:TObject);
begin
  with TQRLabel.Create(Self) do
  begin
    Parent := QuickRep;
    Name := 'QLabelX';
  end;
end;

にして、

>  TQRLabel('QLabelX').Caption := '出力文字';

をコメントアウト
//   TQRLabel('QLabelX').Caption := '出力文字';
した場合は、どうです?


寿命  2006-05-17 20:36:16  No: 21555

スコープというより「寿命」の問題。

  手続き/関数内で宣言した変数は、その手続き/関数を抜けると消滅する

これがわかれば、変数をどこで宣言すべきは自明。


インスタンス  2006-05-17 20:42:54  No: 21556

ただし、クリエートしたインスタンスそのものはメモリ中に残るので、どこでどのように破棄するべきかはよーく考えないと。


take  2006-05-17 21:10:27  No: 21557

こんな感じになりました。

procedure TForm2.FormCreate(Sender: TObject);
var
  cnt:Integer;
begin
  for cnt := 1 to 10 do
  begin
    with TQRLabel.Create(Self) do
    begin
      Parent := QuickRep;
      Name := 'QLabel' + IntToStr(cnt);
    end;
  end;
end;

procedure TForm2.QuickRepBeforePrint(Sender: TCustomQuickRep;
  var PrintReport: Boolean);
var
  cp: TComponent;
  cnt:Integer;
begin
  for cnt := 1 to 10 do
  begin
    cp := FindComponent('QLabel' + IntToStr(cnt));
    TQRLabel(cp).Caption := IntToStr(cnt);
    TQRLabel(cp).Top  := 10 * cnt;
    TQRLabel(cp).Left := 10 * cnt;
  end;
end;

これならPrivate管理しなくて済みますね。
この後、QRShapeと併せて管理したかったので、これなら楽で助かります。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加