AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 15.12.2010, 16:03   #1  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Профессионалы, подскажите есть в Навижн какая-нить функция, с помощью которой можно узнать была ли запись модифицирована, и если жа, то какие именно поля подверглись корректировке?

Ситуация: есть таблица Customer. К ней форма F50191 (Карточка клиента). В таблице (соотвественно и в форме тоже) есть два поля: Information и Note (текстовые).
Задача в следующем: нужно в триггере OnModifyRecord() устроить проверку: если у юзера в его настройках Responsibility Center не совпадает с аналогичным полем в карточке клиента, то этому юзеру можно менять только указанные два поля (Information и Note). При попытке изменить другие поля выдается сообщение об ошибке.
На настоящий момент такой юзер вообще не может ничего менять в карточке.
Как решить поставленную задачу "малой кровью"?
Старый 15.12.2010, 17:19   #2  
alexb_imported is offline
alexb_imported
Участник
 
256 / 12 (1) ++
Регистрация: 25.08.2006
1. Надо включить ChangeLog для таблицы 18 для всех полей, или по крайней мере для всех полей, которые user может изменить в карточке клиента.
(Administration > Application Setup > General > Change Log)
2. В кодеюните 423 Change Log Management прописываете программный код:
если таблица=18 то:
2.1 берёте customer'a (можно взять Customer."No." из RecRef.RECORDID) и смотрите его Respons.Center
2.2 берёте USER'а и смотрите его Respons.Center
2.3 если Respons.Center user'a отличается от Respons.Center customer'a то проверяете, какое поле было изменено
==> например в функции InsertLogEntry() (в том же CU 423 Change Log Management ) передаётся параметер FldRef,
======> Если FldRef.NUMBER <> номер поля Information и FldRef.NUMBER <> номер поля Note то выдаём требуемый ERROR().

Весь фокус в том, что ChangeLog-функционал реагирует/срабатывает только на изменения, вносимые user'ом руками и на изменения из программного кода не реагирует,
( типа customer.MODIFY(TRUE); что вам как раз и нужно.
Старый 15.12.2010, 18:14   #3  
Fordewind is offline
Fordewind
Участник
 
1,134 / 10 (3) +
Регистрация: 01.12.2005
Цитата:
Сообщение от AlexB Посмотреть сообщение
1. Надо включить ChangeLog для таблицы 18 для всех полей, или по крайней мере для всех полей, которые user может изменить в карточке клиента.
(Administration > Application Setup > General > Change Log)
2. В кодеюните 423 Change Log Management прописываете программный код:
если таблица=18 то:
2.1 берёте customer'a (можно взять Customer."No." из RecRef.RECORDID) и смотрите его Respons.Center
2.2 берёте USER'а и смотрите его Respons.Center
2.3 если Respons.Center user'a отличается от Respons.Center customer'a то проверяете, какое поле было изменено
==> например в функции InsertLogEntry() (в том же CU 423 Change Log Management ) передаётся параметер FldRef,
======> Если FldRef.NUMBER <> номер поля Information и FldRef.NUMBER <> номер поля Note то выдаём требуемый ERROR().

Весь фокус в том, что ChangeLog-функционал реагирует/срабатывает только на изменения, вносимые user'ом руками и на изменения из программного кода не реагирует,
( типа customer.MODIFY(TRUE); что вам как раз и нужно.
Есть такая штука CurrentFieldNo. Она возвращает номер поля в котором стоит юзер. И ею можно заменить ChangeLog в данном случае
Старый 16.12.2010, 00:46   #4  
alexb_imported is offline
alexb_imported
Участник
 
256 / 12 (1) ++
Регистрация: 25.08.2006
Цитата:
Сообщение от Fordewind Посмотреть сообщение
Есть такая штука CurrentFieldNo. Она возвращает номер поля в котором стоит юзер. И ею можно заменить ChangeLog в данном случае
CurrfiеldNo хорошая вещь, но в OnModify()-триггере таблицы всегда равен 0.
Чтобы ловить, в каком поле user имеет право изменения делать, а в каком нет и т.д, надо прописывать программный код в каждом поле таблицы в OnValidate()-триггере (по крайней мере вызов соответствующей функции). Представьте, что этот функционал вам нужен и в других таблицах, потом весь этот код надо при update не забывать и MERGE'вать. У меня была похожая задача и по этой причине я прописал код в одном единственном месте- в CU 423: и прекрасно работает, и минимум изменений в стандартном функционале.
Старый 16.12.2010, 15:39   #5  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Да! Забыла написать! Т.к. поменяла CU 423, то сообщение об ошибке в триггере OnModifyRecord (формы 50191) пришлось закомментарить.
Старый 16.12.2010, 15:17   #6  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от AlexB Посмотреть сообщение
Весь фокус в том, что ChangeLog-функционал реагирует/срабатывает только на изменения, вносимые user'ом руками и на изменения из программного кода не реагирует,
( типа customer.MODIFY(TRUE); что вам как раз и нужно.
Сделала как Вы сказали. В CU 423 процедуру изменила след. образом: (мои "нововведения" выделены синим)

LogModification(VAR RecRef : RecordRef;VAR xRecRef : RecordRef)
IF NOT IsLogActive(RecRef.NUMBER,0,1) THEN
EXIT;

IF RecRef.NUMBER = 18 THEN BEGIN // Machen das nur für Tabelle 18 - Customer
BenutzerEinrRec.GET(USERID);
xFldRef := xRecRef.FIELDINDEX(65); //65 - Index vom Feld "Resposibility Center"
CustRespCtr := xFldRef.VALUE;
END;


FOR i := 1 TO RecRef.FIELDCOUNT DO BEGIN
FldRef := RecRef.FIELDINDEX(i);
xFldRef := xRecRef.FIELDINDEX(i);
IF IsNormalField(RecRef.NUMBER,FldRef.NUMBER) THEN
IF FORMAT(FldRef.VALUE) <> FORMAT(xFldRef.VALUE) THEN

//SSG.JK. BEGIN
IF RecRef.NUMBER = 18 THEN BEGIN
IF (BenutzerEinrRec."Sales Resp. Ctr. Filter" <> '') THEN
IF (FldRef.NAME <> 'Information') AND (FldRef.NAME <> 'Note') AND (FldRef.NAME <> 'Last Date Modified') THEN
IF (STRPOS(BenutzerEinrRec."Sales Resp. Ctr. Filter",COPYSTR(CustRespCtr,1,4)) = 0)
THEN BEGIN
ERROR('Änderung von %1 nicht möglich: Dieser Debitor ist einer anderen Zuständigkeitseinheit zugeordnet!',FldRef.NAME);
EXIT;
END;
END;
//SSG.JK.


IF IsLogActive(RecRef.NUMBER,FldRef.NUMBER,1) THEN
InsertLogEntry(FldRef,xFldRef,RecRef,1);
END;

Теперь при попытке покинуть измененную карточку клиента выдается сообщение об ошибке. НО! тем не менее изменения сохраняются и если мы еще раз выйдем из карточки клиента, то уже система не "мявкает",т.к. по ее логике уже ничего и не поменялось. В рез-те имеем: измененное поле в карточке клиента, которое на самом деле менять было нельзя. ;-/
Что делать?
Переносить-такии код в др.место или ...? Какие есть варианты? Где я опять накосячила?
Старый 16.12.2010, 15:43   #7  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от Kadawrik Посмотреть сообщение
[Теперь при попытке покинуть измененную карточку клиента выдается сообщение об ошибке. НО! тем не менее изменения сохраняются и если мы еще раз выйдем из карточки клиента, то уже система не "мявкает",т.к. по ее логике уже ничего и не поменялось. В рез-те имеем: измененное поле в карточке клиента, которое на самом деле менять было нельзя. ;-/
Что делать?
Переносить-такии код в др.место или ...? Какие есть варианты? Где я опять накосячила?
Может тогда имеет смысл оставить CU 423 по-старому, а всю процедуру проверки перенести в триггер OnModify() Таблицы 18? (т.е. прописываем код для проверки только в одном месте и OnValidate по каждому полю трогать не будем)
Старый 16.12.2010, 20:30   #8  
alexb_imported is offline
alexb_imported
Участник
 
256 / 12 (1) ++
Регистрация: 25.08.2006
Цитата:
Сообщение от Kadawrik Посмотреть сообщение
Теперь при попытке покинуть измененную карточку клиента выдается сообщение об ошибке. НО! тем не менее изменения сохраняются и если мы еще раз выйдем из карточки клиента, то уже система не "мявкает",т.к. по ее логике уже ничего и не поменялось. В рез-те имеем: измененное поле в карточке клиента, которое на самом деле менять было нельзя. ;-/
Что делать?
Переносить-такии код в др.место или ...? Какие есть варианты? Где я опять накосячила?

1. Косяк в коде один есть:
надо писать не

xFldRef := xRecRef.FIELDINDEX(65); //65 - Index vom Feld "Resposibility Center"

а

xFldRef := xRecRef.FIELD(65); //65 - Index vom Feld "Resposibility Center"


2. Я на вскидку вставил в моей БД в CU 423 ваш код (с корректировкой в П 1.):
После подтверждения ошибки система возвращает в поле прежнее значение (до изменения), как и должно быть после ERROR, всё работает.
Ошибка вылетает после изменения в поле при попытке перейти к другому customer или закрыть карточку.

Важное примечание: после любых изменений в коде (т. е. в программном коде, имеющем отношение к CU 423):
---- в открывайте навижен сновa, чтобы CU 423 заметил эти изменения: CU423 это SingleInstanece-Codeunit.
Старый 16.12.2010, 23:23   #9  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от AlexB Посмотреть сообщение
1. Косяк в коде один есть:
надо писать не

xFldRef := xRecRef.FIELDINDEX(65); //65 - Index vom Feld "Resposibility Center"

а

xFldRef := xRecRef.FIELD(65); //65 - Index vom Feld "Resposibility Center"
У меня с FieldIndex(65) работает. 65 - это действительно индекс поля в таблице, а не номер его.

Цитата:
2. Я на вскидку вставил в моей БД в CU 423 ваш код (с корректировкой в П 1.):
После подтверждения ошибки система возвращает в поле прежнее значение (до изменения), как и должно быть после ERROR, всё работает.
Ошибка вылетает после изменения в поле при попытке перейти к другому customer или закрыть карточку.
Я выясниснила почему у меня не работает...точнее работает не для всех полей.
Собака порылась в коде триггера OnModify() таблицы 18:
На домашнем компе Навижн нет, потому по памяти напишу что там примерно было:
OnModify()
IF Name <> xRec.Name OR
Address <> xRec.Address OR
Contakt <> xRec.Contakt
и т.д. ...перечислины куча полей с контактными данными клиента
THEN BEGIN
MODIFY;
вызывается процедура, которая записывает контактные данные в какую-то доп.таблицу


Вот это самое MODIFY и портит всю малину. Если меняется какое-то поле из приведенного выше IF'а, тогда сообщение об ошибке появляется, но новое значение тем не менее сохраняется. Если меняю любое другое поле (кроме Information или Note), тогда появляется сообщение об ошибке и введенное новое значение сбрасывается (т.е. работает так, как Вы и описывали)

Цитата:
Важное примечание: после любых изменений в коде (т. е. в программном коде, имеющем отношение к CU 423):
---- в открывайте навижен сновa, чтобы CU 423 заметил эти изменения: CU423 это SingleInstanece-Codeunit.
Спасибо за подсказку. Я это "правило" уже эмпирическим путем выяснила, когда сегодня с дебагером отлаживала и не могла понять, почему CU сохраняю, а ошибка старая лезет и дебагер старый текст показывает
Теперь буду знать, что это не мое предположение, а действительно так и есть
Старый 15.12.2010, 18:53   #10  
Sancho is offline
Sancho
Administrator
Аватар для Sancho
Лучший по профессии 2017
Лучший по профессии 2009
 
1,294 / 221 (10) ++++++
Регистрация: 11.01.2006
Цитата:
Сообщение от Kadawrik Посмотреть сообщение
...
На настоящий момент такой юзер вообще не может ничего менять в карточке.
сначала надо будет отгрызть это, дебаггер вам в помощь
Старый 16.12.2010, 15:29   #11  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от Sancho Посмотреть сообщение
сначала надо будет отгрызть это, дебаггер вам в помощь
Это "отгрызть" не проблема , т.к. код предельно прост:


Form - OnModifyRecord() : Boolean
BenutzerEinrRec.GET(USERID);

IF (BenutzerEinrRec."Sales Resp. Ctr. Filter" <> '') THEN

IF (STRPOS(BenutzerEinrRec."Sales Resp. Ctr. Filter",
COPYSTR("Responsibility Center",1,4)) = 0) OR
(Rec."Responsibility Center" <> xRec."Responsibility Center")
THEN
ERROR('Änderung nicht möglich: Dieser Debitor ist einer anderen Zuständigkeitseinheit zugeordnet!');


Это - триггер OnModifyRecord формы 50191 (Карточка клиента)
Старый 06.01.2011, 15:38   #12  
Sancho is offline
Sancho
Administrator
Аватар для Sancho
Лучший по профессии 2017
Лучший по профессии 2009
 
1,294 / 221 (10) ++++++
Регистрация: 11.01.2006
да, в DocFlowNAV именно так.
проверяются два рефа (старый и новый), а в настройках сказано какое поле контролировать, при каких условиях, ругаться или предупреждать.
 


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 22:33.