Сравнение массивов Vba Excel
Обновлено: 21.11.2024
У меня есть четыре цикла для заполнения и сравнения двух двумерных массивов, а затем добавления результатов в первый массив перед записью на активный рабочий лист. Хотите знать, есть ли у кого-нибудь более чистый альтернативный или более элегантный метод? Он работает как есть, но еще не проверял его на больших массивах!
\$\begingroup\$ Я думал, что более 1 измерения будут классифицироваться как многомерные? Новичок в предметной области! \$\конечная группа\$
\$\begingroup\$ То, что вы называете 3-м и 4-м измерениями, обычно называют столбцами, хотя строки могут быть более подходящими (поскольку вы можете изменить размер только последнего измерения массива). Трехмерный массив будет Arr(от 1 до 100, от 1 до 100, от 1 до 100) \$\endgroup\$
\$\begingroup\$ @IainSaunders Я рекомендую посмотреть Введение в Excel VBA, часть 25 — Массивы. Несмотря на то, что я использую VBA уже 15 лет, я многому научился, просмотрев всю серию из 45 эпизодов. \$\конечная группа\$
\$\begingroup\$ @ThomasInzina Большое спасибо за рекомендацию, я просмотрел весь урок и узнал несколько новых трюков. Думаю, последую вашему примеру и когда-нибудь тоже посмотрю всю серию. \$\конечная группа\$
4 ответа 4
Это более чистый подход к заполнению массивов.
\$\begingroup\$ Спасибо, мне, безусловно, нравится внешний вид метода, но я хотел бы сохранить использование функции lastRow без изменений, поскольку переменные, которые ее используют, повторно используются в коде, и я думаю, что это дает некоторые ясность происходящего. \$\конечная группа\$
\$\begingroup\$ Почему вы снова использовали Worksheets(1).Range внутри скобок? Разве это не будет работать так же? firstArray = Worksheets(1).Range("C1",("A" & firstArrayLastRow)) \$\endgroup\$
\$\begingroup\$ Я выделяю весь диапазон одной строкой. В вашем пути нет ничего плохого. Я планирую сделать полный обзор сегодня вечером. Читая ваш код, кажется, что вы обновляете только одно значение. \$\конечная группа\$
\$\begingroup\$ Это в основном для тренировочного прогона (хотя в настоящее время у него есть практическое применение), и я хотел бы его расширить. Сохранение всего массива и манипулирование им перед записью обратно на рабочий лист должно дать некоторый прирост производительности по сравнению с текущим методом записи формул сопоставления индексов на рабочий лист и вычисления. \$\конечная группа\$
Позвольте мне прояснить несколько неправильных представлений в вашем коде:
Это не совсем так. Помните: ActiveSheet — это то, что можно очень легко изменить. В большинстве случаев не стоит полагаться на ActiveSheet, когда вы можете ему помочь. Я предполагаю, что вы всегда хотите получить последнюю строку в столбце 1 для первого листа в вашей книге.
кстати, в следующей строке также содержится недоразумение, которое следует исправить той же идеей:
Важно помнить, что EXCEL поддерживает не только рабочие листы. Вы не можете полагаться на то, что Таблицы содержат только рабочие листы. По возможности вместо Sheets или ActiveSheet следует использовать коллекцию Worksheets:
Точно так же Range("A1") относится к активному листу, а Worksheets(..) относится к ActiveWorkbook . Для простоты я проигнорировал это в представленном здесь коде, но вы можете не полагаться на эти неявные ссылки. Должно быть понятно, как вы можете это сделать :)
Как упоминалось выше, использование ActiveSheet может укусить вас за спину (особенно в случае продолжительных макросов). Вместо этого вы должны обратиться к Worksheets(1) . Я бы даже зашел так далеко, чтобы обернуть ваши циклы for в With -Block, чтобы уменьшить выделение:
Рекомендация With-block также применяется для следующего вложенного цикла For.
Это может быть записано более кратко с помощью Exit For (что также делает комментарий излишним)
VBAX Regular Зарегистрирован, февраль 2017 г. Сообщений 7
Excel VBA — сравнение двух массивов
У меня есть два массива. Как выполнить перекрестную проверку с использованием простого массива (строка 4) и многомерного массива (строки 8–17) с отображением результатов в двух столбцах от C21 до D25, как показано на рисунке?
Модератор VBAX Sage Присоединился к нам с октября 2006 г. Место рядом с Columbia Сообщений 7 737 Местоположение
Я не вижу корреляции между результатом и данными.
Я ожидаю, что учащийся сделает домашнее задание и найдет все ошибки, которые я оставил.
VBAX Guru присоединился к нам в декабре 2010 г. Местоположение "Где я кладу голову, так это дома" :D Сообщений 2633
выполнить приведенный ниже код при выборе листа.
ПОЖАЛУЙСТА, НЕ ПИШИТЕ В ЛС; ВМЕСТО ОТКРЫВАЙТЕ ТЕМУ.
2) Загрузка файла(ов)
Перейти к дополнительным параметрам/Вложения – Управление вложениями/Добавить файлы/Выбрать файлы/Выбрать файл(ы) (можно выбрать несколько файлов, удерживая нажатой клавишу Ctrl ключ) / Загрузить файлы / Готово
Заменить специфические/чувствительные/конфиденциальные данные компании. Включите столько строк, листов и т. д. в загруженную книгу, чтобы помощники могли визуализировать данные и структуру таблицы. Помощникам не нужна вся рабочая книга.
3) Проверка кодов
всегда создавайте резервные копии файлов перед проверкой кодов.
4) Пометка темы как решенной
в инструментах темы (в правом верхнем углу, над первым сообщением)
VBAX Regular Зарегистрирован, февраль 2017 г. Сообщений 7
Спасибо за ответ. Два массива работают нормально, однако отображаемый результат находится в одном и том же столбце, т.е. в столбце A. Как сделать из него два столбца, как показано на рисунке?
Модератор VBAX Sage Присоединился к нам с октября 2006 г. Место рядом с Columbia Сообщений 7 737 Местоположение
Это довольно сложно, так как два столбца результатов, показанных на картинке, не имеют никакого отношения к данным, показанным на картинке.
В данных нет ни одной строки с двумя собаками, а также ни одной строки с рыбой, кошкой и курицей.
Нет столбцов данных только с собакой, но ни с одним другим, однако есть столбец со всеми четырьмя.
Как найти пустую ячейку в результатах?
Я ожидаю, что учащийся сделает домашнее задание и найдет все ошибки, которые я оставил.
VBAX Regular Зарегистрирован, февраль 2017 г. Сообщений 7
VBAX Guru присоединился к нам в декабре 2010 г. Местоположение "Где я кладу голову, так это дома" :D Сообщений 2633
загрузите свою книгу, чтобы мы могли видеть, где должны отображаться результаты.
вообще-то я не понимаю, почему так важно помещать результаты в две (может быть, 3, 4, в будущем?) колонки.
ПОЖАЛУЙСТА, НЕ ПИШИТЕ В ЛС; ВМЕСТО ОТКРЫВАЙТЕ ТЕМУ.
2) Загрузка файла(ов)
Перейти к дополнительным параметрам/Вложения – Управление вложениями/Добавить файлы/Выбрать файлы/Выбрать файл(ы) (можно выбрать несколько файлов, удерживая нажатой клавишу Ctrl ключ) / Загрузить файлы / Готово
Заменить специфические/чувствительные/конфиденциальные данные компании. Включите столько строк, листов и т. д. в загруженную книгу, чтобы помощники могли визуализировать данные и структуру таблицы. Помощникам не нужна вся рабочая книга.
3) Проверка кодов
всегда создавайте резервные копии файлов перед проверкой кодов.
4) Пометка темы как решенной
в инструментах темы (в правом верхнем углу, над первым сообщением)
VBAX Regular Зарегистрирован, февраль 2017 г. Сообщений 7
Сравнение двух массивов Excel VBA
Изначально для простоты я заменил числа рыбой и морским коньком. Тип данных буквенно-цифровой.
Что касается количества столбцов, это зависит от выбора поля списка, ввода текстового поля, поля со списком и т. д. Например, если пользователь выбирает число 4 из списка, это представляет 4 столбца. Данные будут отображаться в 4 столбцах. Надеюсь, это поможет.
Мне нужно сравнить 2 массива, которые могут быть разной длины, а затем вернуть значения, которые находятся в одном массиве, а не в другом. Вы можете помочь?
Измените это по мере необходимости.
______________________________________________
В мире существует 10 типов людей. Те, кто понимает двоичный код, и те, кто не понимает.
Почему Хэллоуин и Рождество — это одно и то же? Потому что 31 октября = 25 декабря.
_______________________________________________
Спасибо. это возвращает значения, которые находятся в обоих массивах.
Я хочу, чтобы он возвращал полный набор значений. Значения, которые находятся как в my_array, так и в my_array1.
Привет, gpatten, подпрограмма вернет значения, общие для обоих массивов. вы говорите, что просто хотите вернуть полный список элементов в обоих массивах (т.е. добавить массивы вместе?)
______________________________________________
В мире существует 10 типов людей. Те, кто понимает двоичный код, и те, кто не понимает.
Почему Хэллоуин и Рождество — это одно и то же? Потому что 31 октября = 25 декабря.
_______________________________________________
Если вы просто хотите добавить оба массива, то это поможет -
______________________________________________
В мире существует 10 типов людей. Те, кто понимает двоичный код, и те, кто не понимает.
Почему Хэллоуин и Рождество — это одно и то же? Потому что 31 октября = 25 декабря.
_______________________________________________
Спасибо, Гер.
Это возвращает все значения и те, которые есть в обоих массивах дважды. Я хочу, чтобы каждое значение возвращалось только один раз.
Гпаттен, честно говоря, заголовок вашей темы был о сравнении двух массивов динамической длины. В итоге мы добавили два массива динамической длины и идентифицировали уникальные значения в этом массиве (или удалили дубликаты), что полностью отличается от названия темы. Я изменю это. но, пожалуйста, не забудьте указать всю проблему с самого начала. В этом случае пример от вас, показывающий 2 массива и ожидаемый результат, прояснил бы это.
В любом случае, я значительно переработал код: он просто складывает два массива вместе, а затем сохраняет каждый уникальный элемент в результирующем массиве
В демонстрационных целях я отправляю этот массив обратно на активный рабочий лист, чтобы показать вам его содержимое.
Сообщите мне, верно ли это, и я изменю название темы, чтобы оно было более информативным.
Надеюсь, это поможет.
Гер
______________________________________________
В мире существует 10 типов людей. Те, кто понимает двоичный код, и те, кто не понимает.
Почему Хэллоуин и Рождество — это одно и то же? Потому что 31 октября = 25 декабря.
_______________________________________________
Спасибо, Гер. Вы правы, надо было создать новую тему. Теперь я знаю, что в следующий раз.
Код лучше, хотя и не работает должным образом. В примере вывод должен быть (0,1,2,5,6,7,8,9,10). Полный набор записей без дубликатов.
Только возврат (1,2,5,6,7,8,9).
Небольшие изменения в выходном коде Гера.
[vba] 'отправить результаты на рабочий лист.
ActiveSheet.Range(Cells(1, 1), Cells(UBound(result) + 1, 1)) = WorksheetFunction.Transpose(result)
[/vba]
[h4] Ура
Энди [/h4]
Спасибо, Энди и Гер. Теперь это работает!
Спасибо, что обратили внимание на Энди, я должен был проверить это должным образом.
______________________________________________
В мире существует 10 типов людей. Те, кто понимает двоичный код, и те, кто не понимает.
Существует несколько способов поиска строки в массиве — в зависимости от того, является ли массив одномерным или многомерным.
Поиск в одномерном массиве
Для поиска значения в одномерном массиве можно использовать функцию фильтра.
Синтаксис параметра «Фильтр» выглядит следующим образом
Фильтр(Исходный массив, Сопоставить как строку, [Включить как логическое значение], [Сравнить как vbCompareMethod])
Исходный массив и Match as String являются обязательными, а Include as Boolean и Compare as vbCompareMethod являются необязательными. Если они не включены, для них устанавливаются значения True и vbCompareBinary соответственно.
Найти значения, соответствующие фильтру
strName() = Array ("Боб Смит", "Джон Дэвис", "Фред Джонс", "Стив Дженкинс", "Боб Уильямс")
Второй массив будет содержать значения, найденные фильтром. Если ваши значения LBound и UBound не равны -1, то массиву удалось найти значение, которое вы искали.
Вы также можете увидеть, сколько раз текст появляется в исходном массиве.
strName() = Array ("Боб Смит", "Джон Дэвис", "Фред Джонс", "Стив Дженкинс", "Боб Уильямс")
'если вычесть LBound из значений UBound и добавить 1, мы получим количество раз, которое текст появляется
Найти значения, которые НЕ соответствуют фильтру
Опция [Включить как логическое значение] позволяет узнать, сколько значений в вашем массиве НЕ соответствуют вашему фильтру
strName() = Array ("Боб Смит", "Джон Дэвис", "Фред Джонс", "Стив Дженкинс", "Боб Уильямс")
'если вычесть LBound из значений UBound и добавить 1, мы получим количество раз, которое текст появляется
поэтому мы изменили эту строку:
Использование этой строки в коде вернет все имена, НЕ совпадающие с именем «Боб».
Фильтры с учетом регистра
Вы обнаружите, что фильтр по умолчанию чувствителен к регистру. Это верно для всех функций VBA. Если вы хотите искать текст, не чувствительный к регистру, вам нужно немного изменить свой код.
Добавление vbTextCompare в строку фильтра позволит вашему коду находить «bob» или «Bob». Если это опущено, VBA по умолчанию использует vbBinaryCompare, который будет искать только данные, которые являются ТОЧНЫМ совпадением. Обратите внимание, что в приведенном выше примере мы не включили аргумент [Включить как логическое значение], поэтому предполагается значение True.
Вариант сравнения текста
Кроме того, вы можете добавить текст Option Compare Text в верхнюю часть вашего модуля — это сделает все функции, которые вы пишете в этом конкретном модуле, нечувствительными к регистру.
Программирование VBA стало проще
Прекратите искать код VBA в Интернете. Узнайте больше об AutoMacro — конструкторе кода VBA, который позволяет новичкам создавать процедуры с нуля с минимальными знаниями в области кодирования и множеством функций, позволяющих сэкономить время для всех пользователей!
Использование цикла для поиска в массиве
Использование цикла немного сложнее, чем использование функции фильтра. Мы можем создать функцию, которая будет перебирать все значения в массиве.
Читайте также: