Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как закрасить ячейки ;в DBGrid? [D5, MSSQL]


rom900 ©   (2002-10-31 10:20:00) 

Добрый день. Помогите пожалуйста. Можно ли в DBGrid закрашивать ячейки по номеру строки и столбца? Как это сделать? Если можно покажите на примере.
В обработчике DBGrid1DrawColumnCell у меня
выделяются номер столбца и строки ячеек, которых нужно закрасить, из массива, содержащего элементы, в которых перечисляются номер столбца и строки данных ячеек.
Использую Query для MSSQL.


MsGuns   (2002-10-31 13:47:00) [1]

Кстати, я заметил одну фигню. Если в Options у грида стоит AlwaysShowSelection, то при DBGrid1DrawColumnCell State никогдане будет gdSelected. Несмотря на то, что в опциях нет RowSelect. Интересно, почему ?


ЮЮ   (2002-10-31 13:34:00) [2]

Но здесь всё определяется по одной, текущей, записи

procedure TForm1.DBGrid_SpisokDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
Var ARect:TRect;
DBGrid1:TDBGrid;
begin
DBGrid1:=TDBGrid(Sender);

if (gdSelected in State) or (gdFocused in State)
then begin
DBGrid1.Canvas.Brush.Color := $F0F0F0;
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.Pen.Color := clBlue;
DBGrid1.Canvas.MoveTo(Rect.Left,Rect.Top);
DBGrid1.Canvas.LineTo(Rect.Right,Rect.Top);
DBGrid1.Canvas.MoveTo(Rect.Left,Rect.Bottom-1);
DBGrid1.Canvas.LineTo(Rect.Right,Rect.Bottom-1);
end
else begin
DBGrid1.Canvas.Brush.Color := clWindow;
DBGrid1.Canvas.FillRect(Rect);
end;

ARect:=Types.Rect(Rect.Left+1,Rect.Top+1,Rect.Right-2,Rect.Bottom-1);
if DBGrid1.DataSource.DataSet.FieldByName("RepSend").Value
then DBGrid1.Canvas.Font.Color := clBlack
else
if DBGrid1.DataSource.DataSet.FieldByName("SubRepSend").Value
then DBGrid1.Canvas.Font.Color := clNavy
else
DBGrid1.Canvas.Font.Color := clRed;
if DBGrid1.DataSource.DataSet.FieldByName("ReadyToRep").Value
and not DBGrid1.DataSource.DataSet.FieldByName("RepSend").Value
or
DBGrid1.DataSource.DataSet.FieldByName("ReadyToSubRep").Value
and not DBGrid1.DataSource.DataSet.FieldByName("SubRepSend").Value
then DBGrid1.Canvas.Font.Style:=[fsBold]+[fsUnderline]
else DBGrid1.Canvas.Font.Style:=[];

if Column.Field.AsString<>"0"
then begin

if Column.Alignment=taRightJustify
then begin
ARect.Left:=ARect.Left+Column.Width-Canvas.TextWidth(Column.Field.AsString)-3;
if ARect.Left<Rect.Left+1 then ARect.Left:=Rect.Left+1;
end;
DBGrid1.Canvas.TextOut(ARect.Left,ARect.Top,Column.Field.AsString);
end;

end;


MsGuns   (2002-10-31 13:31:00) [3]

>rom900 © (31.10.02 13:26)

Получай мыло !


rom900   (2002-10-31 13:26:00) [4]

В гриде отображается только один запрос.Второй нужен для того, чтобы узнать какие ячейки закрашивать. И вообще можно ли какой-
нибудь пример в Delphi даже простенький по закраске ячеек по выше сказанному вами ЮЮ и MsGuns или никто этим не занимался.


ЮЮ   (2002-10-31 13:14:00) [5]

Если в гриде отображается только один запрос, то в OnDraw
Сделать Locate для второго НД по полям группировки со значениями из первого.(Их, ктати тоже надо добавить в выборку. Или для одного Tab.device возможна толька одна запись? Тогда тут целое поле непаханное для оптимизации, ведь группировка делается по 4 полям!) Записи в обоих НД будут синхронизированы. Здесь и делать анализ.


MsGuns   (2002-10-31 13:13:00) [6]

Прочитай свой же пост. Из траблы раскраски ветка плавно мутировала в проблему оптимизации запросов.

В связи с этим старый анекдот:

Приходит молодая женщина к гинекологу. Заходит в кабинет, а там два молодых чела в халатах обедают. Ну она без лишнитх слов давай им про свои беды, мол, фригидность совсем жить не дает и т.д. А сама разделась уже и расположилась.
Вот один из парней дожевал, подошел к ней, вы.... классно и спрашивает "Ну как, почувствовали ?". Дамочка отвечает "Нет, ничего абсолютно".
"Тогда давай ты, Вася !" Вася проделал то же самое. Застегивает брюки и спрашивает "Ну что ?"
"Нет, говорит, никакого эффекта"
"Даа, тяжелый случай, вам к врачу надо"
"А вы кто ???!!!"
"Да мы вообще-то маляры, стены в коридоре красим, а сюда нас пообедать пустили"


rom900   (2002-10-31 13:01:00) [7]

А можно пример какой-нибудь простенький, а то сразу не соображу?

А запросы такие:

select Tab.device,Sum(R1),Sum(R2) from
(select a_data_general.device ,
R1=(case when (a_data_general.ats="28") and (Count(a_data_general.ats)/a_por.mar)/"1"> porog
then (Count(a_data_general.ats)/a_por.mar)/"1" else null end),
R2=(case when (a_data_general.ats="21") and (Count(a_data_general.ats)/a_por.mar)/"1"> porog
then (Count(a_data_general.ats)/a_por.mar)/"1" else null end)
from a_data_general,a_por
where (a_por.device=a_data_general.device) and (a_por.ats=a_data_general.ats)
and (a_data_general.device<>"2-ГИ") and (a_data_general.device<>"2-ГИМ")
and (a_data_general.device<>"ЭВРД") and (a_data_general.device<>"ПКВ")
and (dt >= "20021022 00:00:00") and (dt <= "20021023 23:59:59") and datepart(hh, dt) >= 1
and datepart(hh, dt) < 23 and datepart(dw, dt) NOT IN (1,7)
group by a_data_general.ats,a_data_general.device,a_por.mar,porog )
Tab
group by Tab.device


select Tab.device,Sum(R1),Sum(R2) from
(select a_data_general.device ,
R1=(case when (a_data_general.ats="28") and (Count(a_data_general.ats)/a_por.mar)/"1"> porog
then (Count(a_data_general.ats)/a_por.mar)/"1" else null end),
R2=(case when (a_data_general.ats="21") and (Count(a_data_general.ats)/a_por.mar)/"1"> porog
then (Count(a_data_general.ats)/a_por.mar)/"1" else null end)
from a_data_general,a_por
where (a_por.device=a_data_general.device) and (a_por.ats=a_data_general.ats)
and (a_data_general.device<>"2-ГИ") and (a_data_general.device<>"2-ГИМ")
and (a_data_general.device<>"ЭВРД") and (a_data_general.device<>"ПКВ")
and (dt >= "20021020 00:00:00") and (dt <= "20021021 23:59:59") and datepart(hh, dt) >= 1
and datepart(hh, dt) < 23 and datepart(dw, dt) NOT IN (1,7)
group by a_data_general.ats,a_data_general.device,a_por.mar,porog )
Tab
group by Tab.device


, как их оптимизировать


MsGuns   (2002-10-31 12:50:00) [8]

Если надо красить определенные записи НД по значению некоторых полей (ключей или номеров записи, если последние имеются), создай TList, куда после открытия (обновления) запроса закачай ссылки на записи (ключи или номера), которые надо красить, а в событии OnDrawColumnCells проверяй ключи записи на предмет наличия в TList, и если есть, то устанавливай для "рисовальщика" выделенные цвета, а потом DefaultDrawColumnCell.


ЮЮ   (2002-10-31 12:39:00) [9]

Я говорю замени номер строки на ключевое поле записи (или несколько полей, однозначно определяющих эту запись), которую ты обрабатывал, когда работал со строкой N. Про столбцы я ничего не говорил.
А в OnDraw смотришь есть ли что-то для отрисовываемой записи в твоей куче или нет.

>а что касается запроса, то он сам по себе сложен, чтобы объединять его в одном запросе
Оптимизируй :-)


rom900   (2002-10-31 12:28:00) [10]

А какое ключевое поле здесь может быть, если может быть закрашена или не закрашена любая ячейка любого столбца,а что касается запроса, то он сам по себе сложен, чтобы объединять его в одном запросе.


ЮЮ   (2002-10-31 12:09:00) [11]

>для этого и создается массив, содержащий элементы, в которых перечисляются номер столбца и строки данных ячеек

Ты глухой, или как? Оставь в покое номер строки и обрати внимание на ключевое поле. Более того, не проще ли объединить всё в одном запросе, чтобы по самой записи определять, красить или не красить, а не городить огород в стороне от DBGrida


rom900   (2002-10-31 12:07:00) [12]

Спасибо за ссылку http://www.delphikingdom.com/helloworld/dbgridcolor.htm, но она
все таки не ответила на мой вопрос


rom900   (2002-10-31 12:02:00) [13]

Вообще то задача стоит такая. Сравнить содержимое таблиц за 2
интервала времени и если в таблицах в одинаковых столбцах при одинаковых значениях строки 0-столбца будет не пусто, какие-то значения, то выделить их цветом, для этого и создается массив, содержащий элементы, в которых перечисляются номер столбца и строки данных ячеек.
И если для таблицы StringGrid действует правильно, т.к. есть ACol,ARow код:

if Query1.Active=true then
begin

if (StringGrid1.Cells[ACol,ARow]<>"") and (ACol<>0) and (ARow<>0) then
begin

for i:=1 to inach-1 do
for i1:=1 to ikon-1 do
begin
if pos(",",mas2[i,i1])<>0 then
begin
if (ACol=strtoint(copy(mas2[i,i1],1,pos(",",mas2[i,i1])-1))) and (ARow=strtoint(copy(mas2[i,i1],pos(",",mas2[i,i1])+1,length(mas2[i,i1])-pos(",",mas2[i,i1])))) then
begin
StringGrid1.Canvas.Brush.Color:=clRed;
StringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.Font.Style:=[fsBold];
StringGrid1.Canvas.TextOut(Rect.left+2,Rect.top+2,StringGrid1.Cells[ACol, ARow]);
end
else begin
StringGrid1.Canvas.Brush.Color:=clYellow;
StringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.Font.Style:=[fsBold];
StringGrid1.Canvas.TextOut(Rect.left+2,Rect.top+2,StringGrid1.Cells[ACol, ARow]);
end;
end


if ARow=0 then
begin
StringGrid1.Canvas.Brush.Color:=clMenu;
StringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.Font.Style:=[fsBold];
StringGrid1.Canvas.TextOut(Rect.left+2,Rect.top+2,StringGrid1.Cells[ACol, ARow]);
end;

А для DBGrid, я не могу это сделать, т.к.RecNo -только для локальных баз :

With DBGrid1.Canvas do Begin
if Query1.Active=true then
begin
if (Query1.Fields[DataCol].AsString<>"") and (DataCol<>0) then
begin

for i:=1 to ComboBox1.Items.Count do
for i1:=1 to Query1.RecordCount-1 do
begin
if pos(",",mas2[i,i1])<>0 then
begin

if (DataCol=strtoint(copy(mas2[i,i1],1,pos(",",mas2[i,i1])-1))) and (DBGrid1.DataSource.DataSet.RecNo = strtoint(copy(mas2[i,i1],pos(",",mas2[i,i1])+1,length(mas2[i,i1])-pos(",",mas2[i,i1])))) then
begin
DBGrid1.Canvas.Brush.Color:=clRed;
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.Font.Style:=[fsBold];
FillRect(Rect);
TextOut(Rect.left+2,Rect.top+2,Column.Field.text);
end
else begin
DBGrid1.Canvas.Brush.Color:=clYellow;
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.Font.Style:=[fsBold];
FillRect(Rect);
TextOut(Rect.left+2,Rect.top+2,Column.Field.text);
//DBGrid1.Canvas.TextOut(Rect.left+2,Rect.top+2,StringGrid1.Cells[ACol, ARow]);
end;
end

end;

end
else
DBGrid1.DefaultDrawColumnCell(Rect,datacol,Column,State);

end;
end;


Александр Спелицин   (2002-10-31 11:46:00) [14]

http://www.delphikingdom.com/helloworld/dbgridcolor.htm


ЮЮ   (2002-10-31 11:32:00) [15]

TDrawColumnCellEvent = procedure (Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState) of object;

Используешь DBGrid(Sender).Canvas
Либо рисуешь всё сам его методами в прямоугольнике Rect (тогда установи DefaultDrawing=false), либо изменяешь у Canvas цвет, шрифт и т.п. и рисовать будет сам Грид.

Но... у тебя здесь есть DataCol - номер сторбца, но нет никаких номеров строк, т.к. у грида их равно столько, сколько отображается, а не сколько записей в НД. Поэтому я и говорю, что запоминать надо не номер строки, а значение ключа. Или вообще ничего запоминать не надо, если всё это определяется полями самой записи. Внутри обработчика и определи, надо ли красить для этой записи. Если же всё сохранено вовне, то теперь, исходя из ключа текущей записи находишь элемент, соответствующий этой записи, сравниваешь DataCol с номером столбца в элементе и если совпадают, то меняешь св-ва Canvas


Aristarh   (2002-10-31 11:29:00) [16]

Пример выделения цветом строки:

with DBGrid1.Canvas do
begin

if (quDolg.FieldByName("DisconnectDate").AsDateTime <> 0) and not (gdSelected in State)
then begin
Brush.Color := clRed;
FillRect(Rect);
if (Column.Field.DataType=ftString) or (Column.Field.DataType=ftDateTime)
then TextOut(Rect.Left+2, Rect.Top+2, Column.Field.Text)
else TextOut(Rect.Right-TextWidth(Column.Field.Text)-3, Rect.Top+2, Column.Field.Text);
end
else DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);

end; // with


rom900   (2002-10-31 11:18:00) [17]

Массив, содержащий элементы, в которых перечисляются номер столбца и строки данных ячеек заполняется раньше в другой процедуре.В обработчике DBGrid1DrawColumnCell у меня выделяются номер столбца и строки ячеек, которых нужно закрасить.


ЮЮ   (2002-10-31 10:53:00) [18]

в обработчике ты уже должен "красить", а массив, содержащего элементы, в которых перечисляются номер столбца и строки данных ячеек следует заполнить раньше.
Кстати, номер строки - тонкое место, лучше использовать значение ключевого поля


Наверх

Титульная страница Поиск, карта сайта Написать письмо