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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.02.2019, 17:11   #1  
Blog bot is offline
Blog bot
Участник
 
25,459 / 846 (79) +++++++
Регистрация: 28.10.2006
Denis Trunin's Blogs: 30 additional methods to the Global class
Источник: https://denistrunin.com//xpptools-devglobal/
==============

Global class is a standard class that contains a lot of small static functions. This post describes additional functions that extend it.

Источник: https://denistrunin.com//xpptools-devglobal/
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
Старый 27.02.2019, 17:49   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Прежде всего: огромное спасибо.

можно добавить:
NZ
StrAfter
StrAfterChar
strAfterLast
strAfterLastChar
StrBefore
StrBeforeChar
StrBeforeLast
StrBeforeLastChar
StrLeft
StrPadLeft
StrPadRight
StrRight
StrSplit
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 27.02.2019 в 17:51.
Старый 27.02.2019, 18:31   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
и еще. а зачем нужен метод cObj?

понятно, что он делает downcast. но зачем?
насколько я понимаю, для System.Object он все равно не подходит.
__________________
полезное на axForum, github, vk, coub.
Старый 27.02.2019, 18:47   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
и еще. уж извините

часто видел метод countTotalQuick на проектах где участвовал Колумбус.
то, что метод в Global, а не в SysQuery - фиг с ним.
то, что возвращает Integer, а не Int64 - тоже фиг с ним.

Но почему пакуется queryRun, а не Query?

Вроде метод выполняется там, где вызывается (нет модификатора server/client), поэтому нет передачи объекта между сервером и клиентом.

ведь можно было бы и так:
X++:
static Integer countTotalQuick(QueryRun _queryRun)
    {
        container               queryPack = _queryRun.Query().pack();
        Query                   countQuery = new Query(queryPack);
...
но сделано вот так:
X++:
static Integer countTotalQuick(QueryRun _queryRun)
    {
        container               queryPack = _queryRun.pack();
        Query                   countQuery;
        QueryRun                countQueryRun;
        ;
        countQueryRun   = new QueryRun(queryPack);
        countQuery      = countQueryRun.query();
...
это не в качестве критики, а просто интересно. может я чего не знаю?
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: sukhanchik (2).
Старый 27.02.2019, 19:43   #5  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,273 / 3466 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Денис, большое спасибо!

Цитата:
Сообщение от mazzy Посмотреть сообщение
и еще. уж извините

часто видел метод countTotalQuick на проектах
...
это не в качестве критики, а просто интересно. может я чего не знаю?
Хм... этот вопрос и меня всегда интересовал. Особенно после того, как в 2012 этот метод сделали в ядре и на вход ему все-таки приходит Query

Нажмите на изображение для увеличения
Название: SNAG_Program-0000.png
Просмотров: 279
Размер:	92.8 Кб
ID:	12229
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 27.02.2019 в 20:37.
Старый 28.02.2019, 03:55   #6  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от mazzy Посмотреть сообщение
можно добавить:
NZ
StrAfter
StrAfterChar
strAfterLast
strAfterLastChar
StrBefore
StrBeforeChar
StrBeforeLast
StrBeforeLastChar
StrLeft
StrPadLeft
StrPadRight
StrRight
StrSplit
А что такое NZ? по остальному - в D365 лучше наверное использовать класс System.String - там есть просто все и даже больше. Если пришлете тексты, могу включить, но лучше наверное в отдельный класс DEVStringHelper

Цитата:
Сообщение от mazzy Посмотреть сообщение
и еще. а зачем нужен метод cObj?
понятно, что он делает downcast. но зачем?
насколько я понимаю, для System.Object он все равно не подходит.
Если не ошибаюсь изначально позаимствовал у Ромы, нужен если у вас есть FormRun и на нем надо вызвать метод. В последнее время кстати приходилось несколько раз пользовать(хотя понятно что лучше этого избегать). Врядли он будет работать для System.Object

Цитата:
Сообщение от mazzy Посмотреть сообщение
и еще. уж извините
Я наоборот за критику, в спорах рождается истина. Более того, по опыту выкладывания утилит, самое частое что я использую сам - это создание экстенш метода(которое добавил skull), т.е. пока это win-win стратегия

Цитата:
Сообщение от mazzy Посмотреть сообщение
часто видел метод countTotalQuick на проектах где участвовал Колумбус.
то, что метод в Global, а не в SysQuery - фиг с ним.
то, что возвращает Integer, а не Int64 - тоже фиг с ним.

Но почему пакуется queryRun, а не Query?

Вроде метод выполняется там, где вызывается (нет модификатора server/client), поэтому нет передачи объекта между сервером и клиентом.

ведь можно было бы и так:
X++:
static Integer countTotalQuick(QueryRun _queryRun)
    {
        container               queryPack = _queryRun.Query().pack();
        Query                   countQuery = new Query(queryPack);
...
но сделано вот так:
X++:
static Integer countTotalQuick(QueryRun _queryRun)
    {
        container               queryPack = _queryRun.pack();
        Query                   countQuery;
        QueryRun                countQueryRun;
        ;
        countQueryRun   = new QueryRun(queryPack);
        countQuery      = countQueryRun.query();
...
это не в качестве критики, а просто интересно. может я чего не знаю?
Идея метода - продублировать стандартный SysQuery::countPrim, но без условия

X++:
if (countQuery.dataSourceCount() == 1)
{ qbds.addSelectionField(fieldNum(Common, RecId), SelectionField::Count);     }
т.е. Count использовать всегда. зачем там пакуется QueryRun и почему они возвращают Integer я честно говоря не знаю, но идея была чтобы заменить один на другой. А какие с этим проблемы?
За это сообщение автора поблагодарили: mazzy (10), EVGL (20).
Старый 28.02.2019, 04:03   #7  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Особенно после того, как в 2012 этот метод сделали в ядре и на вход ему все-таки приходит Query
"А пацаны то и не знали"
А вы смотрели как он работает? не сваливается ли он в обычный loop если несколько источников данных? судя по параметру maxRows вполне можно ожидать
За это сообщение автора поблагодарили: sukhanchik (15), SRF (5).
Старый 28.02.2019, 08:52   #8  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
362 / 542 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Работает он примерно так, в top указано значение второго параметра
Миниатюры
Нажмите на изображение для увеличения
Название: getQueryRowCount.png
Просмотров: 208
Размер:	22.9 Кб
ID:	12232  
__________________
Sergey Nefedov
За это сообщение автора поблагодарили: trud (5), sukhanchik (5).
Старый 28.02.2019, 11:00   #9  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от trud Посмотреть сообщение
А что такое NZ?
NotZero - принимает два аргумента. возвращает первый, если он не пустой и второй, если первый пустой.
удобнее, чем тренарный оператор, если второй параметр что-то быстро вычисляемое (константа, strfmt и т.п.)

Цитата:
Сообщение от trud Посмотреть сообщение
по остальному - в D365 лучше наверное использовать класс System.String - там есть просто все и даже больше.
не очень больше.
System.String не так работает на вправо-выровнянных строках.
а в предыдущих версиях требует постоянного InteropPermission (будь проклят тот архитектор, кто ввел эту шнягу)


Цитата:
Сообщение от trud Посмотреть сообщение
Если пришлете тексты, могу включить, но лучше наверное в отдельный класс DEVStringHelper
Да, опубликую, пришлю.

только наоборот
это методы работы с рэнджами, буферами, датасорсами и прочими сложными объектами нужно переносить в отдельные классы - SysQuery, SysDataSource, SysRecord, SysArgs.
а методы конвертации базовых типов как раз просятся в Global

Цитата:
Сообщение от trud Посмотреть сообщение
Если не ошибаюсь изначально позаимствовал у Ромы, нужен если у вас есть FormRun и на нем надо вызвать метод. В последнее время кстати приходилось несколько раз пользовать(хотя понятно что лучше этого избегать). Врядли он будет работать для System.Object
эх, Рома, Рома.
Понятно. Он использует это для получения внутреннего представления, насколько я помню. Дикие хаки. Но эффективные, чёрт побери.
Насколько я понимаю, в 365fo контейнер реализован на System.Array, поэтому дикие хаки с cObject работать не должны. Но в этом расширении метод cObject предлагается. Вот я и удивляюсь - может еще как это можно использовать?

Цитата:
Сообщение от trud Посмотреть сообщение
Я наоборот за критику, в спорах рождается истина. Более того, по опыту выкладывания утилит, самое частое что я использую сам - это создание экстенш метода(которое добавил skull), т.е. пока это win-win стратегия
Ок, спасибо.
Я тоже за критику. Просто с этим случаем у меня подозрение, что это я чего-то не знаю.

Цитата:
Сообщение от trud Посмотреть сообщение
Идея метода - продублировать стандартный SysQuery::countPrim, но без условия
это-то понятно. без вопросов.
вопрос - почему pack применяется для QueryRun, а не для Query.

Цитата:
Сообщение от trud Посмотреть сообщение
зачем там пакуется QueryRun и почему они возвращают Integer я честно говоря не знаю, но идея была чтобы заменить один на другой. А какие с этим проблемы?
не знаю. вот не знание то и беспокоит. вдруг, проблемы таки есть?
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 28.02.2019 в 11:03.
За это сообщение автора поблагодарили: trud (2).
Старый 28.02.2019, 12:44   #10  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от mazzy Посмотреть сообщение
это методы работы с рэнджами, буферами, датасорсами и прочими сложными объектами нужно переносить в отдельные классы - SysQuery, SysDataSource, SysRecord, SysArgs.
Такая схема не будет работать при аутсорсинговом программировании(т.е. изначально эти все методы и были разбиты по данным классам). При попытке использовать данные расширения велика вероятность что вам вернут задачу в доработку с комментарием - "убрать код не относящийся к задаче."
Доходило до смешного - мы помогали нашим UK коллегам, и начали с импорта всяких утилит, причем в каком-то минимальном варианте, через пару дней пришло разгневанное письмо от вед.разработчика проекта, которое она отправила к ПМ с пометкой важно - типа эти русские заимпортили какие-то классы, я не знаю что мне делать, я же предупреждала что не надо их брать...
Ну т.е. надо иметь максимально удобный к установке вариант, допускающий легкую частичную установку(т.е. методы должны минимально вызывать друг друга), плюс не заменять стандарт
Цитата:
Сообщение от mazzy Посмотреть сообщение
эх, Рома, Рома.
Понятно. Он использует это для получения внутреннего представления, насколько я помню. Дикие хаки. Но эффективные, чёрт побери.
Да, если бы Рома устроился архитетектором в МС, то сейчас бы не было тем "Интеграция - использовать стандарт или писать на коленке ? "
За это сообщение автора поблагодарили: mazzy (2).
Старый 28.02.2019, 12:54   #11  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от SRF Посмотреть сообщение
Работает он примерно так, в top указано значение второго параметра
Странно что МС не заменило стандартный SysQuery::countTotal при этом. Добавил к своему методу комментарий
X++:
//can be replaced by QueryRun::getQueryRowCount(_queryRun.query(), intMax());
Старый 28.02.2019, 13:26   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,867 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от mazzy Посмотреть сообщение
Но в этом расширении метод cObject предлагается. Вот я и удивляюсь - может еще как это можно использовать?
Недавно писал такой же метод cObject .

Мне он пригодился для таких конструкций:
Раньше можно было написать
X++:
if (... && SysDictClass::is(element.args().caller().runBase(), ClassNum(MyClass))
теперь аналог
X++:
if (... && element.args().caller().runBase() is MyClass)
не прокатывает потому что element.args().caller().runBase() это с точки зрения компилятора - anyType и он автоматом не приводится к Object

теперь приходится писать

X++:
if (... && cObject(element.args().caller().runBase()) is MyClass)
За это сообщение автора поблагодарили: mazzy (2), EVGL (5), trud (2).
Старый 28.02.2019, 13:27   #13  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
362 / 542 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
В двенашке и этого нет. Видимо потому, что
Цитата:
Сообщение от trud Посмотреть сообщение
не заменять стандарт
__________________
Sergey Nefedov
Старый 28.02.2019, 18:50   #14  
db is offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Регистрация: 01.04.2004
Адрес: Москва
Пост по заявкам слушателей из ЛС

cobj - приведение/проверка что можно привести _object к _classTargetId. Ну или просто привести к Object в одну строку
Изначально родился и был сильно полезен давным давно когда не было никакик as и is. сейчас полезность сильно меньше
X++:
static Object cobj(Object _object, int _classTargetId = 0, boolean _throwError = true)
{
    if (_classTargetId)
    {
        if (! new mDictClass(classidget(_object)).checkIsEqualOrSuperclass(_classTargetId, _throwError))
        {
            return null;
        }
    }

    return _object;
}
в одну строку привести к object. просто чтобы не объявлять еще переменную Object
X++:
if (formDataSourceHasMethod(this.dataSource(), methodstr(mBankAccountWizard, dialogModifiedField)))
{
    cobj(this.dataSource()).dialogModifiedField(_fieldId);
}
проверить что какой нито конструируемый по имени объект соответствует ожиданиям и если это не так, то вывети не трассировку, а нормальное сообщение об ошибке. ну то есть по сути as
X++:
mGW_Queue queue = cobj(mDictionary::instance().classObjectByName(_queueClassName).makeObject(), classnum(mGW_Queue));
проверка без сообщения об ошибке что объект тот что нужен. эквивалент is
X++:
if (cobj(child, classnum(FormControl), false))
{
}
nz - взять второе значение, если первое пустое. укороченный тернарный оператор, в котором два параметра одинаковые. Кажется в VBA я её увидел впервые
X++:
public static anytype nz(anytype _value, anytype _nonZeroValue)
{
    return (_value && true) ? _value : _nonZeroValue;
}
два основных применения
1. взять значение по умолчанию
X++:
display mPaymSchedBaseDate paymSchedBaseDate()
{
    return nz(this.PaymSchedBaseDate, this.deliveryDate());
}
2. заполнить что нибудь, eсли еще не заполнено
X++:
lines.CurrencyCode    = nz(lines.CurrencyCode,    header.CurrencyCode);
inlist - Однострочная проверка на соответствие списку. замена многоэтажным if|switch
X++:
public static boolean inlist(anytype _value, container _listValues)
{
    return confind(_listValues, _value) != 0;
}
X++:
if (! inlist(_journalTable.Status, [mGroupPostingJournalStatus::Created, mGroupPostingJournalStatus::Reversed, mGroupPostingJournalStatus::Posted]))
{
    ....
}

Последний раз редактировалось db; 28.02.2019 в 19:03.
За это сообщение автора поблагодарили: mazzy (10), trud (5), sukhanchik (10).
Старый 01.03.2019, 02:55   #15  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
спасибо. nz добавил.
первая функция вроде как может быть заменена is as, для inlist лучше наверное контейнер и использовать или новый in - https://blogs.msdn.microsoft.com/mfp...e-in-operator/
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
DynamicsAxSCM: Change license plate, split quantity, skip and override location during inbound put away Blog bot DAX Blogs 0 27.11.2015 16:11
DynamicsAxSCM: Creating Custom Solutions with the Warehouse Mobile Device Portal Blog bot DAX Blogs 0 13.03.2015 16:11
crminthefield: Creating SSL Certificates for CRM Test Environment Blog bot Dynamics CRM: Blogs 0 10.12.2013 02:12
Microsoft Dynamics CRM Team Blog: Using Power View in Excel 2013 to Analyze CRM Data Blog bot Dynamics CRM: Blogs 0 19.04.2013 00:11
DynamicsAxSCM: Personalization of Role Centers in Dynamics AX 2009 Blog bot DAX Blogs 0 21.06.2010 16:05
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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