View Full Version : سوال: ریست کردن گزارش (بازگشت به حالت اولیه)
sara.mahdavi
دوشنبه 28 مرداد 1392, 19:28 عصر
با سلام:لبخندساده:
من یک گزارش درست کردم و در محیط اجرا یک سری شئ به اون اضافه میکنم
حالا چطوری اون اشیائی که اضافه کردم رو در همون محیط اجرا پاک کنم و به حالت اولیه دربیارم؟؟؟
با تشکر:چشمک:
naderanhari
دوشنبه 28 مرداد 1392, 19:37 عصر
از چه ابزار گزارشگیری استفاده میکنی؟
یوسف زالی
دوشنبه 28 مرداد 1392, 22:09 عصر
سلام.
چند تا راه داری:
1- استفاده از متد های Clear
2- استفاده از فری کردن و دوباره ساختن شی ریپورت
3- لود کردن یک ریپورت خالی
4- دسریالایز یک سریالایز ریپورت خالی
5- ...
sara.mahdavi
سه شنبه 29 مرداد 1392, 09:33 صبح
از چه ابزار گزارشگیری استفاده میکنی؟
عذرخواهی می کنم که یادم رفت بنویسم
از FastReport استفاده میکنم
sara.mahdavi
سه شنبه 29 مرداد 1392, 09:36 صبح
سلام.
چند تا راه داری:
1- استفاده از متد های Clear
2- استفاده از فری کردن و دوباره ساختن شی ریپورت
3- لود کردن یک ریپورت خالی
4- دسریالایز یک سریالایز ریپورت خالی
5- ...
ممنونم ازتون :قلب:
اگه امکان داره یکی از همین موارد رو بیشتر توضیح بدید چون من در این مورد چیزی نمیدونم:ناراحت:
با تشکر
یوسف زالی
سه شنبه 29 مرداد 1392, 11:19 صبح
ببینید همون طور که قبلا هم دیدیم اشیای طراحی شده در بدنه شی FrxReport باقی می مونند، به همین دلیل برای خالی کردنش کافیه این شی رو خالی کنیم.
روش اول:
frxReport1.DataSets.Clear;
frxReport1.EnabledDataSets.Clear;
frxReport1.Variables.Clear;
frxReport1.Script.Clear;
frxReport1.Clear;
sara.mahdavi
سه شنبه 29 مرداد 1392, 12:10 عصر
ببینید
من توی محیط اجرا با یک دکمه چند line به گزارش اضافه میکنم
حالا میخوام با یک دکمه دیگه همین Line هایی که اضافه کردم رو پاک کنم
آیا این روش جواب میده؟
من همین دستوراتی که نوشتید رو توی دکمه دومم نوشتم ولی جواب نمیده و فکر میکنم تمام اطلاعات گزارشم رو پاک میکنه درصورتی که من میخوام فقط همون Line ها پاک بشه
ممنون
یوسف زالی
سه شنبه 29 مرداد 1392, 12:48 عصر
خودتون گفتید گزارش به حالت اول برگرده دیگه.
ولی اگر منظور از حالت اول، حالتیه که خودتون توش چیزهایی دارید، روش های 3 و 4 کارتون رو راه می ندازه.
برای این منظور بهتره گزارش حالت اولیه رو در یک استریم ذخیره کنید، کارهاتون رو انجام بدید و برای بازگشت به نقطه ی اولیه، دوباره از همون استریم لود کنید.
sara.mahdavi
سه شنبه 29 مرداد 1392, 12:55 عصر
بله شما درست میگید شاید منظورم رو درست نرسونده بودم
من این روشی که شما فرمودید رو بلد نیستم و با این حالت امتحان کردم که :
وقتی فرمم اجرا میشه با دستور
frxrprt_PDF.SaveToFile('C:/Temp');
گزارشم رو ذخیره کردم
و بعد از دستور
frxrprt_PDF.Clear;
frxrprt_PDF.LoadFromFile('C:/temp') ;
دوباره گزارشم رو لود کردم
حالا نمیدونم درست عمل کردم یا نه؟
ولی خودم دوس دارم این اتفاق توی برنامه بیوفته و اینطوری بیرون از برنامه فایلی ایجاد نکنم:ناراحت:
یوسف زالی
سه شنبه 29 مرداد 1392, 13:11 عصر
به جای فایل بنویسید استریم.
SaveToStream
متد Clear هم در اینجا اجباری نیست.
sara.mahdavi
سه شنبه 29 مرداد 1392, 13:21 عصر
به جای فایل بنویسید استریم.
SaveToStream
متد Clear هم در اینجا اجباری نیست.
خب وقتی که بجای فایل از استریم استفاده میکنم SaveToStream(دراین قسمت) از من یک داده از نوع استریم میخاد، باید چی بذارم؟
یوسف زالی
سه شنبه 29 مرداد 1392, 13:36 عصر
خب یک استریم بذار!
یک شی از TMemoryStream خوبه.
sara.mahdavi
سه شنبه 29 مرداد 1392, 13:57 عصر
خب یک استریم بذار!
یک شی از TMemoryStream خوبه.
اینطوری گذاشتم
var
s:TMemoryStream ;
frxrprt_PDF.SaveToStream(s);
ولی ارور میده:ناراحت:
یوسف زالی
سه شنبه 29 مرداد 1392, 14:47 عصر
کجا استریم رو Create کردید؟
شی هست ها! :لبخند:
باید اول بسازیدش بعد هم که برنامتون داره بسته می شه فری کنید.
sara.mahdavi
سه شنبه 29 مرداد 1392, 15:02 عصر
خب شما با من مثل حرفه ای ها رفتار میکنید:ناراحت:
من هنوز مبتدی هستماااااا
مثلا الان برای Create کردن دقیقا نمیدونم باید چیکار کنم بعد شما میگید کجا ایکارو کردم:ناراحت:
یوسف زالی
سه شنبه 29 مرداد 1392, 15:59 عصر
ببین برای کار کردن با یک "شی" (و نه متغیر - رکورد - ثابت - پوینتر - ..) باید قبل از کار باهاش اون رو "دارای حافظه" کنید. این کار رو با متدهای سازنده (معمولا با نام Create) از کلاس مشتق شده انجام می دند.
وقتی شما می گی B: TButton این B هیچ چی نیست! تا وقتی که بگید: B := TButton.Create حالا با یک سری پارامتر ها.
بعد از این لحظه B "اشاره می کنه" به یک جایی از حافظه که توش یک "شی" قرار داره.
وقتی دکمه رو می ذاری رو فرم؛ دلفی خودش براتون این کارا رو انجام می ده ولی در حالت ران تایم باید شما بهش بگی ..
در این مثال:
S := TMemoryStream.Create;
بعد می تونی باهاش کار کنی.
بعد از تموم شدن کار باهاش باید اون حافظه رو "آزاد" کنید. اگر این کار رو نکنید و به دلفی هم نسپرید (فعلا بی خیال این یک تیکه!) اون وقت بعد از تموم شدن اجرای برنامه، اون تیکه از حافظه تا شات دان شدن سیستم غیر قابل استفاده می شه. به این حالت می گن "Memory Leak" یا نشت حافظه.
برای همین باید بعد از تموم شدن کار باهاش بگید:
S.Free
همین!
sara.mahdavi
سه شنبه 29 مرداد 1392, 19:58 عصر
ممنون بابت این توضیحتون:قلب:
اما بازم مشکل دارم:ناراحت:
من یک دکمه گذاشتم که حالت اولیه گزارشم رو ذخیره کنه
Strm:=TMemoryStream.Create;
frxrprt1.SaveToStream(Strm);
یک دکمه دیگه هم گذاشتم که بعد از تغییرات دوباره همین حالتی که با دکمه اول ذخیره کردم رو برگردونه
frxrprt1.LoadFromStream(Strm) ;
دکمه اول بدون مشکل انجام میشه ولی وقتی روی دکمه دوم کلیک میکنم این اروور میاد:ناراحت:
109400
یوسف زالی
چهارشنبه 30 مرداد 1392, 10:20 صبح
استریم رو در یک فایل بریزید ببینید فرمت فایل رو باز می کنه.
اگر نکرد مشکل در خود گزارشتونه.
باید بررسی بشه.
sara.mahdavi
چهارشنبه 30 مرداد 1392, 10:54 صبح
:متفکر:وقتی استریم رو توی یک فایل میریزم مشکلی نداره و مثل دستور SaveToFile عمل میکنه
با این TfrxMemoryStream نوع هم عمل کردم ولی بازم جواب نداد:افسرده:
firststep
پنج شنبه 31 مرداد 1392, 01:01 صبح
ببینین می تونین کامپوننت ریپورتت رو درون یک datamodul قرار بدی بعد در دکمه ریست این رو بنویسی
1
2
3
4
5
Unit1.DataModule1.Free;
Unit1.DataModule1:=Unit1.TDataModule1.Create(nil);
همین
این روش اگرچه غیر اصولی هست ولی جاب می ده چون
یوسف زالی
پنج شنبه 31 مرداد 1392, 16:39 عصر
دوست من روشی که گفتید همون روش 2 هست.
ایشون چنین چیزی نمی خوان!
یک راه دیگه اینه که از یک frxReport دیگه استفاده کنید و برای ریست کردن، اون رو از دیگری پر کنید.
اگر روش استریم همچنان روی سیستم شما مشکل داره، توضیح بدم که چطور از این روش استفاده کنید.
sara.mahdavi
پنج شنبه 31 مرداد 1392, 19:09 عصر
بله ممنون میشم توضیح بدید:قلب:
دوست دارم این اتفاق توی برنامم بصورت بکگراند انجام بشه :لبخندساده:
یوسف زالی
جمعه 01 شهریور 1392, 01:03 صبح
داشتم برنامشو می نوشتم که دیدم بهتره از همون یک شی استفاده کنید.
روش سریالایز..
توضیحات:
سریالایز کردن یعنی تبدیل یک شی به متن. مثل کاری که در طراحی فرم ها در DFM اتفاق می افته. همون چیزی که در View as Text می بینیم.
دسریالایز هم برعکسه. یک متن رو می گیره و شی تحویلمون می ده.
این توابع مربوط به این کار هستند:
function Serialize(Obj: TComponent): WideString;
var
StringStream: TStringStream;
MemoryStream: TMemoryStream;
begin
MemoryStream := TMemoryStream.Create;
StringStream := TStringStream.Create('');
try
MemoryStream.WriteComponent(Obj);
MemoryStream.Seek(0, 0);
ObjectBinaryToText(MemoryStream, StringStream);
result := StringStream.DataString;
finally
MemoryStream.Destroy;
StringStream.Destroy;
end;
end;
procedure DeSerialize(Obj: TComponent; data: WideString);
var
StringStream: TStringStream;
MemoryStream: TMemoryStream;
begin
MemoryStream := TMemoryStream.Create;
StringStream := TStringStream.Create(data);
try
ObjectTextToBinary(StringStream, MemoryStream);
MemoryStream.Seek(0, 0);
MemoryStream.ReadComponent(Obj);
finally
MemoryStream.Destroy;
StringStream.Destroy;
end;
end;
ذخیره یک گزارش در یک رشته با نام BasicReportString :
BasicReportString := Serialize(frxReport1);
لود کردن گزارش از رشته ی BasicReportString در شی frxReport1 :
frxReport1.Free;
frxReport1 := TfrxReport.Create(Self);
DeSerialize(frxReport1, BasicReportString);
و در آخر:
frxReport1.DesignReport;
sara.mahdavi
چهارشنبه 06 شهریور 1392, 12:16 عصر
سلام
یک مشکل دیگه :ناراحت:
من این قسمت رو
ذخیره یک گزارش در یک رشته با نام BasicReportString :
BasicReportString := Serialize(frxReport1);
به این صورت تغییر دادم
case B_CreateProfile.tag of
0:Report:=DM_Report.frxrprt_Man;
1:Report:=DM_Report.frxrprt_Man_PDF;
2:Report:=DM_Report.frxrprt_Woman;
3:Report:=DM_Report.frxrprt_Woman_PDF;
4:Report:=DM_Report.frxrprt_ManWoman;
5:Report:=DM_Report.frxrprt_ManWoman_PDF;
end;
BasicReportString :=DM_Report.Serialize(Report);
ولی یک مشکل پیش میاد
برای بار اول و دوم بدون مشکل مراحل انجام میشه
ولی بار سوم که این دستور فراخوانی میشه
Report که داخل Case هست مقدار نمیگیره و وقتی از Case برون میاد مقدار Report = Nil میمونه
هرچی فکر میکنم دلیلش رو نمیفهمم :افسرده:
لطفا راهنماییم کنید
مرسی
یوسف زالی
چهارشنبه 06 شهریور 1392, 13:39 عصر
خب این که ربطی به خود فست و این تاپیک نداره.
خود کامپوننت شما مقدار نداره.
باید سورسش بررسی بشه.
sara.mahdavi
جمعه 08 شهریور 1392, 18:17 عصر
سلام
ببینید من بازم چک کردم ولی فکر میکنم این مشکل توی همین ذخیره شدن بصورت استریم بوجود میاد
گزارش من وقتی هنوز آزاد نشده اطلاعاتش درسته (عکسشو در ضمیمه 1 گذاشتم).
ولی وقتی با این دستور آزاد میشه
لود کردن گزارش از رشته ی BasicReportString در شی frxReport1 :
frxReport1.Free;
frxReport1 := TfrxReport.Create(Self);
DeSerialize(frxReport1, BasicReportString);
و دوباره از استریم فراخوانی میشه با مشکل لود میشه (ضمیمه2) و مقدار درست در داخل گزارش قرار نمیگیره
sara.mahdavi
یک شنبه 10 شهریور 1392, 09:29 صبح
بچه ها کارم گیره :گریه: نمیدونم چیکا کنم :ناراحت:
کسی نیس یه راهی بهم نشون بده؟؟؟؟؟؟؟؟؟؟؟؟؟؟:افسرده:
ممنون
firststep
یک شنبه 10 شهریور 1392, 09:57 صبح
سلام
من متوجه نمیشم شما tag تان مقدار نمیگیرد چه ربطی به اون فایل ها داره
اون متن Serialize تون رو نگاه کنین
نگاه کنین ببینین چه مقادیری گرفته
اگه بزارینش هم ید نیست
توی debug تون بار اول دوم و سوم را متن Serialize تون چک کنید
sara.mahdavi
یک شنبه 10 شهریور 1392, 12:14 عصر
ممنون از جوابتون
ببینید فکر میکنم مقداری که تابع Serialize توی گزارش قرار میده اشکال داره و اشتباه چون وقتی این مقدار رو میخواد توی گزارش قرار بده مقادیر درستی دریافت نمیکنه و مقدار گزارش (Report) برابر با Nil میشه
این هم از مقدار بازگشتی تابع Serialize:
110016
firststep
یک شنبه 10 شهریور 1392, 14:23 عصر
نه مقدارش رو کپی پیست نمایید درون تایپک بعد از serilaize کردن مقدار توی یک memo بریزید و سپس او رو کپی کنید در اینجا
sara.mahdavi
یک شنبه 10 شهریور 1392, 16:49 عصر
آهان
خب این متن خروجی تابع
object frxrprt_Woman_PDF: TfrxReport
Version = '4.14'
DotMatrixReport = False
IniFile = '\Software\Fast Reports'
PreviewOptions.Buttons = [pbPrint, pbLoad, pbSave, pbExport, pbZoom, pbFind, pbOutline, pbPageSetup, pbTools, pbEdit, pbNavigator, pbExportQuick]
PreviewOptions.Zoom = 1.000000000000000000
PrintOptions.Printer = #1662#1610#1588' '#1601#1585#1590
PrintOptions.PrintOnSheet = 0
ReportOptions.CreateDate = 41457.803229907400000000
ReportOptions.LastChange = 41508.618399710600000000
ScriptLanguage = 'PascalScript'
ScriptText.Strings = (
''
'begin'
' '
'end.')
Left = 344
Top = 48
Datasets = <
item
DataSet = DM_Report.frxdbDS_NEO_PI_R
DataSetName = 'frxDB_NEO_PI_R'
end>
Variables = <>
Style = <>
object Data: TfrxDataPage
Height = 1000.000000000000000000
Width = 1000.000000000000000000
end
.
.
.
ادامه گزارش
و این هم متن همین گزارش که در حالت View as Text ایجاد شده است
object frxrprt_Woman_PDF: TfrxReport
Version = '4.14'
DataSet = frxdbDS_NEO_PI_R
DataSetName = 'frxDB_NEO_PI_R'
DotMatrixReport = False
IniFile = '\Software\Fast Reports'
PreviewOptions.Buttons = [pbPrint, pbLoad, pbSave, pbExport, pbZoom, pbFind, pbOutline, pbPageSetup, pbTools, pbEdit, pbNavigator, pbExportQuick]
PreviewOptions.Zoom = 1.000000000000000000
PrintOptions.Printer = #1662#1610#1588' '#1601#1585#1590
PrintOptions.PrintOnSheet = 0
ReportOptions.CreateDate = 41457.803229907400000000
ReportOptions.LastChange = 41508.618399710650000000
ScriptLanguage = 'PascalScript'
ScriptText.Strings = (
''
'begin'
' '
'end.')
Left = 344
Top = 48
Datasets = <
item
DataSet = frxdbDS_NEO_PI_R
DataSetName = 'frxDB_NEO_PI_R'
end>
Variables = <>
Style = <>
object Data: TfrxDataPage
Height = 1000.000000000000000000
Width = 1000.000000000000000000
end
.
.
.
یوسف زالی
یک شنبه 10 شهریور 1392, 16:54 عصر
این که جفتش دوتاست! :چشمک:
اگر View as Text هم همین رو داره میاره اشکال از قطعه کد سریالایز نیست.
sara.mahdavi
یک شنبه 10 شهریور 1392, 17:21 عصر
نه دیگه
این
DataSet = frxdbDS_NEO_PI_R
DataSetName = 'frxDB_NEO_PI_R'
در قسمت View as Text هست ولی توی سریالایز نیس
از این مورد نمیتونه باشه؟؟؟
firststep
یک شنبه 10 شهریور 1392, 17:54 عصر
فکر نمی کنم ربطی به اون داشته باشه شما tag نمی گیرین اصلاً در حالت design رو tag ست کردین؟
sara.mahdavi
یک شنبه 10 شهریور 1392, 18:49 عصر
فکر نمی کنم ربطی به اون داشته باشه شما tag نمی گیرین اصلاً در حالت design رو tag ست کردین؟
منظورتون رو از tag متوجه نمیشم
firststep
یک شنبه 10 شهریور 1392, 22:35 عصر
این چیه مگه
case B_CreateProfile.tag of
شما مگه مشکلتون توی nil بودن ریپورت نبود
خوب این مشکلتون می تونه از توی این خط بوجود بیاد
من یک لحظه تصور کردم که تگ ریپورت و می گیرین
حالا همین تگ مقدار میگیره
اطمینان دارین؟؟؟؟
sara.mahdavi
دوشنبه 11 شهریور 1392, 08:37 صبح
بله مطمئنم از این نیست چون در حالت debug چک کردم :ناراحت:
sara.mahdavi
دوشنبه 11 شهریور 1392, 11:56 صبح
بلاخره فهمیدم مشکل کجاست :لبخند:
توی این قسمت مقدار اولیه گزارش رو ذخیره میکردم
case B_CreateProfile.tag of
0:Report:=DM_Report.frxrprt_Man;
1:Report:=DM_Report.frxrprt_Man_PDF;
2:Report:=DM_Report.frxrprt_Woman;
3:Report:=DM_Report.frxrprt_Woman_PDF;
4:Report:=DM_Report.frxrprt_ManWoman;
5:Report:=DM_Report.frxrprt_ManWoman_PDF;
end;
BasicReportString :=DM_Report.Serialize(Report);
با این دستور هم فراخوانیش میکردم
Report.Free;
Report := TfrxReport.Create(Self);
DM_Report.DeSerialize(Report, BasicReportString);
خب مشکل همینجا اتفاق میوفتاد
چون کار من اشتباه بود وقتی Report فری میشه اطلاعتش رو از دست میده و در خط سوم همین دستور موقعی که با تابع DeSerialize میخواد اطلاعات ذخیره شده BasicReportString رو توی گزارش (Report ) بریزه
Report در اینجا مشخص نیست که به کدوم گزارش اشاره میکنه بخاطر همین این دستور درست کار نمیکرد
حالا برای برطرف کردنش چه راه حلی پیشنهاد میکنید (دو3تان خوبم:قلب:)
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.