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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 10.04.2003, 14:54   #1  
Alex_K is offline
Alex_K
Участник
 
531 / 36 (3) +++
Регистрация: 07.02.2003
? Удавление дубликатов
Кто-нибудь решал задачу объединения дублированных записей в справочниках с глобальной заменой ссылок в базе, включая ГК?
При большом количестве товаров/клиентов/поставщиков/etc. это может стать серьезной проблемой.
Старый 10.04.2003, 22:33   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Когда открываешь паспорт записи, то в этой форме есть спрятанная кнопка "Merge" (форма SysRecordInfo).

Это штатная функция для объединения записей.
Будь предельно внимателен. Эта функция работает через наследование типов и не всегда работет правильно. Особенно в сильно модифицированной Аксапте.
Старый 11.04.2003, 08:41   #3  
Alex_K is offline
Alex_K
Участник
 
531 / 36 (3) +++
Регистрация: 07.02.2003
Thanks a lot
Большое спасибо. Во, гады, как запрятали-то...
Старый 08.06.2004, 11:30   #4  
mpa is offline
mpa
Участник
 
64 / 12 (1) ++
Регистрация: 26.01.2002
Адрес: Москва - Нижний Новгород
Изменение кода поставщика через паспорт записи
Axapta 3.0 SP2 CIS
При изменении кода поставщика через паспорт записи, имеющего множество складских и бухгалтерских проводок, и последуещего тестирования информации по поставщику, никаких видимых ошибок выявлено не было.

Во времена 2.1 при аналогичной ситуации некоторые проводки "отвязывались" от поставщика.

Поделитесь опытом, в 3.0 были выявлены "неожиданные" результаты при изменении кода через паспорт записи?
Старый 05.08.2004, 11:42   #5  
FishLog is offline
FishLog
Участник
 
30 / 10 (1) +
Регистрация: 17.12.2003
Адрес: Москва
Все это классно но ...
как то стремно на рабочей базе все это делать...
Тем более когда видишь, что для кнопки Visible равно No
И далее по коду

в методе
void mergePrimaryKey()
стоит :
// common.Merge(mergeTable);

т.е. реальный вызов изменений закомментирован еще на gls слое.

Обыдна. И никаких комментариев почему отчего ит.д.

Сделать и хочется и колется ...

Все таки Сергей, как ни хвали ты Аксапту - но такие вещи - подстава.
Старый 05.08.2004, 16:34   #6  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10

Это тупиковая ветвь развития Аксапты.
Она осталась в недокументированных возможностях.

Говорю же, эта функция может неправильно работать.
Но это не значит, что о ней не стоит знать
Старый 05.08.2004, 17:50   #7  
FishLog is offline
FishLog
Участник
 
30 / 10 (1) +
Регистрация: 17.12.2003
Адрес: Москва
ну да я понимаю.
просто очень жаль, что недокументированная функция...

Хотя она реальна нужна из-за проблемы задвоения.

Одна из основных при внедрении.
Старый 05.08.2004, 18:14   #8  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Здесь, вообще-то, не столько в Axapta дело, сколько вообще в проблеме объединения двух первичных ключей.

Работает функция везде, где есть связь между таблицами (то есть связь построена через EDT или через Relation).

Если во время переименования у Вас возникнет дубликат индекса (в случае, когда внешний ключ входит в уникальный индекс), возникнет runtime error и ttsabort.

Не то, чтобы совсем не документирована: KERNDOC://Classes/xRecord/merge
Или, например, здесь: http://technet.navision.com/workspac...tribId=4&wso=1
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
Старый 05.08.2004, 19:42   #9  
Yaroslav Batozskiy is offline
Yaroslav Batozskiy
Участник
 
15 / 10 (1) +
Регистрация: 19.01.2002
Адрес: Moskow
Цитата:
При большом количестве товаров/клиентов/поставщиков/etc. это может стать серьезной проблемой
При большом количестве можно сделать так (в Query Analyzer):

update CustTrans set CustAccount='Cust2' where CustAccount='Cust1'

для всех таблиц, в которых есть CustAccount.

Или так

update CustTrans set CustAccount='Cust' where CustAccount in ('Cust1', 'Cust2');


Найти таблицы можно с помощью перекрестных ссылок, либо так

select sysobjects.name, syscolumns.name
from sysobjects, syscolumns
where sysobjects.id=syscolumns.id
and syscolumns.name like '%CustAccount'
order by 1,2

При большом количестве объединений можно написать процедуру, которая курсором обойдет все поля CustAccount во всех таблицах.
Но использовать это рекомендую лишь при большом количестве объединений счетов, если другие средства не подошли. Это все таки SQL, а не Axapta. Но это будет очень быстро...

Цитата:
Будь предельно внимателен. Эта функция работает через наследование типов и не всегда работет правильно. Особенно в сильно модифицированной Аксапте.
В любом случае, независимо от того, как объединяли записи, рекомендую выполнить "Проверку целостности данных компании", либо по одному модулю, либо по всем (долго...). Строка this.kernelCheckTable(tableNum(<TableName>)); проверяет как раз ссылочные поля. Если функционал модифицирован, то нужно добавить обработку добавленных таблиц с полем, по которому проводилось объединение кодов.
Старый 05.08.2004, 20:07   #10  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Эээх, Ярослав, ну что ж Вы людей-то пугаете.

Ваши ошибки:
  • В CustTrans нет поля CustAccount. Есть поле AccountNum.
  • Предвосхищяя Ваше следующее решение: поле AccountNum есть еще и в VendTrans, но там это код поставщика, а не клиента.
  • А в PriceDiscTable поле называется AccountRelation, и оно иногда тоже ссылается на CustTable.

Кстати, за то, что Вы рекомендуете запустить проверку целостности - Вам плюс. Проверка целостности найдете большинство ошибок, которые Вы сделаете, меняя данные из Query Analyzer предложенными скриптами.

Предостережение для начинающих: никогда не выполняйте Update БД Axapta в Query Analyzer. По крайней мере, до тех пор, пока Вы начинающие.
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
Старый 08.08.2004, 04:50   #11  
Yaroslav Batozskiy is offline
Yaroslav Batozskiy
Участник
 
15 / 10 (1) +
Регистрация: 19.01.2002
Адрес: Moskow
Провел небольшую исследовательскую работу, результатом которой стало два скрипта http://www.crm.columbus.ru/ep/yarb/C...eHierarchy.xpo и http://www.crm.columbus.ru/ep/yarb/C...ldWithType.xpo

Первый можно использовать просто для исследований—он создает в темповой папке CSV-файл, в который пишет по три значения для каждого поля каждой таблицы—таблица, поле, расширенный тип поля с иерархией до корня. Например так: CustTable,AccountNum,CustAccount<-CustVendAC<-ExternalAccount<-String, что означает: в таблице CustTable есть поле AccountNum с типом CustAccount, который наследуется от CustVendAc, который наследуется от ExternalAccount, который является строкой.

Поскольку файл CSV, для просмотра лучше импортировать его в Excel как CSV, с разделителем «запятая»

Второй файл сделан из первого и решает конкретную задачу—при переименовании первичного ключа находит, какие еще поля в каких таблицах имеют такой же EDT, или унаследованный от него. Он содержит один параметр—в строке 4—тип, который мы ищем. Отличия от стандартного механизма перекрестных ссылок—скрипт находит и те поля, типы которых _унаследованы_ от искомого.

Если нужно сделать одно переименование/объединение—то это можно сделать и вручную через Query Analyzer тем оператором, который я приводил выше для каждого поля. Если много—можно в скрипт после строки 49 (команда aio.write()) добавить вызов этого оператора SQL с проставленными переметрами (таблица, поле, оба значения—старое и новое), пример см. в \Classes\SysRecidRepair\ExecuteUpdate. Тогда в скрипт нужно добавить еще два параметра «что присоединить» и «к чему присоединить»--и он становится почти универсальным.

Скрипт этот можно использовать и для объединения, и для переименования
Добавлю, что скрипт этот работает тоже через иерархию типов. Если таблицы связаны по Relation—он работать не будет. Если его использовать для переименований—то он будет работать так же, как и штатная функция, только на порядок быстрее при большом объеме данных. И если у вас есть поля, в который неправильно проставлен EDT, то оба эти скрипта поле не обновят.

Я довольно часто сталкивался со случаями неправильно расставленных EDT. Например при дефрагментировании RecId я обнаружил, что есть поля со ссылками по Recid, тип которых не наследуется от RecId (в результате чего при экспорте-импорте эти ссылки пересчитаны не будут, т.е. данные в таблице будут повреждены). Пример—поле RTSLSessionTransId в таблице LedgerTrans (номер сессии трансляции, которая породила проводку). Если скрипт используется для переименования только одного поля—то можно в скрипт добавить оператор для обработки такого нестандартного поля, если для многих полей—то это придется сделать врукопашную.

Важно: все обновления должны проводиться в одной транзакции!

Если нужно--можно доработать скрипт, для системного решения проблемы объединения\переименования счетов при любом количестве записей. Используя SQL для обновлений получаем скорость работы как минимум на порядок больше, чем штатными средствами.
Старый 08.08.2004, 12:08   #12  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Спасибо, Ярослав.

Можно вопрос?
Цитата:
Например при дефрагментировании RecId я обнаружил, что есть поля со ссылками по Recid
А как вы это делаете?
Я создал специальную тему для этого вопроса.
http://www.axforum.info/forums/showt...0351#post40351

Yaroslav Batozskiy, если можно, я был бы очень услышать ваше мнение.
Старый 11.08.2004, 12:13   #13  
bucken is offline
bucken
Участник
Аватар для bucken
 
259 / 12 (1) ++
Регистрация: 04.09.2003
Адрес: Москва
Мысль
А как вам такая идея:
Задаем конкретную запись в конкретной таблице - и скипт ищет по ней все связаные записи в других таблицах. Т.е - не просто показывает нам лог. схему БД - а показывает на конкретных данных, как и счем они связаны. IMHO не сложно будет ваш скрипт этой функцией дополнить.
Вопрос конечно в полезности данного инструмента.
Но мне кажется есть:
1) Обучение новичков. Это очень мощно - видеть сразу деревья, сразу же понимать зависимости системы.
2) Анализировать данные с целью выявления ошибок и несответствий.
спасибо.
__________________
Уточните значение слов и вы избавите человечество от половины его заблуждений. (Рене Декарт) / Axapta 2.5
Старый 09.06.2007, 12:06   #14  
longson is offline
longson
Участник
 
231 / 49 (2) +++
Регистрация: 12.12.2006
Адрес: Москва
У меня почему-то не работает этот метод.

Например при объединение записей в таблице клиентов выдаётся такая ошибка (в приложении)

Подскажите пожалуйста в чём же проблема и как ее устранить. Для меня эта функция 0000чень нужна. Спасибо
Миниатюры
Нажмите на изображение для увеличения
Название: 123.JPG
Просмотров: 665
Размер:	102.1 Кб
ID:	2706  
Старый 13.06.2007, 09:23   #15  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Я делал так.
Перекрываем метод merge на таблице InventTable и до super пишем:
X++:
     //удалить из inventTableModule для старой НЕ
     delete_from inventTableModule
     where inventTableModule.ItemId == this.ItemId;

     //удалить из inventItemLocation для старой НЕ
     delete_from inventItemLocation
     where inventItemLocation.ItemId == this.ItemId;
Также для других таблиц которые связаны с InventTable и имеют первичный ключ пишем примерно следующее:
X++:
    //удалить дубли в inventBatch
     while select forupdate inventBatch
     where inventBatch.itemId == this.ItemId
     {
        if (InventBatch::exist(inventTable.ItemId, inventBatch.inventBatchId))
            inventBatch.delete();
     }
Старый 11.11.2008, 11:31   #16  
zelibobis is offline
zelibobis
Участник
 
71 / 24 (1) +++
Регистрация: 15.10.2007
Адрес: Kiev
Ярослав, не могли бы Вы выложить еще раз свои скрипты по обновлению данных, а то они не качаются по приведенным выше ссылкам.
Спасибо
Теги
ax3.0, recid

 

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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