Подмена данных DBGrid?
, ADO
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.175] |
|
|
ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi
Подмена данных DBGrid?
, ADO
|
Сообщ.
#1
,
|
|
|
|
Никто не сталкивался с реализацией такой задачей: в dbgrid, связанной с базой с базой по ADO, необходимо заменять данные в некотором столбце, т.е. отображать не непосредственно считанные с базы данные, а, например, считанные и затем преобразованные некой процедурой?
Заранее спасибо. |
|
Сообщ.
#2
,
|
|
|
|
Если используется к-л компонент TADOTable или TADOQuery, TADOStoredProc, то в них можно создавать вычисляемые поля , которые отображаются в DBGrid.
|
|
Сообщ.
#3
,
|
|
|
|
Часть 4. Что можно поместить в DBGrid
Наталия Елманова Компьютер Пресс - CD, 1999, N 5 © Copyright N.Elmanova & ComputerPress Magazine. Нередко в колонке DBGrid нужно вывести не реальное значение, хранящееся в поле соответствующей таблицы, а другие данные, соответствующие имеющимся (например, символьную строку вместо ее числового кода). В этом случае также используется метод TextOut свойства Canvas компонента TDBGrid: void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) { if (Column->FieldName=="VenueNo") { DBGrid1->Canvas->Brush->Color=clWhite; DBGrid1->Canvas->FillRect(Rect); if (Table1->FieldByName("VenueNo")->Value==1) { DBGrid1->Canvas->Font->Color=clRed; DBGrid1->Canvas->TextOut(Rect.Right-2- DBGrid1->Canvas->TextWidth("our venue"), Rect.Top+2,"our venue"); } else { DBGrid1->Canvas->TextOut(Rect.Right-2- DBGrid1->Canvas->TextWidth("other venue"), Rect.Top+2,"other venue"); } } } Соответствующий код для Delphi имеет вид: procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin if (Column.FieldName='VenueNo') then begin with DBGrid1.Canvas do begin Brush.Color:=clWhite; FillRect(Rect); if (Table1.FieldByName('VenueNo').Value=1) then begin Font.Color:=clRed; TextOut(Rect.Right-2- DBGrid1.Canvas.TextWidth('our venue'), Rect.Top+2,'our venue'); end else begin TextOut(Rect.Right-2- DBGrid1.Canvas.TextWidth('other venue'), Rect.Top+2,'other venue'); end; end; end; end; Еще один пример - использование значков из шрифтов Windings или Webdings в качестве подставляемой строки. void __fastcall TForm1::DBGrid1DrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) { if (Column->FieldName=="VenueNo") { DBGrid1->Canvas->Brush->Color=clWhite; DBGrid1->Canvas->FillRect(Rect); DBGrid1->Canvas->Font->Name="Wingdings"; DBGrid1->Canvas->Font->Size=-14; if (Table1->FieldByName("VenueNo")->Value==1) { DBGrid1->Canvas->Font->Color=clRed; DBGrid1->Canvas->TextOut(Rect.Right-2- DBGrid1->Canvas->TextWidth("J"), Rect.Top+1,"J"); } else { DBGrid1->Canvas->Font->Color=clBlack; DBGrid1->Canvas->TextOut(Rect.Right-2- DBGrid1->Canvas->TextWidth("F"), Rect.Top+1,"F") ; } } } Соответствующий код для Delphi имеет вид: procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin if (Column.FieldName='VenueNo') then begin with DBGrid1.Canvas do begin Brush.Color:=clWhite; FillRect(Rect); Font.Name:='Wingdings'; Font.Size:=-14; if (Table1.FieldByName('VenueNo').Value=1) then begin Font.Color:=clRed; TextOut(Rect.Right-2- DBGrid1.Canvas.TextWidth('J'), Rect.Top+1,'J'); end else begin Font.Color:=clBlack; TextOut(Rect.Right-2- DBGrid1.Canvas.TextWidth('F'), Rect.Top+1,'F'); end; end; end; end; |
|
Сообщ.
#4
,
|
|||
|
|
А еще, у всех TField существует свойство DisplayText которое используется всеми визуальными компонентами чувствительными к данным (DataAware), в том числе и TDBGrid'ом. Т.е. TDBGrid выводит именно это свойство. В свою очередь, значение этого свойства по умолчанию равно значению из поля БД, с учетом свойства DisplayFormat (у кого оно есть). Но это по умолчанию. Реально-же, у всех TField есть событие OnGetText. Если оно определено для поля, то DisplayText этого поля будет возвращать то, что вернет OnGetText. Словами слишком запутанно Если поля созданы в дизайнере, то требуемому полю (например FFF) вешаем обработчик FFFOnGetText событию OnGetText. Если-же поля создаются динамически, то соответственно вешаем обработчик динамически. Пример обработчика:
С таким обработчиком, в поле FFF DBGrid'а, все символы будут заглавными, вне зависимости какие они в БД. Естественно в БД они не меняются. При этом возникает интересный эффект. Если вы начнете редактировать поле FFF, то оно приобретет вид такой как в БД Естественно это работает и для TDBEdit и пр. Этот способ удобно применять когда нужно выполнить только текстовое преобразование для отображения значения поля. |
|
Сообщ.
#5
,
|
|
|
|
Thanks!
|
|
Сообщ.
#6
,
|
|
|
|
>Bas
если сталкивался подскажи как избавиться от каждоразового щелканься по труе-фалсе? а делать через картинки >Петрович можно подробней про Цитата у всех TField есть событие OnGetText. Если оно определено для поля, то DisplayText этого поля будет возвращать то, что вернет OnGetText. Словами слишком запутанно , проще на примере: Если поля созданы в дизайнере, то требуемому полю (например FFF) вешаем обработчик FFFOnGetText событию OnGetText. у меня есть DBGrid, DataSources, где искать OnGetText? Если шелкнуть на DBGrid, то вижу перечень полей моей таблицы, но там нет Event-ов. |
|
Сообщ.
#7
,
|
|
|
|
Цитата tomsksmile, 13.02.04, 09:06 у меня есть DBGrid, DataSources, где искать OnGetText? Если шелкнуть на DBGrid, то вижу перечень полей моей таблицы, но там нет Event-ов. Смотри глубже . Твой DBGrid связан с DataSource, а DataSources связан с каким-либо DataSet'ом (в твоем случае либо ADODataSet, либо ADOTable, либо ADOQuery). Вот "щелкать" надо именно по нему (DataSet'у) - там будет список полей, по умолчанию пустой. Добавь туда все нужные тебе в гриде поля (правый клик -> Add fields). Теперь, встаешь на нужное тебе поле, и наступит счастье - в инспекторе увидишь его OnGetText. А еще, можно в хелпе поискать OnGetText . |
|
Сообщ.
#8
,
|
|
|
|
На твой вопрос посмотри здесь Что можно поместить в DBGrid
Если не поможет то - Можно использовать словарь атрибутов полей (Dictionary) Добавлено в : Петрович : У меня поле int можно ли через OnGetText(|| чтото) дать возможность вводить и показывать число 15835.25 а в базу записать 1583525 Не используя (Mask)Edit. |
|
Сообщ.
#9
,
|
|
|
|
Цитата Bas, 14.02.04, 12:08 У меня поле int можно ли через OnGetText(|| чтото) дать возможность вводить и показывать число 15835.25 а в базу записать 1583525 Легко. Для показывать используй OnGetText а для вводить используй OnSetText |
|
Сообщ.
#10
,
|
|
|
|
>Basпосмотрел ссылку... спасибо. Рисовать в гриде я научился, но вот ка избавиться от старого списка? Раньше в поле был просто список false/true, теперь поверх списка рисую по канве, но смене статуса все равно нужно работать со списком. Как изловчиться, чтобы просто шелкать по груди без выбора списка?
|
|
Сообщ.
#11
,
|
|
|
|
ButtonStyle=cbsNone
|
|
Сообщ.
#12
,
|
|
|
|
действительно список пропал
, но теперь приходиться вводить руками true/false...а хотелось бы просто щелкать по полю... |
|
Сообщ.
#13
,
|
|
|
|
Подробней, если можно.
ButtonStyle дает возможность выбора (или нет из допустимых значений) из PickList. У меня поле int(bool) при OnClick(On...) pole1=!pole1 и подставка галочки в зависимости от значения поля. |
|
Сообщ.
#14
,
|
|
|
|
у меня есть DbGrid, построенный на основе ADOTable.
В таблице есть поле, которое принимает true/false. Хочу чтобы в гриде на месте этого поля были галочки при true в таблице... Сейчас у меня чтобы поставить галочку нужно в гриде (в соответстующем поле грида) открыть список и выбрать true. Спрашиваю как сделать так, чтобы галочка снималась/выставлялась шелчком мыши. Я не пойму, что за событие OnClick? |
|
Сообщ.
#15
,
|
|
|
|
У DBGrid есть событие OnCellClick по нему меняеш значение нужного тебе поля у текущей записи.
|
|
Сообщ.
#16
,
|
|
|
|
>Bas, All
извините, но я действительно туплю... если шелкаю мышкой по гриду, то вылетает сообшение, что таблица (мой датасет) не в режиме замены или вставки... что еще нужно? ![]() ![]() procedure TForm1.DBGrid1CellClick(Column: TColumn); begin if (Column.FieldName='check') then if (Column.Field.Dataset.FieldbyName('check').AsBoolean = true) then Column.Field.Dataset.FieldbyName('check').AsBoolean := false else Column.Field.Dataset.FieldbyName('check').AsBoolean := true; end; procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); const clPaleGreen = TColor($CCFFCC); clPaleRed = TColor($CCCCFF); var Im1: TBitmap; begin Im1:=TBitmap.Create; if (Column.FieldName='check') then begin with DBGrid1.Canvas do begin Brush.Color:=clWhite; FillRect(Rect); if (Column.Field.Dataset.FieldbyName('check').AsBoolean = true) then ImageList1.GetBitmap(3,Im1)//; else ImageList1.GetBitmap(9,Im1); Draw(round((Rect.Left+Rect.Right-Im1.Width)/2),Rect.Top+3,Im1); end; end; if (Column.FieldName='del') then begin with DBGrid1.Canvas do begin Brush.Color:=clWhite; FillRect(Rect); if (Column.Field.Dataset.FieldbyName('del').AsBoolean = true) then begin ImageList1.GetBitmap(3,Im1); end else begin ImageList1.GetBitmap(9,Im1); end; Draw(round((Rect.Left+Rect.Right-Im1.Width)/2),Rect.Top+3,Im1); end; end; end; ![]() ![]() object DBGrid1: TDBGrid Left = 3 Top = 3 Width = 739 Height = 310 DataSource = ModuleModel.DataSourceModel ParentShowHint = False ShowHint = False TabOrder = 0 TitleFont.Charset = DEFAULT_CHARSET TitleFont.Color = clWindowText TitleFont.Height = -13 TitleFont.Name = 'Arial' TitleFont.Style = [] OnCellClick = DBGrid1CellClick OnDrawColumnCell = DBGrid1DrawColumnCell OnExit = DBGrid1Exit Columns = < item Expanded = False FieldName = 'id' Title.Caption = '¹' Width = 29 Visible = True end item ButtonStyle = cbsNone Expanded = False FieldName = 'check' PickList.Strings = ( 'False' 'True') Title.Alignment = taCenter Width = 16 Visible = True end item Expanded = False FieldName = 'del' PickList.Strings = ( 'False' 'True') Width = 18 Visible = True end item Expanded = False FieldName = 'material' Title.Alignment = taCenter Width = 61 Visible = True end item Expanded = False FieldName = 'influence' Title.Alignment = taCenter Width = 248 Visible = True end item Expanded = False FieldName = 'typematerial' Title.Alignment = taCenter Width = 167 Visible = True end item Expanded = False FieldName = 'comment' Title.Alignment = taCenter Visible = True end item Expanded = False FieldName = 'time' Width = 64 Visible = True end |
|
Сообщ.
#17
,
|
|
|
|
При любом перемешении по базе она автоматом вызывает метод Post()
после чего таблитца переходит в режим Browse Просто проверь свойство State (dsEdit || dsInsert) если она в одном из этих сосотояний то изменение возможно,иначе Table1.Edit() |
|
Сообщ.
#18
,
|
|
|
|
подскажите, как узнать активную строку в гриде и закрасить ее целиком?
|
|
Сообщ.
#19
,
|
|
|
|
void __fastcall TPay::PayGridDrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) //color settings { int Selected; THackDBGrid* Grid=(THackDBGrid*)Sender; Selected=Grid->DataLink->Active; TColor fg[4]={clBlack,clBlack,clYellow,clYellow}, bg[2]={clBtnFace,Avg(clAqua,clTeal)}; Grid->Canvas->Brush->Color=bg[Selected]; if(Selected) Grid->Canvas->Font->Style=TFontStyles()<<fsBold; Grid->DefaultDrawColumnCell(Rect,DataCol,Column,State); } |
|
Сообщ.
#20
,
|
|
|
|
кажется жто раздел Дельфи.Общие вопросы....
Цитата что это за приведение типов?THackDBGrid* Grid=(THackDBGrid*)Sender; На паскале это будет примерно вот так ![]() ![]() procedure TMyClass.DBGrid1DrawColumnCell(TObject *Sender, const TRect &Rect, int DataCol, TColumn *Column, TGridDrawState State) const fg: array [1..4] of integer =(clBlack,clBlack,clYellow,clYellow); bg: array [1..2] of integer =(clBtnFace,Avg(clAqua,clTeal)); var Selected : integer; begin THackDBGrid* Grid :=(THackDBGrid*)Sender; Selected := Grid.DataLink.Active; Grid.Canvas.Brush.Color :=bg[Selected]; if(Selected) then Grid.Canvas.Font.Style:=fsBold; Grid.DefaultDrawColumnCell(Rect,DataCol,Column,State); ... end; |
|
Сообщ.
#21
,
|
|
|
|
Цитата tomsksmile, 19.02.04, 13:21 THackDBGrid хм... не знаю такого... Цитата tomsksmile, 19.02.04, 13:21 На паскале это будет примерно вот так а точнее так: ![]() ![]() var Selected:integer; Grid:THackDBGrid; begin Grid:=THackDBGrid(Sender); Selected:=Grid.DataLink.Active; ... end; |
|
Сообщ.
#22
,
|
|
|
|
Цитата ZEE, 19.02.04, 13:29 хм... не знаю такого... THackDBGrid, это вероятено просто: ![]() ![]() type THackDBGrid = class(TDBGrid); Такой трюк используется для доступа к protected методам и свойствам объектов. |
|
Сообщ.
#23
,
|
|
|
|
![]() ![]() .... type THackDBGrid = class(TDBGrid); implementation .... procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); const clPaleGreen = TColor($CCFFCC); clPaleRed = TColor($CCCCFF); fg: array [1..4] of integer =(clBlack,clBlack,clYellow,clYellow); bg: array [1..2] of integer =(clBtnFace,clAqua);//Avg(clAqua,clTeal)); //< --- не знаю тут var Selected : integer; Grid : THackDBGrid; begin Grid :=THackDBGrid(Sender); Selected := Grid.DataLink.ActiveRecord; Grid.Canvas.Brush.Color :=bg[Selected]; if (Selected<>0) then Grid.Canvas.Brush.color :=clAqua; <-- исправил тут Grid.DefaultDrawColumnCell(Rect,DataCol,Column,State); ... end; как соcтыковать с функцией DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);, которую я вызываю позже - она перетирает все. |
|
Сообщ.
#24
,
|
|
|
|
а если не вызывать DBGrid1.DefaultDrawColumnCell?
|
|
Сообщ.
#25
,
|
|
|
|
тогда все разноцветное получается, но чекбоксы не прорисовываются...
|
|
Сообщ.
#26
,
|
|
|
|
Нашел оригинал
![]() ![]() Q: Как изменить цвет отмеченных записей в DBGrid? A: Hапример, так: DefaultDrawing:=False; .... procedure TfrmCard.GridDrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); var Index : Integer; Marked, Selected: Boolean; begin Marked := False; if (dgMultiSelect in Grid.Options) and THackDBGrid(Grid).Datalink.Active then Marked :=Grid.SelectedRows.Find(THackDBGrid(Grid).Datalink.Datasource.Dataset.Bookmark , Index); Selected := THackDBGrid(Grid).Datalink.Active and (Grid.Row-1 = THackDBGrid(Grid).Datalink.ActiveRecord); if Marked then begin Grid.Canvas.Brush.Color:=$DFEFDF;; Grid.Canvas.Font.Color :=clBlack; end; if Selected then begin Grid.Canvas.Brush.Color:=$FFFBF0; Grid.Canvas.Font.Color :=clBlack; if Marked then Grid.Canvas.Brush.Color:=$EFE3DF; { $8F8A30 } end; Grid.DefaultDrawColumnCell(Rect, DataCol, Column, State); end; где THackDBGrid = class(TDBGrid) property DataLink; property UpdateLock; end; Vadim Puzanov vadim@mimex.krasnoyarsk.su (2:5090/20). |
|
Сообщ.
#27
,
|
|
|
|
мой вариант:
кладешь на форму DBEdit, в котором отражаешь поле id таблицы ![]() ![]() if (Table1.FieldByName('id').Value=StrToInt(Form1.CurrentNumber.Text)) then begin with DBGrid1.Canvas do begin Brush.Color:=clBlue; Font.Color:=clWhite; FillRect(Rect); TextOut(Rect.Left+2,Rect.Top+2,Column.Field.Text); end; end; |
|
Сообщ.
#28
,
|
|
|
|
У мения проблема с прорисовкой DBGrid.
Нужно чтоб текущая запис отрисовывалос особенно (допустим красным), конечно ето делается в procedure DrawColumnCell. Я пытался перехватить текушую запис в событи AfterScroll компонента Query но при прокрутке клавишами PageUp и PageDown и при при прокрутке Scroll-ом Grid-а ето собитие не возникает (кстати собитие QueryBeforeScroll работает всегда чотко). Может вы знаете каким способом смогу заставить DrawColumnCell понимать какая запис в данный момент является текушеи. Заранее благодарю за помощ! |
|
Сообщ.
#29
,
|
|
|
|
Цитата гост @ 26.02.04, 11:36 Я пытался перехватить текушую запис в событи AfterScroll компонента Query но при прокрутке клавишами PageUp и PageDown и при при прокрутке Scroll-ом Grid-а ето собитие не возникает (кстати собитие QueryBeforeScroll работает всегда чотко). Попробуй : GridWheel(TObject *Sender,TShiftState Shift, int WheelDelta,const TPoint &MousePos,bool &Handled)//Scroll table with mouse wheel {if(WheelDelta>0) Table1.Prior(); else if(WheelDelta<0) Table1.Next(); } |
|
Сообщ.
#30
,
|
|
|
|
прочитай внимательно мой пост от 24.02.04, 03:40
в твой таблице возможно есть уникальное поле счетчик, так вот это поле выведи в окошко DBEdit, в потом сравнивай значение окошка. Цитата if (Table1.FieldByName('id').Value=StrToInt(Form1.CurrentNumber.Text)) then окошко можно скрыть ![]() ![]() DBEdit.Visible:=false; |
|
Сообщ.
#31
,
|
|
|
|
[в твой таблице возможно есть уникальное поле счетчик, так вот это поле выведи в окошко DBEdit, в потом сравнивай значение окошка.]
[SIZE=7] Все гениалное просто! (просто нужно додуматься).[/ [COLOR=red][SIZE=14]спосибо!!! |