Лоцман API + Плагин + Delphi

Автор Dim, 30.04.08, 10:05:17

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

YorikER

И еще: 'Состоит из ...#1Документы' - у меня вроде такой фокус не проходил - разделитель #1 воспринимается как строка, может быть правильнее таким образом: 'Состоит из ...'+#1+'Документы'?

Dim

Максим, спсибо, ещё раз спасибо! Я пробую! Изучу, постараюсь... И тоже спасибо YorikER!!!...  :)  :)  :)  :o:  ;)

Максим

Да, действительно _TYPE и asinteger ошибочно
asinteger это выбранный вами тип, для считывания из БД, например, ячейку с числом можно считать как строку.

ВОТ 100% рабочий пример, я убрал кляксы.

sel это id объекта

procedure TFmmain.Button2Click(Sender: TObject);
var
  node:Ttreenode;
  ver1:Tversion;
  data1:Tclientdataset;
begin
ver1:=Tversion.fromidversion(sel);
data1:=Tclientdataset.create(nil);
data1.data:=ver1.gettree(sel,'Состоит из ...'+#1+'Документы',false);
data1.first;
while not data1.eof do
begin
  node:=treeview1.items.add(nil,data1.fields.fieldbyname('_PRODUCT').asstring);
  node.overlayindex:=data1.fields.fieldbyname('_ID_VERSION').asinteger;
  node.stateindex:=data1.fields.fieldbyname('_ID_LINK').asinteger;
  node.Text:=node.Text+'_'+inttostr(node.overlayindex)+'_'+inttostr(node.stateindex);
  data1.Next;
end;
data1.free;
ver1.free;
end;

Dim

Здравствуй YorikER и Максим!!! У мя получается неочень хорошо, т.к. не всё выводится дерева, а мне нужно выводить все узлы (с плюсом), у мя выводится тока список без узла
Например, нужен:
- а
-- а1
  --- аа1
  --- аа2
-- а2
- б
--б2
- в
и т.д.
У мя что получилось:
- а
- б
- в
и т.д.
Понимаете или не так о чем?!...  :`(

Максим

Цитата: Dim от 16.07.08, 11:35:59
Здравствуй YorikER и Максим!!! У мя получается неочень хорошо, т.к. не всё выводится дерева, а мне нужно выводить все узлы (с плюсом), у мя выводится тока список без узла
Например, нужен:
- а
-- а1
  --- аа1
  --- аа2
-- а2
- б
--б2
- в
и т.д.
У мя что получилось:
- а
- б
- в
и т.д.
Понимаете или не так о чем?!...  :`(
Я так понял он раскрытый получается.
Поищи функцию для treeview чтобы дерево собралось и примени после построения дерева
Вроде FullCollapse

И ты видимо решил сразу грузить все дерево полностью.
Я загружаю только основную ветвь. ставлю на каждый объект плюсик (node.haschildren:=true;)
побочные ветви подгружаются по нажатию на объекты как и в лоцмане, таким образом уменьшается время при загрузке.

YorikER

Для Dim...
Я бы рекомендовал переписать исходник Масксима следующим образом:

procedure TFmmain.Button2Click(Sender: TObject);
var
  node:Ttreenode;
  ver1:Tversion;
  data1:Tclientdataset;
begin
ver1:=Tversion.fromidversion(sel);
data1:=Tclientdataset.create(nil);
data1.data:=ver1.gettree(sel,'Состоит из ...'+#1+'Документы',false);
data1.first;
while not data1.eof do
begin
  node:=treeview1.items.add(nil,data1.fields.fieldbyname('_PRODUCT').asstring);

  // поместим в свойство node.data указатель на вновь созданный объект типа TVersion
  // с идентификатором взятым из поля _ID_VERSION
  node.data:=Pointer(Tversion.fromidversion(fieldbyname('_ID_VERSION')));

  //в следующей строчке просто нет необходимости, т.к. в node.data мы
  // храним всю структуру TVersion
  //node.overlayindex:=data1.fields.fieldbyname('_ID_VERSION').asinteger;

  node.stateindex:=data1.fields.fieldbyname('_ID_LINK').asinteger;

  // вместо следующей строчки рекомендую написать процедуру чтения необходимых вам атрибутов
  // (даже в зависимости от типа объекта) с помощью сформированного и зафиксированного в node.data объекта TVersion
  // и заполнения свойства node.text
  //node.Text:=node.Text+'_'+inttostr(node.overlayindex)+'_'+inttostr(node.stateindex);
  ReadNodeAttributes(node);

  // Далее необходимо написать функциюпроверки наличия дочерних компонентов у текущей вершины
  // и заполнить свойство node.haschildren - если оно равно True, то вершина появится с крестиком (вы ее сможете раскрыть),
  // если False вершина раскрываться не будет, используйте для этого метод TVersion.GetLinkedFast...
  node.haschildren:=CheckNodeChildren(node);
  // ВНИМАНИЕ!!! Чтобы список раскрывался его надо первначально заполнить, для этого опишите процедуру для события OnExpanding,
  // эта процедура будет вызываться перед раскрытием поддерева (при нажатии на крестик), если крестик есть (haschildren=True),
  // а node.count=0 (дочерних объектов не зарегистрировано) , то необходимо поддерево заполнить, аналогично основной процедуре.

  data1.Next;
end;
data1.free;
ver1.free;
end;

Таким образом вы получите структуру не только визуального дерева, а дерево объектов TVersion с динамическим его заполнением, в зависимости от действий пользователя.

ВАЖНО!!! Не забудьте перед закрытием окна пройтись по списку treeview1.items  и освободить память от объектов TVersion, вызвав метод Free для каждого из них...

var
  curver: TVersion;
...

curver:=TVersion(node.Data);
curver.free;

Написание указанных процедур и функций - Ваше домашнее задание, не справитесь - не страшно, пишите...

Максим

Это я прописываю для плюсиков

procedure TForm1.TreeView3Expanding(Sender: TObject; Node: TTreeNode;
  var AllowExpansion: Boolean);
begin
treeview3.Items.Item[node.AbsoluteIndex].Selected:=true;
end;

Dim

Для Yoriker:
Внимательно изучал. Что за функция ReadNodeAttributes(node) и CheckNodeChildren, у мя все таки не получается  :`( , а можно поподробнее и попонятнее, мне так тяжело понять, заранее спасибо, многоуважаемый!!!
С уважением Dim.  88))

YorikER

ReadNodeAttributes(node) - это процедура, которую надо написать, чтобы сформировать строку вершины дерева TTreeView из атрибутов вершины базы данных...
Например так:

procedure ReadNodeAttribute(node: TTreeNode);
var
  cver:  TVersion;
  sName,sValue:  string;
begin
  if node.Data<>0 then // проверяем есть ли указатель на объект в данной вершине дерева
  begin
    cver:=TVersion(node.data); // преобразуем указатель в тип TVersion
    node.text:=cver.stProduct; // поместить в строку вершины TTreeView ключевой атрибут вершины TVersion
    with TClientDataSet.Create(nil) do // создаем объект типа TClientDataSet (виртуальная таблица - набор данных)
                                                    // - советую почитать об этом типе в книгах про Delphi
    try
      Data:=cver.GetAttribiutes; // заполняем набор данных списком атрибутов, используя метод объекта типа TVersion.GatAttributes
                                           // я плохо помню описание компонента TVersion в плагинах ЛОЦМАНА, поэтому
                                           // возможны ошибки в процедуре, желательно проверить...,
                                           // если я все правильно помню метод возвращает следующий набор данных
                                           //  [_ID] int - уникальный идентификатор значения атрибута; 
                                           //  [_NAME] string - название атрибута; 
                                           //  [_VALUE] string - значение атрибута; 
                                           //  [_ATTRTYPE] int - тип атрибута; 
                                           //  [_ACCESSLEVEL] int - уровень привилегии (1-чтение|2-чтение\запись) ; 
                                           //  [_ID_UNIT] string - идентификатор единицы измерения, в которой отображается значение атрибута; 
                                           //  [_UNIT] string - название единицы измерения, в которой отображается значение атрибута; 
                                           //  [_ID_MEASURE] string - идентификатор сущности, которую измерил данный атрибут; 
                                           //  [_MEASURE] string - название сущности, которую измерил данный атрибут.
      if not isEmpty then           // если набор данных не пуст, т.е. атрибуты у вершины БД есть
      while not Eof do              // запускаем цикл по виртуальной таблице, пока не дойдем до конца
      begin
        sName:=FieldByName('_NAME').AsString; // поместить в локальную переменную sName значение поля с наименованием _NAME (см.выше)
        if sName='Обозначение' then               // если в поле _NAME стоит Обозначение (название атрибута вершины БД - см.выше)
          node.Text:=node.Text+' '+FieldByName('_VALUE').AsString // добавить к строке вершины дерева значение данного атрибута
        else
        if sName='Наименование' then               // если в поле _NAME стоит Наименование (название атрибута вершины БД - см.выше)
          node.Text:=node.Text+' '+FieldByName('_VALUE').AsString; // добавить к строке вершины дерева значение данного атрибута
                                          // атрибуты Обозначение и Наименование взяты только для примера, в процедуре надо использовать свои атрибуты
        Next;                           // перейти на следующую запись
      end;
    finally
      Data:=null; // обнулить набор данных
      Free; // освободить память от объекта типа TClientDataSet
    end; 
  end;
end;

Вроде все правильно...

Dim

Для YYorikER:
Спасибо, вроде чуть получается, а ещё одна функция ChekNodeChildren(node)...
Выводится неизвестная... Я пробовал сам и не получается... Заранее спасибо
С уважением Dim  88))

YorikER

Функция ChekNodeChildren(node) должна проверять наличие дочерних объектов у вершины и возвращать True, если они есть или False если их нет.
Ориентировочно она будет такая...

function CheckNodeChildren(node: TTreeNode): boolean;
var
  curVer: TVersion;
begin
  Result:=False; // присваиваем на всякий случай
  if node.Data<>nil
  begin
    curVer:=TVersion(node.Data); // извлекаем из node.Data объект типа TVersion
    with TClientDataSet.Create(nil) do // в книгах по Delphi прочитай про оператор with ... do и конструкцию try ... finaly... end;
    try
      Data:=curVer.GetLinkedObjects('Состоит из ...',False,False,False); // получаем список объектов по связи "Состоит из ..."
      if IsEmpty then Result:=False // если список пуст, возвращаем False
      else Result:=True; // если список заполнен, возвращаем True
    finally
      Data:=null;
      Free;
    end;
  end;
end;

У сервера приложений есть более быстрый метод GetLinkedFast для получения списка дочерних объектов по связи, но в объекте типа TVersion (насколько я помню) этот метод не представлен...

Dim

Для YorikER - многоуважаемый:
Спасибо огромное, и ещё один вопрос что за переменная sel? Где это взял? В VARе нет sel, а в программе есть - ver1:=Tversion.fromidversion(sel) - подскажите пожалуйста, по-моему это единственный вопрос? Буду благодарен  :)
С уважением Dim!!!

procedure TFmmain.Button2Click(Sender: TObject);
var
  node:Ttreenode;
  ver1:Tversion;
  data1:Tclientdataset;
begin
ver1:=Tversion.fromidversion(sel);
data1:=Tclientdataset.create(nil);
...
...
...
end

Dim

Для YorikER:
Я не могу разобраться процедуру для события OnExpanding, долго думал и изучал и никак не пойму...

Который Вы писали... Можно поподробнее, у мя осталось чуть-чуть...
=======================================
// ВНИМАНИЕ!!! Чтобы список раскрывался его надо первначально заполнить, для этого опишите процедуру для события OnExpanding,
  // эта процедура будет вызываться перед раскрытием поддерева (при нажатии на крестик), если крестик есть (haschildren=True),
  // а node.count=0 (дочерних объектов не зарегистрировано) , то необходимо поддерево заполнить, аналогично основной процедуре.
=======================================

Я же первый раз стал разобраться компонента TreeView, я тебя очень благодарен  :) ... Буду ждать с терпением и с пониманием...
С уважением Dim...

Максим

sel - это индефикатор объекта

заменяет двойное нажатие на объекте нажатием на плюсик
procedure TForm1.TreeView3Expanding(Sender: TObject; Node: TTreeNode;
  var AllowExpansion: Boolean);
begin
treeview3.Items.Item[node.AbsoluteIndex].Selected:=true;
end;

Dim

Цитата: Максим от 24.07.08, 10:51:54

заменяет двойное нажатие на объекте нажатием на плюсик
procedure TForm1.TreeView3Expanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
begin
treeview3.Items.Item[node.AbsoluteIndex].Selected:=true;
end;

Здравствуй Максим!
Я уже пробовал, безрезультатно. Плюсик непослушен, все таки стоит и не выводит дальше...  :`( . Можешь объяснить...
С уважением Dim...

Максим

вот mas1112008 . narod . ru
смотри

YorikER

Для Dim... Sel - это идентификатор объекта, от которого нужно строить дерево... Это переменная типа integer, которая должна быть объявлена (по крайней мере для примера) где-то на уровне выше, чем описания процедур, например глобальная переменная (в var всего модуля)... Идентификатор объекта - это целое число, номер записи в базе данных, определить его можно посмотрев свойства объекта в ЛОЦМАН-Клиенте (см. рис).

YorikER

В нижней строчке окна - Идентификатор.
Теперь событие OnExpanding... В Delphi7 после установки TTreeView на форму, в окне Инспектор свойств на закладке Events (события) найти в списке событие OnExpanding и дважды щелкнуть по нему... Откроется окно процедуры - обработчика данного события

procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
  var AllowExpansion: Boolean);
begin

end;

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

Успехов...

YorikER

Забыл прикрепить картинку

Dim

Для YorikER:
Теперь я понял что за Sel - идентификатор объекта, но как описать прогу с onExpanding ->

procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
  var AllowExpansion: Boolean);
begin
... (не знаю, что написать здесь, т.к. у мя нет опыта TreeView с БД (Лоцман))...  :`(
end;

Напишите пожалуйста исходник с onExpanding  связанный с предыдущими прогами, который Вы написали. Доверяю Вас, что Вы напишите...
Буду благодарен!!!  88))  :)
С уважением Dim.  ::)

Для Максима:
Я посмотрел Ваш пример, всё понятно, но мне надо с Лоцманом, Вы пробуйте с Лоцманом с TreeView, у меня всё равно безрезультатно...  :((( Всё равно не продолжается полностью дерева,
Вот такой у мя получилось:
+ а (не щелкается, т.к. не хочет выводить)
б
+ в
и т.д.
Мне нужен такой чтоб щелкал в плюсик и выводил в минусик и продолжалась все дерева (все узлы)
- а
-- а1
  + аа1
  -- аа2
-- а2
б
+ в
и т.д.

с уважением Dim