Разработка и Конфигурация · 9 мин
Как сгенерировать случайное число в 1С
Как сгенерировать случайное число в 1С: объект ГенераторСлучайныхЧисел, методы СлучайноеЧисло, примеры кода, типичные ошибки и проверка результата.
Во встроенном языке 1С:Предприятие для получения случайных чисел используется специальный объект ГенераторСлучайныхЧисел. Он доступен и на толстом, и на тонком клиенте, и на сервере, поэтому один и тот же код работает практически в любой конфигурации без доработок.
Генератор создаёт псевдослучайные числа в заданном диапазоне: вы указываете нижнюю и верхнюю границы, а метод возвращает целое число, включая обе границы. Этого достаточно для типовых задач: перемешивания данных, формирования тестовых наборов, выбора случайного элемента справочника, жеребьёвки.
Ниже разобраны способы создания генератора, варианты получения чисел в нужном диапазоне, типичные ошибки с повторяющимися последовательностями и способы проверить, что результат действительно выглядит случайным.
Объект ГенераторСлучайныхЧисел: как он работает
Объект создаётся конструктором Новый ГенераторСлучайныхЧисел(). Конструктор принимает один необязательный параметр — начальное число (seed), от которого строится вся последовательность. Если параметр не указан, платформа инициализирует генератор системным значением, обычно привязанным к текущему времени.
Важное свойство генератора: при одинаковом начальном числе он всегда выдаёт одну и ту же последовательность. Это не баг, а стандартное поведение псевдослучайных алгоритмов. Для тестирования воспроизводимость удобна, а вот для реальной случайности одинаковый seed использовать нельзя.
Основной метод — СлучайноеЧисло(НижняяГраница, ВерхняяГраница). Он возвращает целое число, причём обе границы входят в диапазон: вызов СлучайноеЧисло(1, 6) может вернуть любое значение от 1 до 6 включительно, как бросок игрального кубика.
Генератор = Новый ГенераторСлучайныхЧисел();
Число = Генератор.СлучайноеЧисло(1, 100);
Сообщить(Число);Простейший пример: число в заданном диапазоне
Минимальный рабочий код занимает три строки: создание генератора, вызов метода и использование результата. Пример ниже возвращает случайное целое число от 1 до 100:
Генератор = Новый ГенераторСлучайныхЧисел();
СлучайноеЧисло = Генератор.СлучайноеЧисло(1, 100);
Сообщить("Выпало число: " + СлучайноеЧисло);
Если генератор нужен один раз, можно не сохранять его в переменную, а вызвать метод сразу: Новый ГенераторСлучайныхЧисел().СлучайноеЧисло(0, 9). Это допустимо для разовых операций, но при многократных вызовах в цикле такой подход даёт неприятный эффект — об этом ниже.
Для диапазона, который начинается не с нуля, используйте формулу: нижняя граница плюс случайное смещение. Например, число от 50 до 59: 50 + Генератор.СлучайноеЧисло(0, 9). Это удобно, когда границы вычисляются динамически.
Как получить неповторяющуюся последовательность
Классическая ошибка — создавать новый генератор на каждой итерации цикла. Если итерации выполняются быстро, системное время инициализации может совпасть, и вы получите серию одинаковых чисел. Правильный подход — создать генератор один раз до цикла и вызывать метод многократно:
Генератор = Новый ГенераторСлучайныхЧисел();
Для Сч = 1 По 10 Цикл
Сообщить(Генератор.СлучайноеЧисло(1, 1000));
КонецЦикла;
Если требуется управляемая инициализация, передайте seed явно. Хороший вариант — текущее время в миллисекундах: Новый ГенераторСлучайныхЧисел(ТекущаяУниверсальнаяДатаВМиллисекундах()). Вероятность совпадения двух таких значений при последовательных запусках крайне мала.
Практические сценарии использования
Случайный элемент массива или списка
Чтобы выбрать случайный элемент массива, сгенерируйте индекс от нуля до верхней границы массива: Индекс = Генератор.СлучайноеЧисло(0, Массив.ВГраница()). Для списка значений аналогично, но верхняя граница — Список.Количество() - 1.
Случайная строка или пароль для тестовых данных
Для тестовых строк соберите результат посимвольно: задайте строку-алфавит, затем в цикле берите из неё символ по случайной позиции. Так формируют артикулы, коды и наполнители для тестовых баз. Напомним: для реальных паролей этот способ не подходит.
Случайное число с дробной частью
Метод возвращает только целые числа. Для дробных значений сгенерируйте целое в расширенном диапазоне и разделите: число от 0 до 1 с двумя знаками — Генератор.СлучайноеЧисло(0, 100) / 100. Точность задаётся выбором делителя.
- 1Создайте генератор: Новый ГенераторСлучайныхЧисел() — один раз, до цикла
- 2Определите диапазон и вызовите СлучайноеЧисло(НижняяГраница, ВерхняяГраница)
- 3При необходимости воспроизводимости передайте фиксированный seed в конструктор
- 4Проверьте результат: значения должны попадать в диапазон и не повторяться сериями
Типичные ошибки и как их избежать
Самая частая проблема — одинаковые числа в цикле из-за пересоздания генератора на каждой итерации. Вторая по популярности — путаница с границами: разработчик ожидает, что верхняя граница не включается, и получает «лишнее» значение. Запомните: диапазон замкнутый, обе границы возможны в результате.
Ещё одна ошибка — использование одинакового фиксированного seed в рабочем коде. Это удобно при отладке, но в продуктиве превращает «случайный» выбор в заранее известную последовательность, что недопустимо, например, при жеребьёвке или формировании кодов.
Как проверить, что генерация работает правильно
Простейшая проверка — вывести серию из 20–50 чисел и оценить её глазами: значения должны лежать внутри диапазона, не быть отсортированными и не повторяться длинными сериями. Полного отсутствия повторов ждать не стоит: в маленьком диапазоне совпадения закономерны.
Для более строгой проверки сгенерируйте несколько тысяч чисел и посчитайте, сколько раз выпала каждая граница диапазона. При равномерном распределении частоты будут близки. Точного равенства не будет — оценивайте порядок величин, а не совпадение до единицы.
Как проверить результат
Все числа в пределах заданных границ, включая крайние
Значения выходят за границы или одна граница никогда не выпадает
Числа различаются, нет длинных одинаковых серий
Подряд идут одинаковые значения — генератор пересоздаётся в цикле
Частоты значений одного порядка
Отдельные значения выпадают в разы чаще остальных
Альтернативы и смежные приёмы
Если нужна не случайность, а уникальность, используйте Новый УникальныйИдентификатор() — он даёт гарантированно разные значения без совпадений. Для случайной даты сгенерируйте случайное число секунд и прибавьте его к начальной дате.
Для перемешивания коллекции нет встроенного метода, поэтому применяют обмен элементов: проходят по массиву и меняют каждый элемент местами со случайно выбранным. Это простой и достаточный для прикладных задач вариант тасования.
Сравнение вариантов
Подходит для случайных чисел в диапазоне, тестовых данных и жеребьёвки; не даёт уникальности и криптостойкости
Подходит, когда важна уникальность значений, а не случайность; диапазон задать нельзя
Подходит для воспроизводимых тестов; в продуктивном коде делает последовательность предсказуемой
Что важно запомнить
Случайное число в 1С получают через Новый ГенераторСлучайныхЧисел() и метод СлучайноеЧисло с замкнутым диапазоном. Генератор создают один раз вне цикла, seed фиксируют только для тестов, а для паролей и ключей этот механизм не применяют.
Частые вопросы
Почему в цикле выпадают одинаковые случайные числа?
Чаще всего потому, что генератор создаётся заново на каждой итерации и инициализируется одинаковым значением времени. Вынесите создание объекта за пределы цикла — последовательность станет разнообразной.
Входит ли верхняя граница в диапазон СлучайноеЧисло?
Да, диапазон замкнутый: вызов СлучайноеЧисло(1, 10) может вернуть и 1, и 10. Если верхняя граница не нужна, уменьшите её на единицу.
Можно ли получить дробное случайное число?
Напрямую нет — метод возвращает только целые. Сгенерируйте целое в расширенном диапазоне и разделите его: СлучайноеЧисло(0, 1000) / 1000 даст значение от 0 до 1 с тремя знаками.
Как повторить ту же последовательность при отладке?
Передайте в конструктор фиксированное начальное число: Новый ГенераторСлучайныхЧисел(12345). При каждом запуске с этим seed последовательность будет идентичной. После отладки уберите параметр.
Подходит ли генератор для создания паролей?
Нет. ГенераторСлучайныхЧисел выдаёт псевдослучайную, потенциально предсказуемую последовательность. Для паролей, токенов и ключей используйте криптографически стойкие средства, а не встроенный генератор.
Как выбрать случайный элемент справочника?
Сформируйте массив или таблицу ссылок запросом, затем сгенерируйте индекс от 0 до верхней границы коллекции и возьмите элемент по этому индексу. Учитывайте, что для очень больших таблиц предварительная выборка всех ссылок может быть ресурсоёмкой.