Получить одномерный массив значений напрямую через Evaluate - PullRequest
2 голосов
/ 23 октября 2019

Справочная информация:

В моем прежнем вопросе я настроил способ получения диапазона рабочих таблиц в массиве, чтобы выполнить циклчерез них.

Я хотел бы сделать еще один шаг и вместо этого получить массив значений, например: {"Val1", "Val2", "Val3"}

Код:

Чтобы работать со следующими кодами, вы можете воспроизвести то, чего я пытаюсь достичь, создав группу листов с именами «Лист1», «Лист2» ​​и т. Д. И т. Д. Затем введите модуль:

Sub Test

Dim lwr As Long: lwr = 2
Dim uppr As Long: uppr = 5

'Options will follow here *

End sub

Так я бы получил массив листов с динамическими переменными строк. Вы увидите, что он извлечет массив имен листов, которые мы могли бы использовать, например: For Each ws In ThisWorkbook.Sheets(shts):

Dim shts As Variant: shts = Application.Evaluate("TRANSPOSE(""Sheet""&ROW(" & lwr & ":" & uppr & "))")

Теперь, однако, я хотел бы взять массив значений непосредственно из этих листов. Вот как я могу получить интересующие меня ячейки (одну и ту же ячейку на всех листах), например, A1:

Dim shts As Variant: shts = Application.Evaluate("TRANSPOSE(""Sheet""&ROW(" & lwr & ":" & uppr & ")&""!A1"")")

Ссылки на ячейки довольно бессмысленны, но один пример, с которым это будет работатьэто когда все значения будут числовыми, и я хочу иметь возможность суммировать их следующим образом:

Debug.Print Application.Evaluate("SUM(" & Join(shts, ",") & ")")

Однако я хотел бы перетащить их в переменную массива напрямую (без циклического перебора листов), независимо от того, числовыеили не числовые, например: {5,3,"Val1",6}

Проблема:

Я пробовал несколько вещей среди INDIRECT, VALUEи даже ADDRESS, чтобы поместить диапазон в именованный диапазон первым. Все попытки бесполезны, поскольку ни одна из этих функций не работает с массивами. Например:

Dim vals As Variant: vals = Application.Evaluate("TRANSPOSE(INDIRECT(""Sheet""&ROW(" & lwr & ":" & uppr & ")&""!A1""))")

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

Вопрос:

Любой способ успешно получить одномерный массив непосредственно через оценку? Или то, что я ищу, просто невозможно, что в этом случае возвращает меня к циклу, чтобы получить мой массив.

1 Ответ

2 голосов
/ 23 октября 2019

В конце концов используя CHOOSE в .Evaluate сделал это для меня:

Dim lwr As Long: lwr = 2
Dim uppr As Long: uppr = 5

Dim shts As Variant: shts = Application.Evaluate("TRANSPOSE(""Sheet""&ROW(" & lwr & ":" & uppr & ")&""!A1"")")
Dim vals As Variant: vals = Application.Evaluate("TRANSPOSE(CHOOSE(ROW(1:" & uppr - lwr + 1 & ")," & Join(shts, ",") & "))")

Что я сделал здесь:

  • Получить нижнюю границу> lwr
  • Получить верхнюю границу> uppr
  • Получить массив диапазонов через .Evaluate с этими границами
  • Получить массив значений через Join предыдущего массивав .Evaluate, который использует CHOOSE.

Если, например, Sheet2!A1 = 4, Sheet3!A1 = 5, Sheet4!A1 = 1, Sheet5!A1 = Test

Приведенный выше код вернет следующее значение для vals:

enter image description here

Как видно, он содержит одномерный массив с вариантами значений. Именно то, что я хотел. Теперь я могу получить динамический массив, извлекающий значения из разных листов за один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...