Пересобрать отчет из самого отчета
HunterNS
Таганрог
Доброго времени суток.
Есть интересная задача:
Имеется некий шаблон, образно выглядит следующим образом:
ФИО: _______
Заметки: ___Memo1_______
____Memo2______________
Отчет открывается из программы, написанной на Delphi.
У Memo1 свойство FlowTo = Memo2.
На Memo1 стоят обработчики события OnPrewievClick, OnBeforePrint.
В событии OnBeforePrint происходит считывание значения поля из базы с использованием внешней функции (UserFunction).
TfrxMemoView(Sender).Text := SHOW_PARAM_FROM_DB(TfrxMemoView(Sender).Name);
Обработчик события OnPrewievClick выглядит так:
procedure Memo1OnPreviewClick(Sender: TfrxView; Button: TMouseButton; Shift: Integer; var Modified: Boolean);
var
s, sName: string;
begin
s := trim(TfrxMemoView(Sender).Text) + ' ' + trim(Memo2.Text); // Так нельзя делать, потому что так не возвращается содержимое Memo2, но не суть важно, главное, чтобы понять смысл (я делаю по другому)
sName := TfrxMemoView(Sender).Name;
s := MyInputBox('Редактор текста',s);
Modified := True;
DO_INSERT_IN_DB(sName, s);
end;
В процедуре DO_INSERT_IN_DB я произвожу запись значения в базу.
Вот тут-то и начинаются проблемы. Обработчиком Memo1OnPrewievClick нельзя обновить другие мемки, например Memo2, хуже того, FlowTo тоже не работает, а также нельзя поменять высоту мемок. Если например ввели очень длинный текст, то он не растянет мемку.
Что делаю я (самый, на мой взгляд, удачный вариант): В UserFunction DO_INSERT_IN_DB я тупо вызываю ShowReport(True). Параметр означает, что нужно стереть предыдущий отчет. (с False) тоже не работает).
Отчет перерисовывается, подгружает новые данные, отлично форматируется (растягивается, переносится). НО... валится AcessViolation, причем после обновления.
Если не делать Modified = True, то отчет пересобирается, но ошибка не валится. Есть мнение, что успевает сработать обработчик события OnBeforePrint, но так как старого отчета уже нет, то он и валит AV.
Пробовал глушить ошибку, но так и не нашёл где ставить try...except. Пробовал ставить на основной ShowReport, пробовал на ShowReport, который в DO_INSERT_IN_DB, пробовал внутри обработчика события OnPrewievClick. Не помогло.
Пытался найти глушилку в свойствах TfrxReport, не нашел.
Стэк вызовов выглядит следующим образом:
Classes.TList.Get + $A
frxXML.TfrxXMLItem.GetItems (Line 385, "frxXML.pas" + 1) + $5
frxPreviewPages.TfrxPreviewPages.ModifyPage (Line 1371, "frxPreviewPages.pas" + 3) + $5
frxPreviewPages.TfrxPreviewPages.ObjectOver (Line 2382, "frxPreviewPages.pas" + 68) + $A
frxPreview.TfrxPreviewWorkspace.MouseUp (Line 888, "frxPreview.pas" + 28) + $63
Controls.TControl.DoMouseUp + $2C
Controls.TControl.WMLButtonUp + $76
Controls.TControl.WndProc + $2BB
Controls.TWinControl.WndProc + $18D
Controls.TWinControl.IsControlMouseMsg + $13
Controls.TWinControl.WndProc + $4FB
Controls.TWinControl.MainWndProc + $2C
Classes.StdWndProc + $14
Forms.TApplication.ProcessMessage + $FC
Forms.TApplication.HandleMessage + $A
Forms.TCustomForm.ShowModal + $187
Controls.TWinControl.RecreateWnd + $12
frxClass.TfrxReport.ShowPreparedReport (Line 12817, "frxClass.pas" + 23) + $4
Пробовал даже обрамлять в try...except фунцию GetItems в файле "frxXML.pas":
function TfrxXMLItem.GetItems(Index: Integer): TfrxXMLItem;
begin
Result := TfrxXMLItem(FItems[Index]);
end;
Подскажите, что можно сделать...
Есть интересная задача:
Имеется некий шаблон, образно выглядит следующим образом:
ФИО: _______
Заметки: ___Memo1_______
____Memo2______________
Отчет открывается из программы, написанной на Delphi.
У Memo1 свойство FlowTo = Memo2.
На Memo1 стоят обработчики события OnPrewievClick, OnBeforePrint.
В событии OnBeforePrint происходит считывание значения поля из базы с использованием внешней функции (UserFunction).
TfrxMemoView(Sender).Text := SHOW_PARAM_FROM_DB(TfrxMemoView(Sender).Name);
Обработчик события OnPrewievClick выглядит так:
procedure Memo1OnPreviewClick(Sender: TfrxView; Button: TMouseButton; Shift: Integer; var Modified: Boolean);
var
s, sName: string;
begin
s := trim(TfrxMemoView(Sender).Text) + ' ' + trim(Memo2.Text); // Так нельзя делать, потому что так не возвращается содержимое Memo2, но не суть важно, главное, чтобы понять смысл (я делаю по другому)
sName := TfrxMemoView(Sender).Name;
s := MyInputBox('Редактор текста',s);
Modified := True;
DO_INSERT_IN_DB(sName, s);
end;
В процедуре DO_INSERT_IN_DB я произвожу запись значения в базу.
Вот тут-то и начинаются проблемы. Обработчиком Memo1OnPrewievClick нельзя обновить другие мемки, например Memo2, хуже того, FlowTo тоже не работает, а также нельзя поменять высоту мемок. Если например ввели очень длинный текст, то он не растянет мемку.
Что делаю я (самый, на мой взгляд, удачный вариант): В UserFunction DO_INSERT_IN_DB я тупо вызываю ShowReport(True). Параметр означает, что нужно стереть предыдущий отчет. (с False) тоже не работает).
Отчет перерисовывается, подгружает новые данные, отлично форматируется (растягивается, переносится). НО... валится AcessViolation, причем после обновления.
Если не делать Modified = True, то отчет пересобирается, но ошибка не валится. Есть мнение, что успевает сработать обработчик события OnBeforePrint, но так как старого отчета уже нет, то он и валит AV.
Пробовал глушить ошибку, но так и не нашёл где ставить try...except. Пробовал ставить на основной ShowReport, пробовал на ShowReport, который в DO_INSERT_IN_DB, пробовал внутри обработчика события OnPrewievClick. Не помогло.
Пытался найти глушилку в свойствах TfrxReport, не нашел.
Стэк вызовов выглядит следующим образом:
Classes.TList.Get + $A
frxXML.TfrxXMLItem.GetItems (Line 385, "frxXML.pas" + 1) + $5
frxPreviewPages.TfrxPreviewPages.ModifyPage (Line 1371, "frxPreviewPages.pas" + 3) + $5
frxPreviewPages.TfrxPreviewPages.ObjectOver (Line 2382, "frxPreviewPages.pas" + 68) + $A
frxPreview.TfrxPreviewWorkspace.MouseUp (Line 888, "frxPreview.pas" + 28) + $63
Controls.TControl.DoMouseUp + $2C
Controls.TControl.WMLButtonUp + $76
Controls.TControl.WndProc + $2BB
Controls.TWinControl.WndProc + $18D
Controls.TWinControl.IsControlMouseMsg + $13
Controls.TWinControl.WndProc + $4FB
Controls.TWinControl.MainWndProc + $2C
Classes.StdWndProc + $14
Forms.TApplication.ProcessMessage + $FC
Forms.TApplication.HandleMessage + $A
Forms.TCustomForm.ShowModal + $187
Controls.TWinControl.RecreateWnd + $12
frxClass.TfrxReport.ShowPreparedReport (Line 12817, "frxClass.pas" + 23) + $4
Пробовал даже обрамлять в try...except фунцию GetItems в файле "frxXML.pas":
function TfrxXMLItem.GetItems(Index: Integer): TfrxXMLItem;
begin
Result := TfrxXMLItem(FItems[Index]);
end;
Подскажите, что можно сделать...
Комментарии