Получение случайного числа средствами 1С (пример функции)

23 Comments

  1. PowerBoy

    (0) Я даже без теста вижу, что спектр сдесь будет неоднородный — т.е. определённые числа будут выпадать чаще.

    Reply
  2. Abadonna

    Уж лучше цепляться за _GetPerformanceCounter(), чем за ТекущееВремя()

    Reply
  3. noblekey

    Можно еще так

    Функция ПолучитьСлучайноеЧисло(Мин,Макс)

    //вместо Randomize

    Для н = 1 По 100 Цикл

    Уник = Новый УникальныйИдентификатор;

    КонецЦикла;

    //генерируем GUID

    Уник = СокрЛП(Новый УникальныйИдентификатор);

    //оставляем только цифры

    Уник = СтрЗаменить(Уник,»-«,»»);

    Уник = СтрЗаменить(Уник,»a»,»»);

    Уник = СтрЗаменить(Уник,»b»,»»);

    Уник = СтрЗаменить(Уник,»c»,»»);

    Уник = СтрЗаменить(Уник,»d»,»»);

    Уник = СтрЗаменить(Уник,»e»,»»);

    Уник = СтрЗаменить(Уник,»f»,»»);

    //знаменатель должен иметь такое же количество нулей + 1

    Знаменатель = 10;

    Для н = 2 По (СтрДлина(СтрЗаменить(Уник,Символы.НПП,»»))) Цикл

    Знаменатель = Знаменатель * 10;

    КонецЦикла;

    Случ = Число(Уник) / Знаменатель; //здесь получается дробное случайное число от 0 до 1

    //преобразуем его в случайное число из заданного интервала, округляем до целого

    ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс);

    Возврат ЧислоИзИнтервала;

    КонецФункции

    Reply
  4. Shaman100M
    Код
    //////////////////////////
    // ГЕНЕРАТОР СЛУЧАЙНЫХ ЧИСЕЛ
    //       Автор Сергей Нефедов
    //////////////////////////
    Процедура randomize(а=0)  
        // сбрасывает генератор
        Если а=0 тогда    
            randSeed=_getPerformanceCounter();  
        Иначе
            randseed=а;  
        КонецЕсли;    
    КонецПроцедуры
    Функция random()    
        // выдает случайное число 0 <= rand < 1
        // интерпретация интерпритации AVB
        // выдает последовательности лучше, и работает быстрее.
        // (не замедляется)
        // дело в том, что у него возникают очень большие числа,
        // а 1С некокорректно с ними работает (операция %)
        randSeed=(randSeed*1103515245+12345)%2147483648;
        возврат randSeed/2147483648;
    КонецФункции    
    

    Показать полностью

    Reply
  5. kitt

    (3) можно еще так:

    Код
    ГСЧ = Новый ГенераторСлучайныхЧисел(255);
    Рэндом = ГСЧ.СлучайноеЧисло(0, 10000);
    

    Показать полностью

    🙂

    Reply
  6. vovan519

    (0) Ждать целую секунду? … Долго.

    Reply
  7. artbear

    (3) Плюсую.

    Мне нужно было получить несколько случайных чисел для 8.0

    Вариант из (3) помог, т.к. скорость выполнения была не важна.

    Reply
  8. opupety

    Можно просто использовать локальную переменную среды %RANDOM%

    Reply
  9. V.Nikonov

    Может лучше малость подправленный вариант (3)

    //НВЮ/ Получение Случайного Числа
    //
    // Параметры
    //  <Мин>  — <Число> — Нижняя граница Равномерного Распределения
    //  <Макс>  — <Число> — Верхняя граница Равномерного Распределения
    //
    // Возвращаемое значение:
    //   <Число>   — Сгенерированное случайное число
    //
    Функция ПолучитьСлучайноеЧисло(Мин=0,Макс=100) Экспорт
    
    //вместо Randomize
    Для н = 1 По Макс Цикл
    Уник = Новый УникальныйИдентификатор;
    КонецЦикла;
    
    //генерируем GUID
    Уник = СокрЛП(Новый УникальныйИдентификатор);
    
    //оставляем только цифры
    Уник = СтрЗаменить(Уник,»-«,»»);
    Уник = СтрЗаменить(Уник,Символы.НПП,»»);
    
    Случ = 0;
    //знаменатель должен иметь такую же разрядность
    Знаменатель = 1;
    Для н = 1 По (СтрДлина(Уник)) Цикл
    ТекС = Сред(Уник,н,1);
    Если ТекС=»a» Тогда
    Случ = Случ + Знаменатель*10;
    ИначеЕсли ТекС=»b» Тогда
    Случ = Случ + Знаменатель*11;
    ИначеЕсли ТекС=»c» Тогда
    Случ = Случ + Знаменатель*12;
    ИначеЕсли ТекС=»d» Тогда
    Случ = Случ + Знаменатель*13;
    ИначеЕсли ТекС=»e» Тогда
    Случ = Случ + Знаменатель*14;
    ИначеЕсли ТекС=»f» Тогда
    Случ = Случ + Знаменатель*15;
    ИначеЕсли ТекС=»1″ Тогда
    Случ = Случ + Знаменатель;
    ИначеЕсли ТекС=»2″ Тогда
    Случ = Случ + Знаменатель*2;
    ИначеЕсли ТекС=»3″ Тогда
    Случ = Случ + Знаменатель*3;
    ИначеЕсли ТекС=»4″ Тогда
    Случ = Случ + Знаменатель*4;
    ИначеЕсли ТекС=»5″ Тогда
    Случ = Случ + Знаменатель*5;
    ИначеЕсли ТекС=»6″ Тогда
    Случ = Случ + Знаменатель*6;
    ИначеЕсли ТекС=»7″ Тогда
    Случ = Случ + Знаменатель*7;
    ИначеЕсли ТекС=»8″ Тогда
    Случ = Случ + Знаменатель*8;
    ИначеЕсли ТекС=»9″ Тогда
    Случ = Случ + Знаменатель*9;
    КонецЕсли;
    Знаменатель = Знаменатель * 16;
    КонецЦикла;
    
    Случ = Случ / Знаменатель; //здесь получается дробное случайное число от 0 до 1
    
    //преобразуем его в случайное число из заданного интервала, округляем до целого
    ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс);
    
    Возврат ЧислоИзИнтервала;
    
    КонецФункции //ПолучитьСлучайноеЧисло()

    Показать

    Reply
  10. V.Nikonov

    Может лучше малость подправленный вариант (3)

    //НВЮ/ Получение Случайного Числа
    //
    // Параметры
    //  <Мин>  — <Число> — Нижняя граница Равномерного Распределения
    //  <Макс>  — <Число> — Верхняя граница Равномерного Распределения
    //
    // Возвращаемое значение:
    //   <Число>   — Сгенерированное случайное число
    //
    Функция ПолучитьСлучайноеЧисло(Мин=0,Макс=100) Экспорт
    
    //вместо Randomize
    Для н = 1 По Макс Цикл
    Уник = Новый УникальныйИдентификатор;
    КонецЦикла;
    
    //генерируем GUID
    Уник = СокрЛП(Новый УникальныйИдентификатор);
    
    //оставляем только цифры
    Уник = СтрЗаменить(Уник,»-«,»»);
    Уник = СтрЗаменить(Уник,Символы.НПП,»»);
    
    Случ = 0;
    //знаменатель должен иметь такую же разрядность
    Знаменатель = 1;
    Для н = 1 По (СтрДлина(Уник)) Цикл
    ТекС = Сред(Уник,н,1);
    Если ТекС=»a» Тогда
    Случ = Случ + Знаменатель*10;
    ИначеЕсли ТекС=»b» Тогда
    Случ = Случ + Знаменатель*11;
    ИначеЕсли ТекС=»c» Тогда
    Случ = Случ + Знаменатель*12;
    ИначеЕсли ТекС=»d» Тогда
    Случ = Случ + Знаменатель*13;
    ИначеЕсли ТекС=»e» Тогда
    Случ = Случ + Знаменатель*14;
    ИначеЕсли ТекС=»f» Тогда
    Случ = Случ + Знаменатель*15;
    ИначеЕсли ТекС=»1″ Тогда
    Случ = Случ + Знаменатель;
    ИначеЕсли ТекС=»2″ Тогда
    Случ = Случ + Знаменатель*2;
    ИначеЕсли ТекС=»3″ Тогда
    Случ = Случ + Знаменатель*3;
    ИначеЕсли ТекС=»4″ Тогда
    Случ = Случ + Знаменатель*4;
    ИначеЕсли ТекС=»5″ Тогда
    Случ = Случ + Знаменатель*5;
    ИначеЕсли ТекС=»6″ Тогда
    Случ = Случ + Знаменатель*6;
    ИначеЕсли ТекС=»7″ Тогда
    Случ = Случ + Знаменатель*7;
    ИначеЕсли ТекС=»8″ Тогда
    Случ = Случ + Знаменатель*8;
    ИначеЕсли ТекС=»9″ Тогда
    Случ = Случ + Знаменатель*9;
    КонецЕсли;
    Знаменатель = Знаменатель * 16;
    КонецЦикла;
    
    Случ = Случ / Знаменатель; //здесь получается дробное случайное число от 0 до 1
    
    //преобразуем его в случайное число из заданного интервала, округляем до целого
    ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс);
    
    Возврат ЧислоИзИнтервала;
    
    КонецФункции //ПолучитьСлучайноеЧисло()

    Показать

    Reply
  11. artly2000

    Автор ArtLy.

    Я долго искал возможность создания генератора случайных чисел в 1С7.7 и вот свершилось. Разброс чисел по оценке — отлично. Используется средствами VBScript

    //Глобальный модуль

    Функция _СлучайноеЧислоVBA(VBA, N, ВыдаватьНоль = 0) Экспорт
    Если ВыдаватьНоль = 0 Тогда
    N = N + 1;
    КонецЕсли;
    VBA.Language = «VBscript»;
    VBA.AddCode(»
    |Function GetRND(x)
    |R = Int(0 + (Rnd() * x))
    |GetRND = R
    |End Function
    |»);
    Результат=VBA.Modules(«Global»).CodeObject.GetRND(N);
    Если Результат = 0 Тогда
    Если ВыдаватьНоль = 0 Тогда
    Результат = 1;
    КонецЕсли;
    КонецЕсли;
    Возврат Результат;
    КонецФункции

    Показать

    //Где-то в модуле формы

    Процедура ПриОткрытии()
    VBA = СоздатьОбъект(«MSScriptControl.ScriptControl»);
    ДоЧисла = 3;
    ВыдаватьНоль = 0;
    Для Ц = 1 По 100 Цикл
    Ранд = _СлучайноеЧислоVBA(VBA, ДоЧисла, ВыдаватьНоль);
    Сообщить(Ранд);
    КонецЦикла;
    КонецПроцедуры

    Показать

    Reply
  12. MoonAriman

    Нам нужно было получать случайные числа в заданном диапазоне до 2-х знаков после запятой. Типовой генератор случайных чисел не может нецелые числа генерировать. Вышли из ситуации просто, следующим образом:

    ГСЧ = Новый ГенераторСлучайныхЧисел;

    СлучЧисло = ГСЧ.СлучайноеЧисло(НецелоеЧисло1*100, НецелоеЧисло2*100);

    СлучЧисло=Окр(СлучЧисло/100,2);

    Reply
  13. gonkommu

    Может кому пригодится, генератор от 1 до 99, выручает на семерке

    _tmp=СоздатьОбъект(«MSScriptControl.ScriptControl»);

    _tmp.language=»javascript»;

    _rand= Цел(_tmp.eval(«Math.random()»)*100);

    Сообщить(_rand);

    Reply
  14. maksa2005

    ГСЧ = Новый ГенераторСлучайныхЧисел(Формат(ТекущаяДата(),»ДФ=ddMMyyyyhhmmss»));

    ТС.НомерДокумента = СтрЗаменить(ГСЧ.СлучайноеЧисло(0,1000),» «,»»);

    Reply
  15. Mr.Rome

    Проанализировав все что тут написано — объединил в наиболее приемлемое.

    Вставлять в глобальный модуль

    ЗЫЖ 7.7

    Функция ПолучитьСлучайноеЧисло(МаксЗН,ВыдаватьНоль = 0) Экспорт Далее
    
    //**********************************************************************
    Функция ПолучитьСлучайноеЧисло(МаксЗН,ВыдаватьНоль = 0) Экспорт
    
    //Увеличиваем на единицу, т.к. функция не возвращает верхний порог
    МаксЗН = МаксЗН + 1;
    
    Скрипт=СоздатьОбъект(«MSScriptControl.ScriptControl»);
    Скрипт.language=»javascript»;
    Результат= Цел(Скрипт.eval(«Math.random()»)*МаксЗН);
    
    Если (ВыдаватьНоль = 0) и (Результат = 0) Тогда
    Пока Результат = 0 Цикл
    Результат = ПолучитьСлучайноеЧисло(МаксЗН,0)
    КонецЦикла;
    КонецЕсли;
    
    Возврат Результат;
    
    КонецФункции
    

    Показать

    Reply
  16. rpgshnik

    (5) kitt, Эта штатная какашка выдает одно и тоже число((

    Reply
  17. shagua

    (11)

    Перед вызовом Rnd для инициализации генератора случайных чисел с начальным значением на основе системного таймера воспользуйтесь оператором Randomize без указания аргументов.

    Код можно переписать так (будет генерить целые от 1 до 100):

    Функция СлучайноеЧислоVBA(N)
    VBA = СоздатьОбъект(«MSScriptControl.ScriptControl»);
    VBA.Language = «VBscript»;
    VBA.AddCode(»
    |Function GetRND(x)
    |Randomize
    |R = Int(1   (Rnd() * x))
    |GetRND = R
    |End Function
    |»);
    Возврат VBA.Modules(«Global»).CodeObject.GetRND(N);
    КонецФункции
    
    Процедура Тест()
    Для Ц = 1 По 100 Цикл
    Ранд = СлучайноеЧислоVBA(100);
    Сообщить(Ранд);
    КонецЦикла;
    КонецПроцедуры
    

    Показать

    Reply
  18. MariusUrsus

    (16)


    Новый ГенераторСлучайныхЧисел(<НачальноеЧисло>)

    Параметры:

    <НачальноеЧисло> (необязательный)

    Тип: Число.

    Начальное число, которым инициализируется генератор случайных чисел.

    Описание:

    Генератор случайных чисел инициализируется начальным числом из параметра.

    Последовательность случайных чисел для одного и того же начального числа будет одинакова.

    нужно изменяющееся зерно задавать, например так

    ГенераторСлучайныхЧисел  = Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах());
    СлучайноеЧисло = ГенераторСлучайныхЧисел.СлучайноеЧисло(0, 99);
    
    Reply
  19. User80

    Не нужно выдумывать велосипед. При создании генератора случайных чисел не задавайте начальное число и все будет работать.

    ГСЧ = Новый ГенераторСлучайныхЧисел();

    Рэндом = ГСЧ.СлучайноеЧисло(0, 10000);

    Reply
  20. kadild

    В синтаксис помощнике хоть и написали, что «Последовательность случайных чисел для одного и того же начального числа будет одинакова.», но почему-то не указали что это генератор не случайных чисел, а псевдослучайных. Такая функция есть почти у всех языков и они псевдослучайные.

    Генератор псевдослучайных чисел, то есть устройство, которое выдает последовательность чисел, отвечающую определенным статистическим критериям случайности.

    Например можно воспользоватся классов из Win (mscorlib.dll):

    Rnd = СоздатьОбъект(«System.Random»);

    Сообщить(Rnd.Next());

    Reply
  21. НатальяАлекс

    (20) Спасибо! действительно работает!

    Reply
  22. Cucu.ruza

    перем ч,м,с;

    ТекущееВремя(ч,м,с);

    чис=ч*ДатаЧисло(ТекущаяДата())+м*ДатаМесяц(ТекущаяДата())+с*ДатаГод(ТекущаяДата());

    Сообщить(чис % 10000);

    Применяется для генерации промо-кодов.

    Reply
  23. Dolg

    (3) Подскажите пожалуйста, а как его передать в процедуру и сообщить то число, которое получилось?

    &НаКлиенте
    Процедура ВамПредлогаетКомпьютерПриИзменении(Элемент)
    Результат = ПолучитьСлучайноеЧисло(Мин,Макс, Элемент);
    Сообщить (Результат);
    КонецПроцедуры
    

    Выдает ошибку, к преобразованию значения типу Число не может быть выполнено

    {ВнешняяОбработка.ВнешняяОбработка1.Форма.БыкиИКоровыФорма.Форма(30)}: Преобразование значения к типу Число не может быть выполнено

    ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс);

    Help please

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *