Имя: Пароль:
1C
 
Как определить, что строка состоит ТОЛЬКО из цифр?
0 Смит
 
23.10.10
12:38
Функцию-то я написал, но может есть более красивый путь?
1 zak555
 
23.10.10
12:40
СтрДлина(Число(Стр))=СтрДлина(Стр)
2 zak555
 
23.10.10
12:40
?(СтрДлина(Число(Стр))=СтрДлина(Стр), "Числа", "хренушки")
3 Андрюха
 
23.10.10
12:41
Если первый символ не "0" то можно так

Попытка
 ЧисловоеПредставление = Число(СтроковоеЗначение);
Исключение
 ЧисловоеПредставление = -1;
КонецПопытки;

Если Строка(ЧисловоеПредставление) = СтроковоеЗначение Тогда
 Соообщить("Значения эквивалентны.");
КонецЕсли;
4 zak555
 
23.10.10
12:42
кстати, да

0 вначале надо учитывать
5 Смит
 
23.10.10
12:44
Ага. Это был первый
6 Смит
 
23.10.10
12:44
вариант. Но нули есть.
7 Смит
 
23.10.10
12:45
Второй вариант был - сначала замена нулей на "1"
8 zak555
 
23.10.10
12:45
(6) в начале ?
9 Смит
 
23.10.10
12:46
Потом был еще третий вариант, основанный  только на замене.
10 Смит
 
23.10.10
12:46
(8) Ага.
11 zak555
 
23.10.10
12:48
а в строке могут быть буквы в каких вариантах ?
12 Смит
 
23.10.10
12:50
(11) Мне нужно проверять корректность ввода реквизита. Должны быть только цифры.
13 zak555
 
23.10.10
12:51
(12) реквизит сделать числом ?
14 Тьма
 
23.10.10
12:52
(12)Для этого существует маска ввода
15 Смит
 
23.10.10
12:53
(13) Пробовал. Получилось не юзабельно.

(14) Гм. Что это?
16 zak555
 
23.10.10
12:54
(15) это как ?
17 Тьма
 
23.10.10
12:57
18 Смит
 
23.10.10
12:57
(16) Вспомнил. Ведущие нули не вводятся.
19 Смит
 
23.10.10
13:00
(17) Спасибо. Помогло.
20 Невский Александр
 
23.10.10
13:03
ЭтоЧисло = ИСТИНА;
Для Ном = 0 По СтрДлина(СтрокаКоторуюНадоОпределить) Цикл
   ТекСимвол = КодСимвола(Сред(Сред(СтрокаКоторуюНадоОпределить),Ном,1));
Если ТекСимвол < 48 ИЛИ ТекСимвол > 57 Тогда
    ЭтоЧисло = ЛОЖЬ;
    Прервать;
КонецЕсли;
КонецЦикла;
21 Невский Александр
 
23.10.10
13:03
(20) вру ...
Цикл до (СтрокаКоторуюНадоОпределить)-1
22 zak555
 
23.10.10
13:04
(20) число может быть отрицательным и дробным =)
23 Смит
 
23.10.10
13:13
Дарю свою нетленку. :-)

   Стр = СтрЗаменить(Стр, "1", "0");
   Стр = СтрЗаменить(Стр, "2", "0");
   Стр = СтрЗаменить(Стр, "3", "0");
   Стр = СтрЗаменить(Стр, "4", "0");
   Стр = СтрЗаменить(Стр, "5", "0");
   Стр = СтрЗаменить(Стр, "6", "0");
   Стр = СтрЗаменить(Стр, "7", "0");
   Стр = СтрЗаменить(Стр, "8", "0");
   Стр = СтрЗаменить(Стр, "9", "0");  
   
   Стр1 = "0";
   Пока СтрДлина(Стр1) <> СтрДлина(Стр) Цикл
       Стр1 = Стр1 + "0";
   КонецЦикла;
   Если Стр <> Стр1  Тогда  
       Возврат 0;
   Иначе
       Возврат 1;
   КонецЕсли;
24 kiruha
 
23.10.10
13:20
Неявно 9 циклов, вместо одного(даже меньше если строка) в (20)
25 Смит
 
23.10.10
13:23
(24) Угу. Зато читабельно.
26 zak555
 
23.10.10
13:24
все про
-
.
хабыли
27 Смит
 
23.10.10
13:29
(26) Не забыли. В условии ЦЫФРЫ. "-" и "." нет.
28 KishMish
 
23.10.10
13:29
про ноль в начале
Если Строка("1"+ПроверямаяСтрока)=Строка(Число(Строка("1"+ПроверямаяСтрока)))
и (26) (НайтиЗапятую и Минус)
29 big
 
23.10.10
13:32
ГдеИщем="0123456789";

Для а=1 По СтрДлина(Проверяемая) Цикл
  ТекСимвол=Сред(Проверяемая,а,1);
  Если Найти(ГдеИщем,ТекСимвол)=0 Тогда
     Возврат 0;   // ошибка, есть НЕ цифры
  КонецЕсли;
КонецЦикла;
Возврат 1;   // всё ОК, есть только цифры
30 Torquader
 
23.10.10
14:41
Таки тогда можно и так:

// Предполагается, что ИсходнаяСтрока - строковый реквизит на форме, причём неограниченной длины
// Иначе надо сделать TrimRight
Если ИсходнаяСтрока="" Тогда
Результат="ПустаяСтрока";
ИначеЕсли (СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(ИсходнаяСтрока,"0",""),"1",""),"2",""),"3",""),"4",""),"5",""),"6",""),"7",""),"8",""),"9","")="" Тогда
Результат="Верно";
Иначе
Результат="Неверно";
КонецЕсли;
31 Rabbit
 
23.10.10
15:03
(3) пропустит знак и десятичную точку.
32 zak555
 
23.10.10
15:17
Функция ЭтоЧисло(Чис)
  Если СтрЧислоВхождений(Чис,".")>1 Тогда
    Возврат 0;
  КонецЕсли;

  ЧислоРазМинуса = СтрЧислоВхождений(Чис,"-");
  Если ЧислоРазМинуса >1 Тогда
    Возврат 0;
  КонецЕсли;

  Если (ЧислоРазМинуса=1) и (Лев(Чис,1)<>"-") Тогда
     Возврат 0;
  КонецЕсли;

  Для а=1 По СтрДлина(Чис) Цикл
  ТекСимвол=;
  Если Найти(0123456789-.",Сред(Чис,а,1))=0 Тогда
     Возврат 0;  
  КонецЕсли;
КонецЦикла;

КонецФунцкии
33 zak555
 
23.10.10
15:18
Функция ЭтоЧисло(Чис)
  Если СтрЧислоВхождений(Чис,".")>1 Тогда
    Возврат 0;
  КонецЕсли;

  ЧислоРазМинуса = СтрЧислоВхождений(Чис,"-");
  Если ЧислоРазМинуса >1 Тогда
    Возврат 0;
  КонецЕсли;

  Если (ЧислоРазМинуса=1) и (Лев(Чис,1)<>"-") Тогда
     Возврат 0;
  КонецЕсли;

  Для ы=1 По СтрДлина(Чис) Цикл
 
     Если Найти(0123456789-.",Сред(Чис,ы,1))=0 Тогда
        Возврат 0;  
     КонецЕсли;
  КонецЦикла;

КонецФунцкии
34 Rabbit
 
23.10.10
15:26
8)
35 Torquader
 
23.10.10
15:40
Мы как всегда не видим разницы между "Число" и "Строка только из цифр".
Причём, число 0001 и 001 - это одно и то же число, а вот строки-то уже разные.
P.S. видимо, разговор идёт о штрих-кодах - там цифр больше, чтобы влазить в четыре байта, а также могут быть ведущие нули - вот и приходится работать с такими "строками".
36 andrewks
 
23.10.10
16:23
а про Формат-то что никто не вспомнил? ловите

Функция ЭтоЧисло(Стр)
   Если (Формат(Число(Стр),"Ч (0)"+СокрЛП(СтрДлина(Стр)))<>Стр) ИЛИ (Лев(Стр,1)="-") Тогда
       // не строка из цифр
       Возврат 0;
   Иначе
       Возврат 1;
   КонецЕсли;
КонецФункции
37 Torquader
 
23.10.10
16:33
Кстати.
Предположим, что в строке тысяча цифр в случайном порядке - как будет выполняться оператор Число() - и будет ли вообще выполняться ?
38 Torquader
 
23.10.10
16:40
Выполняем такой код:

   s="";
   For i=1 To 1000 Do
       s=s+"1";
   EndDo;
   r=Number(s);
   s1=String(r);
   If s1<>s Then
       t=CreateObject("Text");
       t.AddLine("Не совпало!");
       t.AddLine("Было:"+s);
       t.AddLine("Стало:"+s1);
       t.Write(IBDir()+"123.txt");
   EndIf;

Получаем такой файл.

Не совпало!
Было:1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Стало:1111111111111111111111111111111111111111111111111111111111111111

Как бы, предполагается задуматься над использованием функции "Число" - уж очень она "неудачная".
39 andrewks
 
23.10.10
16:44
(37) ну вот, опять пришел поручик Ржевский и все опо.лил...
на длине строки = 65 ломается, но если это штрих-код то там не больше 13-ти, для них-то сойдет
40 G-Re
 
23.10.10
17:21
Может быть где-то так?

сзЦифры=СоздатьОбъект("СписокЗначений");
сзНеЦифры=СоздатьОбъект("СписокЗначений");

Для ц=0 то 9 Цикл
   сзЦифры.ДобавитьЗначение(""+ц);
КонецЦикла;

Размер=СтрДлина(СтрокаВвода);
Для ц=1 по Размер Цикл
   тЗнач=Сред(СтрокаВвода,ц,1);
   Если сзЦифры.Принадлежит(тЗнач)=0 Тогда
      сзНеЦифры.ДобавитьЗначение(ц,тЗнач);
   КонецЕсли;
КонецЦикла;


Таким образом, сзНеЦифры содержит все позиции с нецифрами и конкретно какими,
Если сзНеЦифры.РазмерСписка()=0 Значит все цифры.

Легко обобщается на случай, когда в строке должны быть только определенные символы, которыми нужно заполнить сзЦифры.
41 Mikeware
 
23.10.10
17:28
Ну тогда уж РегВыражения юзать....
42 Torquader
 
23.10.10
17:33
(40) Вместо списка значений на допустимые символы лучше использовать строку, как в (29) - а так, задумка очень правильная.
43 G-Re
 
23.10.10
17:43
(42) Согласен, просто не знаю, что быстрей отрабатывает,
Найти или Принадлежит, мне показалось, что второе.
Но предложил вариант, как некий типовый алгоритм, инструменты можно менять по вкусу.
Те же нецифры можно собирать и в ТЗ и в Строке, да где угодно, хоть в справочнике:).
44 Torquader
 
23.10.10
17:52
(43) Если надо часто сравнивать, то мы делаем просто:
Массив на 255 элементов - где 1, если символ допустим и 0, если нет, а далее перебираем строку и ищем коды символов в этом массиве - должно быть быстрее любого поиска.
45 Эмбеддер
 
23.10.10
18:19
если ПустаяСтрока(Стр)=0 тогда
если СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Стр,"0",""),"1",""),"2"....)="" тогда
 Сообщить("Только цифры");
конецесли;
конецесли;
46 Эмбеддер
 
23.10.10
18:20
(43) Хотя в (30) уже это было...
47 G-Re
 
23.10.10
18:22
(44) Согласен, на заре программирования, в эпоху неразвитых языков высокого уровня это был, по сути, единстенный достойный вариант, да и сейчас по скорости он, по-видимому, лидер, так как индекс элемента массива уже есть - КодСимв(ТекСимвол).
48 Torquader
 
23.10.10
18:25
На заре программирования 256 байт на какой-то массив было жалко (а ведь его ещё чем-то заполнять надо).
49 kiruha
 
23.10.10
18:28
А еще быстрее разбить строку на подстроки,
и запустить параллельные процессы проверки подстрок на число.
Если хотя бы одна подстрока не число - не число
50 G-Re
 
23.10.10
18:46
(48)256/8=32байта. Конечно, побитное представление.
(49) А разве 1С может параллелить? Как, не знаю, подскажите.
51 kiruha
 
23.10.10
18:53
(50)
1С не может.
Свою компоненту написать
52 G-Re
 
23.10.10
18:57
(51) Ну да..., особенно для того, что бы узнать, есть ли в строке нецифры...
53 Torquader
 
23.10.10
19:29
(51) Вы ещё про кодировку вспомните.
Слава богу, что в семёрке только одна кодировка.
54 Шурик71
 
23.10.10
19:36
Как, еще никто регекспы не предложил?!
55 andrewks
 
23.10.10
19:40
(54) читай внимательнее O_O
56 Эмбеддер
 
23.10.10
21:07
(53) Цифры могут быть только одного алфавита - нашего, т.е. арабского )))
57 andrewks
 
23.10.10
21:14
(56) а как же римские? ;)
58 orefkov
 
23.10.10
21:15
59 Барбариска
 
23.10.10
21:16
Функция ЧислоИзСтроки(Знач Стр) Экспорт
 Стр = СтрЗаменить(Стр,Симв(34),"");
 Сп = СоздатьОбъект("СписокЗначений");
 Сп.ИзСтрокиСРазделителями(Стр);
 Если Сп.Размерсписка()>0 Тогда  
    Возврат Сп.ПолучитьЗначение(1)
 КонецЕсли;
 Возврат "";
КонецФункции

Сравнить "1"+Строка+"1" и ЧислоИзСтроки("1"+Строка+"1")
Ну и еще на вхождение дробного разделителя проверить...
60 Эмбеддер
 
23.10.10
21:18
(57) Мощности не хватит. Заметили, что в паспорте серия теперь тоже арабскими?
61 andrewks
 
23.10.10
21:19
(60) ага заметил. мощности не хватило видимо у компов ФМС, а у нас и мощности, и мозгов хватит
62 andrewks
 
23.10.10
21:24
(59) а что, 123"45 тоже число? каков глубинный смысл в
Стр = СтрЗаменить(Стр,Симв(34),"")?
63 Барбариска
 
23.10.10
21:28
(62) :) ну да, внутренние кавычки.... это тоже вариант
правильнее просто замена крайних символов - если кавычки
64 andrewks
 
23.10.10
21:30
(63) гмм... ну вроде "12345" тоже не число, надо 12345
65 Эмбеддер
 
23.10.10
21:30
Если в строке есть кавычки, она состоит не только из цифр, но и кавычек. Это не правильно
66 Эмбеддер
 
23.10.10
21:31
Понял, не заметил пример вызова
67 Барбариска
 
23.10.10
21:32
ок, убираем про кавычки )))
68 smaharbA
 
23.10.10
21:32
вечная тема
69 andrewks
 
23.10.10
21:35
(59) чем больше я смотрю на содержимое Функция ЧислоИзСтроки
тем меньше я в ней понимаю ...
70 Torquader
 
23.10.10
21:38
(69) Так ведь - "получить число из строки с цифрами" и "проверить, что в строке только цифры" - это две совершенно разные задачи.
71 Барбариска
 
23.10.10
21:39
(69) тем не менее.. потестируй )) убрав строчку про кавычки
72 andrewks
 
23.10.10
21:41
(70) согласен, я вообще не об этом, просто я раньше никогда не замечал такое странное поведение функции ИзСтрокиСРазделителями. оказывается для "эюя345" она выдает число 345, тогда как Число("эюя345")=0. Кто-нибудь видел это в описании или я один такой слепой?
73 Эмбеддер
 
23.10.10
21:45
(72) Скорее всего Барбариска использует эту функцию когда выводит на печать номер документа, удаляя его префикс
74 andrewks
 
23.10.10
21:51
(71) во-первых, сравнивать надо с Строка(ЧислоИзСтроки("1"+Стр+"1")), а во-вторых эта функция слетает уже со строк длины 63, тогда как моя - только с длины 65 :)))
75 andrewks
 
23.10.10
22:57
я тут от нечего делать решил потестить предложенные варианты по быстродействию (эх, ностальгия прошибла, прям как в школе лабы делали), изначально полагал что самый быстрый д.б. (20) (по крайней мере при реализации ч/з массив в нормальном ЯП).
давал на вход 50 тыс. строк, содержащих только цифири,  длиной 60.
оказалось: почти все варианты с использованием строковых процедур (20) (23) (29) (33) дали длительность 50-60, вариант (59) - 68, (40) - 175! (ессесно я вынес формирование списка цифр за функцию), (30) - 34-35 (хотя когда я первый раз на него взглянул, подумал - тормозной), (36) - 34-35.
т.к. у меня длины проверяемых строк не больше 20, решил оставить свой вариант - он на мой взгляд покрасивше (30)
76 smaharbA
 
23.10.10
23:06
(75)
36,6 это строка или число ?
77 smaharbA
 
23.10.10
23:07
а 36 000 это строка или число ?
78 andrewks
 
23.10.10
23:10
по условиям сабжа: мы проверяем, содержит ли строка только цифры.
79 smaharbA
 
23.10.10
23:14
(78) слабое оправдание
80 smaharbA
 
23.10.10
23:15
для этого и формт то не нужен

0+чето = чето
81 andrewks
 
23.10.10
23:17
(79) это не оправдание, это условие. у меня моя функция используется в наборе процедур проверки некоторых реквизитов по ключу (ИНН, ОГРН и т.д.), там в принципе нет чисел, есть строчки, которые должны содержать только цифры.
82 andrewks
 
23.10.10
23:19
(80) не вкурил...
83 Torquader
 
23.10.10
23:21
(75) А с массивом кодов проверял ?
Хотя, есть мнение, что выбор строки Сред(Строка,Позиция,1) уже достаточно тормозная операция.
(в javascript есть charCodeAt(Position) и он побыстрее).
Замена же оказалась быстрой из-за того, что длины строк совпадали - тогда она сводится к Search&Replace.
84 andrewks
 
23.10.10
23:22
(83) с массивом кодов - это как?
85 andrewks
 
23.10.10
23:25
+(84) у меня давно уже сложилось впечатление, что строковые функции в 1С далеки от оптимальности.
86 Torquader
 
23.10.10
23:26
(80)
Проверил таким кодом - не взлетело.
   i=1;
   j="1";
   If i=j Then Message("Круто");EndIf;
Так тоже:
   i="1";
   If 0+i=i Then Message("А так");EndIf;
87 Torquader
 
23.10.10
23:28
(84) Вот так:
// подготовительный этап
Var CharArr[255];
For i=1 To 255 Do CharArr[i]=0;EndDo;
For i=48 To 57 Do CharArr[i]=1;EndDo;
//
Function ThisIsNumString(StringForTest)
l=StrLen(StringForTest);
For i=1 To l Do
 If CharArr[Asc(Mid(StringForTest,i,1))]<>1 Then Return 0;EndIf;
EndDo;
Return 1;
EndFunction
88 andrewks
 
23.10.10
23:30
(87) а-а-а понятно, ява. я принципиально тестил только алгоритмы так сказать на plain 1C
89 smaharbA
 
23.10.10
23:33
(86) а ты ум наморщи
90 andrewks
 
23.10.10
23:33
+(88) ява -> скрипт
91 smaharbA
 
23.10.10
23:34
(90) в (87) что ни на есть адинес
92 Torquader
 
23.10.10
23:35
(88) Таки это тот же самый 1С, только по английски.
Перем МассСимв[255];
Для i=1 По 255 Цикл МассСимв[i]=0;КонецЦикла;
Для i=48 По 57 Цикл МассСимв[i]=1;КонецЦикла;

Функция ЭтоЧисловаяСтрока(Стр)
Дл=ДлинаСтроки(Стр);
Для ТекПоз=1 По Дл Цикл
 Если МассСимв[КодСимв(Сред(Стр,ТекПоз,1))]<>1 Тогда Возврат 0;КонецЕсли;
КонецЦикла;
Возврат 1;
КонецФункции
93 andrewks
 
23.10.10
23:37
(91) во блин глаза замылило по ходу спать пора...
94 Torquader
 
23.10.10
23:42
(89) Ты хотел сказать, что
Число(ПроверяемаяСтрока+"0")/10=Число(ПроверяемаяСтрока)
Так что-ли ?
95 andrewks
 
23.10.10
23:43
(92) длительность - 48-52 + дополнительная нехилая структура с заполнением. прямо класс - данные, конструктор, метод
96 Torquader
 
23.10.10
23:44
(95) Структуру надо вызывать только один раз - перед началом использования.
97 andrewks
 
23.10.10
23:45
(96) ессесно так и делал
98 andrewks
 
23.10.10
23:49
(94) длительность - 33-34, но не учитывает минус. вот так:

Функция ЭтоЧисло10(Стр)
   Если (Число(Стр+"0")/10=Число(Стр)) И (Лев(Стр,1)<>"-") Тогда
       Возврат 1;
   Иначе
       Возврат 0;
   КонецЕсли;
КонецФункции
99 andrewks
 
23.10.10
23:52
+(98) и кстати не падает после 65-симв.строк. красиво!
100 andrewks
 
23.10.10
23:53
бли-и-ин! сломалось на "а1234"
101 andrewks
 
23.10.10
23:56
ну да все верно число(бяка+0)=0 / 10 = 0 = число (бяка) = 0
102 Torquader
 
24.10.10
00:17
Тогда
Число(Бяка)*10+1=Число(Бяка+1)
103 andrewks
 
24.10.10
20:58
(102) не понял...
104 Сигизмунд Прокофьеви
 
24.10.10
21:23
регулярные выражения не предлагать?
105 andrewks
 
24.10.10
21:25
(104) блин, третий раз уже... читай лучше O_O
106 Torquader
 
24.10.10
21:48
(103)
Точнее так:
Если Число(НашаСтрока)*10+1=Число(НашаСтрока+"1") Тогда "Ура";

То есть если у нас число (причём целое), то мы просто умножаем его на 10 и прибавляем единицу.
Если число записано строкой, то действие - добавить единицу в конец.
Если не число, то 0*10+1=1
Число(Фигня+"1")=0
Но, надо учитывать, что функция Число получит число из строки "  123" (то есть пробелы в начале будут отброшены).
Другими словами, нам данное решение не подходит.
107 zak555
 
24.10.10
22:18
так где правильно ?
108 Мимохожий Однако
 
24.10.10
22:26
(107) см.(80) "Доступно и всерьез"
109 zak555
 
24.10.10
22:35
(108) хня
110 andrewks
 
24.10.10
22:36
(108) шютник...
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс