Вопросы при работе с деревьями

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

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

Ответить
Nikos
Местный житель
Сообщения: 577
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Томск

Вопросы при работе с деревьями

Сообщение Nikos »

Добрый день. Есть интерфейс, в котором прорисовывается дерево (tree). Все промежуточные узлы представляют собой сумму дочерних, можно менять значения только листьев, при этом должны пересчитываться значения всех родителей до корня, кроме того, можно менять родителей у листьев или у целых веток (стандартное дерево). Почти все реализовал, но остались 2 вопроса:
1. Когда меняю родителя, то ветка уходит в нужное место, а вот курсор остается на том же самом. Хотелось бы, чтобы он переместился вместе с той записью, где и был. Использовал функцию TreeJumpToRecord – дерево ломается, при нажатии на кнопку обновить все восстанавливается. Может, я эту функцию как-то не правильно использую:

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

cmPick : 
   {
     case curField of
      #BUDMNCSPAR.NAME: 
        begin
          var cpar, ctek : comp;
          cpar := BUDMNCS.CBUDMNCS; 
          ctek := tek_budjet.getStBud(var_budjet, var_fpco);
          if ctek > 0
          {
            BUDMNCS.CBUDMNCS := ctek;
            update current BUDMNCS;
            RecalcPerentSum(BUDMNCS.CBUDMNCS);
            RecalcPerentSum(cpar);
            TreeJumpToRecord(tr1, BUDMNCS.NREC);
            ReReadRecord(#BUDMNCS);
          }
        end;
     end; 	//case
   }
2. Проблемы с обновлением экрана. Данные в листах меняю, если перехожу затем мышкой или стрелками на другую запись, то все Ok. Если же после смены значения нажать Enter (как пользователи обычно делают), то другие записи не перерисовываются, даже если потом перейти на другую запись и помогает опять только кнопка обновить

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

cmUpdateRecord: 
  { 
    if BUDMNCS.IS_LEAF = 0
    {
      update current BUDMNCS; 
      RecalcPerentSum(BUDMNCS.CBUDMNCS);
      ReReadRecord(#BUDMNCS);
    }
  }
edward_K
Заслуженный деятель интернет-сообщества
Сообщения: 5187
Зарегистрирован: 29 мар 2005, 17:49
Откуда: SPB galaxy spb

Сообщение edward_K »

RescanPanel(#budmncs) может помочь.
Nikos
Местный житель
Сообщения: 577
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Томск

Сообщение Nikos »

Пробовал ReScanPanel - не помогает. К тому же если верить документации, то ReReadRecord вызывает ReScanPanel.
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Сообщение galover »

для tree указал table?
Nikos
Местный житель
Сообщения: 577
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Томск

Сообщение Nikos »

Приведу весь код - не такой и большой. Может, кто ошибку заметит...

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

interface BudjetMNCS 'Бюджет', cyan, EscClose
show at (,,150,30);

view 
var
  cCurSpkau	: comp;
  aCurTree 	: comp;
  KodKau	  : word;
  NameTitle	: string;
  tek_budjet : BudMNCS;
  var_budjet, var_fpco : comp;
as select BUDMNCS.*, BUDMNCS2.* 
from BUDMNCS, synonym BUDMNCS BUDMNCS2, synonym BUDMNCS BUDMNCS3, synonym BUDMNCS BUDMNCSPAR
where ((aCurTree	== BUDMNCS.CBUDMNCS and
	BUDMNCS.NREC 	== BUDMNCS2.CBUDMNCS and BUDMNCS.CBUDMNCS == BUDMNCSPAR.NREC));
	
tree tr1(,,sci1478EscTreeG);
table BUDMNCS;
fields
  BUDMNCS.FULLCODE 'Код'		: [15], protect;
  BUDMNCS.NAME 'Наименование' 		: [45], protect;
  BUDMNCS.PLANMONTH[1] 'Январь'		: [10], noprotect;
  BUDMNCS.PLANMONTH[2] 'Февраль'	: [10], noprotect;
  BUDMNCS.PLANMONTH[3] 'Март'		  : [10], noprotect;
end; 

window winEditBudjet 'Редактирование статьи бюджета' EscClose; show at (,,73,5);
  panel pBudjet;
  screen scrBudjet (,,);
  table BUDMNCS;
  fields
  BUDMNCSPAR.FULLCODE (,,sci13Esc) : protect;
  BUDMNCSPAR.NAME (,,sci13Esc)    : pickbutton, protect;
  BUDMNCS.FULLCODE    : noprotect;
  BUDMNCS.NAME        : noprotect;
<<

 Вышестоящая статья .@@@@@@@@@@@@@  .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

 Код .@@@@@@@@@@@@@ Наименование .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 
>>
  end;
  end; 
  
  HandleEvent
   cmPick : 
   {
     case curField of
      #BUDMNCSPAR.NAME: 
        begin
          var cpar, ctek : comp;
          cpar := BUDMNCS.CBUDMNCS; 
          ctek := tek_budjet.getStBud(var_budjet, var_fpco);
          if ctek > 0
          {
            BUDMNCS.CBUDMNCS := ctek;
            update current BUDMNCS;
            RecalcPerentSum(BUDMNCS.CBUDMNCS);
            RecalcPerentSum(cpar);
            TreeJumpToRecord(tr1, BUDMNCS.NREC);
            ReReadRecord(#BUDMNCS);
          }
        end;
     end; 	//case
   }
 end;
end; 

TableEvent table BUDMNCS
  cmTreeTop:
  {
    aCurTree := 0;
  }
  cmTreeDown:
  {
    aCurTree := BUDMNCS.NREC;
  }
  cmTreeUp:
  {
    aCurTree := BUDMNCS.CBUDMNCS;
  }
  cmTreeNodeType:
  {
    if(not IsValid(#BUDMNCS2))
    {
      TreeSetNodeType(tr1,ntfText);
    }
    else
    {
      TreeSetNodeType(tr1,if(TreeNodeIsOpen(tr1),ntfOpen,ntfClose));
    }
  }
  
  cmUpdateRecord: 
  { 
    if BUDMNCS.IS_LEAF = 0
    {
      update current BUDMNCS; 
      RecalcPerentSum(BUDMNCS.CBUDMNCS);
      ReReadRecord(#BUDMNCS);
    }
  }
  cmInsertRecord: 
  { 
    if BUDMNCS.NAME <> '' 
    {
      insert current BUDMNCS;
      RecalcPerentSum(BUDMNCS.CBUDMNCS);
      ReReadRecord(#BUDMNCS);
    }
  } 
  cmDeleteRecord: 
  { 
  }
  cmSetDefault:
  { 
    BUDMNCS.CVARBUD   := var_budjet;
	  BUDMNCS.CFPCO     := var_fpco;
	  SetModified(true);
	  PutCommand(cmEdit);  
  }

end; 

HandleEvent
  cmEdit:
  {
    RunWindow(winEditBudjet); 
  }
  cmInsert: 
  { 
  } 
  cmDelete:
  {
    var perent_rec : comp;
    perent_rec := BUDMNCS.CBUDMNCS;
    if Message('Удалить статью ' + BUDMNCS.FULLCODE + '?',YesNo+Confirmation) = cmYes 
    {
      if BUDMNCS.IS_LEAF = 1
      {
        if Message('Данная статья содержит подчиненные! Продолжить?',YesNo+Confirmation) = cmYes 
        {
          deleteRecBudjet(BUDMNCS.NREC);
          delete current BUDMNCS; 
          RecalcPerentSum(BUDMNCS.CBUDMNCS);
        }
      }
      else
      {
        delete current BUDMNCS;
        RecalcPerentSum(BUDMNCS.CBUDMNCS);
      }
    } 
  }
  cmInit:
  {
    var_budjet := 1000000000001h;
    var_fpco   := 4001C996A5415F12h;
  }
  cmDefault:
  { 
  }
end;
end.
Screw
Слесарь-системщик
Сообщения: 304
Зарегистрирован: 29 мар 2005, 17:49
Откуда: р.Беларусь, Унитарное предприятие "ТОП СОФТ"
Контактная информация:

Сообщение Screw »

Для корректного позиционирования в дереве с помощью TreeJumpToRecord обязательно описать обработчик cmTreeNeedOwner.
Виталий
Nikos
Местный житель
Сообщения: 577
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Томск

Сообщение Nikos »

Screw, с TreeJumpToRecord все получилось, спасибо!
Как бы еще программно нажать кнопку "обновить"? ReReadRecord (ReScanPanel) так и не работают, как бы мне хотелось.
Screw
Слесарь-системщик
Сообщения: 304
Зарегистрирован: 29 мар 2005, 17:49
Откуда: р.Беларусь, Унитарное предприятие "ТОП СОФТ"
Контактная информация:

Сообщение Screw »

А чего недостаёт в вызове ReReadRecord?
Виталий
Screw
Слесарь-системщик
Сообщения: 304
Зарегистрирован: 29 мар 2005, 17:49
Откуда: р.Беларусь, Унитарное предприятие "ТОП СОФТ"
Контактная информация:

Сообщение Screw »

Грех такое советовать, но попробуйте PutCommand(cmRefreshBDdata).
Виталий
Nikos
Местный житель
Сообщения: 577
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Томск

Сообщение Nikos »

В вызове ReReadRecord недостает того, что не происходит обновление родительских узлов в дереве. После изменения дочерней записи вызывается процедура и обновляет родителей до корня. Если стрелками или мышкой уйти с измененной записи, то все ОК - сразу видны изменения. Если после изменения нажать ENTER, то даже если затем уйти с данной записи, то изменения в таблице на экране не видны, а они есть, т.к. если нажать кнопку обновить, то все отображается как надо.
PutCommand(cmRefreshBDdata) не помогает.
Ответить