Lazreport

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Lazreport

Сообщение А.Н. » 08.07.2010 12:16:02

Как создать отчёт в LazReport, в котором для одной записи в таблице у меня несколько записей в другой?
Например, есть договор. Для договора у меня несколько водителей в другой таблице.
Связываются по ID_DOGOVOR. Как вывести в отчёте всех водителей для каждого договора?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Lazreport

Сообщение WAYFARER » 08.07.2010 12:42:25

SQL запросом наверное?
Сначало выберем данные из двух таблиц -
что то типа
Код: Выделить всё
select Dogovors.*, Voditel.*
from
(Dogovors inner join Voditel on Dogovors.ID_DOGOVOR=Voditel.blablabla);

А потом просто в frDBDataSet укажем DataSet с запросом.
или я вопроса не понял?
Аватара пользователя
WAYFARER
энтузиаст
 
Сообщения: 537
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Re: Lazreport

Сообщение krab » 08.07.2010 13:10:10

Вам нужен Master-Detail отчет. Подробнее не расскажу, так как в LazReport его еще не делал.

В c:\lazarus\components\lazreport\samples есть пример. Документация в Wiki, мягко говоря, слабая, но можно почитать manual к FreeReport 2.3. Не совсем то, но на 99.9 % применимо и к LazReport.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
krab
постоялец
 
Сообщения: 108
Зарегистрирован: 17.02.2010 18:23:08

Re: Lazreport

Сообщение А.Н. » 08.07.2010 13:48:57

WAYFARER писал(а):SQL запросом наверное?
Сначало выберем данные из двух таблиц -
что то типа
Код: Выделить всё
select Dogovors.*, Voditel.*
from
(Dogovors inner join Voditel on Dogovors.ID_DOGOVOR=Voditel.blablabla);

А потом просто в frDBDataSet укажем DataSet с запросом.
или я вопроса не понял?

Всё бы так, но:
1. У договора есть страхователь с ФИО.
2. У водителей есть ФИО.

Структура БД примерно такова:
1. Таблица "Договора". dogovor. Ключ - ID_DOGOVOR.
2. "Водители". driver. Ключ - ID_DRIVER. FK - ID_DOGOVOR, ID_CLIENT.
3. "Клиенты". client. Ключ ID_CLIENT.

Водители ссылаются на client. Договор ссылается на client. Получить простым способом не получится.
К тому же, с полями путаница будет.

krab писал(а):Вам нужен Master-Detail отчет. Подробнее не расскажу, так как в LazReport его еще не делал.

Мануал у меня есть. Даже русский. Я примерно так и понял, что мне это нужно.
Но, проблема в том, что я не понимаю откуда брать detail?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Lazreport

Сообщение А.Н. » 09.07.2010 15:22:14

Как делать master-detail Отчёт? Откуда брать detail данные? Возможно ли каким-то образом получить detail из запроса с параметрами?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Lazreport

Сообщение krab » 09.07.2010 17:52:08

А.Н. писал(а):Как вывести в отчёте всех водителей для каждого договора?

А.Н. писал(а):Как делать master-detail Отчёт? Откуда брать detail данные? Возможно ли каким-то образом получить detail из запроса с параметрами?

Концептуально:
master - запрос Договор (select ID_DOGOVOR, NAME_DOGOVOR)
detail - запрос Водители (select ID_DRIVER, ID_DOGOVOR, NAME_DRIVER)

Если делать через TfrUserDataset, то будет примерно так. User-датасет в lazReport отвечает, фактически, только за переключение от одной записи к другой:
Код: Выделить всё
var
    index_variable : longint;

procedure TForm1.UserDataset1CheckEOF(Sender: TObject; var Eof: Boolean);
begin
  Eof := index_variable > MaxValue;
end;

procedure TForm1.UserDataset1First(Sender: TObject);
begin
  index_variable := 1;
end;

procedure TForm1.UserDataset1Next(Sender: TObject);
begin
  Inc(index_variable);
end;

Сама выдача организуется через frReport1GetValue:
Код: Выделить всё
procedure TForm1.frReport1GetValue(const ParName: String; var ParValue: Variant  );
begin
  if ParName = 'DOGOV_var' then
    ParValue := значение_переменной;
   
  if ParName = 'VODITEL_var1' then
    ParValue := значение_переменной_2;

  if ParName = 'VODITEL_var2' then
    ParValue := значение_переменной_3;

end;


То есть нужно два UserDataset, один для договоров, другой для водителей. В зависимости от состояния index_variable каждого из них процедура frReport1GetValue должна выдавать данные. Откуда они берутся, дело десятое (можно программно читать из базы, например).

Подробнее:
Сгрузить записи кодов договоров из БД в списки TStringList. При чтении [DOGOV_var] в отчете в зависимости от index_variable_of_dogovor_dataset из списка выбирается N-я по счету запись и выдается код договора. При чтении VODITEL_var'ов в зависимости от index_variable_of_driver_dataset к базе любым способом делаются запросы (select ID_VODITEL, NAME, VODITEL from Водители where ID_DOGOVOR=...) и сгружаются в списки StringGrid. Дальше, в зависимости от index_variable_of_driver_dataset из списков выдаются данные через VODITEL_var'ы.

В отчет в редакторе отчетов добавляются master_data band и detail_data band для данных. Каждому проставляются датасеты, создаются memo с выводом переменных, добавляются master_header/detail_header (заголовки колонок) и т. д. Вроде все описал.

Наверное, можно как-то можно и через frDBDataSet, но информации по нему маловато.
krab
постоялец
 
Сообщения: 108
Зарегистрирован: 17.02.2010 18:23:08

Re: Lazreport

Сообщение А.Н. » 09.07.2010 23:44:11

Спасибо. Посмотрел ваш код, понял как делать. Сделал через frDBDataSet. Там, вообще, ничего писать почти не надо.
Только для Master:
Код: Выделить всё
procedure TdmReports.frdsCBDReportFirst(Sender: TObject);
begin
  myRepContractsByDate.First();
  dmData.GetDriversByContID(myRepContractsByDate.FieldByName('ID_DOGOVOR').AsString);
end;
//---------------------------------------------------------------------------
procedure TdmReports.frdsCBDReportNext(Sender: TObject);
begin
  myRepContractsByDate.Next();
  dmData.GetDriversByContID(myRepContractsByDate.FieldByName('ID_DOGOVOR').AsString);
end;


Но возникла другая проблема. Как я понял, detail должен повторяться для каждого master до того, пока в detail не возникнет eof. Поэтому, в части detail данных у меня одно поле с ФИО водителя. И одна строка.
Но он всегда выводит одного водителя. Почему? Как сделать, чтобы выводились все водители по договору?

Добавлено спустя 19 часов 7 минут 2 секунды:
Блок detail данных должен находиться на блоке Master данных?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Lazreport

Сообщение Brainenjii » 10.07.2010 20:10:51

Нет
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Lazreport

Сообщение А.Н. » 10.07.2010 22:02:44

А почему? У меня не работает (показывает только одну запись), если на Master. Если нет, то всё работает.
Минус в том, что, например, я хочу отделить Master записи линиями, у меня это никак не получится.
Плюс, в руководстве по fast (или по free - Не помню), сказано, что Detail должен находиться на Master.

Почему здесь наоборот?
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Lazreport

Сообщение AkANz » 12.07.2010 07:23:21

Доброго времени суток.
Подскажите, пожалуйста, работает, ли Lazreport с компонентами Zeos 6.6.6.
Не могу вывести в отчет значения полей БД.

На форму положил frReport и frDBDataSet у frReport указал DataSet -> frDBDataSet у frDBDataSet указал DataSet -> zQuery (zQuery настроен в D
В бланк отчета необходимо вывести значение одного поля БД (например только оду фамилию в текст бланка).
В дизайнере отчетов: Вставить объект-прямоугольник -> Поле БД. В доступных БД вижу все zQuery, но не вижу полей БД.

Читал букварь к FastReport 2.3 не помогает.
AkANz
новенький
 
Сообщения: 26
Зарегистрирован: 16.03.2010 13:59:02
Откуда: Алтайский край

Re: Lazreport

Сообщение А.Н. » 12.07.2010 11:06:07

Вроде бы, zQuery должен быть активен, чтобы дизайнер определил какие поля в нём есть.
Или поля должны быть явно указаны в редакторе полей.
И соединение, естественно, тоже должно быть активно.
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Lazreport

Сообщение AkANz » 12.07.2010 12:50:30

А.Н. писал(а):Вроде бы, zQuery должен быть активен, чтобы дизайнер определил какие поля в нём есть.
Или поля должны быть явно указаны в редакторе полей.
И соединение, естественно, тоже должно быть активно.


Да вот и ZQuery активно (Grid заполняется на основании этого Zquery) и соединение активно.
В редакторе не могу явно указать поля БД, равно как и переменную не могу создать.
AkANz
новенький
 
Сообщения: 26
Зарегистрирован: 16.03.2010 13:59:02
Откуда: Алтайский край

Re: Lazreport

Сообщение А.Н. » 12.07.2010 13:02:51

Попробуй указать поля явно: Модуль_данных.Запрос."Имя_поля".
Например: [dmData.myAlerter."FULL_NAME"].
Или просто: [Имя_поля].
И посмотри что получится.
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

Re: Lazreport

Сообщение AkANz » 12.07.2010 14:53:49

Я пока вставляю отдельные значения из БД в отчет через GetValue.

А.Н. писал(а):Попробуй указать поля явно: Модуль_данных.Запрос."Имя_поля".
Например: [dmData.myAlerter."FULL_NAME"].


Да при явно указании поля [fmDM.zqParams."Nameorg"] работает (даже без frDBDataSet).

Спасибо за помощь, далее будем осваивать более сложные отчеты.
AkANz
новенький
 
Сообщения: 26
Зарегистрирован: 16.03.2010 13:59:02
Откуда: Алтайский край

Re: Lazreport

Сообщение А.Н. » 12.07.2010 15:24:25

Попробуй поиграться с полями CloseDataSource/OpenDataSource TfrDBDataSet'а. Вряд ли влияет, но, может, заработает показ полей в редакторе.
Плюс, если это не поможет, попробуй добавить поля явно, в список полей набора данных.

P.S.:
Zeos - далеко не лучший выбор.

Добавлено спустя 4 минуты 32 секунды:
Да при явно указании поля [fmDM.zqParams."Nameorg"] работает (даже без frDBDataSet).

И лучше, думаю, будет написать просто [Nameorg].
А.Н.
постоялец
 
Сообщения: 230
Зарегистрирован: 13.03.2010 12:23:58

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 54

Рейтинг@Mail.ru