Excel VBA: диапазон до строкового массива в 1 шаг
Я знаю, что вы можете легко взять ряд ячеек и пощекотать их в Variant Array, но я хочу работать со строковым массивом (потому что он одномерный и занимает меньше памяти, чем массив Variant).
Есть ли способ автоматического преобразования диапазона в массив строк?
В настоящее время я использую функцию, которая будет принимать диапазон и сохранять значения в альтернативном массиве, а затем преобразовать массив вариантов в массив строк. Он работает хорошо, но я ищу способ перейти непосредственно из диапазона в строковый массив. Любая помощь будет принята с благодарностью.
Function RangeToArray(ByVal my_range As Range) As String()
Dim vArray As Variant
Dim sArray() As String
Dim i As Long
vArray = my_range.Value
ReDim sArray(1 To UBound(vArray))
For i = 1 To UBound(vArray)
sArray(i) = vArray(i, 1)
Next
RangeToArray = sArray()
End Function
UPDATE:
Похоже, что нет способа пропустить шаг метаданных в переменный массив, прежде чем преобразовать его в одномерный массив строк. Позор, если это правда (даже если это не требует больших усилий, мне нравится ультра-оптимизировать, поэтому я надеялся, что есть способ пропустить этот шаг). Я закрою вопрос через несколько дней, если решение не представится. Спасибо за полезные комментарии, ребята!
UPDATE2:
Ответ идет к Симону, который прилагал большие усилия (так же сделал и все остальные), и предельно указал на то, что действительно невозможно перейти от диапазона к массиву строк за один выстрел. Спасибо, всем.
Ответы
Ответ 1
Как насчет...
Public Function RangeToStringArray(theRange As Excel.Range) As String()
' Get values into a variant array
Dim variantValues As Variant
variantValues = theRange.Value
' Set up a string array for them
Dim stringValues() As String
ReDim stringValues(1 To UBound(variantValues, 1), 1 To UBound(variantValues, 2))
' Put them in there!
Dim columnCounter As Long, rowCounter As Long
For rowCounter = UBound(variantValues, 1) To 1 Step -1
For columnCounter = UBound(variantValues, 2) To 1 Step -1
stringValues(rowCounter, columnCounter) = CStr(variantValues(rowCounter, columnCounter))
Next columnCounter
Next rowCounter
' Return the string array
RangeToStringArray = stringValues
End Function
Ответ 2
Фактически вы можете перейти непосредственно из диапазона в массив, используя функции Split, Join и разделитель, не содержащийся в тексте.
Предполагая, что вы уже присвоили 1D диапазон значений как SrcRange
Dim Array() As String: Array = Split(Join(Application.Transpose(SrcRange), "#"), "#")
Ответ 3
Function RangeToStringArray(myRange as range) as String()
ReDim strArray(myRange.Cells.Count - 1) As String
Dim idx As Long
Dim c As Range
For Each c In myRange
Set strArray(idx) = c.Text
idx = idx + 1
Next c
RangeToStringArray = strArray
End sub
Ответ 4
Если вы не возражаете изменить содержимое буфера обмена, выполните следующие действия:
-
КОПИРОВАТЬ диапазон в буфер обмена с помощью метода Копировать:
MyTargetRange.Copy
-
Скопируйте содержимое из буфера обмена в строковую переменную (выполните поиск на этом сайте или в другом месте для функций для передачи строк в/из буфера обмена).
-
SPLIT строку в массив вариантов:
MyStringArray = Split(MyClipboardText, vbCrLf)
-
ДОПОЛНИТЕЛЬНО: массив будет иметь один дополнительный пустой элемент, потому что в конце текста, который вы только что скопировали в буфер обмена, всегда есть дополнительный Return (vbCrLf). Для удаления просто измените размер массива:
Redim Preserve MyStringArray(Ubound(MyStringArray) - 1)
Очень просто и быстро!!!
Недостатки заключаются в том, что буфер обмена может измениться, когда вы в наименьшей степени ожидаете его (во время перерасчета), и что он создает только массивы строк (не числа или другие типы числовых значений).
Это было бы ЧРЕЗВЫЧАЙНО ПОМОЩЬ, если вы работаете с множеством повторяющихся функций (тысяч), которые используют одни и те же данные (тысячи точек данных). При первом вызове функции выполняйте все промежуточные вычисления в диапазонах данных, которые вам нужны, но сохраните результаты в статических переменных. Также сохраните строчную копию ваших диапазонов ввода через буфер обмена. С каждым последующим вызовом вашей функции преобразуйте диапазоны ввода в текст, снова через буфер обмена и сравните с сохраненной копией. Если они одинаковы, вы можете обойти все предварительные расчеты.
Ответ 5
Именованные диапазоны, используемые в VBA, уже являются массивами. Поэтому сначала сделайте диапазон в именованный диапазон, затем обратитесь к нему и удалите именованный диапазон.
Например:
ThisWorkbook.Names.Add Name:="test_array", RefersTo:=Sheet1.Range("A4:B10")
a = Sheet1.Range("test_array")
ThisWorkbook.Names("test_array").Delete