03.05.2017, 16:14 | #1 |
Участник
|
Символ с кодом 160 в качестве пробела
Столкнулся с тем, что некоторые системы, например, SAP или 1C версии 7.7 выгружают числа типа 5555 в обычные текстовые файлы или в Эксель в виде строки "5 555", в которой в качестве разделителя используется не пробел, а символ с ASCII-кодом 160.
В результате, когда в Аксапте надо строку обратно преобразовать в число, приходится писать целые функции. Есть ли какой-нибудь простой способ получить из строки "55 555,55" число в Аксапте 55555.55 ? Я делаю так: X++: str normalizeNum(str _s) { int n; str ret; ; for (n = 1; n <= strLen(_s); n++) { if (char2num(_s, n) != 160) ret += subStr(_s, n, 1); } return strrem(ret, " "); } ; strSum = strreplace("55 555,55", ",", "."); strSum = normalizeNum(strSum); realSum = str2num(strSum); |
|
03.05.2017, 16:28 | #2 |
Участник
|
Почему бы вместо этой функции второй раз strreplace не сделать - заменить символ 160 на пустоту?
|
|
03.05.2017, 16:33 | #3 |
Участник
|
Не хочется все время помнить про символ с кодом 160.
Несколько раз в год возникают задачи по интеграции, в которых такая штука может встретиться, и не хочется все время вспоминать про магическое число 160. Хотелось бы, чтобы функция str2num или какая-то другая стандартная функция сама умела это делать. |
|
03.05.2017, 16:35 | #4 |
Участник
|
Это неразрывный пробел.
Из-за работы со сборщиком мусора, в аксапте предпочтительнее обходится встроенными функциями вместо циклов на языке. даже в CIL. поэтому вместо normalizeNum() лучше использовать встроенную strRem https://msdn.microsoft.com/en-us/library/aa629339.aspx но еще лучше воспользоваться функцией strKeep() для чисел https://msdn.microsoft.com/en-us/library/aa867746.aspx strkeep(s, "01234567890,.E+-") стоит также посмотреть на formattedstr2num https://msdn.microsoft.com/en-us/library/cc570788.aspx но я не уверен, что эта функция нормально работает с неразрывным пробелом |
|
|
За это сообщение автора поблагодарили: Ace of Database (3). |
03.05.2017, 16:39 | #5 |
Участник
|
Спасибо!
strkeep(s, "01234567890,.E+-") - как раз то, что надо. |
|
03.05.2017, 16:49 | #6 |
Участник
|
На память оставлю, чтобы потом залезть и посмотреть
X++: static void Job388(Args _args) { str s = " 5 555, 55 "; real r; ; r = str2Num(strreplace(strkeep(s, "01234567890,.E+-"), ",", ".")); info(strfmt("%1", r)); } |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
03.05.2017, 17:35 | #7 |
Участник
|
ну... в некоторых странах запятая используется как разделитель разрядов.
так что в общем случае нужно чуть тщательнее. но в данном конкретном случае вполне пойдет. для исследований стоит также заглянуть в Global::str2numOk и в Global::str2intOk. там народ вообще через регулярку проверяет. но если уж через interop, то можно использовать нормальные функции преобразования с учетом cultural context из .net |
|
|
За это сообщение автора поблагодарили: Logger (1). |
03.05.2017, 18:57 | #8 |
Участник
|
В общем случае, задача конвертации строки в число - не имеет решения. Преобразование всегда будет только для конкретных (локальных, частных) условий. Только если точно знать, в каком формате ожидать символьную строку для преобразования
Например, даже по приведенному коду можем получить не корректное преобразование в зависимости от формата строки info(strFmt('%1', str2num('1e+5'))); // Не корректное преобразование info(strFmt('%1', str2num('1.0e+5'))); // Корректное преобразование А по поводу "некоторых стран", некоторые бухгалтера в качестве разделителя целой и дробной части числа используют дефис (минус) info(strFmt('%1', str2num('123-45'))); Это "переводится" не 123 минус 45, а 123 руб 45 коп
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
|
|