Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос по DBGrid-у.Помогите пожалуйста. DBGrid........... 
:(
    Опции темы
BGladiator
Дата 15.9.2003, 17:51 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Здравствуйте. Вот в чём проблема: есть DBGrid - в нём несколько колонок, указан некоторый DataSource откуда и берутся данные. При печати печатаются все строки этого DBGrida. Мне же нужно чтобы печатались лишь выбранные. Для этого в запросе, который использ. для этого DBGrida я добавил ещё одно поле SELECTION - соответственно и втаблицу БД откуда выбираются данные тоже пришлось добавить такое же поле, в котором ничего не содержится (' '). Теперь при нажатии пробела сделал обработчик, который заносит в это поле произвольную метку ('X').
Теперь при печати печатаются только те строки в которых поле SELECTION имеет метку ('X').
Всё бы хорошо да только вот установка этих меток (особенно для нескольких строк) происходит слишком медленно. sad.gif И ещё было проверено что во время установки этих меток, которые служат всего лишь для печати происходит UPDATE таблици в БД. Из-за чего при работе нескольких пользователей возникают блокировки.
Если кто-то знает как можно реализовать эти метки для печати проще пожалуйста подскажите. Если можно по подробнее, потому что перепробовал много вариантов - не выходит.
Заранее спасибо.
  Вверх
x77
Дата 15.9.2003, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



можно сделать проще через метки (включить в Options dgMultiSelect) . при нажатии на кнпку печать, пробегаем по гриду и смотрим в свойство CurrentRowSelected. если оно TRUE, то добавляем поле в список печатаемых полей. после этого останется только вывести на печать сам список. здесь есть варианты. самый, на мой взгляд, грамотный - TRxMemoryTable. формируем виртуальную таблицу и цепляем её к отчёту. более геморройные варианты - вручную формировать данные в том же QuickReport, т.е. в OnNeedData (так, кажется? давно с этим монстром не работал) добавляем записи из нашего списка. трейтий вариант: печатать через excel или даже word. там тоже всё достаточно просто - CreateOleObject и вперёд, на эту тему материалов просто море.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 15.9.2003, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



З.Ы. выносить флаг печати в отдельное поле таблицы при мультиюзверном доступе - это смерть, imho smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 15.9.2003, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



хотя, на крайняк, можно попробовать и с таблицей. установить Cashed Updates в TRUE, стартовать транзакцию, когда юзверь начинает формировать выборку, а после печати эту транзакцию откатывать. блокировки уйдут. блин, но там будут свои геморрои с транзакциями. не, лучше всего - метки smile.gif.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 15.9.2003, 18:54 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спасибо за ответы.
В Options dgMultiSelect у меня включён и список выводится на печать с помощью QuickReport. Но мне надо чтобы пользователь видел что он выбрал, ну типа моего 'X' в поле SELECTION.
  Вверх
BGladiator
Дата 15.9.2003, 19:03 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











x77И ещё так как уменя небольшой опыт программирования в Delphi можешь показать отрывок текста в котором как, ты говоришь пробегаешь по гриду и смотришь свойство CurrentRowSelected.
Вот моя процедура ответсвенная за вывод напечать:
procedure TLineData.aPrintExecute(Sender: TObject);
Var
pr:TrepLineData;
begin
inherited;
pr:=nil;
with Grd.DataSource.DataSet do try
Filter := 'SELECTION ='+'''X''';
Filtered := True;
pr:=TrepLineData.Create(nil);
// pr.Preview;
pr.PrinterSetup;
pr.print;
pr.free;
Filtered := False;
pr:=nil;
except
on Exception do if pr<>nil then pr.free;
end;
end;

Заранее благодарен.
  Вверх
x77
Дата 15.9.2003, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



так если запись выделена, он что, её не увидит? если непременно нужно отдельное поле, сделай CalculatedField и в OnCalcFields присваивай ему, чего надо если в гриде соответствующее поле является выделенным.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 15.9.2003, 19:16 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











x77 На счёт CalculatedField можно какой нибудь примерчик, потому что когда я пролбовал такое сделать выдавалась ошибка что Dataset не находится в режиме редактирования или вставки. Когда я включал режим Edit; моя метка в поле не отображалась.
  Вверх
x77
Дата 15.9.2003, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



это потому, что calculated поля надо присваивать только и только в OnCalcFields. при этом датасет не переводится в режим редактирования и физические значения в базе не меняются. собственно, их там и нету smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Unregistered
Дата 15.9.2003, 19:26 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











А если все Query i DataSource и соответствующие обработчики в том числе и On CalcFields у меня находятся в отдельной форме мне надо каждый раз из своей формы вызывать этот обработчик или нет. Если да то как?
Огромное спасибо тебе. Уже по чучуть начинаю разбираться.
  Вверх
x77
Дата 15.9.2003, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



нет, OnCalcFields будет отрабатывать сам по себе всегда.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 15.9.2003, 19:43 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Так а как мне в этой отдельной форме где хранится мой OnCalcFields проверять выделена ли моя строка в гриде. Ответь пожалуйста.
  Вверх
x77
Дата 15.9.2003, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



попробовал - довольно проблематично smile.gif единственное, что приходит в голову, это хранить список выделенных полей в какой-то внешней переменной типа TStringList. в DbGrid1.OnMouseUp добавлять поле в список если его там нету, или удалять если оно там есть. при этом надо делать что-то типа Table1.Edit; Table1.Cancel; чтобы заставить датасет пересчитать поля. а после всего этого гемморра в OnCalcFields проверять, если данное поле есть в списке - то ему присваивать значение "Х", если нету - пусто.

слушай, есть вариант попроще, если ты ещё здесь.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 15.9.2003, 20:03 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спасибо тебе, итак за помощь, а то целый день мучаюсь. Какой вариант.
  Вверх
x77
Дата 15.9.2003, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



насчёт крестиков. вот такой:

Код

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
 DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
 with DbGrid1 do begin
   if SelectedRows.CurrentRowSelected and
     (SelectedRows.Count > 1) and
     (Column.Index = 0)
   then
     with Canvas do begin
       Font.Color := clRed;
       TextOut (Rect.Left + 2, Rect.Top + 1, 'X');
     end;
 end;
end;



--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 15.9.2003, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



эта штука будет рисовать крест в первом столбце. но, собственно говоря, его рисовать можно где угодно, в том же вычисляемом поле. у меня оно называется Selected, соответственно код будет такой:

Код

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
 DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
 with DbGrid1 do begin
   if SelectedRows.CurrentRowSelected and
     (SelectedRows.Count > 1) and
     (Column.FieldName = 'Selected') // вот и вся разница :)
   then
     with Canvas do begin
       Font.Color := clRed;
       TextOut (Rect.Left + 2, Rect.Top + 1, 'X');
     end;
 end;
end;



--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Bgladiator
Дата 15.9.2003, 20:08 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











А покакому признаку выводить на печать в моей процедуре печати (см. выше)?
  Вверх
x77
Дата 15.9.2003, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



щас будем думать smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Bgladiator
Дата 15.9.2003, 20:10 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











И ещё, А какого типа у тебя это поле Selected - fData, fCalculated?
  Вверх
x77
Дата 15.9.2003, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



оно Calculated, c datatype = ftString. фишка в том,что нам просто нужно место, на котором мы сами нарисуем чего нам надо, и чтобы там ничего не рисовала система. в случае отрисовки на первом поле грида может быть наложение данных, которые отрисует сам грид. а когда рисуешь в отдельном поле, гарантированно пустом, можно этого не боятся.

так, щас один глюк подправлю и скину код.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 15.9.2003, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



в общем, смысл такой. отчёт придётся выводить полностью руками. для этого в свойствах отчёта отключается DataSet (свойство должно быть пустым). после этого в отчёте начинает возникать замечательное событие OnNeedData, в котором можно запихать в текущий банд всё, что угодно. у меня на одной форме (Unit1, Form1) лежит Table1, прицепленная к таблице biolife.db. во втором модуле (Unit2, Form2) находится QuickRep1. приведу оба текста.

Код

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 Grids, DBGrids, Db, DBTables;

type
 TForm1 = class(TForm)
   DataSource1: TDataSource;
   Table1: TTable;
   Table1SpeciesNo: TFloatField;
   Table1Category: TStringField;
   Table1Common_Name: TStringField;
   Table1SpeciesName: TStringField;
   Table1Lengthcm: TFloatField;
   Table1Length_In: TFloatField;
   Table1Notes: TMemoField;
   Table1Graphic: TGraphicField;
   DBGrid1: TDBGrid;
   Table1Selected: TStringField; // вычисляемое поле для отрисовки
   procedure DBGrid1KeyPress(Sender: TObject; var Key: Char);
   procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
     DataCol: Integer; Column: TColumn; State: TGridDrawState);
 private
 public
 end;

var
 Form1: TForm1;

implementation

uses Unit2;

{$R *.DFM}

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
 if Key = 'p' then // при нажатии "p"  - выводим на просмотр
   Form2.QuickRep1.Preview;
end;

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
 DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
 // отрисовка креста для выбранных записей
 with DbGrid1 do begin
   if SelectedRows.CurrentRowSelected and
     (SelectedRows.Count > 1) and
     (Column.FieldName = 'Selected') // только в нашем поле
   then
     with Canvas do begin
       Font.Color := clRed;
       TextOut (Rect.Left + 2, Rect.Top + 1, 'X');
     end;
 end;
end;

end.



во втором модуле на QuickRep1 лежат обычные метки, TQRLabel. фишка в том, чтобы динамически сформировать их значения, перебирая руками таблицу.

Код

unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ExtCtrls, QuickRpt, Qrctrls;

type
 TForm2 = class(TForm)
   QuickRep1: TQuickRep;
   QRBand1: TQRBand;
   QRLabel1: TQRLabel;
   procedure QuickRep1NeedData(Sender: TObject; var MoreData: Boolean);
   procedure QuickRep1BeforePrint(Sender: TCustomQuickRep;
     var PrintReport: Boolean);
 private
   { Private declarations }
   CurrentIndex: integer; // текущая "закладка" (TBookmark)
 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

uses Unit1;

{$R *.DFM}

procedure TForm2.QuickRep1BeforePrint(Sender: TCustomQuickRep;
 var PrintReport: Boolean);

begin
 // перед печатью сбрасываем счётчик
 CurrentIndex := 0;
end;

procedure TForm2.QuickRep1NeedData(Sender: TObject; var MoreData: Boolean);
begin
 with Form1 do begin
   // если перебрали все "закладки" - сваливаем
   if CurrentIndex >= DbGrid1.SelectedRows.Count then begin
     MoreData := FALSE;
   end else begin     // ну, а если нет - то в путь
     // переходим на следующую закладку
     Table1.GotoBookmark (pointer(DBGrid1.SelectedRows.Items[CurrentIndex]));
     // присваиваем нужный текст
     QRLabel1.Caption := Table1Common_Name.AsString;
     // увеличиваем значение счётчика
     Inc (CurrentIndex);
     // говорим уроду, что будут ещё записи
     MoreData := TRUE;
   end;
 end;
end;

end.



вот, в принципе, и всё smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 15.9.2003, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



З.Ы. а всё-таки - оптимальный вариант - TRxMemoryTable. тебе не пришлось бы переделывать отчёт, просто поменять у него датасорс, ,переназначив на виртуальную таблицу. при нажатии на печать ты бы обнулял её, пробегал по выбранным полям, добавляя их туда, и делал Preview. и всё.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 12:24 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спасибо тебе большое сейчас буду пробовать. И, если несложно расскажи (покажи) как это можно сделать с помощью TRxMemoryTable. Никогда такой фишкой не пользовался.
  Вверх
x77
Дата 16.9.2003, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



сначала надо установить RxLib. TRxMemoryTable - это аналог TTable, с аналогичными своствами и методами, с той только разницей, что таблицы физически не существует. т.е. ты делаешь ей Insert, Update, Delete, и всё это хранится у тебя в памяти. тебе надо будет создать такую таблицу, в ней создать поля, абсолютно аналогичные полям в твоей таблице. после этого обработчик из unit1 будет выглядеть примерно так:

Код

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
var
 i, j: integer;
begin
 if Key = 'p' then begin // при нажатии "p"  - выводим на просмотр
   
   // обнуляем таблицу
   RxTable1.First;
   while not RxTable1.Eof do
     RxTable.Delete;
   
   // перебираем выбранные записи
   for i := 0 to DbGrid1.SelectedRows.Count - 1 do begin
     Table1.GotoBookmark (pointer(DBGrid1.SelectedRows.Items[i]));

     // копируем каждую найденную по "закладке" запись
     RxTable1.Insert;
     for j := 0 to Table1.Fields.Count - 1 do
       RxTable1.Fields [j].Value := Table1.Fields [j].Value;
     RxTable1.Post;
   end;
   
   // выводим отчёт на просмотр
   Form2.QuickRep1.Preview;
 end;
end;


если я ничего не путаю, то TMemoryTable может быть указана в качестве dataset'а для QR. т.е. там вешаются обычные data-aware контролы, обычным образом указываются для них источники данных, и весь код, приведённый в Unit2 становится просто не нужен.

ещё один момент, который я вчера впопыхах опустил. Bookmark'и в конце концов надо бы освобождать. т.е. где-то на OnDestroy формы привесить код, который освобождает всю, выделенную под них память.

Это сообщение отредактировал(а) x77 - 16.9.2003, 13:07


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 13:19 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











А как же мне формировать мой QuickReport. Сейчас он у меня формировался в отдельной форме и без единой строчки текста. Т. е. я шлёпал на форму пару Caption, к примеру
Напечатано QRSysData1 'кол.'+STR(PAGENUMBER)

Затем пару Expression, такого типа

qrLineData.TEL_ATS_ATS+'-'+qrLineData.TEL_NUMBER +qrLineData.TYPE_TELE_CONNECTS+' ';

qrLineData.SPR_MPLEX_NAME+ ' ' + qrLineData.LINE_DATA_CALC+' ' +IF(qrLineData.INDICATION = '', '', '['+qrLineData.INDICATION+']')

и т. д.

Теперь, если я хочу выбрать , к примеру другой источник (ну место qrLineData наш
TRxMemoryTable) я не могу, я так понял что ему нужно только Query. Но и элементы Query из формы где находится мой Grid я не вижу только те которые находятся в моей второй форме со всеми Query. Если прописать мою форму с Grid-ом в USES, то возникает закономерная ошибка CIRCULAR UNIT REFERENCE.

Можно ли как то в таком случае осуществить такую же форматированную печать моего отчёта.



  Вверх
x77
Дата 16.9.2003, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



не совсем понял.

насчёт circular и пр.: прописывается uses не в интерфейсной части, а в implementation. тогда всё будет видно и никаких циклических ссылок не возникнет. посмотри, как выше у меня объявлены два модуля:

Код

unit1;

interface

uses
 Forms, etc.

implemantation

uses
 Unit2;

end.



unit2;

interface

uses
 Forms, etc.

implemantation

uses
 Unit1;

end.



--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 16.9.2003, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



если не касаться TRxMemoryTable и закончить, для начала, с вариантом выше, то там всё форматирование делается руками. ты же выводишь отчёт построчно. т.е. в любой момент можешь начать новый банд, вывести номер строки (соответственно, придётся их учитывать) и т.д.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 13:27 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











И ещё ответь пожалуйста можно ли как-то в процедуре печати задать фильтр чтобы печатались только выбраные строки Grida вместо моего Filter := 'SELECTION ='+'''X''';.

Привожу мою процедуру печати:

procedure TLineData.aPrintExecute(Sender: TObject);
Var
pr:TrepLineData;
begin
inherited;
pr:=nil;
CurrentIndex := 0;
with Grd.DataSource.DataSet do try
Filter := 'SELECTION ='+'''X''';
Filtered := True;
pr:=TrepLineData.Create(nil);
// pr.Preview;
pr.PrinterSetup;
pr.print;
pr.free;
Filtered := False;
pr:=nil;
except
on Exception do if pr<>nil then pr.free;
end;
end;

Большое спасибо.
  Вверх
x77
Дата 16.9.2003, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22




мда. как ты думаешь, нафига я всё это писал? smile.gif

ещё раз.

процедура печати выглядит так (это вместо твоей):

Код

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = 'p' then // при нажатии "p"  - выводим на просмотр
  Form2.QuickRep1.Preview;
end;


после того, как отчёт запускается на превью, у него срабатывает событие BeforePrint:

Код

procedure TForm2.QuickRep1BeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
begin
// перед печатью сбрасываем счётчик
CurrentIndex := 0;
end;


после этого начинает срабатывать событие OnNeedData, в котором возвращаемый параметр MoreData определяет, будет ли оно вызвано ещё раз или нет. в этом событии мы двигаемся перебираем записи, выбранные в гриде, и печатаем только их:

Код

procedure TForm2.QuickRep1NeedData(Sender: TObject; var MoreData: Boolean);
begin
with Form1 do begin
  // если перебрали все "закладки" - сваливаем
  if CurrentIndex >= DbGrid1.SelectedRows.Count then begin
    MoreData := FALSE;
  end else begin     // ну, а если нет - то в путь
    // переходим на следующую закладку
    Table1.GotoBookmark (pointer(DBGrid1.SelectedRows.Items[CurrentIndex]));
    // присваиваем нужный текст
    QRLabel1.Caption := Table1Common_Name.AsString;
    // увеличиваем значение счётчика
    Inc (CurrentIndex);
    // говорим уроду, что будут ещё записи
    MoreData := TRUE;
  end;
end;
end;



хочешь, я сброшу тебе этот проект, посмотришь сам, как оно там всё устроено. только мыло дай.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 13:55 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Скидывай на мыло: [email protected]. Огромное тебе спасибо, только вот как будет происходить сама печать, если мне надо вывести сначала заголовок а потом все мои поля отформатированными - строка за строкой.

Спасибо тебе за ответы и извиняюсь за глупые вопросы.
  Вверх
x77
Дата 16.9.2003, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



письмо ушло. в проекте есть недоделки: не освобождается список закладок и пр., но сам функционал у меня (Delphi5/WinXP PRO) работает.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 16.9.2003, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



заголовок можно нарисовать любой в BeforePrint или вообще задать статически в design-time. а строка за строкой - за это, как раз, и отвечает OnNeedData.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 15:36 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спасибо огромное. Проект получил сейчас буду разбираться.
  Вверх
BGladiator
Дата 16.9.2003, 17:02 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











А что значит в строчке QRLabel1.Caption := Table1Common_Name.AsString
Common_Name.
И можно ли QRLabel1 присваивать не всю строку таблицы а какое-то поле таблицы.

  Вверх
x77
Дата 16.9.2003, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



я цеплялся к таблице biolife.db из алиаса DBDemos. в этой таблице есть строковое поле Common_Name. на форму я повесил TTable, в которой все поля объявил статически. они получили название вида <TableName><FieldName>, т.е. в данном случае Table1Common_Name: TStringField. в результате появилась возможность работать с каждым полем, как с самостоятельным объектом (что далеко не всегда полезно, но это - дебри). и я так с ним и работаю. вместо Table1Common_Name.AsString я мог бы написать Table1 ['CommonName'].AsString, или Table1.FindField ('Common_Name').AsString или Table1.FieldByName ('Common_Name').AsString или Table1.Fields [N].AsString, где N - порядковый номер нужного поля в свойстве Fields. всё это абсолютно однохренственно. и строчкой QRLabel1.Caption := Table1Common_Name.AsString я как раз и присваиваю значение конкретного, статически объявленного, поля Common_Name из текущей записи таблицы.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Unregistered
Дата 16.9.2003, 18:02 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Всё сделал так как у тебя единственно что с Preview немного изменил :

procedure TLineData.aPrintExecute(Sender: TObject);
Var
pr:TrepLineData2;
begin
pr := nil;
pr:=TrepLineData2.Create(nil);
pr.Preview;
end;

-- Полностью второй мой Unit где содержится мой QuickReports --
unit frepLinedata2;

interface

uses Windows, SysUtils, Messages, Classes, Graphics, Controls,
StdCtrls, ExtCtrls, Forms, Quickrpt, QRCtrls;

type
TrepLineData2 = class(TQuickRep)
QRBand1: TQRBand;
QRLabel2: TQRLabel;
QRSysData1: TQRSysData;
QRExpr5: TQRExpr;
DetailBand1: TQRBand;
ChildBand1: TQRChildBand;
SummaryBand1: TQRBand;
QRLabel1: TQRLabel;
QRExpr6: TQRExpr;
QRLabel3: TQRLabel;
QRLabel4: TQRLabel;
QRLabel5: TQRLabel;
QRLabel6: TQRLabel;
procedure BeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
procedure NeedData(Sender: TObject; var MoreData: Boolean);
private
CurrentIndex : integer;
public

end;

var
repLineData2: TrepLineData2;

implementation
uses fLineData;
{$R *.DFM}

procedure TrepLineData2.BeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
begin
CurrentIndex := 0;
end;

procedure TrepLineData2.NeedData(Sender: TObject; var MoreData: Boolean);
begin
with fLineData.LineData do begin
if CurrentIndex >= GRD.SelectedRows.Count then begin
MoreData := FALSE;
end else begin // &#237;&#243;, &#224; &#229;&#241;&#235;&#232; &#237;&#229;&#242; - &#242;&#238; &#226; &#239;&#243;&#242;&#252;
PrintTable.GotoBookmark (pointer(GRD.SelectedRows.Items[CurrentIndex]));
QRLabel3.Caption := PrintTable.FindField('TEL_NUMBER').AsString;
Inc (CurrentIndex);
MoreData := TRUE;
end;
end;

end;

end.

После нажатия кнопки ПЕЧАТЬ программа выдаёт ошибку:
Exception EAccessViolation in module ..... at 0012ECAC

Не знаешь в чём тут дело?
  Вверх
x77
Дата 16.9.2003, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



Цитата

procedure TLineData.aPrintExecute(Sender: TObject);
Var
pr:TrepLineData2;
begin
pr := nil;
pr:=TrepLineData2.Create(nil);
pr.Preview;
end;


я думаю, глюк здесь. попробуй пока не создавать новый экземпляр отчёта. просто делай:
RepLineData2.Preview;


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 16.9.2003, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



т.е. подразумевается, что оба юнита создаются автоматически, чтово втором юните в секции интерфейса добавлена переменная var RepLineData2: TRepLineData2, а в первом юните ты просто вызываешь её на просмотр.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Unregistered
Дата 16.9.2003, 18:16 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Если просто пишу TrepLineData2.Preview; или имя_формы.TrepLineData2.Preview;
начинает ругться компилятор
[Error] fLineData.pas(437): This form of method call only allowed for class methods
[Fatal Error] GTelecom.dpr(98): Could not compile used unit 'fLineData.pas'

Если же пишу
Var
pr:TrepLineData2;
begin
pr.Preview;
end;
то всё компилируется, но при нажатии на кнопке печать ничего не происходит.
  Вверх
BGladiator
Дата 16.9.2003, 18:22 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Короче, только что поставил Breakpoint на начало процедуры TrepLineData2.NeedData.
До неё вообще не доходит управление.
Точно также как и до TrepLineData2.BeforePrint.
Обрабатываются какие стандартные библиотеки, типа RXCtrls, ToolsEdit, DBGrid
и т. д. и на этом ВСЁ !



  Вверх
x77
Дата 16.9.2003, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



TrepLineData2 - это так называемый class reference, т.е. говоря попросту - тип. ты пытаешься вызвать не метод переменной, а метод типа этой переменной. и компилятор вежливо намекает, что это возможно только в случае наличия методов класса (которых у тебя нет, ибо они нахрен не нужны). посмотри на код модуля, который ты опубликовал:

Цитата

...
 
  CurrentIndex : integer;
  public

end;

var
  repLineData2: TrepLineData2; // вот твоя переменная !

implementation
uses fLineData;
{$R *.DFM}

...


repLineData2 объявлена во втором модуле, и доступна в модуле 1. т.е. ты пишешь не TrepLineData2.Preview, а repLineData2.Preview; и всё будет работать.

а в случае с pr конечно нифига не происходит smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 18:30 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Написал repLineData2.Preview; всё компилится, но при нажатии ПЕЧАТЬ выдаётся таже лобуда Exception EAccessViolation in module ..... at 0012ECAC.
  Вверх
x77
Дата 16.9.2003, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



если можешь, намыль мне исходники.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
x77
Дата 16.9.2003, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



не пойму, что это:
Цитата

unit frepLinedata2;

interface

uses Windows, SysUtils, Messages, Classes, Graphics, Controls,
StdCtrls, ExtCtrls, Forms, Quickrpt, QRCtrls;

type
TrepLineData2 = class(TQuickRep)
QRBand1: TQRBand;
QRLabel2: TQRLabel;
QRSysData1: TQRSysData;


у тебя во втором модуле нет ни одной формы, объявлен один компонент. это дельфя такой код сгенерила?? должно быть

Код

...
 TfLineData2 = class (TForm)
   QuickRep1: TQuickRep;
...


или что-то типа.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGLadiator
Дата 16.9.2003, 18:42 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Весь проект довольно большой, но эти два основных юнита вышлю, давай адресс.
И ещё не может ли это быть из-за того что Delphi у меня версии 4. И ещё я подключаюсь к БД Oracle а сам источник (dbGIS) создаётся динамически в программе.
  Вверх
BGladiator
Дата 16.9.2003, 18:45 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Да там я ничего не трогал - так сгенерил Delphi.
  Вверх
x77
Дата 16.9.2003, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



[email protected]

да нет, вряд ли. я пока грешу на неправильную декларацию классов, а там разберёмся smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Bgladiator
Дата 16.9.2003, 18:48 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Я посмотрел точно также всё (TrepLineData2 = class(TQuickRep)...) и в моих старых QuickReports и всё работает.
Вот я и спрашиваю может это из-за версии Delphi или нет.
  Вверх
x77
Дата 16.9.2003, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



т.е. ты выбрал в меню New...\Report. а я сделал новую форму и кинул на неё компонент, отсюда разница в объявлениях. ладно, щас попробую переделать свой вариант под твой.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 18:55 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Да ты прав я сделал New...\Report. Файлы я выслал.
  Вверх
x77
Дата 16.9.2003, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



ну, я тоже также сделал: у меня всё по-прежнему работает. такой вопрос: в fLineData GRD - заремлено. а в fRepLineData2 на него есть ссылки. я так понимаю, это позже было сделано? или вообще непонятно, как оно компиляется, не то что работает smile.gif

кстати ссылаться через имя модуля можно, но не обязательно. т.е. вместо fLineData.LineData достаточно просто LineData.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 19:17 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











На счёт // GRD : TBorDBGrid;
Так раньше в этом модуле его вообще не было и всё работало. А это яу же экспериментировал и забыл это удалить. А как было сделано что всё без этого объявлени работает - я не знаю (этот GRD не я создавал).

  Вверх
x77
Дата 16.9.2003, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



мда. заочная отладка - это круто. дальше я могу тебе только советовать. эксепшн вылетает потому, что в отчёте ты ссылаешься на объект, которого нет на форме, либо этот объект не инициализирован. сделай Build all. на первую строчку aPrintExecute повесь breakpoint. по F7 выясни, в каком конкретно месте вылетает AV, к каокму объекту он в этот момент пытается обратиться. дальше будем думать smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
BGladiator
Дата 16.9.2003, 19:33 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Хорошо попробую. Но всё таки интересно почему на форме этот самый GRD существует а в Unit его определения нет. Сегодня уже наверно не успею (хочется ещё Лигу Чемпионов посмотреть) - завтра напишу.

Спасибо за помощь.
  Вверх
x77
Дата 16.9.2003, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



"на форме существует - а в unit нет" - не могет такого быть, imho.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1513 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.