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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 14.10.2009, 14:18   #1  
Alexx7 is offline
Alexx7
Сам.AX
Аватар для Alexx7
Самостоятельные клиенты AX
1C
 
305 / 28 (1) +++
Регистрация: 22.07.2009
update_recordset не работает с системными полями и таблицами?
Добрый день.

Я пробую изменить компанию в таблице с помощью update_recordset. Выдает ошибку "Системные поля не могут быть добавлены или обновлены.". Вопрос. Можно как то обойти эту ошибку.

Вот джоб:
X++:
static void CangeCompany(Args _args)
{

    PersonTitleTable   personTitleTable;
    ;
    
    update_recordset personTitleTable
        setting DataAreaId = 'cmp';
 
}
Старый 14.10.2009, 14:24   #2  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Alexx7 Посмотреть сообщение
Добрый день.

Я пробую изменить компанию в таблице с помощью update_recordset. Выдает ошибку "Системные поля не могут быть добавлены или обновлены.". Вопрос. Можно как то обойти эту ошибку.

Вот джоб:
X++:
static void CangeCompany(Args _args)
{

    PersonTitleTable   personTitleTable;
    ;
    
    update_recordset personTitleTable
        setting DataAreaId = 'cmp';
 
}
А при чём тут update_recordset? ))
Upd Ну в том смысле что и через обычный update() вы так не сделаете...

Удалить запись в одной компании, потом вставить в другую (использовать оператор changeCompany)...
__________________
Zhirenkov Vitaly

Последний раз редактировалось ZVV; 14.10.2009 в 14:26.
Старый 14.10.2009, 14:28   #3  
Alexx7 is offline
Alexx7
Сам.AX
Аватар для Alexx7
Самостоятельные клиенты AX
1C
 
305 / 28 (1) +++
Регистрация: 22.07.2009
Цитата:
Сообщение от ZVV Посмотреть сообщение
А при чём тут update_recordset? ))
Удалить запись в одной компании, потом вставить в другую (использовать оператор changeCompany)...
Мне надо в таблице поменять знчение поля "DataAreaId".
Какие ещё способы можно использовать?
Старый 14.10.2009, 14:32   #4  
e@gle is offline
e@gle
MCTS
MCBMSS
 
164 / 72 (3) ++++
Регистрация: 11.04.2005
Адрес: Минск
попробуйте так:
X++:
    while select forupdate personTitleTable
    {
        personTitleTable.(fieldNum(personTitleTable, dataAreaId)) = 'cmp';
        personTitleTable.update();
    }
__________________
С уважением, Павел Цераниди.
На пути к совершенству нет конца. Каждое новое достижение является отправной точкой для следующего крупного шага.
За это сообщение автора поблагодарили: ZVV (2).
Старый 14.10.2009, 14:47   #5  
Alexx7 is offline
Alexx7
Сам.AX
Аватар для Alexx7
Самостоятельные клиенты AX
1C
 
305 / 28 (1) +++
Регистрация: 22.07.2009
Цитата:
Сообщение от e@gle Посмотреть сообщение
попробуйте так:
X++:
    while select forupdate personTitleTable
    {
        personTitleTable.(fieldNum(personTitleTable, dataAreaId)) = 'cmp';
        personTitleTable.update();
    }
Не получается. Вот инфолог:

"Сообщение (16:44:33)
Невозможно отредактировать запись в Должности контакнтых лиц (PersonTitleTable).
Обновление должно выполняться внутри операции.
(S)\Classes\xRecord\update
(C)\Jobs\CangeCompany - line 13

Обновление должно выполняться внутри операции. [W-456746819624370298]"


Цитата:
Сообщение от lev Посмотреть сообщение
на таблицах есть метод overwriteSystemfields()... если хотите изменять системные поля, перед апдейтом нужно вызывать этот метод с параметром true (overwriteSystemfields(true))...
Странно. Компилятор выдает ту же самую ошибку.
Старый 14.10.2009, 14:32   #6  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
на таблицах есть метод overwriteSystemfields()... если хотите изменять системные поля, перед апдейтом нужно вызывать этот метод с параметром true (overwriteSystemfields(true))...
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем

Последний раз редактировалось lev; 14.10.2009 в 14:35.
Старый 16.10.2009, 06:37   #7  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Цитата:
Сообщение от lev Посмотреть сообщение
на таблицах есть метод overwriteSystemfields()... если хотите изменять системные поля, перед апдейтом нужно вызывать этот метод с параметром true (overwriteSystemfields(true))...
Добрый день.

На самом деле метод overwriteSystemfields() предназначен для другого - изменить значения системных полей у вновь создаваемых записей.
Ниже пример, таблица Test - имеет одно текстовое поле ItemId.

X++:
static void SRF_Test(Args _args)
{
    Test    test;
    ;
    test.ItemId = 'dmo';
    test.overwriteSystemfields(true);
    test.(fieldNum(Test, DataAreaId)) = 'dmo';
    test.insert();
}
Для уже существующих записей, изменить системные поля штатными средствами AX нельзя, и метод overwriteSystemfields() тут не поможет.
__________________
Sergey Nefedov
За это сообщение автора поблагодарили: lev (4), S.Kuskov (1).
Старый 16.10.2009, 09:29   #8  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,322 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от SRF Посмотреть сообщение
На самом деле метод overwriteSystemfields() предназначен для другого - изменить значения системных полей у вновь создаваемых записей.
А с чего Вы взяли?
Цитата:
Сообщение от SRF Посмотреть сообщение
Для уже существующих записей, изменить системные поля штатными средствами AX нельзя, и метод overwriteSystemfields() тут не поможет.
Вот это неправда. На поля modified* вполне можно таким образом воздействовать. Они не изменятся при вызове update если вызвать overwriteSystemFields(true).

Более того - их можно изменить
X++:
static void Job(Args _args)
{
    VendTable vendTable;
    ;
    ttsbegin;
    select forupdate vendTable;
    info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy));
    vendTable.overwriteSystemfields(true);
    vendTable.(fieldnum(VendTable, modifiedBy)) = 'zzzz';
    vendTable.doUpdate();
    ttscommit;
    info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy));
}
Нажмите на изображение для увеличения
Название: job.PNG
Просмотров: 314
Размер:	23.5 Кб
ID:	5267

При этом пользователя zzzz может не существовать в базе

DAX 4.0 SP2
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 16.10.2009 в 09:41.
Старый 16.10.2009, 09:57   #9  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
А с чего Вы взяли?


Вот это неправда. На поля modified* вполне можно таким образом воздействовать. Они не изменятся при вызове update если вызвать overwriteSystemFields(true).

Более того - их можно изменить
X++:
static void Job(Args _args)
{
    VendTable vendTable;
    ;
    ttsbegin;
    select forupdate vendTable;
    info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy));
    vendTable.overwriteSystemfields(true);
    vendTable.(fieldnum(VendTable, modifiedBy)) = 'zzzz';
    vendTable.doUpdate();
    ttscommit;
    info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy));
}
Вложение 5267

При этом пользователя zzzz может не существовать в базе

DAX 4.0 SP2
Взял с того, как используется этот метод в стандартной аксапте.

У меня на DAX 4.0 TAP 3(виртуалка по 4-ке от МС) Ваш job не изменил значение поля modifiedBy.

То, что выводится в инфолог, еще не значит, что значения изменились в таблице.
Поставьте перед вторым info или посмотрите значение в базе
X++:
vendTable.reread();
__________________
Sergey Nefedov
Старый 16.10.2009, 10:34   #10  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,322 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от SRF Посмотреть сообщение
То, что выводится в инфолог, еще не значит, что значения изменились в таблице.
Ваша правда. Я забыл, что для этого требуется изменения хотя бы одного поля.

X++:
static void Job(Args _args)
{
    VendTable vendTable;
    ;
    ttsbegin;
    select forupdate vendTable;
    info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy));
    ttscommit;
    return;
    vendTable.overwriteSystemfields(true);
    vendTable.Address += ' ';
    vendTable.(fieldnum(VendTable, modifiedBy)) = 'zzzz';
    vendTable.doUpdate();
    ttscommit;
    info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy));
    vendTable.reread();
    info(strfmt("%1 %2", vendTable.AccountNum, vendTable.modifiedBy));
}
Вот так работает. Попробуйте - и у Вас тоже все изменится. Это и на 3.0 работало.
__________________
Возможно сделать все. Вопрос времени
За это сообщение автора поблагодарили: SRF (1).
Старый 14.10.2009, 14:49   #11  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
а обновление выполняете внутри транзакции ?
если открыта то правильно ли закрыта?
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 14.10.2009, 14:55   #12  
Alexx7 is offline
Alexx7
Сам.AX
Аватар для Alexx7
Самостоятельные клиенты AX
1C
 
305 / 28 (1) +++
Регистрация: 22.07.2009
Цитата:
Сообщение от lev Посмотреть сообщение
а обновление выполняете внутри транзакции ?
если открыта то правильно ли закрыта?
Нет. Вообще не открываю транзакцию. На всякий случай проверил с трназакцией. Ответ системы тот же.
Старый 14.10.2009, 15:02   #13  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Alexx7 Посмотреть сообщение
Нет. Вообще не открываю транзакцию. На всякий случай проверил с трназакцией. Ответ системы тот же.
Всё нормально работает, как то не так окрываете...
X++:
    ttsBegin;

    while select forupdate personTitleTable
    {
        personTitleTable.(fieldNum(personTitleTable, dataAreaId)) = 'cmp';
        personTitleTable.update();
        break;
    }  

    ttsAbort;
__________________
Zhirenkov Vitaly
Старый 14.10.2009, 15:02   #14  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
выложите джоб в нынешнем варианте, плиз
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 14.10.2009, 16:50   #15  
corner77 is offline
corner77
Участник
 
18 / 25 (1) +++
Регистрация: 28.04.2009
Цитата:
Всё нормально работает, как то не так окрываете...
Все нормально компилируется, но не работает

Джоб сделал такой:
X++:
    ttsBegin;
        address.overwriteSystemfields(true);
    while select forupdate address
    {
        address.(fieldNum(personTitleTable, dataAreaId)) = 'dat';
        address.overwriteSystemfields(true);
        address.update();
        //break;
    }

    ttsAbort;
метод overwriteSystemfields как мертвому припарка. Что с ним, что без него данные остаются неизменные, хотя джоб отрабатывает и ошибка не воспроизводится.

Можно сменить двумя способами - через чистый SQL c Connection, Statement и пр. Или через создание новой записи в другой компании и копировании данных в нее:

X++:
    select address;
    addressNew.company('dat');
    buf2buf(address, addressNew);
    addressNew.insert();
    address.delete();
buf2buf нужен, чтобы компания осталась без изменения (data() сменит компанию)
Старый 14.10.2009, 18:20   #16  
Oz is offline
Oz
Участник
Аватар для Oz
 
293 / 51 (2) ++++
Регистрация: 22.08.2002
Адрес: Москва
Цитата:
Сообщение от corner77 Посмотреть сообщение
Все нормально компилируется, но не работает

X++:
     ttsAbort;
...данные остаются неизменные, хотя джоб отрабатывает и ошибка не воспроизводится...
Всё правильно, вы же прервали транзакцию, хотя само обновление прошло без ошибок
Ставьте ttscommit;
__________________
Здесь могла быть Ваша реклама!
Старый 14.10.2009, 17:10   #17  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
к вашему джобу пару замечаний...
0. что бы строка изменилась в БД, по моему, необходимо в конце вызвать ttscommit; (точно утверждать не могу, но вроде ttsAbort откатывает транзакцию и изменения не сохраняются)
1. overwriteSystemfields() достаточно вызвать один раз.
2. для обновления вы выбираетет таблицу Address, а FieldId для обновления определяете по таблице personTitleTable (fieldNum(personTitleTable, dataAreaId)) - может поэтому ничего не отработало?
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем

Последний раз редактировалось lev; 14.10.2009 в 17:20.
Старый 14.10.2009, 18:38   #18  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от lev Посмотреть сообщение
к вашему джобу пару замечаний...
0. что бы строка изменилась в БД, по моему, необходимо в конце вызвать ttscommit; (точно утверждать не могу, но вроде ttsAbort откатывает транзакцию и изменения не сохраняются)
1. overwriteSystemfields() достаточно вызвать один раз.
2. для обновления вы выбираетет таблицу Address, а FieldId для обновления определяете по таблице personTitleTable (fieldNum(personTitleTable, dataAreaId)) - может поэтому ничего не отработало?
0. Э народ, вы чего? Типа юмор? Я в своём примере написал ttsAbort, просто чтоб ничего не менять в базе.но при этом показать, что всё работает, а не выкидывает ошибку транзакции, как утверждал Alexx7. Конечно надо ttsCommit, чтоб изменения вступили в силу.
1....
2. С одной стороны да, верное замечание, а с другой чтороны, код поля dataareaId всё равно будет одинаковый (типа 655ХХ, точно не помню) в обеих таблицах, поэтому разницы человек не заметит. (ну т.е. обновится конечно не та таблица...) Но если б это было не dataareaId, а обычное поле, то заметили бы, наверняка...
__________________
Zhirenkov Vitaly
Старый 14.10.2009, 18:48   #19  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от ZVV Посмотреть сообщение
0. Э народ, вы чего? Типа юмор? Я в своём примере написал ttsAbort, просто чтоб ничего не менять в базе.но при этом показать, что всё работает, а не выкидывает ошибку транзакции, как утверждал Alexx7. Конечно надо ttsCommit, чтоб изменения вступили в силу.
Протестил, даже если там написать ttscommit; ничего не меняется
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 14.10.2009, 19:04   #20  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от lev Посмотреть сообщение
Протестил, даже если там написать ttscommit; ничего не меняется
Тогда см. мой первый ответ.
__________________
Zhirenkov Vitaly
Теги
update_recordset, законченный пример, как правильно, полезное, системые поля

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
непонятности с полями modifiedTime, modifiedDate др. PavelSR DAX: Программирование 4 17.03.2007 10:28
Фильтр в форме по Looup с двумя таблицами LexusS DAX: Программирование 3 21.07.2006 10:42
JOIN программно на форме не работает rohlenko DAX: Программирование 2 31.03.2005 15:41
CRM ABC, SWOT анализ Как это работает и работает ли вообще. ShadowFromXZone DAX: Функционал 16 02.03.2004 18:09
связь между таблицами Valia DAX: Программирование 2 09.10.2003 18:36

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

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

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