IE2017

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

Программирование - Практика программирования

Принцип основан на том, что от момента получения случайного числа до наступления следующей секунды программа увеличит счетчик каждый раз на разное количество.
функция генерирует случайное (или псевдослучайное?) число от НачЧисло до КонЧисло
Функция СлучайноеЧисло(НачЧисло = 0,КонЧисло = 1,флЦелое = 0)
ТекВремя =ТекущееВремя();
СлЧисло = 0;
Пока ТекущееВремя() =ТекВремя Цикл

СлЧисло =СлЧисло + 1;
	

КонецЦикла;
СлЧисло =Число(Прав("000" +СлЧисло, 3)) / 1000;

// число от 0 до 0.999 

СлЧисло =НачЧисло + (КонЧисло -НачЧисло) *СлЧисло; 

// число от НачЧисло до КонЧисло
Возврат ?флЦелое = 1,Окр(СлЧисло, 0),СлЧисло);
КонецФункции 

См. также

Комментарии
1. Александр Окулов (PowerBoy) 2573 03.10.08 07:07 Сейчас в теме
(0) Я даже без теста вижу, что спектр сдесь будет неоднородный - т.е. определённые числа будут выпадать чаще.
2. Аркадий Кучер (Abadonna) 3681 03.10.08 07:17 Сейчас в теме
Уж лучше цепляться за _GetPerformanceCounter(), чем за ТекущееВремя()
3. Князев Евгений Юрьевич (noblekey) 97 03.10.08 08:35 Сейчас в теме
Можно еще так

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

//вместо Randomize
Для н = 1 По 100 Цикл
Уник = Новый УникальныйИдентификатор;
КонецЦикла;

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

//оставляем только цифры
Уник = СтрЗаменить(Уник,"-","");
Уник = СтрЗаменить(Уник,"a","");
Уник = СтрЗаменить(Уник,"b","");
Уник = СтрЗаменить(Уник,"c","");
Уник = СтрЗаменить(Уник,"d","");
Уник = СтрЗаменить(Уник,"e","");
Уник = СтрЗаменить(Уник,"f","");

//знаменатель должен иметь такое же количество нулей + 1
Знаменатель = 10;
Для н = 2 По (СтрДлина(СтрЗаменить(Уник,Символы.НПП,""))) Цикл
Знаменатель = Знаменатель * 10;
КонецЦикла;

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

//преобразуем его в случайное число из заданного интервала, округляем до целого
ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс);

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

КонецФункции
rpgshnik; feel_deep; rayastar; sanfoto; V.Nikonov; artbear; +6 Ответить 4
4. Михаил Семенов (Shaman100M) 1178 03.10.08 09:37 Сейчас в теме
Код
////////////////////////// 
// ГЕНЕРАТОР СЛУЧАЙНЫХ ЧИСЕЛ
//       Автор Сергей Нефедов
////////////////////////// 
Процедура randomize(а=0)   
    // сбрасывает генератор
    Если а=0 тогда    
        randSeed=_getPerformanceCounter();  
    Иначе
        randseed=а;  
    КонецЕсли;    
КонецПроцедуры
Функция random()    
    // выдает случайное число 0 <= rand < 1
    // интерпретация интерпритации AVB
    // выдает последовательности лучше, и работает быстрее. 
    // (не замедляется)
    // дело в том, что у него возникают очень большие числа,
    // а 1С некокорректно с ними работает (операция %)
    randSeed=(randSeed*1103515245+12345)%2147483648; 
    возврат randSeed/2147483648;
КонецФункции     
Показать полностью
5. kitt al;dskjf;ldasjkf (kitt) 319 03.10.08 10:54 Сейчас в теме
(3) можно еще так:
Код
ГСЧ = Новый ГенераторСлучайныхЧисел(255);
Рэндом = ГСЧ.СлучайноеЧисло(0, 10000);
Показать полностью

:)
Shadow326; Montecrizto; v.krivenko; adhocprog; Mir-mup; DrAku1a; twin; iceser1; mix; +9 1 Ответить 1
6. Владимир (vovan519) 274 03.10.08 12:42 Сейчас в теме
(0) Ждать целую секунду? ... Долго.
7. Артур Аюханов (artbear) 872 05.05.09 18:20 Сейчас в теме
(3) Плюсую.
Мне нужно было получить несколько случайных чисел для 8.0
Вариант из (3) помог, т.к. скорость выполнения была не важна.
8. Yakov Fast (opupety) 25.04.10 23:17 Сейчас в теме
Можно просто использовать локальную переменную среды %RANDOM%
9. Вадим Никонов (V.Nikonov) 115 17.09.11 12:08 Сейчас в теме
Может лучше малость подправленный вариант (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 

//преобразуем его в случайное число из заданного интервала, округляем до целого 
ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс); 

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

КонецФункции //ПолучитьСлучайноеЧисло()
...Показать Скрыть
10. Вадим Никонов (V.Nikonov) 115 17.09.11 12:08 Сейчас в теме
Может лучше малость подправленный вариант (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 

//преобразуем его в случайное число из заданного интервала, округляем до целого 
ЧислоИзИнтервала = Мин(Макс(Окр(Мин + (Макс-Мин)*Случ),Мин),Макс); 

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

КонецФункции //ПолучитьСлучайноеЧисло()
...Показать Скрыть
Mails79; Mir-mup; +2 Ответить
11. alex kru (artly2000) 09.07.13 09:33 Сейчас в теме
Автор 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, ДоЧисла, ВыдаватьНоль);
    Сообщить(Ранд);
  КонецЦикла;		
КонецПроцедуры
...Показать Скрыть
12. Константин Коробов (MoonAriman) 13.02.14 11:38 Сейчас в теме
Нам нужно было получать случайные числа в заданном диапазоне до 2-х знаков после запятой. Типовой генератор случайных чисел не может нецелые числа генерировать. Вышли из ситуации просто, следующим образом:

ГСЧ = Новый ГенераторСлучайныхЧисел;
СлучЧисло = ГСЧ.СлучайноеЧисло(НецелоеЧисло1*100, НецелоеЧисло2*100);
СлучЧисло=Окр(СлучЧисло/100,2);

Прикрепленные файлы:
13. Денис Пантюшин (gonkommu) 26.07.15 08:55 Сейчас в теме
Может кому пригодится, генератор от 1 до 99, выручает на семерке

_tmp=СоздатьОбъект("MSScriptControl.ScriptControl");
_tmp.language="javascript";
_rand= Цел(_tmp.eval("Math.random()")*100);

Сообщить(_rand);
14. Максим Литвинов (maksa2005) 93 09.02.16 14:13 Сейчас в теме
ГСЧ = Новый ГенераторСлучайныхЧисел(Формат(ТекущаяДата(),"ДФ=ddMMyyyyhhmmss"));
ТС.НомерДокумента = СтрЗаменить(ГСЧ.СлучайноеЧисло(0,1000)," ","");
15. Mr.Rome 1 (Mr.Rome) 14.05.16 11:57 Сейчас в теме
Проанализировав все что тут написано - объединил в наиболее приемлемое.
Вставлять в глобальный модуль

ЗЫЖ 7.7

Функция ПолучитьСлучайноеЧисло(МаксЗН,ВыдаватьНоль = 0) Экспорт Далее

//**********************************************************************    
Функция ПолучитьСлучайноеЧисло(МаксЗН,ВыдаватьНоль = 0) Экспорт
	                    
	//Увеличиваем на единицу, т.к. функция не возвращает верхний порог
	МаксЗН = МаксЗН + 1;
	
	Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl"); 
	Скрипт.language="javascript"; 
	Результат= Цел(Скрипт.eval("Math.random()")*МаксЗН); 
	  
	Если (ВыдаватьНоль = 0) и (Результат = 0) Тогда
		Пока Результат = 0 Цикл
			Результат = ПолучитьСлучайноеЧисло(МаксЗН,0)
		КонецЦикла;
	КонецЕсли;                                   
		
	Возврат Результат;
	
КонецФункции
...Показать Скрыть
16. Дмитрий Котов (rpgshnik) 7 12.09.16 10:26 Сейчас в теме
(5) kitt, Эта штатная какашка выдает одно и тоже число((
17. Максим Максим (shagua) 20.12.16 18:52 Сейчас в теме
(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);
    	Сообщить(Ранд);
	КонецЦикла;        
КонецПроцедуры
...Показать Скрыть
Оставьте свое сообщение