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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.12.2007, 09:47   #1  
lemchey_white is offline
lemchey_white
Участник
Axapta Retail User
 
22 / 13 (1) ++
Регистрация: 08.08.2007
Передача переменного числа параметров в метод
Всем доброго времени суток. Подскажите пожалуста возможно ли написать собственный метод(наподобие strfmt), который может принемать переменное количество параметров?
Старый 27.12.2007, 09:53   #2  
if_maks is offline
if_maks
Участник
 
226 / 15 (1) ++
Регистрация: 26.08.2003
конечно не совсем "то", но может контейнер передавать, в него можно что угодно упихать в любом количестве...
Старый 27.12.2007, 09:54   #3  
Alex_KD is offline
Alex_KD
Участник
AxAssist
MCBMSS
Соотечественники
 
522 / 362 (14) ++++++
Регистрация: 06.07.2006
Адрес: Melbourne, Down Under
Можно пользоваться контейнером:
X++:
container MyMethod(container _params)
__________________
AxAssist 2012 - Productivity Tool for Dynamics AX 2012/2009/4.0/3.0
Старый 27.12.2007, 09:55   #4  
lemchey_white is offline
lemchey_white
Участник
Axapta Retail User
 
22 / 13 (1) ++
Регистрация: 08.08.2007
контейнер - это само собой понятно. Но именно интересно что то вроде strfmt.
Старый 27.12.2007, 10:49   #5  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,652 / 1158 (42) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Ну, если очень хочется, то забей штук 20 параметров типа anyType и анализируй их содержимое в начале метода

X++:
void MyMethod(
	anyType par1 = "",
	anyType par2 = "",
	anyType par3 = "",
	anyType par4 = "",
	anyType par5 = "",
	anyType par6 = "",
	...
	)
{
	if (PrmIsDefault(par1) == 0)
	{
		switch (typeOf(par1))
		{
		case types::INTEGER :
		case types::REAL :
		case types::ENUM :
		default :
		}
	}
...
}
Анализ переданного типа параметра можно вынести в отдельный метод или функцию внутри метода

Только через контейнер или объект - проще.
Старый 27.12.2007, 10:58   #6  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
X++:
static void Job_TestStrFmt(Args _args)
{
    str newStrFmt(str _template,
        anytype _par01='', anytype _par02='', anytype _par03='', anytype _par04='', anytype _par05='', anytype _par06='',
        anytype _par07='', anytype _par08='', anytype _par09='', anytype _par10='', anytype _par11='', anytype _par12='',
        anytype _par13='', anytype _par14='', anytype _par15='', anytype _par16='', anytype _par17='', anytype _par18='',
        anytype _par19='', anytype _par20='', anytype _par21='', anytype _par22='', anytype _par23='', anytype _par24='',
        anytype _par25='', anytype _par26='', anytype _par27='', anytype _par28='', anytype _par29='', anytype _par30='',
        anytype _par31='', anytype _par32='', anytype _par33='', anytype _par34='', anytype _par35='', anytype _par36='',
        anytype _par37='', anytype _par38='', anytype _par39='', anytype _par40='', anytype _par41='', anytype _par42='',
        anytype _par43='', anytype _par44='', anytype _par45='', anytype _par46='', anytype _par47='')

    {
        return strfmt(  _template,
                        _par01, _par02, _par03, _par04, _par05, _par06,
                        _par07, _par08, _par09, _par10, _par11, _par12,
                        _par13, _par14, _par15, _par16, _par17, _par18,
                        _par19, _par20, _par21, _par22, _par23, _par24,
                        _par25, _par26, _par27, _par28, _par29, _par30,
                        _par31, _par32, _par33, _par34, _par35, _par36,
                        _par37, _par38, _par39, _par40, _par41, _par42,
                        _par43, _par44, _par45, _par46, _par47);
    }
    ;

    info( newStrFmt('Int: %1 --- Real: %2 --- Date: %3 --- Boolean: %4 --- Enum: %5',
                    10000, 1200.456 , 01\10\2006, TRUE, RAssetTransType::Depreciation));
}
P.S. Попутно выяснился предел кол-ва параметров функции strFmt. Если добавить еще один (_par48), то компилятор ругается ошибкой переполнения стека.
За это сообщение автора поблагодарили: Zick-Zibn (1), e@gle (2), gl00mie (5), Silphidae (1).
Старый 27.12.2007, 11:15   #7  
lemchey_white is offline
lemchey_white
Участник
Axapta Retail User
 
22 / 13 (1) ++
Регистрация: 08.08.2007
варианты с записью от 20 до 48 параметров очень поравились. Но хочется разобраться как же все таки параметры в strfmt передаются, (в С++ можно было так сделать указав в параметрах ...(три точки)).
Старый 27.12.2007, 11:38   #8  
Russland is offline
Russland
MCTS
Аватар для Russland
MCBMSS
 
267 / 116 (4) +++++
Регистрация: 17.10.2005
Адрес: Донеччина, Україна
Посмотрите в сторону функции runbuf()
__________________

В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню
Старый 11.09.2009, 12:07   #9  
IvanS is offline
IvanS
Участник
Аватар для IvanS
 
241 / 44 (2) +++
Регистрация: 30.06.2006
Адрес: Екатеринбург
В общем мне пришлось что то подобно делать и обобщив все сказанное сделал так чтобы можно было вызывать sfrfmt с неизвестными количеством параметров. Получилось примерно следующее:
X++:
static void Job7(Args _args)
{
    str         textparm = "strfmt('%1 + %2 - 3', '5','6')";
    str         pseudoFunc;
    anytype         result ;
    ;
    pseudoFunc = evalBuf(textparm);
    result = evalBuf(pseudoFunc);
}
То есть используем strfmt как текст и сами можем добавить сколько угодно параметров (ну то есть почти сколько угодно, как раньше выяснилось не больше 48 ) в приходится дважды пользоваться функцией evalBuf
За это сообщение автора поблагодарили: alex55 (1).
Старый 11.09.2009, 13:11   #10  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
642 / 347 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
2Gustsav: Зачем так извращаться? Контейнер - самое оптимальное решение.
X++:
static void printValues(container _values)
{
    for (i=1; i <= conlen(_values); i++)
    {
        print(conpeek(_values, i));
    }
}
__________________
// no comments
Старый 11.09.2009, 14:31   #11  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от dech Посмотреть сообщение
2Gustsav: Зачем так извращаться? Контейнер - самое оптимальное решение.
эммм... Вы ж, наверное, всю ветку читали, не только моё сообщение в отрыве от общего контекста? Там вроде всё написано...
Цитата:
Сообщение от lemchey_white Посмотреть сообщение
контейнер - это само собой понятно. Но именно интересно что то вроде strfmt.
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Ну, если очень хочется, то забей штук 20 параметров типа anyType и анализируй их содержимое в начале метода
Старый 14.09.2009, 15:19   #12  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
Можно ещё посмотреть в сторону макросов, они ведь могут быть с одним именем и с разным числом параметров.
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy
Старый 14.09.2009, 17:30   #13  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Цитата:
Сообщение от lemchey_white
...
именно интересно что то вроде strfmt
...
А зачем вам это нужно? Вероятно, не спортивный азарт?

Как вы эти параметры будете разбирать (обрабатывать) потом?

Кроме контейнеров и классов а-ля List в Аксапте есть еще пример реализации с классом Args.
__________________
С уважением,
glibs®
Старый 15.09.2009, 10:49   #14  
lemchey_white is offline
lemchey_white
Участник
Axapta Retail User
 
22 / 13 (1) ++
Регистрация: 08.08.2007
Собственно просто интересно было, есть такая возможность или нет. Может где-нибудь можно было бы применить.

Цитата:
Как вы эти параметры будете разбирать (обрабатывать) потом?
Ну это уже другой вопрос, хотя бы глянуть в сторону С++.
Старый 13.12.2009, 22:18   #15  
Kabardian is offline
Kabardian
Талантливый разгвоздяй
Аватар для Kabardian
 
424 / 338 (12) ++++++
Регистрация: 14.12.2008
Адрес: Москва
Записей в блоге: 14
! Методам и переменным нельзя передать более 47 аргументов
Цитата:
Сообщение от Gustav Посмотреть сообщение
P.S. Попутно выяснился предел кол-ва параметров функции strFmt. Если добавить еще один (_par48), то компилятор ругается ошибкой переполнения стека.
Аналогичная проблема появилась при передаче 48 и более аргументов методу, который принимает значения типа Container в формате [арг1, арг2,арг3 ...]. Проблема решилась передачей методу переменной типа Container, а не указанной кострукции. Это навело меня на мысль, что:

методам и переменным хардкодом нельзя передать более 47 аргументов

Например, даже переменной типа Container путем грубой силы не может быть присвоено более 47 аргументов:
X++:
//Проверка максимального количества аргументов, которые можно передавать в коде через запятую
static void ArgsLimitCheck(Args _args)
{
    InventTable     inventTable;
    Container       conFields;
    int             i;
    ;

    select firstFast inventTable;

    conFields = conIns([
                    inventTable.ItemGroupId     //1
                    ,inventTable.ItemId     //2
                    ,inventTable.ItemName     //3
                    ,inventTable.ItemType     //4
                    ,inventTable.PurchModel     //5
                    ,inventTable.Height     //6
                    ,inventTable.Width     //7
                    ,inventTable.SalesModel     //8
                    ,inventTable.ReqGroupId     //9
                    ,inventTable.EPCManager     //10
                    ,inventTable.PrimaryVendorId     //11
                    ,inventTable.NetWeight     //12
                    ,inventTable.Depth     //13
                    ,inventTable.UnitVolume     //14
                    ,inventTable.BOMUnitId     //15
                    ,inventTable.Density     //16
                    ,inventTable.Dimension     //17
                    ,inventTable.Dimension     //18
                    ,inventTable.Dimension     //19
                    ,inventTable.CostModel     //20
                    ,inventTable.UseAltItemId     //21
                    ,inventTable.AltItemId     //22
                    ,inventTable.Intracode     //23
                    ,inventTable.ProdFlushingPrincip     //24
                    ,inventTable.PBAItemAutoGenerated     //25
                    ,inventTable.BOMManualReceipt     //26
                    ,inventTable.StopExplode     //27
                    ,inventTable.Phantom     //28
                    ,inventTable.IntraUnit     //29
                    ,inventTable.BOMLevel     //30
                    ,inventTable.BatchNumGroupId     //31
                    ,inventTable.AutoReportFinished     //32
                    ,inventTable.OrigCountryRegionId     //33
                    ,inventTable.StatisticsFactor     //34
                    ,inventTable.AltConfigId     //35
                    ,inventTable.StandardConfigId     //36
                    ,inventTable.ProdPoolId     //37
                    ,inventTable.PropertyId     //38
                    ,inventTable.ABCTieUp     //39
                    ,inventTable.ABCRevenue     //40
                    ,inventTable.ABCValue     //41
                    ,inventTable.ABCContributionMargin     //42
                    ,inventTable.CommissionGroupId     //43
                    ,inventTable.Configurable     //44
                    ,inventTable.SalesPercentMarkup     //45
                    ,inventTable.SalesContributionRatio     //46
                    ,inventTable.SalesPriceModelBasic     //47
/*                    ,inventTable.MinAverageSettle     //48     Для проверки переместить комментарий на одну строку ниже
                    ,inventTable.NameAlias     //49
                    ,inventTable.ProdGroupId     //50
                    ,inventTable.projCategoryId     //51
                    ,inventTable.grossDepth     //52
                    ,inventTable.grossWidth     //53
                    ,inventTable.grossHeight     //54
                    ,inventTable.standardPalletQuantity     //55
                    ,inventTable.qtyPerLayer     //56
                    ,inventTable.sortCode     //57
                    ,inventTable.ConfigSimilar     //58
                    ,inventTable.SerialNumGroupId     //59
                    ,inventTable.DimGroupId     //60
                    ,inventTable.ModelGroupId     //61
                    ,inventTable.ItemBuyerGroupId     //62
                    ,inventTable.TaxPackagingQty     //63
                    ,inventTable.WMSPalletTypeId     //64
                    ,inventTable.OrigStateId     //65
                    ,inventTable.WMSPickingQtyTime     //66
                    ,inventTable.TaraWeight     //67
                    ,inventTable.PackagingGroupId     //68
                    ,inventTable.ScrapVar     //69
                    ,inventTable.ScrapConst     //70
                    ,inventTable.StandardInventColorId     //71
                    ,inventTable.StandardInventSizeId     //72
                    ,inventTable.ItemDimCombinationAutoCreate     //73
                    ,inventTable.ItemDimCostPrice     //74
                    ,inventTable.ItemIdCompany     //75
                    ,inventTable.AltInventSizeId     //76
                    ,inventTable.AltInventColorId     //77
                    ,inventTable.ForecastDMPInclude     //78
                    ,inventTable.PalletTagging     //79
                    ,inventTable.ItemTaggingLevel     //80
                    ,inventTable.BOMCalcGroupId     //81
                    ,inventTable.PBAItemConfigurable     //82
                    ,inventTable.PBAInventItemGroupId     //83
                    ,inventTable.PBAHideDialog     //84
                    ,inventTable.PBAHideApproval     //85
                    ,inventTable.PBAAutoStart     //86
                    ,inventTable.PBAMandatoryConfig     //87
                    ,inventTable.Packing_RU     //88
                    ,inventTable.IntrastatWeight_CZ     //89
                    ,inventTable.dataAreaId     //90
                    ,inventTable.recVersion     //91
                    ,inventTable.RecId     //92
                    */
                      ], 1);

    for (i = 1 ; i <= conLen(conFields); i++)
    {
        info(strFmt("%1 - %2", i, typeOf(conPeek(conFields, i)) ));
    }
}
Но если присваивать переменной-контейнеру значения в цикле, то проблему можно избежать.

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

upd: изменил джоб, убрал поля DEL_. Джоб работает в AX4.0 SP2, в AX2009 SP1 -- не работает. Времени не хватило придумать новый пример.

Последний раз редактировалось Kabardian; 14.12.2009 в 00:07.
Старый 14.12.2009, 07:01   #16  
Bishop is offline
Bishop
Участник
 
89 / 60 (3) ++++
Регистрация: 12.08.2004
Адрес: Москва
Цитата:
Сообщение от Kabardian Посмотреть сообщение
методам и переменным хардкодом нельзя передать более 47 аргументов
Например, даже переменной типа Container путем грубой силы не может быть присвоено более 47 аргументов:
...
Но если присваивать переменной-контейнеру значения в цикле, то проблему можно избежать.
Можно просто просуммировать контейнеры прямо в передаче параметров:
conIns( [item1, item2, ..., item47] + [item48, ..., item94] + ... , 1);
Интересно, это еще относится к понятию "хардкод" или уже нет?

Цитата:
Сообщение от Kabardian Посмотреть сообщение
Думаю, ограниченние введено нарочно, чтобы разработчики шевелили извилинами, а не баловались копипейстом .
Смелое предположение
Старый 14.12.2009, 21:21   #17  
Kabardian is offline
Kabardian
Талантливый разгвоздяй
Аватар для Kabardian
 
424 / 338 (12) ++++++
Регистрация: 14.12.2008
Адрес: Москва
Записей в блоге: 14
вав
Цитата:
Сообщение от Bishop Посмотреть сообщение
Можно просто просуммировать контейнеры прямо в передаче параметров:
conIns( [item1, item2, ..., item47] + [item48, ..., item94] + ... , 1);
Интересно, это еще относится к понятию "хардкод" или уже нет?
Спасибо, возьму на заметку. Интересно, что получится, если просуммировать более 47 раз.

Цитата:
Сообщение от Bishop Посмотреть сообщение
Смелое предположение
При написании джоба, который должен выстрелить один единственный раз в жизни, не зачем заботиться о красоте кода. Главное, чтобы он правильно и быстро отпработал. Но такие особенности компилятора просто заставляют включать голову
Теги
метод, параметры, переменное число

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Передача массива в метод COM-объекта Вадим DAX: Программирование 6 24.01.2005 12:31
Передача параметров Vpooh DAX: Программирование 2 21.10.2003 13:43
передача ссылки на метод Антон Солдатов DAX: Программирование 5 14.07.2003 13:58
Передача массива VARIANTов в Automation метод Maximin DAX: Программирование 0 09.10.2002 19:31
передача параметров в Report eugene egorov DAX: Программирование 1 25.06.2002 19:34
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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