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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.08.2017, 13:40   #1  
online
kashperuk
Senior SDE, Dynamics AX
Аватар для kashperuk
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
 
4,314 / 2013 (76) +++++++++
Регистрация: 30.05.2004
Адрес: Копенгаген, Дания
Преобразование к и из строк
У меня еще один быстрый вопрос, возможно кто-то знает ответ сразу, чтоб мне не пришлось экспериментировать.

Мне нужно преобразовать две переменные в строки, а потом назад
Нужно гарантировать, что это будет допустимо, то есть чтобы формат в строковом виде был неважен.

Какие методы стоит использовать?

X++:
utcDateTime variable1; // какое-то значение
Qty variable2; // какое-то значение

str var1Str = datetime2str(variable1);
str var2Str = num2str(variable2, -1, -1, -1, -1);

utcDateTime variable1_new = str2Datetime(var1Str);
Qty variable2_new = str2Num(var2Str);
К примеру если я в XML хочу эти значения запихать, или в какой-то строковой ключ хранимый в БД.


Спасибо
Старый 31.08.2017, 13:50   #2  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,935 / 2078 (77) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
В общем случае это невозможно, так как тип переменных может быть такой, что их невозможно серилизовать. То есть в задаче должны быть какие-то ограничения. Можешь посмотреть как сейчас происходит обработка SysLastValue - там при определенном флаге все фигачится в XML.

Надо понять
1) какие типы ты собираешься преобразовывать, а какие нет
2) Какие требования к получившейся строке

Стандартные преобразования для XML есть в XMLCOnvert
Старый 31.08.2017, 14:15   #3  
dech is offline
dech
Участник
Аватар для dech
 
434 / 188 (7) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Практически любой тип можно преобразовать в строку простой операцией:
X++:
s = strFmt("%1", value);
А вот обратное преобразование... тут все от типа зависит.
__________________
// no comments
Старый 31.08.2017, 14:17   #4  
online
kashperuk
Senior SDE, Dynamics AX
Аватар для kashperuk
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
 
4,314 / 2013 (76) +++++++++
Регистрация: 30.05.2004
Адрес: Копенгаген, Дания
Мне нужно только utcDateTime и real, как указано в примере.
Другие типы не интересуют
Старый 31.08.2017, 15:18   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2014
 
2,900 / 1536 (57) ++++++++
Регистрация: 12.10.2004
Иван, для real не прокатит
Вот такая константа 12345.789012345
усекается дробная часть.
Т.е. var2Str = '12 345.79'
А variable2_new - вообще равно 12
Проявился старый баг str2Num()

Последний раз редактировалось Logger; 31.08.2017 в 15:20.
Старый 31.08.2017, 15:24   #6  
online
kashperuk
Senior SDE, Dynamics AX
Аватар для kashperuk
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
 
4,314 / 2013 (76) +++++++++
Регистрация: 30.05.2004
Адрес: Копенгаген, Дания
Похоже, что для utcDateTime лучше всего
X++:
DateTimeUtil::toStr() && DateTimeUtil::parse()
Для чисел чуть похуже:
X++:
num2str(value, -1, numOfDec(value), DecimalsSeparator::Dot, ThousandsSeparator::Comma);
str2num();
За это сообщение автора поблагодарили: Logger (3).
Старый 31.08.2017, 15:28   #7  
online
kashperuk
Senior SDE, Dynamics AX
Аватар для kashperuk
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
 
4,314 / 2013 (76) +++++++++
Регистрация: 30.05.2004
Адрес: Копенгаген, Дания
Цитата:
Сообщение от Logger Посмотреть сообщение
Иван, для real не прокатит
Вот такая константа 12345.789012345
усекается дробная часть.
Т.е. var2Str = '12 345.79'
А variable2_new - вообще равно 12
Проявился старый баг str2Num()
Ну дык я потому и спрашиваю, какие функции использовать, чтоб правильные результат был. В примере заведомо неверно
Старый 31.08.2017, 16:53   #8  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
Most Valuable Professional
 
28,486 / 3365 (169) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Мне нужно преобразовать две переменные в строки, а потом назад
Нужно гарантировать, что это будет допустимо, то есть чтобы формат в строковом виде был неважен.

Какие методы стоит использовать?
если строка не должна быть человеко-читаемой, то примерно так
Container, bin data, Binary, base64
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 31.08.2017, 17:42   #9  
dech is offline
dech
Участник
Аватар для dech
 
434 / 188 (7) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Ну в принципе да, можно значение завернуть в контейнер, причем не только одно. И не надо заморачиваться с Binary или Base64. И строка в принципе получается очень даже человекочитаемой (для real и utcdatetime, другие типы смотреть надо, экспериментировать, так сказать).
X++:
static void ASmallTest(Args _args)
{
    Qty         q, qty = 12345.789012345;
    utcDateTime d, dt = DateTimeUtil::utcNow();
    str         s = con2str([qty, dt]);
    ;
    
    [q, d] = str2con(s);
    info(strfmt("%1, %2", qty, dt));
    info(strfmt("%1, %2", q, d));
}
__________________
// no comments
За это сообщение автора поблагодарили: mazzy (2), trud (3).
Старый 31.08.2017, 17:52   #10  
Vadik is offline
Vadik
Модератор
Аватар для Vadik
 
3,290 / 1304 (50) ++++++++
Регистрация: 18.11.2002
Адрес: гражданин Москвы
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Мне нужно только utcDateTime и real, как указано в примере
Как Максим уже писал, можно посмотреть как сериализуются SysLastValue начиная с PU9
X++:
public static void main(Args _args)
{       
        real myRealValue = 12345.789012345;
        utcdatetime myUtc = DateTimeUtil::utcNow();

        str serializedStr = ContainerHelper::serialize([myRealValue, myUtc]);
        [myRealValue, myUtc] = ContainerHelper::deserialize(serializedStr);
}
__________________
-ТСЯ или -ТЬСЯ ?
За это сообщение автора поблагодарили: mazzy (2), trud (3).
Старый 31.08.2017, 18:27   #11  
belugin is offline
belugin
Участник
Аватар для belugin
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
Сотрудники Microsoft Dynamics
 
3,935 / 2078 (77) +++++++++
Регистрация: 16.01.2004
Адрес: Москва
Я бы использовал XMLConvert и разделитель. Например |. Так как XMLConvert расчитан на преобразование туда и сюда
За это сообщение автора поблагодарили: Vadik (1), mazzy (2), gl00mie (1).
Старый 13.09.2017, 09:06   #12  
mayk is offline
mayk
Участник
Аватар для mayk
 
37 / 29 (1) +++
Регистрация: 07.03.2008
Цитата:
Сообщение от kashperuk Посмотреть сообщение
К примеру если я в XML хочу эти значения запихать, или в какой-то строковой ключ хранимый в БД.
Для БД есть SqlSystem(есть даже в ax3). Он не поддерживает DateTime и вроде даже не боится Little Bobby Tables

X++:
    info(new SqlSystem().sqlLiteral(DateTimeUtil::utcNow()));
    info(new SqlSystem().sqlLiteral("Robert'); DROP TABLE Students;--"));
    info(new SqlSystem().sqlLiteral(-1234.567890123));
выдаст

Цитата:
'1900-01-01T00:00:00'
N'Robert''); DROP TABLE Students;--'
-1.234567890123E3
Цитата:
Сообщение от dech Посмотреть сообщение
Практически любой тип можно преобразовать в строку простой операцией:
X++:
s = strFmt("%1", value);
А вот обратное преобразование... тут все от типа зависит.
Для большинства типов есть трюк с использованием anytype.

anytype хоть и зовётся any, но на самом деле он запоминает тип после первого присвоения. Последующие попытки присвоения запустят штатный механизм преобразований между типами.

str же преобразуется почти во всё, кроме DateTime, к сожалению

X++:
    str typeBinding;
    anytype any = typeBinding;
    transDate transDate = today(), transDateTest;
    real realNum = -12345.789012345, realNumTest;
    int64 i64 = 12345678901234567, i64Test;
    NoYes enum = NoYes::Yes, enumTest;
    UtcDateTime dateTime = DateTimeUtil::utcNow(), dateTimeTest;
    ;
    Debug::assert(typeof(any) == Types::String);

    any = transDate;
    transDateTest = any;
    Debug::assert(transDateTest == transDate);

    any = realNum;
    realNumTest = any;
    Debug::assert(realNumTest == realNum);

    any = i64;
    i64Test = any;
    Debug::assert(i64Test == i64);

    any = enum;
    enumTest = any;
    Debug::assert(enumTest == enum);

    any = dateTime;
    dateTimeTest = any;
    info("OK");
Старый 13.09.2017, 19:55   #13  
dech is offline
dech
Участник
Аватар для dech
 
434 / 188 (7) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Привет, Андрей.
Речь идет о сериализации, чтобы быстро конвертнуть туда и обратно, а не о преобразовании в формат для T-SQL.
А с экранизацией спецсимволов SysQuery::value() вполне себе справляется.
any2str, str2any подходит, только если в any был записан тип str. По другим типам выскочит ошибка.
Если у нас enum, int или UtcDateTime, то о какой конвертации через any2str может идти речь?
__________________
// no comments
Старый 14.09.2017, 02:38   #14  
skuull is offline
skuull
Участник
Лучший по профессии 2014
Most Valuable Professional
 
325 / 277 (10) ++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от belugin Посмотреть сообщение
Можешь посмотреть как сейчас происходит обработка SysLastValue - там при определенном флаге все фигачится в XML.
И заодно починить баги в ней для EDT массивов, чтобы рантаймы не кидала
Старый 14.09.2017, 11:33   #15  
mayk is offline
mayk
Участник
Аватар для mayk
 
37 / 29 (1) +++
Регистрация: 07.03.2008
Цитата:
Сообщение от dech Посмотреть сообщение
any2str, str2any подходит, только если в any был записан тип str. По другим типам выскочит ошибка.
Если у нас enum, int или UtcDateTime, то о какой конвертации через any2str может идти речь?
Наверное, поэтому речь не шла об any2str? ¯\_(ツ)_/¯

Ещё раз. Примитивные типы могут быть преобразованы в строку одинаковой конструкцией anytype any = ""; any = transDate;. Ошибка не выскочит.

Обртаное преобразование не зависит от типа и выглядит transDate = any;, где any - строка, полученная образом выше.

Ошибка не выскочит. Исключение составляет лишь упрямый DateTime(в упомянутом con2str кстати на ax2009 та же ерунда и из-за того-же преобразования), но для него есть DateTimeUtil.
Старый 14.09.2017, 11:36   #16  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
Most Valuable Professional
 
28,486 / 3365 (169) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Цитата:
Сообщение от mayk Посмотреть сообщение
anytype any = ""; any = transDate;.
в таком случае выскакивала, вроде.

в anytype можно положить значение любого типа пока она не инициализирована.
после инициализации переменная получает вполне конкретный тип. и сменить тип уже не получится.
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 14.09.2017, 11:38   #17  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
Most Valuable Professional
 
28,486 / 3365 (169) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Цитата:
Сообщение от mayk Посмотреть сообщение
anytype any = ""; any = transDate;.
Подобное поведение реализует SysAnyType.
За счет боксинга значения в map
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Количество строк в Query Владимир Максимов DAX: Программирование 19 11.08.2014 18:27
Преобразование строк UTF-8 в ANSI в DAX 2009 (без файловых операций) Ar DAX: Программирование 0 21.08.2012 19:24
Как имитировать подсветку активной строки/строк? uchenik DAX: Программирование 17 13.12.2011 16:18
"Инвентаризационный код" в группах инвентаризации и создание строк инвентаризации lev DAX: Функционал 0 11.10.2011 09:49
Тормозит копирование строк в буфер обмена ivas DAX: Программирование 20 21.08.2007 15:05
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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