Страница 1 из 1

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

Добавлено: 07 апр 2010, 11:42
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);
    }
  }

Добавлено: 07 апр 2010, 12:45
edward_K
RescanPanel(#budmncs) может помочь.

Добавлено: 07 апр 2010, 14:24
Nikos
Пробовал ReScanPanel - не помогает. К тому же если верить документации, то ReReadRecord вызывает ReScanPanel.

Добавлено: 07 апр 2010, 14:45
galover
для tree указал table?

Добавлено: 07 апр 2010, 15:07
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.

Добавлено: 12 апр 2010, 15:22
Screw
Для корректного позиционирования в дереве с помощью TreeJumpToRecord обязательно описать обработчик cmTreeNeedOwner.

Добавлено: 13 апр 2010, 08:04
Nikos
Screw, с TreeJumpToRecord все получилось, спасибо!
Как бы еще программно нажать кнопку "обновить"? ReReadRecord (ReScanPanel) так и не работают, как бы мне хотелось.

Добавлено: 14 апр 2010, 16:57
Screw
А чего недостаёт в вызове ReReadRecord?

Добавлено: 14 апр 2010, 16:58
Screw
Грех такое советовать, но попробуйте PutCommand(cmRefreshBDdata).

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