27.02.2019, 17:11 | #1 |
Участник
|
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 |
Участник
|
Прежде всего: огромное спасибо.
можно добавить: NZ StrAfter StrAfterChar strAfterLast strAfterLastChar StrBefore StrBeforeChar StrBeforeLast StrBeforeLastChar StrLeft StrPadLeft StrPadRight StrRight StrSplit Последний раз редактировалось mazzy; 27.02.2019 в 17:51. |
|
27.02.2019, 18:31 | #3 |
Участник
|
и еще. а зачем нужен метод cObj?
понятно, что он делает downcast. но зачем? насколько я понимаю, для System.Object он все равно не подходит. |
|
27.02.2019, 18:47 | #4 |
Участник
|
и еще. уж извините
часто видел метод 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(); ... |
|
|
За это сообщение автора поблагодарили: sukhanchik (2). |
27.02.2019, 19:43 | #5 |
Administrator
|
Денис, большое спасибо!
Цитата:
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 27.02.2019 в 20:37. |
|
28.02.2019, 03:55 | #6 |
Участник
|
Цитата:
Цитата:
Я наоборот за критику, в спорах рождается истина. Более того, по опыту выкладывания утилит, самое частое что я использую сам - это создание экстенш метода(которое добавил 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(); ... X++: if (countQuery.dataSourceCount() == 1) { qbds.addSelectionField(fieldNum(Common, RecId), SelectionField::Count); } |
|
|
За это сообщение автора поблагодарили: mazzy (10), EVGL (20). |
28.02.2019, 04:03 | #7 |
Участник
|
Цитата:
А вы смотрели как он работает? не сваливается ли он в обычный loop если несколько источников данных? судя по параметру maxRows вполне можно ожидать |
|
|
За это сообщение автора поблагодарили: sukhanchik (15), SRF (5). |
28.02.2019, 08:52 | #8 |
Участник
|
Работает он примерно так, в top указано значение второго параметра
__________________
Sergey Nefedov |
|
|
За это сообщение автора поблагодарили: trud (5), sukhanchik (5). |
28.02.2019, 11:00 | #9 |
Участник
|
NotZero - принимает два аргумента. возвращает первый, если он не пустой и второй, если первый пустой.
удобнее, чем тренарный оператор, если второй параметр что-то быстро вычисляемое (константа, strfmt и т.п.) Цитата:
System.String не так работает на вправо-выровнянных строках. а в предыдущих версиях требует постоянного InteropPermission (будь проклят тот архитектор, кто ввел эту шнягу) Цитата:
только наоборот это методы работы с рэнджами, буферами, датасорсами и прочими сложными объектами нужно переносить в отдельные классы - SysQuery, SysDataSource, SysRecord, SysArgs. а методы конвертации базовых типов как раз просятся в Global Цитата:
Понятно. Он использует это для получения внутреннего представления, насколько я помню. Дикие хаки. Но эффективные, чёрт побери. Насколько я понимаю, в 365fo контейнер реализован на System.Array, поэтому дикие хаки с cObject работать не должны. Но в этом расширении метод cObject предлагается. Вот я и удивляюсь - может еще как это можно использовать? Цитата:
Я тоже за критику. Просто с этим случаем у меня подозрение, что это я чего-то не знаю. Цитата:
вопрос - почему pack применяется для QueryRun, а не для Query. не знаю. вот не знание то и беспокоит. вдруг, проблемы таки есть? Последний раз редактировалось mazzy; 28.02.2019 в 11:03. |
|
|
За это сообщение автора поблагодарили: trud (2). |
28.02.2019, 12:44 | #10 |
Участник
|
Цитата:
Доходило до смешного - мы помогали нашим UK коллегам, и начали с импорта всяких утилит, причем в каком-то минимальном варианте, через пару дней пришло разгневанное письмо от вед.разработчика проекта, которое она отправила к ПМ с пометкой важно - типа эти русские заимпортили какие-то классы, я не знаю что мне делать, я же предупреждала что не надо их брать... Ну т.е. надо иметь максимально удобный к установке вариант, допускающий легкую частичную установку(т.е. методы должны минимально вызывать друг друга), плюс не заменять стандарт Да, если бы Рома устроился архитетектором в МС, то сейчас бы не было тем "Интеграция - использовать стандарт или писать на коленке ? " |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
28.02.2019, 12:54 | #11 |
Участник
|
|
|
28.02.2019, 13:26 | #12 |
Участник
|
Цитата:
Мне он пригодился для таких конструкций: Раньше можно было написать X++: if (... && SysDictClass::is(element.args().caller().runBase(), ClassNum(MyClass)) X++: if (... && element.args().caller().runBase() is MyClass) теперь приходится писать X++: if (... && cObject(element.args().caller().runBase()) is MyClass) |
|
|
За это сообщение автора поблагодарили: mazzy (2), EVGL (5), trud (2). |
28.02.2019, 13:27 | #13 |
Участник
|
__________________
Sergey Nefedov |
|
28.02.2019, 18:50 | #14 |
Роман Долгополов (RDOL)
|
Пост по заявкам слушателей из ЛС
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; } X++: if (formDataSourceHasMethod(this.dataSource(), methodstr(mBankAccountWizard, dialogModifiedField))) { cobj(this.dataSource()).dialogModifiedField(_fieldId); } X++: mGW_Queue queue = cobj(mDictionary::instance().classObjectByName(_queueClassName).makeObject(), classnum(mGW_Queue)); X++: if (cobj(child, classnum(FormControl), false)) { } 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()); } X++: lines.CurrencyCode = nz(lines.CurrencyCode, header.CurrencyCode); 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 |
Участник
|
спасибо. nz добавил.
первая функция вроде как может быть заменена is as, для inlist лучше наверное контейнер и использовать или новый in - https://blogs.msdn.microsoft.com/mfp...e-in-operator/ |
|
|
|