© 2002 Сергей Секела
Прочитав статью Виталия Кубекина FastReport: менеджер отчетов, я решил показать вам другой вариант менеджера отчетов. Я предлагаю вашему вниманию менеджер отчетов, в котором нет дополнительных форм - он построен на базе стандартного меню в программе. Идея хранения отчетов в базе конечно интересная, НО ее не выгодно использовать, когда твоя программа стоит в нескольких отделах и в зависимости от отдела выводит абсолютно разные отчеты в таком случае нужно писать еще и процедуру, которая будет сохранять в блобы шаблоны этих отчетов. Моя идея намного проще: сохранять шаблоны прямо в файлах, и папках в какой нибуть папке 'templates' и отображать все прямо в меню. Таким образом можно создать любую древовидную иерархию отчетов, каждый из них будет "сидеть" на своем месте - в своей папке и своем пункте меню.

А теперь ближе к делу:
Програма после загрузки рекурсивно сканирует каталог "templates" и вносит пункты меню, имена которых берутся из названий каталогов а также файлов с шаблонами. Полный путь к файлу сохраняем в хинте MenuItem'a. Таким образом, можна анализировать на какой пункт меню "нажал" пользователь и относительно того, какой флаг стоит в пункте меню (редактор) показывать Редактор шаблона или предварительный просмотр (при желании можна также сделать и сразу диалог параметров вывода печати - это описано Виталием Кубекиным в предыдущей статье).

О меню:
Поскольку сканирование идет не по алфавиту и не вікидает первыми каталоги, то заносим сначала в пункты меню одни каталоги, потом проходимся рекурсивно по всем пунктам меню и добавляем ссылки на шаблоны. В проперти tag будем держать количество "детей", для того чтобы не "заблудиться" в иерархии каталогов и количестве шаблонов.
Процедура сканирования каталогов выглядит так:
Procedure insertDIR(var MNU:TMenuItem;s:string);
var
NewItem: TMenuItem;
sr: TSearchRec;
begin
if FindFirst(s+'\*.*', fadirectory, sr) = 0 then
repeat
if (sr.Attr and fadirectory) = sr.Attr then
if (sr.name<>'.')and (sr.name<>'..') Then
begin
NewItem := TMenuItem.Create(MNU);
try
MNU.tag:=mnu.tag+1;
MNU.hint:=s;
NewItem.Caption := SR.Name;
newitem.Tag:=0;
newitem.Hint:=s+'\'+sr.name;
newitem.onclick:=itemclick;
MNU.Insert(0,NewItem);
if (sr.Attr and fadirectory) = sr.Attr then
insertDIR(NewItem,s+'\'+sr.Name);
except
NewItem.Free;
raise; { reraise the exception }
end;
end;
until FindNext(sr) <> 0;
findclose(sr);
end;
Процедура сканирования меню(читаем каталогов) и внесения туда ссылок на отчеты:
procedure insertfile(MNU:TMenuItem;mask:string);
var
i:integer;
Newitem1:TMenuItem;
SR:TSearchRec;
SItem1:string;
begin
if FindFirst(MNU.hint+'\'+mask, faanyfile, sr) = 0 then
repeat
if ((sr.Attr and faanyfile) = sr.Attr)and((sr.Attr and fadirectory) <> sr.Attr) then
if (sr.name<>'.')and (sr.name<>'..') Then
begin
NewItem1:=TMenuItem.Create(MNU);
try
SItem1:=SR.Name;
Delete(SItem1,pos('.frf',SItem1),4);
NewItem1.Caption := SItem1;
newitem1.Hint:=MNU.hint+'\'+sr.name;
newitem1.OnClick:=itemclick;
mnu.add(newitem1);
except
newitem1.Free;
raise;
end;
end;
until FindNext(sr) <> 0;
for i:=0 to MNU.tag-1 do
insertfile(MNU.items[i],'*.frf');
end;
begin
if filemenu.tag>0 then
for i:=0 to filemenu.tag-1 do
filemenu.Items[i].free;
filemenu.tag:=0;
insertDIR(filemenu,extractfilepath(application.exename)+'\templates');
InsertFile(filemenu,'*.frf');
end;
procedure TForm1.itemClick(Sender: TObject);
begin
if pos('.frf',(sender as tmenuitem).hint)<>0 then
begin
showmessage((sender as tmenuitem).hint);
If frreport1.LoadFromFile((sender as tmenuitem).hint) then
If edittemplate1.checked Then
frreport1.designreport
else begin
frreport1.PrepareReport;
frreport1.ShowPreparedReport;
end
else showmessage('Не могу загрузить шаблон!');
End
end;
Процедура обработким события OnClick:
procedure TForm1.itemClick(Sender: TObject);
begin
if pos('.frf',(sender as tmenuitem).hint)<>0 then
begin
If frreport1.LoadFromFile((sender as tmenuitem).hint) then
If edittemplate1.checked Then
frreport1.designreport
else begin
frreport1.PrepareReport;
frreport1.ShowPreparedReport;
end
else showmessage('Не могу загрузить шаблон!');
end
End;
Теперь при загрузке программы достаточно вызвать две процедуры заполнения меню и они построят его и оно будет отображать дерево каталогов вместе с шаблонами отчетов. Теперь если нужно принести клиенту новый отчет, достаточно принести файл, скинуть его в папку 'templates' (можно там еще создать целую кучу папок) и перегрузить программу - ВСЕ! Если пользователь выберет какой нибуть отчет то на экран выведется окно предварительного просмотра с отчетом, если же при этом будет отмечен пункт меню "показывать дизайнер", то запустится дизайнер отчета, и можна будет сделать изменения в шаблоне.
Желающие могут скачать исходные тексты примера (11.1K)
Все пожелание можете писать на DrWeb@torba.com.
Copyright© 2002 Сергей Секела Специально для Delphi Plus