Раскрытие дерева производственной спецификации

Программирование на Атлантисе (VIP, FCOM, ARD), FastReport

Модераторы: m0p3e, edward_K, Модераторы

Ответить
Epifanich
Сообщения: 18
Зарегистрирован: 30 окт 2006, 15:39

Раскрытие дерева производственной спецификации

Сообщение Epifanich »

Всем здравствуйте!
Кто-нибудь знает алгоритм построения дерева производственной спецификации как в стандартном отчёте "Технологический состав изделия"? То есть, необходим отчёт примерно такого вида:

Кронштейн 581460.01.18.440
├─Кронштейн СБ-172-1.01.03.253
│`└─Лист 6х1500х6000 Ст3сп3 Б-ПН-НО ГОСТ 19903-74
├─Ниппель 581460.01.18.445
│`└─Ниппель 581460.01.18.445 [02]
│```└─Труба 53х6 В20 7100 ГОСТ 8734-75 (м)
├─Опора 581460.01.18.442
│`└─Труба 48х4 В20 7100 ГОСТ 8734-75
├─Проволока сварочная d 1,2 OK Autrod 12.51
├─Сопло 581460.01.18.444
│`└─Сопло 581460.01.18.444 [02]
│```└─Труба 48х4 В20 7100 ГОСТ 8734-75
└─Щека СБ-172-1.01.03.261
```└─Лист 6х1500х6000 Ст3сп3 Б-ПН-НО ГОСТ 19903-74

Я сделал, но с раскрытием по уровням (сначала все элементы 1-го уровня вхождения, затем 2-го, и т.д. до конечного уровня). Говорят: "Нечитаемо и ненаглядно, не видно структуры":

Кронштейн 581460.01.18.440
-----Кронштейн СБ-172-1.01.03.253 // 1 уровень
-----Ниппель 581460.01.18.445 // 1 уровень
-----Опора 581460.01.18.442 // 1 уровень
-----Проволока сварочная d 1,2 OK Autrod 12.51 // 1 уровень
-----Сопло 581460.01.18.444 // 1 уровень
-----Щека СБ-172-1.01.03.261 // 1 уровень
Кронштейн СБ-172-1.01.03.253
-----Лист 6х1500х6000 Ст3сп3 Б-ПН-НО ГОСТ 19903-74 // 2 уровень
Ниппель 581460.01.18.445
-----Ниппель 581460.01.18.445 [02] // 2 уровень
Опора 581460.01.18.442
-----Труба 48х4 В20 7100 ГОСТ 8734-75 // 2 уровень
Сопло 581460.01.18.444
-----Сопло 581460.01.18.444 [02] // 2 уровень
Щека СБ-172-1.01.03.261
-----Лист 6х1500х6000 Ст3сп3 Б-ПН-НО ГОСТ 19903-74 // 2 уровень
Ниппель 581460.01.18.445 [02]
-----Труба 53х6 В20 7100 ГОСТ 8734-75 (м) // 3 уровень
Сопло 581460.01.18.444 [02]
-----Труба 48х4 В20 7100 ГОСТ 8734-75 // 3 уровень

А как раскрыть дерево на всю глубину ветки?
edward_K
Заслуженный деятель интернет-сообщества
Сообщения: 5187
Зарегистрирован: 29 мар 2005, 17:49
Откуда: SPB galaxy spb

Сообщение edward_K »

проще всего конечно по древу и бежать. TreeGetNext ну и TreeLevel чтобы отступы определять. Если же прям в форме то позиционирование в цикле
.{ while
нужно делать с помощью какой ли бо спец.функции
(мне больше нравиться тыды рекурсивная функция- поищите в форуме, ну и вывод в excel).
RAJAH
Местный житель
Сообщения: 932
Зарегистрирован: 18 фев 2008, 12:49

Сообщение RAJAH »

А можно поподробнее... Сначала что, дерево построить в фейсе и его распечатывать? Что за "спец.функция"? А если уровней порядка 20-ти рекурсия сработает?
edward_K
Заслуженный деятель интернет-сообщества
Сообщения: 5187
Зарегистрирован: 29 мар 2005, 17:49
Откуда: SPB galaxy spb

Сообщение edward_K »

если делать аккуратно то сработает.
суть в том что нужно в локальной переменной сохранить позицию
после вызова цикла по нижестоящим вернуться точно на ту же позицию и не сломать дальнейший цикл по этому уровню. Подробней ищите по форуму. По древу проще. К тому же не обязательно же его на экран отображать.
RAJAH
Местный житель
Сообщения: 932
Зарегистрирован: 18 фев 2008, 12:49

Сообщение RAJAH »

Так это ж куча локальных переменных получится! Чем сложнее спецификация, тем необозримее будет. Я тоже над этим думал, даже массивы хотел использовать, но как вернуться на ту же позицию? Если около 20 уровней, то и 20 разветвлений получается только на одной ветке! Веток, кстати, тоже немало. По-моему, это нереально... Или я чего-то не понимаю?
edward_K
Заслуженный деятель интернет-сообщества
Сообщения: 5187
Зарегистрирован: 29 мар 2005, 17:49
Откуда: SPB galaxy spb

Сообщение edward_K »

я грил про локальную для функции. + 2 параметра у самой функции ( уровень - чтобы слишком глубоко не упасть, и nrec узла), ну желательно передавать через доп.переменные (локальные) - итого 5.
function treescan(wlev :word ; wparent :comp ) :boolean ;
var wwlev :word ;
wwparent: comp ;
wnrec:comp ;
{treescan:=false ;
wwlev:=wlev ;
if gefirst ... where (( wprarent == .....cnode ))=0
do {
if not nextvisual then exit ;
...
wnrec := ....nrec
wwparent:=wnrec
if not treescan( wwlev , wwparent) then exit ;
if getfirst .... where (( wnrec === ....nrec ))=0 {}

} while genext ... where (( wprarent == .....cnode ))=0 ;
treescan:=true ;
}

что то типа того.
первый вызов
treescan(0,0)
RAJAH
Местный житель
Сообщения: 932
Зарегистрирован: 18 фев 2008, 12:49

Сообщение RAJAH »

Что-то мой фейс с этой функцией не хочет компилиться. Говорит: "нет такой функции, поля или метода GetFirst". Что не так написал? TLIST - это куда элементы ПС выгружаются - таблица в памяти, она в проекте описана. TLIST.FMCNR - нрек МЦ, TLIST.FPAR - её родитель, TLIST.FMC - название. Пробовал modifier getfirst - на "modifier" ругается.

Код: Выделить всё

interface TreePS 'Построение производственной спецификации' escClose,  doAccept, cyan
   show at (15,4,130,25);

var
   mc, pmc, har, pdr, pdrk, ppdrk, skl, sklk, psklk, obz, pobz, ediz, pediz, edizm, tip, ptip, nn, pnn, tmpt, tmpr, starob, novob, okp, razmer: string;
   wtip, pwtip: word;
   ur, i: integer;
   j, pnum: longint;
   mcnr, tmpmc, nrc, dopar, ispar, mc_, par_, tmps: comp;
   isb, uzl: boolean;
   kvo, kol, pkol, mnz, otk: double;

function treescan(wlev :word ; wparent :comp ): boolean;

var
  wwlev :word;
  wwparent: comp;
  wnrec: comp;

{
  treescan:=false ; 
  wwlev:=wlev ; 
  if (modifier getfirst tlist where wparent = tlist.fpar ) <> tsok
  do
  { 
    message(tlist.fmc);
    wnrec := tlist.fmcnr;
    wwparent:=wnrec;
    if not treescan(wwlev, wwparent) then exit; 
    if getfirst tlist where (( wnrec === tlist.fmcnr ))=0
    {}
  }
  while getnext tlist where (( wprarent == tlist.fpar ))=0; 
  treescan:=true ; 
}

create view spis as
select katmc.name, katmc.barkod, kmc.nrec, kmc.name, katmc.nrec, katmc.prmat, katmc.obozn, typemc.name, katpodr.name, katpodr.kod, katotped.abbr, sklad.name, sklad.kod, ps_lines.kol, kated.abbr, ps_lines.ced, katotped.koef, kmc.okdp, ps_lines.nrec
from hdr_ps, katmc, ps_lines, katmc kmc, typemc, katpodr, katotped, katpodr sklad, kated
where
((
mcnr             == kmc.nrec and
kmc.nrec        /== hdr_ps.cizd and
4                == hdr_ps.ctypeizd and
hdr_ps.cpodr     == katpodr.nrec and
hdr_ps.nrec     /== ps_lines.chdr and
ps_lines.canval1 == sklad.nrec and
ps_lines.ced     == katotped.nrec and
katmc.ced       /== kated.nrec and
ps_lines.cdet   /== katmc.nrec and
katmc.ctype      == typemc.nrec
))
and kmc.nrec<>katmc.nrec;
....
Den
Местный житель
Сообщения: 1842
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Ярославская область ОАО "Часовой завод Чайка" г. Углич
Контактная информация:

Сообщение Den »

<интерфейс> = [<константы-исходного-файла>]
interface <имя> [<заголовок>] [<атрибуты-окна>];
[<конструкция-Pascal>]
[<координаты>]
<оператор-создания-логической-таблицы>
<параметры-интерфейса>
<раздел-описания-блокировок>
<раздел-форм>
{ <окно> | <область-ввода> | <панель> | <обработчик-событий>
| <константы-интерфейса> | <процедура> | <функция>
}
end.
RAJAH
Местный житель
Сообщения: 932
Зарегистрирован: 18 фев 2008, 12:49

Сообщение RAJAH »

Спасибо! Я уже опытным путём догадался. :-)
Только такое чувство, что wlev и wwlev всегда равны 0.
RAJAH
Местный житель
Сообщения: 932
Зарегистрирован: 18 фев 2008, 12:49

Сообщение RAJAH »

Зацикливается рекурсия...
edward_K
Заслуженный деятель интернет-сообщества
Сообщения: 5187
Зарегистрирован: 29 мар 2005, 17:49
Откуда: SPB galaxy spb

Сообщение edward_K »

wwlev:=wlev+1 ;
if (modifier getfirst tlist where (( wparent = tlist.fpar )) =0
ну и могет быть order by надо задать.
logstrtofile вам поможет
это образчик а не готовый кусок - так что мучайтесь :)
RAJAH
Местный житель
Сообщения: 932
Зарегистрирован: 18 фев 2008, 12:49

Сообщение RAJAH »

Вроде, с рекурсией более-менее разобрался. Всем СПАСИБО! Кому интересно - выкладываю. Вся загвоздка была в том, что МЦ может входить в ПС несколько раз в разных узлах :) . Поле fnum - это просто нумерация, что-то вроде nrec (для уникальности)

Код: Выделить всё

function treescan(wlev :word ; wparent :comp ): boolean;

var
  wwlev, num: word;
  wwparent, wnrec: comp;

{
  treescan:=false ;
  if ((sost.getfirst tlist where tlist.fpar = wparent) = tsOK)
  do
  {
//  тут у меня вставка в локальную таблицу...
    wnrec := sost.tlist.fmcnr;
    num := sost.tlist.fnum;
    wwparent:=wnrec;
    wwlev := word(sost.tlist.fin)+1;
    if not treescan(wwlev, wwparent) then exit;
    if ((sost.getfirst tlist where num = tlist.fnum) = tsOK)
    {}
  }
  while ((sost.getnext tlist where wparent = tlist.fpar)= tsOK) ;
  treescan:=true;
}
Теперь бы как-нибудь эту локальную таблицу в отчёте увидеть :-) - но это тема другая (уже горячо обсуждается)
http://www.tyumbit.ru/gal_forum/viewtopic.php?t=9052
Ответить