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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 16.01.2012, 17:13   #1  
NNB is offline
NNB
Участник
 
103 / 12 (1) ++
Регистрация: 31.08.2006
Ошибка Microsoft
Добрый день
При отмене закрытия склада в некоторой специфической ситуации (думаю в данном случае не важно в какой) вдруг перестала перестали корреспондитоваться постинги в LedgerTrans.
После разбирательства показалось станным, что в методе LedgerVoucherTransList.first() не меняется значение refId_RU.
Вставка оператора refId_RU = ledgerTransObject ? transIterator.key() : 0; исправила ситуацию. (Ax3, Ax4, Ax5 - все аналогично). Судя по всему ошибка локализации
За это сообщение автора поблагодарили: Logger (3), b_nosoff (2).
Старый 16.01.2012, 17:18   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Можете подробнее указать место ?
Старый 17.01.2012, 10:08   #3  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
Thumbs up GEEU
Там мало того, что при выборке первого элемента не инициализируется refId, так еще и в LedgerVoucherTransList.next() происходит неявное приведение str к int А сработает эта мина в том случае, если вдруг кто захочет еще разок пройтись по этому итератору и вызовет first()...
__________________
Axapta non erubescit
За это сообщение автора поблагодарили: NNB (1).
Старый 17.01.2012, 11:07   #4  
NNB is offline
NNB
Участник
 
103 / 12 (1) ++
Регистрация: 31.08.2006
По просьбе Logger:
Класс LedgerVoucherTransList метод first()

В нашем случае получилась явно неправильная корреспонденция
Надо выбрать время и посмотреь что было в других ситуациях

Я так понимаю что Microsoft готовит следующую локализациют (набирает людей). Господа исправьте пожалуйста
Старый 17.01.2012, 12:11   #5  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Прежде, чем бросаться громкими заявлениями, неплохо бы посмотреть а для чего это значение вообще используется. Насколько я вижу, цикл first()...next() использует refId_RU только для индикатора прогресса. Просто, чтобы показать, что процесс идет. Так что, без разницы, что там будет за значение. Разумеется, если Вы сами не прикрутили какой-то функционал к этой переменной именно в цикле first()..next().

Так что, очень даже имеет смысл пояснить о какой такой "специфической ситуации" идет речь. Т.е. где-это Вам потребовалось использовать значение refId_RU иначе чем индикатор прогресса.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 17.01.2012, 12:29   #6  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Насколько я вижу
LedgerVoucherObject.postRoundingDifferencesPerDate()
X++:
ledgerBondServer.findBondTransObject(ledgerTransList.itemRefId_RU())
ну, т.е., вы согласны, что это потенциальная бомба, если только никто не будет бросаться громкими заявлениями?
__________________
Axapta non erubescit
Старый 17.01.2012, 13:41   #7  
NNB is offline
NNB
Участник
 
103 / 12 (1) ++
Регистрация: 31.08.2006
Что бы на бросаться громкими фразами предлагаю заинтересовавшихся запустить поиск refId_RU по классам LedgerVoucherObject, LedgerVoucherTransList, LedgerBondServer_RU, LedgerBoundTransList_RU, LedgerBondClient_RU, LedgerBondTransObject_RU (для начала хватит) и сделать собственные выводы
Старый 17.01.2012, 14:58   #8  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от b_nosoff Посмотреть сообщение
LedgerVoucherObject.postRoundingDifferencesPerDate()
X++:
ledgerBondServer.findBondTransObject(ledgerTransList.itemRefId_RU())
ну, т.е., вы согласны, что это потенциальная бомба, если только никто не будет бросаться громкими заявлениями?
Не уверен. Выдранный кусок кода, в данном случае, ни о чем не говорит. Надо же поднять всю историю. Откуда взялся экземпляр ledgerBondServer? Какое значение идентификатора он ожидает получить? То, что он получает, соответствует ожиданиям?

Цитата:
Сообщение от NNB
Что бы на бросаться громкими фразами предлагаю заинтересовавшихся запустить поиск refId_RU по классам LedgerVoucherObject, LedgerVoucherTransList, LedgerBondServer_RU, LedgerBoundTransList_RU, LedgerBondClient_RU, LedgerBondTransObject_RU (для начала хватит) и сделать собственные выводы
Найти классы по перекрестным ссылкам - не проблема. Куда бОльшая проблема понять, для чего используется то или иное значение. Особенно, когда конечная цель "погребена" под многочисленной иерархией вложенных классов. Вы можете "человеческим" языком объяснить как используется полученное значение? Ну, получили в коде значение refId_RU. Ну, передали его как параметр в другой класс. А зачем передали-то? Как, в конце концов, это значение было использовано?
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...

Последний раз редактировалось Владимир Максимов; 17.01.2012 в 15:03.
Старый 17.01.2012, 15:48   #9  
NNB is offline
NNB
Участник
 
103 / 12 (1) ++
Регистрация: 31.08.2006
Могу
Только завтра - сегодня некогда
Старый 17.01.2012, 16:02   #10  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
Cool
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Не уверен. Выдранный кусок кода, в данном случае, ни о чем не говорит. Надо же поднять всю историю. Откуда взялся экземпляр ledgerBondServer? Какое значение идентификатора он ожидает получить? То, что он получает, соответствует ожиданиям?
Вот на таких домыслах система и превращается в неуправляемого монстра.
А ItemRefId не что иное, как порядковый номер проводки в списке ваучера. И значение его должно быть вполне предсказуемо.
Я вас убедил, или вы все еще рассматриваете локализацию LedgerVoucherTransList как образцовую?
__________________
Axapta non erubescit
Старый 17.01.2012, 16:52   #11  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от b_nosoff Посмотреть сообщение
Вот на таких домыслах система и превращается в неуправляемого монстра.
А ItemRefId не что иное, как порядковый номер проводки в списке ваучера. И значение его должно быть вполне предсказуемо.
Я вас убедил, или вы все еще рассматриваете локализацию LedgerVoucherTransList как образцовую?
Нет. Не убедили. Поскольку Вы смотрите на конечную точку безотносительно истории. Сразу же возникает вопрос, а откуда взялся объект ledgerTransList? А у него значение refId_RU на момент вызова корректно? Оно вообще как-то связано с циклом по first()..next()?

Я же говорю, "тщательнЕе" надо. Более внимательно изучать код. То, что это идентификатор и так понятно. Но в данном случае есть проблема с идентификаторами? Насколько я вижу, методы first() и next() вообще не имеют никакого отношения к идентификации. Они существуют "паралельно" с методом add(), который как раз и относится к идентификации.

Как образцовую, я реализацию LedgerVoucherTransList естессвенно, не рассматриваю. Именно в силу не очевидности кода. Существование в одном и том же классе неких "паралельных" логических структур.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 17.01.2012, 17:23   #12  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
!
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Нет. Не убедили.
Ну и ладно. Может кого другого убедил.

Просто, в качестве заключения - я полностью уверен в том, что это была попытка добавить к итератору функционал получения индекса текущего элемента. Duck typing, знаете ли...
__________________
Axapta non erubescit
Старый 17.01.2012, 17:53   #13  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от b_nosoff Посмотреть сообщение
Просто, в качестве заключения - я полностью уверен в том, что это была попытка добавить к итератору функционал получения индекса текущего элемента. Duck typing, знаете ли...
Так я тоже в этом уверен.

В данном случае я не уверен в том, что методы first()..next() имеют какое-либо отношение к этому самому индексу текущего элемента. Неужели с Ax3.0 никто не налетал на эти грабли?

Ведь очевидно же, что метод next() противоречит методу add(). Метод next() на последнем элементе даст значение 1. Метод first() на первом элементе даст значение либо 1 (после последнего next()), либо elements()+1 (после add()). Явно же, что после использования методов first() и next() метод itemRefId_RU() возвращают какую-то ерунду, а не идентификаторы. Просто некий счетчик, не имеющий вообще никакого отношения к идентификаторам.

Вот в эту ловушку NNB и попал. Он использовал first() .. next() как способ получения идентификатора. А в данном классе это не так.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 17.01.2012, 18:16   #14  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,909 / 5730 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
После использования методов first() и next(), метод itemRefId_ru() возвращает как раз не ерунду. Достаточно посмотреть на код из LedgerVoucherObject.Post().

Просто ошибка эта может стрельнуть только в случае, если происходит повторный вызов first() на полпути, так сказать. Типа начали итерацию, поитерировали, а потом не дожидаясь исчерпания итератора (возвращения значения false методом next()), попробовали вызвать first(). В этом случае, следующий вызов itemRefId_ru() вернет значение рассинхронизированное с методом item().
Однако, я в коде стандартных классов, такого места не нашел. Везде вызывается first() и потом итерируется до тех пор, пока next() не вернет false, сбросив, таким образом, refId_ru в исходное нулевое значение.
Так что на первый взгляд:
  • Если вы не изменяли стандартные классы корреспонденции и разноски в ГК,отсутствие инициализации никогда не должно приводить к ошибкам.
  • Возможно, отсутствие инициализации - это баг.А возможно и нет. Я не уверен, что по идеологии работы с итераторами, их можно многократно итерировать, не закончив предыдущую итерацию. Мне, конечно тоже отсутствие инициализации глаз режет, но не уверен что это формально можно считать ошибкой...
Старый 17.01.2012, 18:47   #15  
Pustik is offline
Pustik
Участник
 
807 / 372 (14) ++++++
Регистрация: 04.06.2004
Автор, говорит о некоторой специфической ситуации. Т.е. если я правильно понимаю эта ошибка происходит не постоянно всегда, а в какой-то момент, когда может быть до отмены закрытия собрана некая редко-случаемая комбинация данных или настройка склада такова, или еще что-то, что приводит к некорректной корреспонденции. В данном случае, просто просмотрев код тяжело понять где мина взорвется. Иногда, в такой "скрытой ошибке" досконально разберешься только тогда, когда не один час пошагово погуляешь по коду.
__________________
-Ты в гномиков веришь?
-Нет.
-А они в тебя верят, смотри, не подведи их.
Старый 17.01.2012, 18:51   #16  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от fed Посмотреть сообщение
После использования методов first() и next(), метод itemRefId_ru() возвращает как раз не ерунду. Достаточно посмотреть на код из LedgerVoucherObject.Post().
А дальше? Ну, получили значение lastRefId и как оно дальше было использовано? В классе LedgerVoucherObject - никак. Так какая разница, что именно в этой переменной записано?

Т.е., по большому счету, именно что "ерунду" возвращает. Некое число, не имеющее никакого отношения к идентификации. Просто некая возрастающая последовательность чисел. Может, там просто счетчик надо было поставить

=============================
И, кстати, насчет идентификации...

На всякий случай напомню, что MAP автоматически упорядочивает список по значению ключа. Но порядок следования чисел в символьном представлении отличается от порядка следования в числовом представлении.

Так что, и с этой стороны данный класс "не подарок" И опять же, явно противоречит использованию first() и next(). Не та последовательность перебора элементов. Отличная от последовательности создания элементов.

X++:
static void Job_Test(Args _args)
{
    MAP         transObject  = new Map(Types::String, Types::Integer);
    MapIterator  transIterator;
    ;

    transObject.insert('2', 1);
    transObject.insert('11', 1);

    transIterator = new MapIterator(transObject);
    while (transIterator.more())
    {
        info(transIterator.key());    // Сначала будет "11", потом "2"
        transIterator.next();
    }
}

Я просто не вижу зачем вообще нужно значение refId_RU при переборе элементов через first() и next(). Не вижу его использование как идентификатора именно после этих методов. После метода add() - есть использование. А после first(), next() - нет.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
За это сообщение автора поблагодарили: b_nosoff (1).
Старый 17.01.2012, 18:55   #17  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,701 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от Pustik Посмотреть сообщение
В данном случае, просто просмотрев код тяжело понять где мина взорвется. Иногда, в такой "скрытой ошибке" досконально разберешься только тогда, когда не один час пошагово погуляешь по коду.
Угу. Использование refId_RU в методе LedgerVoucherTransList.next() если не бессмысленное, то, как минимум, не очевидное. По крайней мере, я до сих пор не понимаю, зачем оно там вообще? А у автора, видимо, на этом какой-то свой функционал был построен. На чем он и "погорел".
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 17.01.2012, 19:08   #18  
b_nosoff is offline
b_nosoff
Читатель
Аватар для b_nosoff
MCP
MCBMSS
 
197 / 143 (5) +++++
Регистрация: 01.12.2004
Адрес: Msk
Записей в блоге: 13
:(
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
И, кстати, насчет идентификации...

На всякий случай напомню, что MAP автоматически упорядочивает список по значению ключа.
блиин, во это подстава, так подстава я даже не обратил внимания. Это что ж получается, если мы этим итератором начнем выбирать проводки из ваучера с количеством строк больше 10, то на третьем шаге получим десятую строку и т.д. И ведь это уже не локализаторы...
__________________
Axapta non erubescit
Старый 17.01.2012, 19:25   #19  
Pustik is offline
Pustik
Участник
 
807 / 372 (14) ++++++
Регистрация: 04.06.2004
Цитата:
Сообщение от b_nosoff Посмотреть сообщение
блиин, во это подстава, так подстава я даже не обратил внимания. Это что ж получается, если мы этим итератором начнем выбирать проводки из ваучера с количеством строк больше 10, то на третьем шаге получим десятую строку и т.д. И ведь это уже не локализаторы...
Детально обсуждалось здесь Не корректная сортировка в Map-e и Set-е. AX2009 RU5
__________________
-Ты в гномиков веришь?
-Нет.
-А они в тебя верят, смотри, не подведи их.
Старый 17.01.2012, 19:28   #20  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,909 / 5730 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
А дальше? Ну, получили значение lastRefId и как оно дальше было использовано? В классе LedgerVoucherObject - никак. Так какая разница, что именно в этой переменной записано?
Сохраненное значение возвращается методом ledgerVoucherObject.lastRefid_ru(). Который, в свою очередь, активно вызывается и используется методом ledgerBondServer.splitTrans() Фактически этот метод вынимает из lastRefId идентификатор последнего обрабатываемого постинга, который сейчас разносится. Метод splitTrans(), как раз таки вызывается по цепочке ledgerVoucherObject.Post()->LedgerVoucherTransObject.post()->LedgerVoucher.postGroup()->ledgerBondServer.splitTrans(). То есть - это как раз позволяет классу корреспонденции добраться до контекста верхнего уровня и понять чего же это мы сейчас разбиваем в списке проводок (в случае детального постинга - без группировки сходных разносок).

Последний раз редактировалось fed; 17.01.2012 в 19:33.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
emeadaxsupport: New Content for Microsoft Dynamics AX 2012 : October 2011 Blog bot DAX Blogs 0 27.10.2011 17:11
Sample Design Patterns: Microsoft Dynamics AX - Remedy for slow Microsoft Excel import Blog bot DAX Blogs 0 29.05.2011 17:13
axinthefield: Dynamics AX Event IDs Blog bot DAX Blogs 0 01.03.2011 22:11
axStart: Microsoft Dynamics AX 2009 Hot Topics Web Seminar Series Blog bot DAX Blogs 0 06.08.2008 12:05
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

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

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

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