Выборка из массива excel vba
Функция RandomRowsFromArray предназначена для выборки из двумерного массива случайных строк.
К примеру, исходный массив (таблица) имеет размер 1000*20 (1000 строк, и 20 столбцов)
Нам требуется выбрать из этой таблицы, случайным образом, 50 строк
(получив, таким образом, таблицу размерами 50*20)
Кроме того, необходимо, чтобы при каждом новом запуске макроса,
в выборку попадали новые строки.
В прикреплённом к статье файле вы найдете пример такого макроса:
Код функции RandomRowsFromArray:
Комментарии
Спасибо за ответ, Игорь!
Да там в коде нет никаких изменений, только добавил Do Loop Until
Немного погуглив, я пришел к выводу, что моя проблема в самой Randomize, точнее в том, что она генерирует числа, зависящие от предыдущего результата. Оттого и зацикливание макроса до удовлетворения условию, заданному Until, приводит к одинаковым результатам.
Тогда вопрос - возможно ли усложнить (или заменить) функцию Randomize на что-то более непредсказуемое?
можно ли пристроить как-то класс RandomNumberGenerator? (Оставляя при этом смысл вашего макроса - выборка случайных строк из массива)
По вашему описанию, не видя кода, сложно что-либо понять
Тем более, ваш вопрос не относится к теме статьи
Обратитесь на форумы по Excel - там помогут быстро и бесплатно.
Приветствую, Игорь (и посетители сего полезного ресурса).
Спасибо вам, что делитесь своей работой!
Я злостный гуманитарий, поэтому возможно (скорее всего) я сделал что-то не правильно.
Имеется массив, к примеру, в 300 уникальных строк ([a1:f300]), в каждой ячейке числа в диапазоне от 1 до 45. Там же на листе формула (СЧЁТЕСЛИ), считающая значения во вновь сформированном массиве (к примеру в 25 строк).
ЗАДАЧА: зациклить макрос генератор, пока СЧЁТЕСЛИ не достигнет определенного значения.
КАК Я ЭТО РЕШИЛ (на самом деле, знакомый индус подсказал): зацикливание Do (до считывания массива) Loop Until сссылка на ячейку со СЧЁТЕСЛИ и нужное значение.
ПРОБЛЕМА: цикл как бы работает, т.е. цикл останавливается, когда в Untill получает нужное значение, но при повторном запуске, некоторого времени работы цикла, такая конструкция выдает в newarr построчно одинаковые массивы. то есть поначалу рэндом как бы есть, а потом его кагбы нет. Макрос вроде бы работает, но выдает одинаковый результат.
Надеюсь на помощь. Намастэ!
n& = coll(i): For j = LBound(arr, 2) To UBound(arr, 2): newarr(i, j) = arr(n, j): Next j
Добрый день появился вопрос, ": " двоеточие и пробел это вместо переноса строки?
Хорошо, я понимаю.
Благодарю за быстрый ответ! : )
А если на заказ, то сколько это будет стоить?
Rokinso, увы, помочь не смогу.
Тут надо совсем другой макрос делать, и ваш файл смотреть, чтобы понять, что и как.
Ну и должны быть где-то настройки, - вероятность выпадения того или иного предмета.
Сделать можно, - но только под заказ (работы много)
Если хотите бесплатно, - обращайтесь на форумы по Excel.
Хочу сделать, чтобы приоритет можно было указывать в отдельном столбце - для каждой строки своё значение.
Чтобы Юзер (Ведущий) мог сам изменять приоритет выпадения каждого предмета по ходу игры.
Пожалуйста, подскажите, как увеличить вероятность попадания в выборку определённой строки?
Я делаю генератор предметов, которые игрок может найти в тайниках.
Мне нужно, чтобы спички он мог найти в 30% случаев обыска, а вот артефакты - лишь в 1% случаев.
Дублирование строк для увеличения вероятности выпадения - очень неудобно, когда уникальных строк более 300-та. ))
-
P.S. Уважаемый Администратор, ОГРОМНОЕ Вам СПАСИБО за то, что делитесь с нами плодами своего бесценного труда и, к тому же, снабжаете свои коды подробными описаниями, чтобы даже такой стопроцентный гуманитарий как я смог быстро вникнуть в экселевские премудрости и сосредоточиться, главным образом, на творческом процессе разработки игры.
Низкий Вам поклон. : )
Доброго, а как сделать так чтобы он не копировал данные ячейки а вырезал из исходной?
Подскажи плиз как догда можно зделать чтобы интервал поиска ячеек arr = worksheets("Название листа").[a1:e20].Value, можно было вводит на листе excel, тот который будет унас размешен массив.
Славься о мудрейший, офигенно полезный макрос!
чтобы он считывал данные не стекушего листа а стого который нам нужен
как данный макрос превратить так чтобы он считывал данные не стекушего листа а стого который нам нужен при этом чтобы учитывал пустые ячейки и не считывал их
Объявление одномерных (линейных) статических массивов в VBA Excel:
В первом случае публичный массив содержит 10 элементов от 0 до 9 (нижний индекс по умолчанию — 0, верхний индекс — 9), а во втором случае локальный массив содержит 9 элементов от 1 до 9.
По умолчанию VBA Excel считает в массивах нижним индексом нуль, но, при желании, можно сделать нижним индексом по умолчанию единицу, добавив в самом начале модуля объявление «Option Base 1». Вместо верхнего индекса можно использовать переменную.
Многомерные массивы
Объявление многомерных статических массивов в VBA Excel аналогично объявлению одномерных массивов, но с добавлением размерностей дополнительных измерений через запятую:
Третий массив состоит из 10000 элементов — 10×10×10×10.
Динамические массивы
Динамические массивы в VBA Excel, в отличие от статических, объявляются без указания размерности:
Такие массивы используются, когда заранее неизвестна размерность, которая определяется в процессе выполнения программы. Когда нужная размерность массива становится известна, она в VBA Excel переопределяется с помощью оператора ReDim:
Переопределять размерность динамических массивов в процессе работы программы можно неоднократно, как по количеству измерений, так и по количеству элементов в измерении.
При переопределении размерности динамических массивов в VBA Excel теряются значения их элементов. Чтобы сохранить значения, используйте оператор Preserve:
Обратите внимание!Переопределить с оператором Preserve можно только последнюю размерность динамического массива. Это недоработка разработчиков, которая сохранилась и в VBA Excel 2016. Без оператора Preserve можно переопределить все размерности.
Максимальный размер
Размер массива – это произведение длин всех его измерений. Он представляет собой общее количество элементов, содержащихся в данный момент в массиве.
По информации с сайта разработчиков, максимальный размер массивов зависит от операционной системы и доступного объема памяти. Использование массивов, размер которых превышает объем доступной оперативной памяти компьютера, приводит к снижению скорости, поскольку системе необходимо выполнять запись данных и чтение с диска.
Использование массивов
Приведу два примера, где не обойтись без массивов.
1. Как известно, функция Split возвращает одномерный массив подстрок, извлеченных из первоначальной строки с разделителями. Эти данные присваиваются заранее объявленному строковому (As String) одномерному динамическому массиву. Размерность устанавливается автоматически в зависимости от количества подстрок.
2. Данные в массивах обрабатываются значительно быстрее, чем в ячейках рабочего листа. Построчную обработку информации в таблице Excel можно наблюдать визуально по мерцаниям экрана, если его обновление (Application.ScreenUpdating) не отключено. Чтобы ускорить работу кода, можно значения из диапазона ячеек предварительно загрузить в динамический массив с помощью оператора присваивания (=). Размерность массива установится автоматически. После обработки данных в массиве кодом VBA полученные результаты выгружаются обратно на рабочий лист Excel. Обратите внимание, что загрузить значения в диапазон ячеек рабочего листа через оператор присваивания (=) можно только из двумерного массива.
Функции Array, LBound, UBound
Функция Array
Функция Array возвращает массив элементов типа Variant из первоначального списка элементов, перечисленных через запятую. Нумерация элементов в массиве начинается с нуля. Обратиться к элементу массива можно, указав в скобках его номер (индекс).
Чтобы скопировать значения из диапазона ячеек в массив, необходимо объявить переменную универсального типа (As Variant) и присвоить ей значения диапазона ячеек с помощью оператора присваивания (=):
VBA Excel автоматически преобразует объявленную переменную в двумерный массив, соответствующий размерности диапазона ячеек, в нашем случае в массив — a(1 To 3, 1 To 3), и заполняет его значениями. Нумерация измерений массивов, созданных таким образом, начинается с единицы (1).
Можно, в этом случае, объявить сразу динамический массив, чтобы изначально указать, что эта переменная будет массивом. Так как свойством диапазона ячеек по-умолчанию в VBA Excel является значение (Value), его можно в коде явно не указывать, но, при желании, можно и указать. Получится такая конструкция, аналогичная первой:
Копирование значений из массива в диапазон ячеек
Значения в диапазон ячеек добавляются из массива с помощью оператора присваивания (=):
Обратите внимание, что вставить значения в диапазон ячеек можно только из двумерного массива. Размерность такого массива может начинаться с нуля (0). Количество элементов в измерениях массива должно совпадать с количеством строк и столбцов в диапазоне ячеек. Если вам нужно вставить значения в одну строку или в один столбец, укажите размерность единственной строки или единственного столбца как (0) или (1 To 1), если вы хотите использовать нумерацию измерений своего массива с единицы. Например, для записи десяти значений из массива в одну строку можно объявить такой массив — massiv(9, 0), или в один столбец — massiv(0, 9).
Для вставки значений в диапазон ячеек из массива идеально подойдет массив, созданный для копирования в него значений из диапазона. В этом случае, данные с рабочего листа Excel переносятся в массив, обрабатываются и, после обработки, вставляются обратно в ту же или другую таблицу на том же или другом рабочем листе.
Простейшие примеры обмена значениями
Эти примеры составлены так, чтобы вам не пришлось совершать лишних действий, просто скопируйте их в свой модуль любой книги Excel с поддержкой макросов и запустите по-очереди на выполнение.
Пример 1
Заполнение двумерного массива значениями и и их присвоение диапазону ячеек на рабочем листе Excel:
Оптимизация условий отбора данных с таблицы по разным критериям
Всем привет. Есть таблица-классификатор, в которой досконально расклассифицирован совершенно.
Разделение таблицы по разным листам
Здравствуйте, нашел здесь на форуме макрос (сам в ВБА я ноль), который таблицу по заданному.
Поиск данных по добавляющимся листам и динамическим диапазоном
Есть книга, в которой каждый месяц будет добавлять по одному листу. И есть в книге лист с отчетом.
Из одной таблицы разнести данные по разным листам
Здравствуйте. Есть таблица "отгрузки" с данными. Необходимо разнести из нее соответствующие данные.
Помощь в написании контрольных, курсовых и дипломных работ здесь Или я после поля такой тупой, или что-то другое. Опять я не понял. Спасибо - это ооочень хорошо и вкусно , но меня больше интересует или работает.
я отписал,что все круто и все работает,видимо не прошла связь) Спасибо.
Добавлено через 3 минуты
Есть еще пару идей, но нужно их правильно сформулировать. По программе возьму период 4-5 дней жесткого тестирования.
Не было времени вникать, да и лениво.
Но вот наш совместный вариант - чуть попаразитировал где мог, остальное кажется упростил
Если выгружаемых данных тысячи строк - то к выгрузке тоже можно прикрутить массив, будет быстрее.
Если не много - то прикручивать лениво To Hugo. Я считал, что если Set ntDict = Nothing , тогда ntDict.RemoveAll (именно в такой ситуации) лишнее. Убиваем ведь сразу, гуманно. А вот то, что считал, что суб дикт, как составной, убивается паралельно - явно ошибка. Теперь посмотрел в Locals. Да, нужен еще один патрон. Вообще-то я не уверен, что необходимо сперва очищать словарь - но лишним не будет, и времени много не займёт.
Можно посмотреть, что там будет с памятью с очисткой и без неё - но как-нибудь в другой раз
Может быть кто-то точно знает, как правильно? Я не проверял, просто побегал по глобусу. Замеры не нашел, но везде, при выходах из процедур, просто Set . = Nothing . Это же рекомендует и Patrick G. Matthews , в т.ч.
Да, опытным путём эффекта от RemoveAll не обнаружено!
Значит можно сэкономить миллисекунду.
Добавлено через 8 минут
Хотя померил время на 100к строк - если не делать RemoveAll, то почти столько же времени тратится на nothing.
Массив: Вывод на экран массива согласно условию
var a:arrayof integer; i,j,x,n,p,k:integer; begin write('n='); readln(n); for i:=1 to n do.
Вычислить сумму элементов массива согласно условию
В одномерном массиве А(10) вычислить сумму элементов массива, отличающихся от максимального на.
Разбить массив на два массива согласно условию
Нужна помощь с лабораторной. Дан массив А, состоящий из 2N элементов. Разбейте его на массивы В и С.
Сформировать матрицу из исходного одномерного массива согласно условию
не получается, кто разбирается, помогите с решением
Считать данные из файла в два массива согласно условию
В файле исходных данных содержится одномерный массив A(2n). Написать, отладить и протестировать.
Написать программу, переставляющую элементы массива согласно условию
Вот задачка, надо в универ, на C++: Даны действительные числа A,A,A. A. Переставить числа в.
Читайте также: