Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.04.2015, 11:04   #1
mixa33rus
Пользователь
 
Регистрация: 28.11.2014
Сообщений: 10
По умолчанию Вывод списка с уровнями вложенности в treeview из БД

Здравствуйте!
Помогите разобраться, как лучше сделать, где у меня ошибка.
Есть база данных firebird.
Таблица базы данных изображена на рис. 1.
Столбец PARENT нужен для определения уровня вложенности и сортировки. Целое число - родитель. С Долями - дочерняя, где целое число указывает на родителя.
2 уровня вложенности.

Получается только так, как на рис. 2.

Код:
TN : TTreeNode;
I:Integer;
begin
  i:=-1;
  DataModule3.IBQuery1.SQL.Text := 'select * from waste order by PARENT ASC';
  DataModule3.IBQuery1.Open;
  while not DataModule3.IBQuery1.Eof do
    begin
      if (DataModule3.IBQuery1.FieldByName('PARENT').AsFloat)= Round(DataModule3.IBQuery1.FieldByName('PARENT').AsFloat) then
        begin
         TN := TreeView1.Items.AddObject(nil, DataModule3.IBQuery1.FieldValues['Name'], TObject(DataModule3.IBQuery1.FieldByName('ID_waste').AsInteger));
        end;
      if (DataModule3.IBQuery1.FieldByName('PARENT').AsFloat)<> Round(DataModule3.IBQuery1.FieldByName('PARENT').AsFloat) then
        begin
         TN := TreeView1.Items.AddChild(TreeView1.Items.Item[i], DataModule3.IBQuery1.FieldValues['Name']);
        end;
      i:=i+1;
      DataModule3.IBQuery1.Next;
    end;
  DataModule3.IBQuery1.Transaction.Commit;
  DataModule3.IBQuery1.Close;
end;
"мясо" уходит еще на уровень дальше.
Изображения
Тип файла: jpg Снимок1.JPG (19.2 Кб, 127 просмотров)
Тип файла: jpg Снимок2.JPG (11.4 Кб, 111 просмотров)
mixa33rus вне форума Ответить с цитированием
Старый 05.04.2015, 11:20   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
    if DataModule3.IBQuery1.FieldByName('PARENT').AsFloat=Round(DataModule3.IBQuery1.FieldByName('PARENT').AsFloat
      then TN:=TreeView1.Items.AddObject(nil, DataModule3.IBQuery1.FieldValues['Name'], TObject(DataModule3.IBQuery1.FieldByName('ID_waste').AsInteger))
      else TreeView1.Items.AddChild(TN,DataModule3.IBQuery1.FieldValues['Name']);
Если в таблице будет порушена корректность уровней этот код рухнет
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 05.04.2015 в 11:25.
Аватар вне форума Ответить с цитированием
Старый 05.04.2015, 12:49   #3
mixa33rus
Пользователь
 
Регистрация: 28.11.2014
Сообщений: 10
Счастье

Аватар, спасибо большое. Все работает.
mixa33rus вне форума Ответить с цитированием
Старый 07.04.2015, 19:30   #4
mixa33rus
Пользователь
 
Регистрация: 28.11.2014
Сообщений: 10
По умолчанию

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

Код:
      if DataModule3.IBQuery1.FieldByName('INVISIBLE').AsInteger=0 then
        begin
          if (DataModule3.IBQuery1.FieldByName('PARENT').AsFloat=Round(DataModule3.IBQuery1.FieldByName('PARENT').AsFloat))
          then TN:=Form1.TreeView1.Items.AddObject(nil, DataModule3.IBQuery1.FieldValues['Name'], TObject(DataModule3.IBQuery1.FieldByName('ID_waste').AsInteger))
          else Form1.TreeView1.Items.AddChild(TN,DataModule3.IBQuery1.FieldValues['Name']);
          DataModule3.IBQuery1.Next;
        end;
        if DataModule3.IBQuery1.FieldByName('INVISIBLE').AsInteger=1 then
        begin
          if (DataModule3.IBQuery1.FieldByName('PARENT').AsFloat=Round(DataModule3.IBQuery1.FieldByName('PARENT').AsFloat))
          then TN:=Form1.TreeView1.Items.AddObject(nil, DataModule3.IBQuery1.FieldValues['Name'], TObject(DataModule3.IBQuery1.FieldByName('ID_waste').AsInteger))
          else Form1.TreeView1.Items.AddChild(TN,DataModule3.IBQuery1.FieldValues['Name']);
          DataModule3.IBQuery1.Next;
        end;
Например, при INVISIBLE=0 шрифт делать красным
mixa33rus вне форума Ответить с цитированием
Старый 07.04.2015, 22:59   #5
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

использовать событие (Events) OnDrawItem (или что-то подобное)

по item узнавать (находить) соотв. запись
Код:
IBQuery1.Locate('id_vaste', integer(item.Data), []);
и устанавливать параметы рисования.
Код:
if ibquery1.fieldbyname('invisible').AsInteger=0 then
  TreeView1.Canvas.font.color:=clred
else
  TReeView1.Canvas.font.color:=clblack;
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 09.04.2015, 15:12   #6
mixa33rus
Пользователь
 
Регистрация: 28.11.2014
Сообщений: 10
По умолчанию

Код:
IBQuery1.Locate('id_vaste', integer(item.Data), []);
integer(item.Data) это от treeview?

Вот такая реализация? или я что-то не понимаю
Код:
procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
DataModule3.IBQuery2.SQL.Text := 'select * from waste order by PARENT ASC';
DataModule3.IBQuery2.Open;
DataModule3.IBQuery2.Locate('id_waste', integer(item.Data), []);

if DataModule3.IBQuery2.fieldbyname('invisible').AsInteger=0 then
  TreeView1.Canvas.font.color:=clred
else
  TReeView1.Canvas.font.color:=clblack;

DataModule3.IBQuery2.Close;

end;
окрашивает в какой-то один цвет все строки, в зависимости от значения integer(item.Data)
mixa33rus вне форума Ответить с цитированием
Старый 09.04.2015, 15:19   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
integer(item.Data) это от treeview?
От него и туда засунуть чего-то нужно при заполнении тривью, прежде чем использовать

И в OnCustomDrawItem выполнять запрос крайне не эффективно. Во-первых это событие отрабатываеи множество раз, во-вторых если уж использовать данные из базы, то их можно один раз потянуть, а в OnCustomDrawItem просто locate в этих данных
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 09.04.2015, 19:04   #8
mixa33rus
Пользователь
 
Регистрация: 28.11.2014
Сообщений: 10
По умолчанию

Цитата:
От него и туда засунуть чего-то нужно при заполнении тривью, прежде чем использовать
Ну я так понимаю, что засовываем число столбца id_waste добавляемой строки.

Например, есть у нас в БД две записи с id_waste 42 и 43 со значениями INVISIBLE 0 и 1
Прописываем вручную заместо значения item.Data integer(42)
Код:
DataModule3.IBQuery2.Locate('id_waste', integer(42), []);

if DataModule3.IBQuery2.fieldbyname('INVISIBLE').AsInteger=0 then
  TreeView1.Canvas.font.color:=clred
else
  TReeView1.Canvas.font.color:=clblack;
в итоге цвет шрифта черный (по последнему, 43).

Цитата:
И в OnCustomDrawItem выполнять запрос крайне не эффективно.
Поместил запрос в компонент.

Реализовал вывод дерева с выделением элементов разными цветами вот так:

Код:
procedure TreeView;
var TN: TTreeNode;
    p: PMyRecord;
begin
  Form1.TreeView1.Items.Clear;
  DataModule3.IBQuery1.SQL.Text := 'select * from waste order by PARENT ASC';
  DataModule3.IBQuery1.Open;
  while not DataModule3.IBQuery1.Eof do
    begin
          if (DataModule3.IBQuery1.FieldByName('PARENT').AsFloat=Round(DataModule3.IBQuery1.FieldByName('PARENT').AsFloat))
          then
            begin
              GetMem(p,SizeOf(TMyRecord));
              p^.IDwaste:=DataModule3.IBQuery1.RecNo;
              p^.invisible:=DataModule3.IBQuery1.FieldByName('INVISIBLE').Asinteger;
              TN:=Form1.TreeView1.Items.AddObject(nil,DataModule3.IBQuery1.FieldByName('Name').AsString,p);
            end

          else
            begin
              GetMem(p,SizeOf(TMyRecord));
              p^.IDwaste:=DataModule3.IBQuery1.RecNo;
              p^.invisible:=DataModule3.IBQuery1.FieldByName('INVISIBLE').Asinteger;
              Form1.TreeView1.Items.AddChildObject(TN,DataModule3.IBQuery1.FieldByName('Name').AsString,p);
            end;

          DataModule3.IBQuery1.Next;
    end;
  DataModule3.IBQuery1.Transaction.Commit;
  DataModule3.IBQuery1.Close;
  Form1.TreeView1.FullExpand;
end;
Код:
procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
begin
if PMyRecord(Node.Data)^.invisible=0 then
Sender.Canvas.Font.Color:=clBtnShadow;
end;
Может кому пригодится.

Интересует вот что еще. Есть такая связка: таблица БД->IBTable->DataSource->DBGrid. По простому, выводим информацию таблицы в DBGrid.

Например, в таблице БД 5 столбцов, мне нужно вывести данные 3х. Как это сделать? Пробовал удалять столбцы из FildDefs в IBTable - не помогает. Через код тоже не пойму как.

Последний раз редактировалось Stilet; 04.05.2015 в 10:34.
mixa33rus вне форума Ответить с цитированием
Старый 13.04.2015, 20:52   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

А не полагайся на авторазметку, разметь колонки грида явно на этапе проектирования формы. Кликни на гриде правой кнопкой, в меню увидешь
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 15.04.2015, 11:35   #10
mixa33rus
Пользователь
 
Регистрация: 28.11.2014
Сообщений: 10
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
А не полагайся на авторазметку, разметь колонки грида явно на этапе проектирования формы. Кликни на гриде правой кнопкой, в меню увидешь
Спасибо. Решил эту задачу.

я пробовал кодом вот так разметить:

Код:
  DBGrid1.DataSource:=DataModule3.DataSource4;
  DBGrid1.Columns[0].FieldName:='DATE';
  DBGrid1.Columns[0].Title.Caption:='Дата';
  DBGrid1.Columns[0].Width:=60;
  DBGrid1.Columns[1].FieldName:='SUMM_BY';
  DBGrid1.Columns[1].Title.Caption:='Сумма покупки';
  DBGrid1.Columns[1].Width:=20;
  ...
Но все равно включалась авторазметка. Как раз в том месте, в columns editor насоздавать пустых элементов (columns) и все заработало как надо.
mixa33rus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
TreeView - идентификатор элемента списка spirit-ua Общие вопросы Delphi 10 08.08.2013 16:05
VC++ нарисовать плюс/минус как в злементе treeView для раскрывания списка mikl1981 Visual C++ 0 28.05.2013 10:07
Вывод списка символов справа налево 5 раз подряд и исключить вывод цифр Gareek Помощь студентам 2 23.12.2011 21:41
TreeView - необходимо развернуть нужный узел, независимо от степени вложенности Mikhail Bakurov Общие вопросы C/C++ 0 20.05.2009 07:42
Вывод БД в TreeView? Snegovik Помощь студентам 23 30.09.2008 20:43