Случайная сортировка диапазона медленно
Автор: Александр Хохлов   
22.01.2011 20:28

Случайная сортировка данных диапазона.

Постановка задачи.

Нужно разработать и реализовать на VBA алгоритм сортировки строк заданного диапазона случайным образом. Пусть меются 5 строк столбца A, в результате выполнения макроса мы должны получить 5 строк столбца B, взятых их A случайным образом.

Действие 1. Алгоритм обработки массивов.

Задача сводится к обработке двух линейных массивов заданного размера. A - исходный массив и B - массив, содержащий результат сортировки.

Основные моменты алгоритма случайной сортировки:

  • Обращаемся к случайной ячейке массива A и записываем полученное значение в первую (очередную) ячейку массива B;
  • При выборе случайных элементов из A нельзя допускать повторов, исключая уже использованные ячейки.
  • Однажды выбранные элементы из A будем "исключать", записывая в них (-1);
  • Операции выполняются в цикле нужное количество раз (5), постепенно заполняя массив B случайными неповторяющимися элементами из A.

Если представить себе состояние массивов A и B после двух прокруток предложенного алгоритма, то результат может быть таким:

В конечном итоге, массив A будет содержать только (-1), массив B будет полностью заполнен исходными значениями из A в случайном порядке. Недостаток такого алгоритма заключается в большом количестве "пустых" генераций случайного числа при поиске ячеек массива A, значение которых > -1. Это приводит к медленной работе программы при большом количестве элементов массива A. Кроме того, если содержимое A заранее неизвестно, то нужно будет определяться с "меткой" для использованных ячеек, так как значение "метки" должно быть уникально до начала работы алгоритма.

Действие 2. Реализация. Процедура Sort().

Открываем редактор кода и реализуем процедуру сортировки на VBA.

Public Sub Sort()
 'исходные диапазоны данных
 Dim myRangeA, myRangeB As Range
 Set myRangeA = Range("A1:A5")
 Set myRangeB = Range("B1:B5")
 'случайное число 1..5
 Dim MyRndValue as Byte
 'вспомогательные массивы A и B
 Dim A(5) As Variant
 Dim B(5) As Variant
 'заполнение массива А строками столбца A
 For i = 1 To myRangeA.Rows.Count
  A(i) = myRangeA.Rows(i).Value
 Next i
 'заполнение массива B данными из А в случайном порядке
 For i = 1 To myRangeB.Rows.Count
 'генерация случайного числа из диапазона 1..5 до тех пор пока
 'значение ячейки не будет A(MyRndValue) >= 0
   Do
     MyRndValue = Int((5 * Rnd) + 1)
   Loop Until A(MyRndValue) >= 0
   'запись полученного значения в B
   B(i) = A(MyRndValue)
   'исключаем из A использованное значение, записав (-1)
   A(MyRndValue) = -1
   'заполнение строк столбца B значениями из массива B
   myRangeB.Rows(i) = B(i)
 Next i
End Sub

Действие 3. Проверка работоспособности.

"Вешаем" полученный макрос на кнопку или запускаем вручную на вкладке Разработчик - Код - Макросы.

 

Добавить комментарий

Защитный код
Обновить