Как сгенерировать последовательность случайных чисел без повторений в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При решении задач автоматизации часто возникает необходимость получить набор случайных значений, в которых отсутствуют дубли. Стандартный генератор случайных чисел ГенераторСлучайныхЧисел выдает значения независимо, поэтому повторения неизбежны. Давайте разберем, как правильно реализовать алгоритм, гарантирующий уникальность элементов.

Метод 1: Проверка на вхождение (метод исключений)

Этот способ интуитивно понятен: мы пытаемся получить случайное число и проверяем, есть ли оно уже в нашем массиве результатов. Если число уже содержится в массиве, генератор «выбрасывает» его и запрашивает новое значение, пока не получит уникальное.

Разберем реализацию этого метода по шагам:

  1. Создаем пустой Массив.
  2. Инициируем ГенераторСлучайныхЧисел.
  3. Используем цикл Пока для заполнения, пока количество элементов не достигнет требуемого значения.
  4. Внутри цикла используем метод Найти для проверки наличия сгенерированного числа в массиве.

МойМассив = Новый Массив();
Генератор = Новый ГенераторСлучайныхЧисел();
Пока МойМассив.Количество() < 20 Цикл
    Число = Генератор.СлучайноеЧисло(0, 30);
    Если МойМассив.Найти(Число) = Неопределено Тогда
        МойМассив.Добавить(Число);
    КонецЕсли;
КонецЦикла;

Этот метод хорошо работает для небольших выборок, однако при необходимости выбрать почти все числа из диапазона он может стать медленным из-за большого количества итераций поиска.

Метод 2: Алгоритм «перетасовки» (оптимизированный)

Если нам нужно получить уникальную последовательность быстро, рассмотрим более профессиональный подход. Мы заранее создаем массив всех возможных чисел (наш «пул»), а затем по очереди вытаскиваем из него случайные элементы. Выбранный элемент сразу удаляется из пула, что автоматически гарантирует отсутствие повторов.

Посмотрим на пример кода:


// Допустим, нам нужно 20 чисел из диапазона 0-30
ПределЧисел = 30;
ДлинаМассива = 20;

ИсходныйМассив = Новый Массив();
Для й = 0 По ПределЧисел Цикл
    ИсходныйМассив.Добавить(й);
КонецЦикла;

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

Для й = 1 По ДлинаМассива Цикл
    // Выбираем случайный индекс из оставшихся элементов
    Индекс = ГСЧ.СлучайноеЧисло(0, ИсходныйМассив.Количество() - 1);
    Результат.Добавить(ИсходныйМассив[Индекс]);
    // Удаляем элемент, чтобы он больше не выпал
    ИсходныйМассив.Удалить(Индекс);
КонецЦикла;

Этот метод значительно эффективнее, так как мы точно знаем количество операций: оно равно размеру необходимой выборки. Мы не тратим время на бесконечные проверки и повторные генерации чисел.

Важные рекомендации по стилю и производительности

При написании кода в 1С важно придерживаться стандартов разработки, чтобы ваши модули были читаемыми и поддерживаемыми.

Если задача становится комплексной и требует генерации очень больших массивов случайных данных, возможно, стоит рассмотреть перенос логики на сторону СУБД с использованием функций NEWID() или RAND() в запросах, однако для большинства прикладных задач 1С описанные выше алгоритмы будут работать идеально.

← На главную