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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.08.2017, 13:40   #1  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Преобразование к и из строк
У меня еще один быстрый вопрос, возможно кто-то знает ответ сразу, чтоб мне не пришлось экспериментировать.

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

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

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
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
В общем случае это невозможно, так как тип переменных может быть такой, что их невозможно серилизовать. То есть в задаче должны быть какие-то ограничения. Можешь посмотреть как сейчас происходит обработка SysLastValue - там при определенном флаге все фигачится в XML.

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

Стандартные преобразования для XML есть в XMLCOnvert
Старый 31.08.2017, 14:15   #3  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Практически любой тип можно преобразовать в строку простой операцией:
X++:
s = strFmt("%1", value);
А вот обратное преобразование... тут все от типа зависит.
__________________
// no comments
Старый 31.08.2017, 14:17   #4  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Мне нужно только utcDateTime и real, как указано в примере.
Другие типы не интересуют
Старый 31.08.2017, 15:18   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,953 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Иван, для real не прокатит
Вот такая константа 12345.789012345
усекается дробная часть.
Т.е. var2Str = '12 345.79'
А variable2_new - вообще равно 12
Проявился старый баг str2Num()

Последний раз редактировалось Logger; 31.08.2017 в 15:20.
Старый 31.08.2017, 15:24   #6  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Похоже, что для 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  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Цитата:
Сообщение от Logger Посмотреть сообщение
Иван, для real не прокатит
Вот такая константа 12345.789012345
усекается дробная часть.
Т.е. var2Str = '12 345.79'
А variable2_new - вообще равно 12
Проявился старый баг str2Num()
Ну дык я потому и спрашиваю, какие функции использовать, чтоб правильные результат был. В примере заведомо неверно
Старый 31.08.2017, 16:53   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Мне нужно преобразовать две переменные в строки, а потом назад
Нужно гарантировать, что это будет допустимо, то есть чтобы формат в строковом виде был неважен.

Какие методы стоит использовать?
если строка не должна быть человеко-читаемой, то примерно так
Container, bin data, Binary, base64
__________________
полезное на axForum, github, vk, coub.
Старый 31.08.2017, 17:42   #9  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Ну в принципе да, можно значение завернуть в контейнер, причем не только одно. И не надо заморачиваться с 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
Лучший по профессии 2017
Лучший по профессии 2015
 
3,631 / 1849 (69) ++++++++
Регистрация: 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
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Я бы использовал XMLConvert и разделитель. Например |. Так как XMLConvert расчитан на преобразование туда и сюда
За это сообщение автора поблагодарили: Vadik (1), mazzy (2), gl00mie (1).
Старый 13.09.2017, 09:06   #12  
mayk is offline
mayk
Участник
Аватар для mayk
 
43 / 65 (3) ++++
Регистрация: 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
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Привет, Андрей.
Речь идет о сериализации, чтобы быстро конвертнуть туда и обратно, а не о преобразовании в формат для T-SQL.
А с экранизацией спецсимволов SysQuery::value() вполне себе справляется.
any2str, str2any подходит, только если в any был записан тип str. По другим типам выскочит ошибка.
Если у нас enum, int или UtcDateTime, то о какой конвертации через any2str может идти речь?
__________________
// no comments
Старый 14.09.2017, 02:38   #14  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
700 / 752 (27) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от belugin Посмотреть сообщение
Можешь посмотреть как сейчас происходит обработка SysLastValue - там при определенном флаге все фигачится в XML.
И заодно починить баги в ней для EDT массивов, чтобы рантаймы не кидала
Старый 14.09.2017, 11:33   #15  
mayk is offline
mayk
Участник
Аватар для mayk
 
43 / 65 (3) ++++
Регистрация: 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
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от mayk Посмотреть сообщение
anytype any = ""; any = transDate;.
в таком случае выскакивала, вроде.

в anytype можно положить значение любого типа пока она не инициализирована.
после инициализации переменная получает вполне конкретный тип. и сменить тип уже не получится.
__________________
полезное на axForum, github, vk, coub.
Старый 14.09.2017, 11:38   #17  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от mayk Посмотреть сообщение
anytype any = ""; any = transDate;.
Подобное поведение реализует SysAnyType.
За счет боксинга значения в map
__________________
полезное на axForum, github, vk, 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, время: 08:52.