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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 23.12.2008, 17:46   #1  
Yury J is offline
Yury J
Участник
Аватар для Yury J
 
11 / 34 (2) +++
Регистрация: 30.10.2007
Как передать параметр из Job-a в Class с возможностью перезаписи?
Всем доброго времени суток!
У меня такая проблема:
Я запускаю сценарий (Job) из класса. Но передать значение переменной (даже при использовании системных классов) после первого "захода" в Job не получается. Предыдущее значение не перезаписывается.
Вариант временно хранить в таблице не подходит. Требование Клиента.

Уважаемые коллеги, подскажите, как мне решить эту проблему.

Исходные данные:

Job:

X++:
static AmountMST ScenarioScript134218100335()
{
/////////////////////////////////////// Системное объявление переменных. Не редактировать! -->
Date                                             startDate;               // Начальная дата для пересчета сценария
Date                                             endDate;                // Конечная дата для пересчета сценария
AmountMST                                 reslt;                      // Промежуточный результат пересчета сценария
JobName                                      jobName;              // Название сценария \Data Dictionary\Extended Data Types\JobName
LedgerRRGOperationTable_RU  ledgerRRGOperationTable; // Запись таблицы "Оперции над ячейкой отчета"
LedgerRRGCellTable_RU           ledgerRRGCellTable;      // Запись таблицы "Ячейки отчетов"
LedgerPeriodCode                      ledgerPeriodCode;        // Запись таблицы "Интервалы дат"
RefRecId                                      RRecId;    // RecId записи таблицы "Оперции над ячейкой отчета"
job                                                jb = new Job();          // Экземпляр сценария
JobName                                      rr;                      // Значение RecId
AmountMST                                 result;      // Промежуточный результат пересчета сценария
AmountMST                                 relt;      // Результат пересчета сценария
/////////////////////////////////////// Системное объявление переменных. Не редактировать! <--
// USER VARIABLES -->
CustTable  ct;
CustTrans  ctr;
VendTable  vt;
VendTrans  vtr;
AmountMst Amount;
// USER VARIABLES <--
;
////////////////////////////////////// Системная инициализация переменных. Не редактировать! -->
jobName = funcname();
// Выбор записи таблицы "Оперции над ячейкой отчета"
ttsbegin;
select firstonly forupdate ledgerRRGOperationTable
where ledgerRRGOperationTable.CIT_JobName == jobName;
// Выбор записи таблицы "Ячейки отчетов"
select firstonly forupdate ledgerRRGCellTable
where ledgerRRGCellTable.RecId == ledgerRRGOperationTable.CellRecId;
// Если в записи таблицы "Оперции над ячейкой отчета" определен интервал дат из таблицы "Интервалы дат"
if(ledgerRRGOperationTable.LedgerPeriodCode)
{
select firstonly forupdate ledgerPeriodCode
where ledgerPeriodCode.Code == ledgerRRGOperationTable.LedgerPeriodCode;
startDate = ledgerPeriodCode.StartFixedDate;
endDate = ledgerPeriodCode.EndFixedDate;
}
else
{
// В противном случае определяем интервал дат из таблиц "Ячейки отчетов" и "Интервалы дат"
select firstonly forupdate ledgerPeriodCode
where ledgerPeriodCode.Code == ledgerRRGCellTable.LedgerPeriodCode;
startDate = ledgerPeriodCode.StartFixedDate;
endDate = ledgerPeriodCode.EndFixedDate;
}
rr = substr(jobName,23,10); // Определение значения RecId записи таблицы "Оперции над ячейкой отчета"
RRecId = str2int64(rr);
////////////////////////////////////// Системная инициализация переменных. Не редактировать! <--
// USER CODE -->
Amount=0;
while select  *  from ct
WHERE  ct.CustGROUP == "UPS"      ||
       ct.CustGROUP == "REGION"
{
  select sum(AmountMst) from ctr
  WHERE  ctr.ACCOUNTNUM ==ct.ACCOUNTNUM &&
 (ctr.TRANSDATE >=startdate  &&  ctr.transDATE<= endDATE);
  IF (ctr.AmountMst < 0)   AMOUNT+=ABS(ctr.AmountMst );
}
while select  * from  vt 
WHERE  vt .VendGroup   == "PUMA"          ||
                 vt .VendGroup  == "SERIAL"
{
   select sum(amountMst) from vtr
   WHERE  vtr.AccountNum == vt.ACCOUNTNUM &&
    (vtr.TRANSDATE >=startdate &&  vtr.transDATE<= endDATE);
   IF (vtr.AmountMst < 0)   AMOUNT+=ABS(vtr.AmountMst );
}
relt=amount;
// USER CODE <--
//////////////////////////////// Присвоение значения результата пересчета сценария. Не редактировать! -->
ledgerRRGOperationTable.CIT_Result = relt; //  \Data Dictionary\Tables\LedgerRRGOperationTable_RU\Fields\ Result добавленное поле где мы временно храним значение переменной
ledgerRRGOperationTable.update();
appl.parmResssy(relt);  // Здесь проблемное место. Передаем значение переменной во вновь созданный метод \Classes\Application\parmResssy для \Classes\Application\classDeclaration: AmountMST resssy;
ttscommit;
//////////////////////////////// Присвоение значения результата пересчета сценария. Не редактировать! <--
return relt;
}

\Classes\LedgerRRGRunReport_RU\CIT_ScenarioScriptVend:

X++:
protected AmountMST CIT_ScenarioScriptVend(LedgerRRGAccountNumMap_RU _ScenarioAccountNumMap,  // Таблица настроек Генератора
                                           DateCode                  _ScenarioDateCode,       // Скрипт сценария (Не нужно)
                                           CIT_JobName               _JobName,                // Название job-а
                                           FreeTxt                   _ScenarioFreeTxt)        // Скрипт сценария (Не нужно)
{
    #AOT
    AmountMST                   resultVend;
    AmountMST                   ressst;
    job                         j= new Job();
    str                         jobName;                  // Название job-а
    LedgerRRGOperationTable_RU  ledgerRRGOperationTable;  // Таблица настроек Генератора
    ;
    jobName = _JobName;
    j = TreeNode::findNode(#JobsPath + "\\" + JobName);
    if(j)
    j.AOTrun();
    resultVend = appl.parmResssy(); // Проблемное место. Не перезаписывается значение переменной.
    return resultVend;
}

\Classes\Application\parmResssy:

X++:
public AmountMST parmResssy(AmountMST _resssy = resssy)
{
    ;
    resssy = _resssy;
    return resssy;
}
Старый 23.12.2008, 17:49   #2  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Сделайте вместо Джоба нормальный Класс, потомок RunBase. Джобы используются для неких разовых операций и не участвуют в бизнес-логике.
__________________
С уважением,
Олег.
Старый 23.12.2008, 17:52   #3  
Lemming is offline
Lemming
Участник
Аватар для Lemming
 
1,144 / 343 (14) ++++++
Регистрация: 20.04.2004
Адрес: Москва, Чайнатаун в Люблино
Записей в блоге: 10
OMG

X++:
jobName = _JobName;
    j = TreeNode::findNode(#JobsPath + "\\" + JobName);
    if(j)
    j.AOTrun();
Вообще то не рекомендуется использовать джобы для манипуляции данными, для этих целей нужно использовать наследники RunBase, но если уж так хочется поизвращаться, то попробуйте запускать свои Job-ы через пункт меню, передовать ему args, а из args уже вытаскивать что душе угодно...
Старый 23.12.2008, 17:56   #4  
Yury J is offline
Yury J
Участник
Аватар для Yury J
 
11 / 34 (2) +++
Регистрация: 30.10.2007
Thumbs down
Сценарий нужен для доработки Генератора финансовых отчетов.
Из формы настроек конструктором я генерю Job-ы.
При этом Клиент имеет возможность дорабатывать сам сценарий в форме.
А дальше по настройкам формируются отчеты.
Классы генерить конструктором не правильно.
Дляэтого есть соответствующая ветка сценариев - \Jobs
Старый 23.12.2008, 18:18   #5  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1234 (44) ++++++++
Регистрация: 11.04.2008
Можно пользовать, например, GlobalCache, передавать\забирать параметры через него.
infolog.globalCache().set
infolog.globalCache().get
Кстати с системными классами тож должно работать... попробуйте info вместо application.
За это сообщение автора поблагодарили: Yury J (1).
Старый 23.12.2008, 19:28   #6  
Alex_KD is offline
Alex_KD
Участник
AxAssist
MCBMSS
Соотечественники
 
522 / 362 (14) ++++++
Регистрация: 06.07.2006
Адрес: Melbourne, Down Under
Еще про кэширование:
http://erpkb.com/Axapta/Singleton
__________________
AxAssist 2012 - Productivity Tool for Dynamics AX 2012/2009/4.0/3.0
Старый 23.12.2008, 19:58   #7  
Михаил Андреев is offline
Михаил Андреев
Участник
Компания АМАНД
Лучший по профессии 2009
 
1,284 / 239 (10) ++++++
Регистрация: 09.11.2001
Адрес: Химки, Московская область
Цитата:
Сообщение от Yury J Посмотреть сообщение
Классы генерить конструктором не правильно.
Дляэтого есть соответствующая ветка сценариев - \Jobs
Это где Вы такое прочитали или сами придумали?
Конструкторы штатные, например, конфигуратор или мастер создания налогового регистра, формируют именно классы.
__________________
Михаил Андреев
https://www.amand.ru
Старый 23.12.2008, 22:20   #8  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Yury J Посмотреть сообщение
Сценарий нужен для доработки Генератора финансовых отчетов.
Из формы настроек конструктором я генерю Job-ы.
При этом Клиент имеет возможность дорабатывать сам сценарий в форме.
Вообще-то основное правило в Аксапте - посмотри как это уже сделали до тебя и сделай по аналогии. Это я к тому, что все вставки на X++ (например при импорте данных) хранятся в таблице в контейнере. Конечно - код приложения в таблице хранить - это та еще засада, но модифицировать только ради этого класс Application я считаю тоже излишне.
Пусть генерится класс. А чем плох класс? Чем джоб лучше класса? Тем что он лучше виден в АОТе и его легче прибить?
Ну так сделайте у классов некоторый префикс и пусть его будет также легко и непринужденно прибить как джоб.
Можно дальше пойти. Можно создать проект, в который добавлять программно классы, созданные из кода. Тогда эти классы будет прибить еще легче чем джобы.
__________________
Возможно сделать все. Вопрос времени
Старый 24.12.2008, 07:16   #9  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Пусть генерится класс. А чем плох класс? Чем джоб лучше класса? Тем что он лучше виден в АОТе и его легче прибить?
Сильно подозреваю что автор просто не знает как запустить выполнение класса из AOT - не знает, что статическая функция main в классе дает такую возможность.
Вот и извращается.
__________________
полезное на axForum, github, vk, coub.
Старый 24.12.2008, 07:22   #10  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Yury J Посмотреть сообщение
Я запускаю сценарий (Job) из класса. Но передать значение переменной ... не получается.

X++:
static AmountMST ScenarioScript134218100335()
Конечно же не получается, раз вы не объявили значения переменных.
Обратите внимание, что все job'ы имеют аргументы Args _args.
Через них родимых и надо передавать, если уж твердо решили делать через job'ы.

Т.е. вы должны объявить
X++:
static AmountMST ScenarioScript134218100335(Args _args)
__________________
полезное на axForum, github, vk, coub.
Старый 24.12.2008, 09:28   #11  
Yury J is offline
Yury J
Участник
Аватар для Yury J
 
11 / 34 (2) +++
Регистрация: 30.10.2007
Доброго времени суток.
Спасибо большое всем за оперативную помощь!
Проблему решил воспользовавшись помощью DSPIC:
Можно пользовать, например, GlobalCache, передавать\забирать параметры через него.
infolog.globalCache().set
infolog.globalCache().get

Мой тебе, DSPIC респект!
Тему можно закрывать.

Постараюсь по максимуму ответить на ваши вопросы
Михаил Андреев
Это где Вы такое прочитали или сами придумали?
Конструкторы штатные, например, конфигуратор или мастер создания налогового регистра, формируют именно классы.

Я создал свой класс конструктор в 4-ке, который при помощи xppCompiler, freeTxt,treenode,job
X++:
        t = infolog.findNode("Jobs");
        j = t.AOTfindChild(jobName);
формировал сам Job с уже "зашитым скриптом".
Для пользователя добавил вставочку где он может объявлять объекты и переменные. А также вставочку где он рисовал свой ко логики.
Сам Job вывается по кнопочке из строк настроек Генератора финансовых ротчетов. Для этого добавлен тип строки "Сценарий". как в конкорде. Вот и все.
Таким инструментом пользователь может строить любую отчетность. Пример был разобран мною выше по коду Jb-а.


sukhanchik

Цитата:
Вообще-то основное правило в Аксапте - посмотри как это уже сделали до тебя и сделай по аналогии. Это я к тому, что все вставки на X++ (например при импорте данных) хранятся в таблице в контейнере. Конечно - код приложения в таблице хранить - это та еще засада, но модифицировать только ради этого класс Application я считаю тоже излишне.
Пусть генерится класс. А чем плох класс? Чем джоб лучше класса? Тем что он лучше виден в АОТе и его легче прибить?
Ну так сделайте у классов некоторый префикс и пусть его будет также легко и непринужденно прибить как джоб.
Можно дальше пойти. Можно создать проект, в который добавлять программно классы, созданные из кода. Тогда эти классы будет прибить еще легче чем джобы.
Со всем согласен.
Но для работы нужен был именно этот вариант решения. Таковы были требования Клиента.
А Клиент, сам понимаешь, всегда прав.
И работа уже выполнена и сдана.
Но только промежуточное значение? как ты и пишешь храyилось в таблице.
Что не есть правильно.
И при высокой плотности обращений падала производительность построения отчета. Кроме прочего отчет еще выводится в Excel.

mazzy
X++:
            AOT -  ,    main     .
  .
Ваши подозрения не обоснованы.
Вспомните модуль GALAXY. И Вам много станет понятно.
Или Датчане тоже извращенцы?

mazzy
PHP код:
Конечно же не получаетсяраз вы не объявили значения переменных.
Обратите вниманиечто все job'ы имеют аргументы Args _args.
Через них родимых и надо передавать, если уж твердо решили делать через job'
ы.
 
Т.евы должны объявить
 
X
++:static AmountMST ScenarioScript134218100335(Args _args
Спасибо, Сергей!
Я всё это знаю.
Но я пошёл свом путём .
Старый 24.12.2008, 09:33   #12  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Yury J Посмотреть сообщение
Мой тебе, DSPIC респект!
Тему можно закрывать.
Внизу каждого сообщения есть ссылка "Поблагодарить автора сообщения".
Нажмите и ваш респект отобразится в его профиле.
Пока респект только на словах

Цитата:
Сообщение от Yury J Посмотреть сообщение
Вспомните модуль GALAXY. И Вам много станет понятно.
Или Датчане тоже извращенцы?
Да, среди них встречаются те еще затейники, блин.

Цитата:
Сообщение от Yury J Посмотреть сообщение
Спасибо, Сергей!
Я всё это знаю.
Но я пошёл свом путём .
Ок.
Цезарь, идущие на смерть приветствуют тебя! (С)
__________________
полезное на axForum, github, vk, coub.
Старый 24.12.2008, 14:06   #13  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Yury J Посмотреть сообщение
Но для работы нужен был именно этот вариант решения. Таковы были требования Клиента.
А Клиент, сам понимаешь, всегда прав.
И работа уже выполнена и сдана.
Но только промежуточное значение? как ты и пишешь храyилось в таблице.
Что не есть правильно.
И при высокой плотности обращений падала производительность построения отчета. Кроме прочего отчет еще выводится в Excel.
Я не говорю о том, чтобы хранить в таблице. Я ж говорю - это та еще засада.
Я говорю о том, что изначальное решение - формировать джобы - неверное. Не нужно было с ними изначально связываться. Таково мое мнение.

А вот в отношении правоты Клиента готов поспорить. Конечно, при уже оттестированном коде, который генерит джобы - ломать все - не есть правильно.
С одной стороны.
С другой стороны, если этот функционал будет еще активно развиваться - то лучше сразу его сломать.
Работал я по принципу - Клиент всегда прав. Оказалось - что Клиент-то на самом деле не всегда прав. Если исключить откровенную дурость - то всегда можно прийти к консенсусу, который выродится в минимальное кол-во изменений.
В противном случае - работа выльется в то, что придется туда-сюда переделывать, а Клиент будет недоволен - что никак все не сделаете.
А в случае откровенной дурости - надо танцевать от позиции "В Аксапте это невозможно". Это хорошо действует, даже если это технически возможно.

В общем-то "Жираф большой ему видней" - так что если Вы решили свои задачи - значит для Вас все ок.
__________________
Возможно сделать все. Вопрос времени
За это сообщение автора поблагодарили: oip (1).
Старый 24.12.2008, 14:08   #14  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
А в случае откровенной дурости - надо танцевать от позиции "В Аксапте это невозможно". Это хорошо действует, даже если это технически возможно.
Я обычно говорю "в Аксапте это сделать очень трудоемко" и говорю свою временную оценку (несколько завышенную) и о последствиях предупреждаю, чтобы уж не сильно обманывать. Действует. И всех учу не работать слепо по принципу "клиент всегда прав". Клиент НЕ всегда прав. А так полностью согласен. Более того, я не верю, что у клиента было требование сделать именно джоб. Думаю, клиенту надо чтобы работало. А уж как это будет сделано - не его забота.

Оффтоп: Аналогично, когда программист читает ТЗ, то тоже не надо считать, что "консультант всегда прав, поэтому раз так написано в задании, то надо делать именно так." А то часто тут на форуме проскакивает "это не моя вина, мне так написали в ТЗ". Если в ТЗ написано не так, как надо, необходимо сказать об этом постановщику и найти компромис.

Upd. http://www.amand.ru/modules/wordpres...ves/67#more-67
__________________
С уважением,
Олег.
За это сообщение автора поблагодарили: Logger (4).
Старый 11.01.2009, 17:11   #15  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,867 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от oip Посмотреть сообщение
Я обычно говорю "в Аксапте это сделать очень трудоемко" и говорю свою временную оценку (несколько завышенную) и о последствиях предупреждаю, чтобы уж не сильно обманывать. Действует. И всех учу не работать слепо по принципу "клиент всегда прав". Клиент НЕ всегда прав. А так полностью согласен. Более того, я не верю, что у клиента было требование сделать именно джоб. Думаю, клиенту надо чтобы работало. А уж как это будет сделано - не его забота.

Оффтоп: Аналогично, когда программист читает ТЗ, то тоже не надо считать, что "консультант всегда прав, поэтому раз так написано в задании, то надо делать именно так." А то часто тут на форуме проскакивает "это не моя вина, мне так написали в ТЗ". Если в ТЗ написано не так, как надо, необходимо сказать об этом постановщику и найти компромис.

Upd. http://www.amand.ru/modules/wordpres...ves/67#more-67

Все правильно, но, к сожалению, разработчик не всегда имеет соответствующий вес, чтобы так говорить.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Kashperuk Ivan: Description of ClassBuild class:Today I want to ... Blog bot DAX Blogs 0 26.01.2007 05:51
Передать контейнер в job через COM sao DAX: Программирование 5 21.02.2006 19:34
Можно ли передать котрол формы как параметр метода? nicky DAX: Программирование 6 23.05.2005 18:40
Передать параметр Hobo DAX: Программирование 2 05.03.2004 19:18
Говорят вышел SP2 для Axapta 3. Кто нибуть что знает на эту тему? soin DAX: Прочие вопросы 10 13.10.2003 10:43
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 13:46.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.