Ценники (реализация печати)
Столкнулся с такой непростой задачей:
есть таблица, в ней роля код, наименование, цена. Необходимо печатать ценники такого шаблона:
1
Апельсин
5,00 грн.
тоесть код, наименование, цена. Покопался в компонентах, самое подходящее нашел StringGrid. Разместил ее на форме, инициализировал значениями, максимальная высота формы получилась 780, больше не делается, поэтому появились полосы прокрутки (так как StringGrid я сделал размером лист а4), осталось дело за малым - пускаю форму на печать, но как оказалось печатается только видимая часть. Подскажите выход с этой ситуации.
я его сразу отбросил, так как в грид я могу загонять циклом значения, а в репорте придется руками писать, либо не догоняю как, на крайняк буду пробовать. посоветовали еще фаст репорт.
какие значения?
он берет из базы значения и их отображает, фаст репорт принцип тот же
он берет из базы значения и их отображает, фаст репорт принцип тот же
структура другая:
1
Апельсин
5,00 грн.
это отображение строки, но отображается она в столбик, и таким образом надо заполнить листы, пока не выгребет таблицу. Реализовать это можно разве что накидав лабелов на квик репорт и ручками все прописать (или я недоганяю как по другому)
1
Апельсин
5,00 грн.
это отображение строки, но отображается она в столбик, и таким образом надо заполнить листы, пока не выгребет таблицу. Реализовать это можно разве что накидав лабелов на квик репорт и ручками все прописать (или я недоганяю как по другому)
Используйте поиск по форуму - я уже приводил пример как рисовать самостоятельно сформировать отчет из программы.
TCanvas *pCanvas = Prn->Canvas;
int PosVert = Vert,PosGor = 0;
if(PosVert >= (Prn->PageHeight-BottomWidth)){
Prn->NewPage();
PosVert = TopWidth;
}
...
PosVert += pCanvas->TextHeight(String)*2;
PosGor = LeftWidth;
TRect Num;
TRect Cod;
TRect Name;
TRect EdIz;
TRect Cena;
TRect Colvo;
TRect Summ;
if(PosVert >= (Prn->PageHeight-BottomWidth)){
Prn->NewPage();
PosVert = TopWidth;
}
Num.Left = PosGor;
Num.Right = PosGor+pCanvas->TextWidth("№ п/п")+1;
Num.Top = PosVert;
Num.Bottom = PosVert+pCanvas->TextHeight("№ п/п")+40;
Cod.Left = Num.Right;
Cod.Right = Num.Right+(pCanvas->TextWidth("Код")+20);
Cod.Top = PosVert;
Cod.Bottom = Num.Bottom;
Name.Left = Cod.Right;
Name.Right = Cod.Right+(pCanvas->TextWidth("Наименование")+500);
Name.Top = PosVert;
Name.Bottom = Num.Bottom;
EdIz.Left = Name.Right;
EdIz.Right = Name.Right+(pCanvas->TextWidth("Ед.изм")+2);
EdIz.Top = PosVert;
EdIz.Bottom = Num.Bottom;
Cena.Left = EdIz.Right;
Cena.Right = EdIz.Right+(pCanvas->TextWidth("Цена")+300);
Cena.Top = PosVert;
Cena.Bottom = Num.Bottom;
Colvo.Left = Cena.Right;
Colvo.Right = Cena.Right+(pCanvas->TextWidth("Кол-во")+300);
Colvo.Top = PosVert;
Colvo.Bottom = Num.Bottom;
Summ.Left = Colvo.Right;
Summ.Right = Colvo.Right+(pCanvas->TextWidth("Сумма")+500);
Summ.Top = PosVert;
Summ.Bottom = Num.Bottom;
pCanvas->Pen->Color = clWindowText;
pCanvas->Font->Size = 10;
pCanvas->Brush->Color = clActiveCaption;
pCanvas->Font->Color = clWhite;
pCanvas->TextRect(Num,Num.Left+1,Num.Top+10,"№ п/п");
pCanvas->TextRect(Cod,Cod.Left+10,Cod.Top+10,"Код");
pCanvas->TextRect(Name,Name.Left+10,Name.Top+10,"Наименование");
pCanvas->TextRect(EdIz,EdIz.Left+1,EdIz.Top+10,"Ед.изм");
pCanvas->TextRect(Cena,Cena.Left+10,Cena.Top+10,"Цена");
pCanvas->TextRect(Colvo,Colvo.Left+10,Colvo.Top+10,"Кол-во");
pCanvas->TextRect(Summ,Summ.Left+10,Summ.Top+10,"Сумма");
pCanvas->Brush->Color = clBlack;
pCanvas->FrameRect(Num);
pCanvas->FrameRect(Cod);
pCanvas->FrameRect(Name);
pCanvas->FrameRect(EdIz);
pCanvas->FrameRect(Cena);
pCanvas->FrameRect(Colvo);
pCanvas->FrameRect(Summ);
for(int i=0;i<InvoiceIn.GetProductCount();i++){
pCanvas->Brush->Color = clNone;
pCanvas->Brush->Style = bsClear;
pCanvas->Pen->Color = clWindowText;
pCanvas->Font->Color = clBlack;
if(PosVert >= (Prn->PageHeight-BottomWidth)){
Prn->NewPage();
PosVert = TopWidth;
}
PosVert += Num.Height();
Num.Top = PosVert;
Num.Bottom = PosVert+pCanvas->TextHeight("№ п/п")+10;
Cod.Top = PosVert;
Cod.Bottom = Num.Bottom;
Name.Top = PosVert;
Name.Bottom = Num.Bottom;
EdIz.Top = PosVert;
EdIz.Bottom = Num.Bottom;
Cena.Top = PosVert;
Cena.Bottom = Num.Bottom;
Colvo.Top = PosVert;
Colvo.Bottom = Num.Bottom;
Summ.Top = PosVert;
Summ.Bottom = Num.Bottom;
ScladList.Product = ScladList.findId(InvoiceIn.getProduct(i));
pCanvas->TextRect(Num,Num.Left+10,Num.Top+10,IntToStr(i+1));
pCanvas->TextRect(Cod,Cod.Left+10,Cod.Top+10,IntToStr(ScladList.Product->GetCode()));
pCanvas->TextRect(Name,Name.Left+10,Name.Top+10,ScladList.Product->GetName());
pCanvas->TextRect(EdIz,EdIz.Left+1,EdIz.Top+10,ScladList.Product->GetPack());
pCanvas->TextRect(Cena,Cena.Left+10,Cena.Top+10,FloatToStr(ScladList.Product->GetPriceIn()));
pCanvas->TextRect(Colvo,Colvo.Left+10,Colvo.Top+10,FloatToStr(ScladList.Product->GetCount()));
pCanvas->TextRect(Summ,Summ.Left+10,Summ.Top+10,FloatToStr(ScladList.Product->GetPriceIn()*ScladList.Product->GetCount()));
pCanvas->Brush->Color = clBlack;
pCanvas->FrameRect(Num);
pCanvas->FrameRect(Cod);
pCanvas->FrameRect(Name);
pCanvas->FrameRect(EdIz);
pCanvas->FrameRect(Cena);
pCanvas->FrameRect(Colvo);
pCanvas->FrameRect(Summ);
}
...
PosVert += Num.Height()*6;
return PosVert;
}
Кроме того, не очень понятно - что мешает использовать генератор отчетов - например для фастрепорта код будет таким:
{
ListMonth = new TStringList;
ListAnnuitet = new TStringList;
GLCredit = GetCredit(StrToFloat(edTovarSumm->Text),StrToFloat(edAvans->Text),GLContractComm,0.0);
float annuitet;
for(int i = TermMin; i<= TermMax;i++){
ListMonth->Add(IntToStr(i));
annuitet = GetAnnuitet(GLCredit,GLPrsSt,i);
ListAnnuitet->Add(FloatToStr(RoundTo(annuitet,-2)));
}
frxUsrDS->RangeEndCount = ListMonth->Count;
frxUsrDS2->RangeEndCount = 1;
// = 1;
frxSimul2->ShowReport();
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::frxSimulGetValue(const AnsiString VarName,
Variant &Value)
{
//
//int CurrentRecord;
if(VarName == "MonthCount"){
CurrentRecord = frxUsrDS->RecNo;
Value = ListMonth->Strings[CurrentRecord];
}
else if(VarName=="Annuitet"){
Value = ListAnnuitet->Strings[CurrentRecord];
}
else if(VarName == "CreditSchem"){
Value = CreditSchem;
}
else if(VarName == "TovarSumm"){
Value = edTovarSumm->Text;
}
else if(VarName=="Avans"){
Value = edAvans->Text;
}
else if(VarName == "Credit"){
Value = FloatToStr(RoundTo(GLCredit,-2));
}
else if(VarName == "EmployeeName"){
Value = IspFIO;
}
else if (VarName == "Address"){
Value = Address;
}
else if (VarName == "Phone"){
Value = Phone;
}
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::frxUsrDSFirst(TObject *Sender)
{
fRec = 0;
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::frxUsrDSNext(TObject *Sender)
{
fRec++;
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::frxUsrDSPrior(TObject *Sender)
{
fRec--;
}
//---------------------------------------------------------------------------
void __fastcall TfmMain::frxUsrDSCheckEOF(TObject *Sender, bool &Eof)
{
if(fRec==ListMonth->Count)Eof = true;
}
//---------------------------------------------------------------------------
На отчет бросаешь мастердату, создаешь датасет с нужными полями, заполняешь его, рисуешь на отчете нужные тебе поля - и все нормально заполняется. Пример заполнения полей значениями и какие события и как нужно определить здесь указанно.
В свойстве отчета есть такая весчь как количество страниц. Не помнью относится ли оно непосредственно к отчету или же в мастер детали - разбирайся сам.
читал мануал по фаст репорту и увидел свойство страницы - column. Если поставить колличество колонок, и в компоненте SubDetail в свойстве ForceNewColumn установить в истину, то отчет будет формироваться не вниз вертикально, а в ширину страницы, как раз как мне надо (до этого читал в двух книгах о отчетах, там такого и в помине не было), но когда он доходит до конца страницы, он на этом и останавливается, по идее можно как то сделать чтоб он печатался таким образом дальше. Я уже пересношал все как мог, - ставил еще один сабдетаил, ставил в его свойстве мастер первый сабдетаил, но ничего(((((
Что значит "он на этом и останавливается"?
Я пользуюсь стандартным QuickReport-ом. Всё прекрасно работает.
И твоя задача легко решаема.
TQuickRep* QRep; - указатель на отчёт
TQRBand* QBand; - указатель на строку в отчёте
QRep->Page->Columns = 4; // количество колонок
QBand->BandType = rbDetail; // тип строки - запись таблицы
Вот выдержка из справки:
rbSubDetail Reserved for use by the TQRSubDetail component.
Do not set this band type manually
Обрати внимание, Я использую не строку данных при печати отчёта master-detail - TQRSubDetail,
а просто строку отчёта TQRBand с типом данных - запись таблицы.
Печать столбцов происходит на каждой странице, без проблем.
И вообще, у меня в программе нет ни одного отчёта созданного в designe mode. ;)
Работать с Quick Report очень просто!
Я пользуюсь стандартным QuickReport-ом. Всё прекрасно работает.
И твоя задача легко решаема.
TQuickRep* QRep; - указатель на отчёт
TQRBand* QBand; - указатель на строку в отчёте
QRep->Page->Columns = 4; // количество колонок
QBand->BandType = rbDetail; // тип строки - запись таблицы
Вот выдержка из справки:
rbSubDetail Reserved for use by the TQRSubDetail component.
Do not set this band type manually
Обрати внимание, Я использую не строку данных при печати отчёта master-detail - TQRSubDetail,
а просто строку отчёта TQRBand с типом данных - запись таблицы.
Печать столбцов происходит на каждой странице, без проблем.
И вообще, у меня в программе нет ни одного отчёта созданного в designe mode. ;)
Работать с Quick Report очень просто!
"но когда он доходит до конца страницы, он на этом и останавливается" - тоесть он заполняет строку (слево направо), а на следующюю строку не переходит, нисмотря на то что в таблице есть данные.
Попробую твой вариант.
TQuickRep* QRep; - указатель на отчёт
TQRBand* QBand; - указатель на строку в отчёте
QRep->Page->Columns = 4; // количество колонок
QBand->BandType = rbDetail; // тип строки - запись таблицы
работает зашибительно))))
спасиба всем.
Я пользуюсь стандартным QuickReport-ом. Всё прекрасно работает.
И твоя задача легко решаема.
TQuickRep* QRep; - указатель на отчёт
TQRBand* QBand; - указатель на строку в отчёте
QRep->Page->Columns = 4; // количество колонок
QBand->BandType = rbDetail; // тип строки - запись таблицы
Вот выдержка из справки:
rbSubDetail Reserved for use by the TQRSubDetail component.
Do not set this band type manually
Обрати внимание, Я использую не строку данных при печати отчёта master-detail - TQRSubDetail,
а просто строку отчёта TQRBand с типом данных - запись таблицы.
Печать столбцов происходит на каждой странице, без проблем.
И вообще, у меня в программе нет ни одного отчёта созданного в designe mode. ;)
Работать с Quick Report очень просто!
"но когда он доходит до конца страницы, он на этом и останавливается" - тоесть он заполняет строку (слево направо), а на следующюю строку не переходит, нисмотря на то что в таблице есть данные.
Попробую твой вариант.
твой простой вариант пашет.
Спасибо всем!!!