Имя: Пароль:
1C
1С v8
Есть у кого вменяемая функция Число()?
0 DES
 
26.07.15
15:57
из строки?
1 Asmody
 
26.07.15
16:10
типовая чем не устраивает?
2 cathode
 
26.07.15
16:12
У меня невменяемая есть.
Пытается все, что можно, преобразовать в число.


// Преобразует строковое представление числа в число.
//
// Версия: 2.1.
//
// Параметры
//  Парам - Строка - Выражение для преобразования.
//  Пусто - Неопределенный - Представление пустого значения (0 или пустая строка).
//  Ошибка - Неопределенный - Представление значения при ошибке преобразования.
//
// Возвращаемое значение:
//  Число - переданное значение в виде числа. Если переданное значение пусто
//  или нулевое, возвращает значение параметра Пусто. В случае ошибки
//  распознавания, возвращает значение параметра Ошибка.
//
Функция СтрокаВЧисло(Знач Строка, Знач Пусто = 0, Знач Ошибка = 0) Экспорт
    
    Перем Результат, НомерСимвола, МаксНомерСимвола, ТекущийСимвол, Алфавит
        , Отрицательное, ЕстьДробнаяЧасть;
        
    Если Не ПустаяСтрока(Строка) Тогда
        Строка = СокрЛП(Строка);
        МаксНомерСимвола = СтрДлина(Строка);
        
        // Определяем знак числа и удаляем его из исходной строки.
        ТекущийСимвол = Лев(Строка, 1);
        Алфавит = "+-";
        Если Найти(Алфавит, ТекущийСимвол) > 0 Тогда
            Строка = Сред(Строка, 2);
            МаксНомерСимвола = МаксНомерСимвола - 1;
            Отрицательное = (ТекущийСимвол = "-");
        Иначе
            Отрицательное = Ложь;
        КонецЕсли;
        
        // С начала исходной строки определяем последовательность максимальной длины,
        // конторая может быть распознана как число.
        НомерСимвола = 1;
        Алфавит = "0123456789 .," + Символы.НПП;
        Пока НомерСимвола <= МаксНомерСимвола Цикл
            ТекущийСимвол = Сред(Строка, НомерСимвола, 1);
            Если Найти(Алфавит, ТекущийСимвол) = 0 Тогда
                Прервать;
            КонецЕсли;
            НомерСимвола = НомерСимвола + 1;
        КонецЦикла;
        
        // Удаляем правую часть строки, которая не участвует в распознавании.
        Если НомерСимвола <= МаксНомерСимвола Тогда
            Строка = Лев(Строка, НомерСимвола - 1);
            МаксНомерСимвола = НомерСимвола - 1;
        КонецЕсли;
        
        Если МаксНомерСимвола > 0 Тогда
            // Очищаем строку слева и справа от пробельных символов.
            Алфавит = " " + Символы.НПП;
            Пока Найти(Алфавит, Лев(Строка, 1)) > 0 Цикл
                Строка = Сред(Строка, 2);
                МаксНомерСимвола = МаксНомерСимвола - 1;
            КонецЦикла;
            Пока Найти(Алфавит, Прав(Строка, 1)) > 0 Цикл
                Строка = Лев(Строка, МаксНомерСимвола - 1);
                МаксНомерСимвола = МаксНомерСимвола - 1;
            КонецЦикла;
            
            // Определяем максимальное количество цифр справа, которые могут быть
            // распознаны как дробная часть
            НомерСимвола = МаксНомерСимвола;
            Алфавит = "012345679";
            Пока НомерСимвола >= 1 Цикл
                ТекущийСимвол = Сред(Строка, НомерСимвола, 1);
                Если Найти(Алфавит, ТекущийСимвол) = 0 Тогда
                    Прервать;
                КонецЕсли;
                НомерСимвола = НомерСимвола - 1;
            КонецЦикла;
            
            Если НомерСимвола > 0 Тогда
                // Для строки "123,456": "456" - дробная часть
                // Для строки "1,123,456": "456" - последняя триада целой части
                Если Найти(".,", ТекущийСимвол) > 0
                    И Не (МаксНомерСимвола - НомерСимвола = 3
                        И МаксНомерСимвола >= 9
                        И Сред(Строка, НомерСимвола - 4, 1) = ТекущийСимвол) Тогда
                    Строка = СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Лев(Строка, НомерСимвола - 1), ".", ""), ",", ""), " ", ""), Символы.НПП, "") + "." + Сред(Строка, НомерСимвола + 1);
                Иначе
                    Строка = СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Строка, ".", ""), ",", ""), " ", ""), Символы.НПП, "");
                КонецЕсли;
            КонецЕсли;
            
            Строка = ?(Отрицательное, "-", "") + Строка;
        КонецЕсли;
    КонецЕсли;
    
    Если ПустаяСтрока(Строка) Тогда
        Результат = Пусто;
    Иначе
        Попытка
            Результат = Число(Строка);
        Исключение
            Результат = Ошибка;
        КонецПопытки;
    КонецЕсли;
    
    Возврат Результат;

КонецФункции // СтрокаВЧисло()
3 DES
 
26.07.15
16:23
спс
4 ildary
 
26.07.15
16:34
(1) тем, что в случае кривых данных - вместо продолжения работы, происходит останов по ошибке, причем такой, что даже попыткой не перехватить.

(2) спасибо за функцию, а для даты нечто подобное есть?

p.s. Позор Селезневской, простые одинэсники пишут за нее базовые функции...
5 spectre1978
 
26.07.15
20:39
(4) причем такой, что даже попыткой не перехватить
ух ты... А можно сэмпл строки которая так делает?
8.2.19.76 - вроде перехватывает исключение, вот сейчас попробовал
6 Провинциальный 1сник
 
26.07.15
20:40
Переходите на семерку, там это реализовано. По крайней мере эксцепшен не вылетает при попытке преобразовать в число не-число.)
7 Фокусник
 
26.07.15
20:41
(0) зачем читать данные которые непойми какого типа?
8 Zamestas
 
26.07.15
20:46
(7) Вам про ёксель напомнить?
9 el7cartel
 
26.07.15
21:03
(8) ну как бы сначала делается вменяемый файл, а затем уже пишется обработка, если есть несоответствия, то можно указать их пользователю.
10 Zamestas
 
26.07.15
21:12
(9) Согласен - только поставщикам абсолютно пох.
11 Злопчинский
 
26.07.15
22:06
(2) бяка
Отсутствует анализ на верхний одиночный апостроф
Тщательно не сиотрел но скорее всего криво возьмет число у которого дробная часть отделена дефисом - так часто пишут суммы
Сомнительно распознает ли если разряды разделены запятой а дробная часть точкой
12 XLife
 
26.07.15
22:26
(11) лечить надо таких...
13 ЧеловекДуши
 
27.07.15
07:07
(0) Дарю:

Функция ЧислоМоё(ЧислоМ,ПоИсключ=0) Экспорт
    
Попытка
   Возврат Число(ЧислоМ);
Исключение
   Возврат ПоИсключ;
КонецПопытки;
    
КонецФункции
14 ЧеловекДуши
 
27.07.15
07:09
(1) Вываливается в Исключение, при кривой передачи информации, которая не зависит от Программы, а контролируется "Руками" Пользователя :)
15 spectre1978
 
27.07.15
08:37
(11) Ну это много чего можно напридумывать так. Например, мне попадался отчет на excel, сформированный в Великобритании, где отрицательные суммы пишутся в скобках. Этого оно бы тоже не поняло :) и что теперь? По-моему, такие вещи всегда можно подписать под конкретную задачу, нафига городить универсальный код, который дольше работает и все равно на 100% не решает задачу, потому что изобретательности в написании чисел нет предела?
16 newbling
 
27.07.15
09:34
Тебе надо с дробной частью?