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

Почему обнуляется переменная?

Добавлено: 10 апр 2009, 16:54
Nikos
Добрый день. Есть такой интерфейс:

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

interface orgcube 'Сопоставление каталогов контрагентов', cyan, EscClose;
show at (,,115,50);

create view 
var
  tek_User	: string;
as select *
from KATORG, CUBEKATAL
where ((
	1		== CUBEKATAL.WTABLE
and	tek_User	== CUBEKATAL.USERNAME
and	KATORG.CORPOIN	== CUBEKATAL.ID
));

browse brCor 'Соответствие контрагентов' (,,sci1Esc);
table KATORG;
fields
  KATORG.UNN  'ИНН'		:[15];
  KATORG.NAME 'Наименование'	:[40];
  CUBEKATAL.CODE 'ИНН'		:[15],protect,pickbutton;
  CUBEKATAL.NAME 'Наименование'	:[40],protect,pickbutton;
end;

TableEvent table KATORG
  cmUpdateRecord:
  {
    update current KATORG;
  }
end;

HandleEvent
  cmpick:
  {
    case CurField of
      #CUBEKATAL.CODE, #CUBEKATAL.NAME:
      {
        RunInterface('GetCubeOrg',tek_User, KATORG.CORPOIN);
      }
    end;
  }
  cmDel:
  {
    case CurField of
      #CUBEKATAL.CODE, #CUBEKATAL.NAME:
      {
        update current KATORG set KATORG.CORPOIN := 0;
      }
    end;
  }
  cminit:
  {
    tek_User := sGetTune('USER.OWNNAME');
  }
end;
end.
Все хорошо работает до тех пор, пока не нажать на кнопку DEL. В этом случае переменная tek_User обнуляется (пустая строка). Не подскажите почему?

Добавлено: 10 апр 2009, 19:40
edward_K
1. Username используйте прямо в запросе
2. для удаления нужно использовать cmDelOnProtect и в конце rescanpanel(#katorg)
3. а cube это что за прога?

Добавлено: 12 апр 2009, 13:30
Nikos
1. Изменил вьюху:

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

create view 
var
  tek_User	: string;
as select *
from KATORG, CUBEKATAL
where ((
	1		== CUBEKATAL.WTABLE
and	sGetTune('USER.OWNNAME')	== CUBEKATAL.USERNAME
and	KATORG.CORPOIN	== CUBEKATAL.ID
));
Результата нет. Точнее tek_User теперь не обнуляется, но такое ощущение, что обнуляется sGetTune('USER.OWNNAME') - после нажатия на DEL все связи исчезают с экрана, хотя они остаются (при повторном открытии интерфейса все соответствия на месте, кроме того, на котором нажал DEL).
2. cmDelOnProtect не помогает - результат ничем не отличается
3. КУБ - сторонняя программа. Требуется организовать экспорт первичных документов из Галактики в нее.
Что еще можно попробовать? Возможно, дело в типе? KATORG.CORPOIN - это LongInt

Добавлено: 12 апр 2009, 16:04
edward_K
а rescanpanel(#katorg) что не помогает? У вас просто проблема с прорисовкой. по идее он должен перерисоавть интерфейс аналогично переоткрытию - вы по ctrl+F4 то проверяли прежде чем заявляить, что переменная сбрасывается?
тип KATORG.CORPOIN при условии, что он совпадает с CUBEKATAL.ID или имеет достаточную длину не важен. в галке часто string вяжут с comp -и ничего работатет.

Добавлено: 13 апр 2009, 08:49
Nikos
Проверял все, до чего мог додуматься. Если поставить rescanpanel(#katorg), то при нажатии DEL с экрана исчезают все связи! Причем исчезают как с вариантом
and tek_User == CUBEKATAL.USERNAME
так и с
and sGetTune('USER.OWNNAME') == CUBEKATAL.USERNAME
А переменную tek_User я выводил на экран с помощью Message - После нажатия DEL она пустая, а до нажатия нормальная.

Добавлено: 13 апр 2009, 11:04
galover
Nikos
ReReadRecord(#katorg) пробовали?
Попробуйте еще модифицировать не сам KatOrg, а его псевдоним

Добавлено: 13 апр 2009, 11:46
Nikos
Пробовал и с ReReadRecord(#katorg) и сейчас попробовал с псевдонимом - результат не изменился.
Проблема точно не с прорисовкой. Т.к. при вызове
RunInterface('GetCubeOrg',tek_User, KATORG.CORPOIN);
в интерфейс переменная приходин нулевая, а до DEL нормальная.
Пришлось поле сделать nodel, а чистить связь через F8. В таком варианте:
cmDelete:
{
update current KATORG set KATORG.CCUBE := 0;
}
работает все нормально. Можно, конечно, оставить и так, но мне просто интересно - почему же она обнуляется!!!
Может, в синтаксисе что-то не так написал? Вот работающий вариант:

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

interface orgcube 'Сопоставление каталогов контрагентов', cyan, EscClose;
show at (,,115,50);

create view 
var
  tek_User	: string;
as select *
from KATORG, CUBEKATAL
where ((
	1		== CUBEKATAL.WTABLE
and	tek_User	== CUBEKATAL.USERNAME
and	KATORG.CORPOIN	== CUBEKATAL.ID
));

browse brCor 'Соответствие контрагентов' (,,sci138Esc);
table KATORG;
fields
  KATORG.UNN  'ИНН'		:[15],protect,nodel;
  KATORG.NAME 'Наименование'	:[40],protect,nodel;
  CUBEKATAL.CODE 'ИНН'		:[15],protect,pickbutton;
  CUBEKATAL.NAME 'Наименование'	:[40],protect,pickbutton;
end;

TableEvent table KATORG
  cmUpdateRecord:
  {
    update current KATORG;
  }
end;

HandleEvent
  cmpick:
  {
    case CurField of
      #CUBEKATAL.CODE, #CUBEKATAL.NAME:
      {
        RunInterface('GetCubeOrg',tek_User, KATORG.CORPOIN);
      }
    end;
  }
  cminit:
  {
    tek_User := sGetTune('USER.OWNNAME');
  }
  cmDelete:
  {
    update current KATORG set KATORG.CORPOIN := 0;
  }
end;
end.

Добавлено: 14 апр 2009, 04:59
Screw
А вообще, это нормальное поведение Атлантиса - по нажатию Del заносить в поле(tek_User), на которое зацеплен классификатор (CUBEKATAL) значение по умолчанию. Чистить поле, одним словом. Только nodel в примере следует вешать на поля CUBECATAL, а не на KATORG.
А еще - использовать cmDelete для очистки поля - это как-то странно. Это ж команда удаления записи! И для Атлантиса она много значит, он ее как родную любит. Лучше пусть поле по Del чистится. Люди к этому привыкли, не нужно их сбивать с толку.

Добавлено: 14 апр 2009, 08:23
Nikos
Так я тоже хочу сделать, чтоб через DEL поле очищалось, понимаю, что по F8 очищать - это не совсем верно, но не получается! Если переменная и должна чиститься, то как правильно делать? В стандартных интерфейсах все красиво работает...
Вот такой вариант ближе других похож на правду:

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

interface orgcube 'Сопоставление каталогов контрагентов', cyan, EscClose;
show at (,,115,50);

create view 
var
  tek_User	: string;
as select *
from KATORG, CUBEKATAL
where ((
	1		== CUBEKATAL.WTABLE
and	tek_User	== CUBEKATAL.USERNAME
and	KATORG.CCUBE	== CUBEKATAL.ID
));

browse brCor 'Соответствие контрагентов' (,,sci13Esc);
table KATORG;
fields
  KATORG.UNN  'ИНН'		:[15],protect;
  KATORG.NAME 'Наименование'	:[40],protect;
  CUBEKATAL.CODE 'ИНН'		:[15],protect,pickbutton,nodel;
  CUBEKATAL.NAME 'Наименование'	:[40],protect,pickbutton,nodel;
end;

TableEvent table KATORG
  cmUpdateRecord:
  {
    update current KATORG;
  }
end;

HandleEvent
  cmDelOnProtect:
  {
    update current KATORG set KATORG.CCUBE := 0;
    ReReadRecord(#KATORG);
  } 
  cmpick:
  {
    case CurField of
      #CUBEKATAL.CODE, #CUBEKATAL.NAME:
      {
        RunInterface('GetCubeOrg',tek_User, KATORG.CCUBE);
      }
    end;
  }
  cminit:
  {
    tek_User := sGetTune('USER.OWNNAME');
  }
end;
end.
Но в нем DEL работает на полях таблицы KATORG, а пользователи привыкли, чтоб работало на поле с PickButton.
(что поле CORPOIN изменилось на CCUBE не имеет значение, это я добавил)

Добавлено: 14 апр 2009, 10:51
LaaLaa
В вашем случае, наверно надо как то так:

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

interface orgcube 'Сопоставление каталогов контрагентов', cyan, EscClose;
show at (,,115,50);

create view
var
  tek_User   : string;
as select *
from KATORG, CUBEKATAL
where ((
   1      == CUBEKATAL.WTABLE
and   tek_User   == CUBEKATAL.USERNAME
and   KATORG.CCUBE   == CUBEKATAL.ID
));

browse brCor 'Соответствие контрагентов' ;
table KATORG;
fields
  KATORG.UNN  'ИНН'      (,,sci1Esc) :[15],protect,nodel;
  KATORG.NAME 'Наименование'  (,,sci1Esc) :[40],protect,nodel;
  CUBEKATAL.CODE 'ИНН'      (,,sci13Esc):[15],protect,pickbutton;
  CUBEKATAL.NAME 'Наименование'  (,,sci13Esc) :[40],protect,pickbutton;
end;

TableEvent table KATORG
  cmUpdateRecord:
  {
    update current KATORG;
  }

  cmDelOnProtect:
  {
    set KATORG.CCUBE := 0;
  }

  cmPick:
  {
    case CurField of
      #CUBEKATAL.CODE, #CUBEKATAL.NAME:
      {
        RunInterface('GetCubeOrg',tek_User, KATORG.CCUBE);
      }
    end;
  }
end;

HandleEvent
  cminit:
  {
    tek_User := sGetTune('USER.OWNNAME');
  }
end;

end.
События cmDelOnProtect и cmPick обрабатывать лучше в табличном обработчике. Кроме того, если не ошибаюсь, явная обработка cmDelOnProtect отключит стандартный системный обработчик и поле tek_User не будет автоматом обнуляться. А поле KATORG.CCUBE сохраниться в базу когда придет cmUpdateRecord.

Коллеги, еще совет. Изучать какие и когда приходят события поможет встроенная в галактический отладчик функция трассировки событий.

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

- включить отладчик
  [DEBUG] 
    EnableVipDebugger=on
  затем
    Ctrl+Shift+F12

- когда зайдете в отладку интерфейса кнопка "окно просмотр логов"

- в окне логов
    Ctrl+L - пауза /продолжить. Приостанавливает или возобновляет ведение лога.
    Ctrl+M - фильтр сообщений интерфейсов. Включить /выключить или наложить фильтр на перехваченные события отлаживаемых интерфейсов

Добавлено: 14 апр 2009, 11:35
Den
LaaLaa писал(а): ...События cmDelOnProtect и cmPick обрабатывать лучше в табличном обработчике...
cmPick вроде всегда был был интерфейсным событием ?

Добавлено: 14 апр 2009, 14:47
LaaLaa
Den писал(а):cmPick вроде всегда был был интерфейсным событием ?
как бы да, но в табличный обработчик тоже оно приходит.

Добавлено: 14 апр 2009, 16:04
Nikos
LaaLaa, сделал как Вы посоветовали - результата нет, переменная обнуляется.

Добавлено: 15 апр 2009, 18:19
Screw
Я, видимо, не совсем понял суть проблемы и, похоже, дал неверный совет. Если целью ставится запретить Атлантису автоматом чистить все поля, по которым CUBEKATAL цепляется как классификатор, то в предложенном LaaLaa примере нужно в обработчик cmDelOnProtect добавить abort (или stop - поэкспериментируйте с вариантами). Это будет для Атлантиса сигналом прервать стандартную обработку события, в результате переменная tek_user не будет очищена.

Добавлено: 16 апр 2009, 09:47
Nikos
С abort все получилось.
Всем большое спасибо за помощь!