Получение случайного числа средствами 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 не будет опубликован. Обязательные поля помечены *