вот последние что я сделал по этой теме. Работает через ADO, но это вообще непринципиально. Работает с любым классификатором СМ. Работает очень быстро!!!
1. Создал юнит :
Код:
unit Unit_ProceduresAndFunctions_TreeP;
interface
uses
Windows, SysUtils, Forms, ComCtrls, StdCtrls, DB, ADODB, DBTables, Classes;
type
pADOQyery = ^TADOQuery;
pStringStream = ^TStringStream;
{Процедуры}
procedure chTreeClassifierP(NameTableClassifier: PString; QueryName: pADOQyery; ResultStringStream: pStringStream);
implementation
procedure chTreeClassifierP(NameTableClassifier: PString; QueryName: pADOQyery; ResultStringStream: pStringStream);
function QuantitySymbolsInString(Line, Symbol: PString) : Integer;
var
i: Integer;
begin
Result:=0;
for i:=1 to Length(Line^) do
begin
if Line^[i] = Symbol^ then
begin
inc(Result);
end;
end;
end;
var
i, CurrentLevel, MaxLevel: Integer;
StringForStream,l,s: String;
begin
//Определяем максимальный уровень вложенности дерева
//Изначально задаём максимальный уровень вложенности дерева 0
MaxLevel:=0;
//Подготавлеваем запрос
QueryName^.SQL.Clear;
QueryName^.SQL.Add('select TREE from ' + NameTableClassifier^);
//Выполняем запрос
QueryName^.Open;
//Пробегаем по запросу и определяем максимальный уровень вложенности дерева
s:='.';
while not QueryName^.Eof do
begin
l:=QueryName^.FieldByName('TREE').AsString;
CurrentLevel:=QuantitySymbolsInString(@l,@s);
if MaxLevel < CurrentLevel then
begin
MaxLevel:=CurrentLevel;
end;
QueryName^.Next;
end;
//Закрываем запрос
QueryName^.Close;
//Подготавлеваем запрос на выборку из вьювера со структурой дерева
QueryName^.SQL.Clear;
QueryName^.SQL.Add('select ID,TREE,NAME,');
for i:=0 to MaxLevel - 1 do
begin
QueryName^.SQL.Add('nvl(To_number(substr(Classifier.GetTreeItem(tree,'+IntToStr(i)+'),1,Length(Classifier.GetTreeItem(tree,'+IntToStr(i)+'))-1)),0) as Item' + IntToStr(i));
if i <> MaxLevel - 1 then
begin
QueryName^.SQL.Add(',');
end;
end;
QueryName^.SQL.Add(' from ' + NameTableClassifier^ + ' order by ');
for i:=0 to MaxLevel - 1 do
begin
QueryName^.SQL.Add('Item'+IntToStr(i));
if i <> MaxLevel - 1 then
begin
QueryName^.SQL.Add(',');
end;
end;
//QueryName^.SQL.SaveToFile('d:\cardclass.sql');
//Выполняем запрос
QueryName^.Open;
//Пробегаем по запросу и заполняем строковый поток
s:='.';
while not QueryName^.Eof do
begin
l:=QueryName^.FieldByName('TREE').AsString;
CurrentLevel:=QuantitySymbolsInString(@l,@s);
StringForStream:='';
for i:=0 to CurrentLevel - 1 do
begin
StringForStream:=StringForStream + ' ';
end;
if QueryName^.FieldByName('TREE').AsString <> '#' then
begin
StringForStream:=StringForStream + QueryName^.FieldByName('TREE').AsString + ' ';
end;
StringForStream:=StringForStream + QueryName^.FieldByName('NAME').AsString + char(13);
ResultStringStream^.WriteString(StringForStream);
QueryName^.Next;
end;
//Закрываем запрос
QueryName^.Close;
//Устанавливам позицию потока в начало
ResultStringStream^.Position:=0;
end;
end.
2. Вызываем так :
Код:
procedure TForm_Card.FormCreate(Sender: TObject);
var
TreeStringStream: TStringStream;
NameTableClassifier: String;
begin
...
//Создаём поток
TreeStringStream:=TStringStream.Create('');
//Задаём имя таблицы
NameTableClassifier:='sacardclass';
//в процедуру передаём всё как указатели на объекты
chTreeClassifierP(@NameTableClassifier,@ADOQuery_CardClass,@TreeStringStream);
//загрузаем в деревово содержимое потока
TreeView_CardClass.LoadFromStream(TreeStringStream);
// ну и "KILLALL"
ADOQuery_CardClass.Close;
TreeStringStream.Free;
...
end;
Если чтото не заработает пишите я проверю и исправлю. Т.е. у меня то работает на 100%, может я сдесь ошибся.