|
28.07.2011, 11:50 | #1 |
Участник
|
Работа с транзакциями
Здраствуйте! Помогите разобраться в чем дело!
X++: real sumEur, sumUsd,Coef; date dt = systemdateget();// <-ïîëó÷àåì ñåãîäíÿøíóþ äàòó str Eur, Usd, stVal; while select cur // Âûáèðàåì âàëþòû êîò. ÿâë óñëîâíûìè åäèíèöàìè where cur.UE == NoYes::Yes { stVal = cur.CurrencyCode; // Çàïîìèíàåì íàèìåíîâàíèå âàëþòû Coef = cur.rate; // Çàïîìèíàåì êîýôôèöèåíò select excR where excR.CurrencyCode == cur.CurrencyCodeParent && excR.FromDate == dt; { if (excR.CurrencyCode == enum2str(CurrencyUECod::EURcod)) { sumEur = excR.ExchRate * Coef; ttsbegin; excR.FromDate = dt; excR.ExchRate = sumEur; excR.CurrencyCode = stVal; excR.insert(); ttscommit; } else if (excR.CurrencyCode == enum2str(CurrencyUECod::USDcod)) { sumUsd = excR.ExchRate * Coef; ttsbegin; excR.FromDate = dt; excR.ExchRate = sumUsd; excR.CurrencyCode = stVal; excR.insert(); ttscommit; } |
|
29.07.2011, 11:05 | #2 |
Участник
|
Этот код даже не компилируется.
Неясно же что за табличные переменные ты используешь и что у тебя после него входит в цикл. А уж если нормально его отформатируешь с отступами и пр. может кто-то даже и ответит...
__________________
Ален ноби, ностра алис. Что означает - если один человек построил, другой завсегда разобрать может. |
|
29.07.2011, 11:19 | #3 |
Участник
|
Судя по кракозябрам у вас ax3.0
совет: переключайтесь в русский язык ПЕРЕД копированием в буфер обмена, чтобы сохранить русский текст неизменным. Очень подозрительным выглядит этот участок кода. Цитата:
скорее всего, были какие-то правки. Что касается кода вообще, то вот как он переводится на человеческий: 1. перебрать ВСЕ валюты, удовлетворяющие условию 2. выбрать ОДИН курс, удовлетворяющий условию 3. если курс выбран И его код равен некоему enumstr(!!!!!!) 3.1. то ДОБАВИТЬ еще один курс ... и так далее Во-первых, по смыслу - вы ДОБАВЛЯЕТЕ курс, если он УЖЕ ЕСТЬ. Поэтому во втором проходе получаете ДВА курса. Аксапточка сделала ровно то, что ей сказали. Во-вторых, по стилю - сравнивать CurrencyCode с EnumStr - предельно некорректно. Прежде всего потому, что Аксапта может работать с разными языками и никто не гарантирует, что enumstr в разных языках будут одинаковыми. НИКОГДА так не делайте. Заведите строковые параметры в таблице параметров. |
|
29.07.2011, 15:31 | #4 |
Участник
|
Здраствуйте! Спасибо что обратили внимание! На счет Axapta 3.0 вы правы! А алгоритм работы следующий:
->Заходим в Currency, ищем валюты у кот. есть признак у.е. и от какой валюты они считаются и запоминаем коеффициент ->Заходим в ExchRates, там находим валюту и ее значение на сегодняшний день (т.к. предполагается что курсы валют грузятся до работы этого кода) ->Потом через if делаются записи, валюты всего 2 поэтому 2 транзакции. Не понятно почему если я один раз запускаю код, он может создать по 2 записи для каждой у.е.??? Ниже приведу нормальный листинг с коментариями и отступами. |
|
29.07.2011, 15:35 | #5 |
Участник
|
X++: void clicked() { Currency cur; ExchRates excR, excRval; real sumEur, sumUsd,Coef; date dt = systemdateget();// <-получаем сегодняшную дату str Eur, Usd, stVal, StrDt; StrDt = Date2Str(dt,2,2,2,2,2,4); while select cur // Выбираем валюты кот. явл условными единицами where cur.UE == NoYes::Yes { stVal = cur.CurrencyCode; // Запоминаем наименование валюты напр. YEEUR Coef = cur.rate; // Запоминаем коэффициент select excR where excR.CurrencyCode == cur.CurrencyCodeParent && excR.FromDate == dt; { if (excR.CurrencyCode == enum2str(CurrencyUECod::EURcod)) { sumEur = excR.ExchRate * Coef; ttsbegin; excR.FromDate = dt; excR.ExchRate = sumEur; excR.CurrencyCode = stVal; excR.insert(); ttscommit; } else if (excR.CurrencyCode == enum2str(CurrencyUECod::USDcod)) { sumUsd = excR.ExchRate * Coef; ttsbegin; excR.FromDate = dt; excR.ExchRate = sumUsd; excR.CurrencyCode = stVal; excR.insert(); ttscommit; } } } element.closeCancel(); info(strfmt("На: %1", StrDt)); info("Курсы у.е. успешно расчитаны"); info(strfmt("Курс YEEUR: %1", sumEur)); info(strfmt("Курс YEUSD: %1", sumUsd)); } |
|
29.07.2011, 16:11 | #6 |
Участник
|
понятно почему вы поставили точку с запятой.
непонятно почему вы не убрали фигурную скобку - по синаксису ее здесь не должно быть. но если бы выше было "while select excR", то фигурная скобка обязательна, а точка с запятой была бы лишней. вы определитесь что именно у вас лишнее. ============== Что значит "делаются записи"? записи могут: insert, update, delete. Что именно вы подразумеваете под словом "делаются" Пожалуйста, пока не постите в эту ветку ваш код - на него просто физически больно смотреть. Сформулируйте на простом и родном для вас языке - что именно вы хотите получить в результате. Пожалуйста, не надо в стиле "акына" - заходим, запоминаем, делаем. А именно каков ожидаемый результат? |
|
29.07.2011, 18:00 | #7 |
Участник
|
Ну, тут явная кастомизация сделана. В данном случае, в таблице Currency записаны не коды валют, а коды условных единиц. Причем сделана иерархия. Добавлены следующие поля
Currency.UE - признак того, что данная запись относится к условным единицам Currency.CurrencyCodeParent - код валюты "родителя". Т.е. той валюты, по отношению к которой следует рассчитывать курс этих самых условных единиц Задача сводится к тому, чтобы найти курс "родительской" валюты на текущую дату и на ее основе создать (записать) курс условной единицы тоже на текущую дату. Внешний цикл - это просто перебор всех условных единиц. В принципе, код, вроде бы, рабочий ("корявенько", но работает ), если не считать того, что не проверяется факт существования курса условных единиц на текущую дату. Это значит, что сколько раз запустишь код, столько раз заново и будет создано по еще одной записи с курсами условных единиц на текущую дату. Или что подразумевается под фразой "он может создать по 2 записи для каждой у.е"? Если я правильно понял, что надо сделать, то код должен быть примерно таким X++: void clicked() { Currency currency; ExchRates exchRates; ExchRates exchRatesUE; FromDate fromDate = systemdateget(); ; while select exchRates where exchRates.FromDate == fromDate join currency where currency.CurrencyCodeParent == exchRates.CurrencyCode && currency.UE == NoYes::Yes { // Сначала проверяем тот факт, что курс УЕ на текущую дату уже заведен select firstonly exchRatesUE where exchRatesUE.FromDate == fromDate && exchRatesUE.CurrencyCode == currency.CurrencyCode; // Если уже есть, то берем следующую запись выборки if (exchRatesUE) { continue; } // Если нет, то создаем новую запись exchRatesUE.clear(); exchRatesUE.CurrencyCode = currency.CurrencyCode; exchRatesUE.FromDate = fromDate; exchRatesUE.ExchRate = exchRates.ExchRate * currency.Rate; exchRatesUE.insert(); info(strFmt("Курс %1: %2", exchRatesUE.CurrencyCode, exchRatesUE.ExchRate)); } // while select exchRates info(strFmt("Формирование курсов УЕ на %1 завершено!", fromDate)); element.closeCancel(); } |
|
|
За это сообщение автора поблагодарили: JuniorAx (1). |
29.07.2011, 20:37 | #8 |
Участник
|
Спасибо большое всем за помощь! Изначально надо было четко сформулировать конечную цель)))) А по поводу двойного inserta, я проверяю работу кода так: изменяю системную дату, завожу в таблице курсы валют на эту дату, и запускаю процедуру! и допустим на сегодня создалось всего 2 записи (т.к. валют 2 YEEUR и YEUSD), а допустим меняю сист. дату на завтра и запускаю выдает по 2 записи для каждой у.е. - вот сама проблема!!!)))) У меня есть не большая просьба к участникам скинуть какую нибудь ссылку на то как запихнуть мне это в пакетную обработку??? Я читаю несколько книг по Axapta, и все что я нашел так это то, что надо создать наследник класса RunBaseBath и т.д, но не одного примера пока ни видел, тяжело опираться только на теорию! Спасибо
|
|
29.07.2011, 20:53 | #9 |
Участник
|
|
|