Vba excel диапазон в одномерный массив

I’m presently populating my array Securities with the following code:

Option Base 1
Securities = Array(Worksheets(3).Range("A8:A" & SymbolCount).Value)

This produces a 2-dimensional array where every address is (1…1,1…N). I want a 1-dimensional array (1…N).

How can I either (a) populate Securities as a 1-dimensional array, or, (b) efficiently strip Securities to a 1-dimensional array (I’m stuck at a with each loop).

asked Oct 4, 2011 at 13:57

Felix's user avatar

I know you already accepted an answer but here is simpler code for you:

If you are grabbing a singe row (with multiple columns) then use:

Securities = application.transpose(application.transpose _
             (Worksheets(3).Range("A8:A" & SymbolCount).Value))

If you are grabbing a single column (with multiple rows) then use:

Securities = application.transpose(Worksheets(3).Range("A8:A" & SymbolCount).Value)

So, basically you just transpose twice for rows and once for columns.

Update:

Large tables might not work for this solution (as noted in the comment below):

I used this solution in a large table, and I found that there is a limitation to this trick: Application.Transpose(Range("D6:D65541").Value) ‘runs without error, but Application.Transpose(Range("D6:D65542").Value) ‘run-time error 13 Type mismatch

Update 2:

Another problem you might have as mentioned in the comments:

If one exceeds 255 characters, the function fails.

It has been a long time since I worked with Excel VBA but this might be a general limitation of accessing the data this way?

answered Oct 4, 2011 at 17:00

Jon49's user avatar

Jon49Jon49

4,3844 gold badges36 silver badges73 bronze badges

9

Sub test2()
    Dim arTmp
    Dim securities()
    Dim counter As Long, i As Long
    arTmp = Range("a1").CurrentRegion
    counter = UBound(arTmp, 1)
    ReDim securities(1 To counter)
    For i = 1 To counter
        securities(i) = arTmp(i, 1)
    Next i
    MsgBox "done"
End Sub

answered Oct 4, 2011 at 14:16

iDevlop's user avatar

iDevlopiDevlop

24.6k11 gold badges89 silver badges147 bronze badges

6

This will reflect the answer iDevlop gave, but I wanted to give you some additional information on what it does.

Dim tmpArray As Variant
Dim Securities As Variant

'Dump the range into a 2D array
tmpArray = Sheets(3).Range("A8:A" & symbolcount).Value

'Resize the 1D array
ReDim Securities(1 To UBound(tmpArray, 1))

'Convert 2D to 1D
For i = 1 To UBound(Securities, 1)
    Securities(i) = tmpArray(i, 1)
Next

Probably the fastest way to get a 1D array from a range is to dump the range into a 2D array and convert it to a 1D array. This is done by declaring a second variant and using ReDim to re-size it to the appropriate size once you dump the range into the first variant (note you don’t need to use Array(), you can do it as I have above, which is more clear).

The you just loop through the 2D array placing each element in the 1D array.

I hope this helps.

answered Oct 6, 2011 at 4:46

Gaijinhunter's user avatar

GaijinhunterGaijinhunter

14.5k4 gold badges50 silver badges57 bronze badges

2

If you read values from a single column into an array as you have it then I do think you will end up with an array that needs to be accessed using array(1, n) syntax.

Alternatively, you can loop through all cells in your data and add them into an array:

Sub ReadIntoArray()
    Dim myArray(), myData As Range, cl As Range, cnt As Integer, i As Integer
    Set myData = Worksheets(3).Range("A8:A" & SymbolCount) //Not sure how you get SymbolCount

    ReDim myArray(myData.Count)

    cnt = 0
    For Each cl In myData
        myArray(cnt) = cl
        cnt = cnt + 1
    Next cl

    For i = 0 To UBound(myArray) //Print out the values in the array as check...
        Debug.Print myArray(i)
    Next i
End Sub

answered Oct 4, 2011 at 14:33

Alex P's user avatar

Alex PAlex P

12.2k5 gold badges51 silver badges69 bronze badges

6

Копирование значений из диапазона ячеек в массив и обратно с помощью VBA Excel. Простейшие примеры обмена значениями между диапазоном и массивом.

Как известно, VBA обрабатывает информацию в массивах значительно быстрее, чем в ячейках рабочего листа Excel. Поэтому, при работе с большими объемами данных, удобнее использовать массивы, чем наблюдать во время выполнения кода за мерцанием изображения на экране или просто смотреть в неизменную картинку, если обновление экрана отключено (Application.ScreenUpdating = False). Здесь обмен значениями между массивом и диапазоном ячеек будет вполне уместен.

Копирование значений из диапазона ячеек в массив

Чтобы скопировать значения из диапазона ячеек в массив, необходимо объявить переменную универсального типа (As Variant) и присвоить ей значения диапазона ячеек с помощью оператора присваивания (=):

Dim a As Variant

a = Range(«A1:C3»)

VBA Excel автоматически преобразует объявленную переменную в двумерный массив, соответствующий размерности диапазона ячеек, в нашем случае в массив — a(1 To 3, 1 To 3), и заполняет его значениями. Нумерация измерений массивов, созданных таким образом, начинается с единицы (1).

Можно, в этом случае, объявить сразу динамический массив, чтобы изначально указать, что эта переменная будет массивом. Так как свойством диапазона ячеек по умолчанию в VBA Excel является значение (Value), его можно в коде явно не указывать, но, при желании, можно и указать. Получится такая конструкция, аналогичная первой:

Dim a() As Variant

a = Range(«A1:C3»).Value

Стоит отметить, что для копирования значений из диапазона ячеек в массив можно использовать только обычную переменную или динамический массив универсального типа (Variant). VBA Excel автоматически преобразовывает их в двумерный массив. Если объявить двумерный массив с указанной заранее размерностью, использовать его не получится, будет сгенерирована ошибка с сообщением: Can’t assign to array (Нельзя назначать массив).

Копирование значений из массива в диапазон ячеек

Значения в диапазон ячеек добавляются из массива с помощью оператора присваивания (=):

Range(«A6:F15») = a

‘или

Range(«A6:F15»).Value = a

‘где a — переменная двумерного массива

Обратите внимание, что вставить значения в диапазон ячеек можно только из двумерного массива. Размерность такого массива может начинаться с нуля (0). Количество элементов в измерениях массива должно совпадать с количеством строк и столбцов в диапазоне ячеек. Если вам нужно вставить значения в одну строку или в один столбец, укажите размерность единственной строки или единственного столбца как (0) или (1 To 1), если вы хотите использовать нумерацию измерений своего массива с единицы. Например, для записи десяти значений из массива в одну строку можно объявить такой массив — massiv(9, 0), или в один столбец — massiv(0, 9).

Для вставки значений в диапазон ячеек из массива идеально подойдет массив, созданный для копирования в него значений из диапазона. В этом случае, данные с рабочего листа Excel переносятся в массив, обрабатываются и, после обработки, вставляются обратно в ту же или другую таблицу на том же или другом рабочем листе.

Обмен значениями между двумя диапазонами

Обмен значениями можно осуществить в VBA Excel не только между массивом и диапазоном, но и между двумя диапазонами одинаковой размерности:

Range(«B2:D6») = Range(«G7:I11»).Value

У диапазона, являющегося источником значений, обязательно должно быть указано свойство Value.

Если диапазон ячеек, принимающий значения, по размеру меньше диапазона-источника, то он будет заполнен полностью:

Range(«B2:D6») = Range(«G5:L13»).Value

Если принимающий диапазон ячеек по размеру больше передающего, то часть его будет заполнена значениями диапазона-источника, а остальные ячейки — значениями #Н/Д:

Range(«B2:D6») = Range(«G7:H9»).Value

Простейшие примеры обмена значениями

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

Пример 1

Заполнение двумерного массива значениями и и их присвоение диапазону ячеек на рабочем листе Excel:

Sub Test1()

Dim a(2, 2) As Variant

a(0, 0) = «телепузик»

a(0, 1) = «журналист»

a(0, 2) = «ящерица»

a(1, 0) = «короед»

a(1, 1) = «утенок»

a(1, 2) = «шмель»

a(2, 0) = 200

a(2, 1) = 300

a(2, 2) = 400

Range(«A1:C3»).Value = a

End Sub

В данном случае переменная массива не обязательно должна быть универсального типа (As Variant), например, если бы в нее записывались только текстовые данные, ее можно было бы объявить как строковую (As String), и все бы работало.

Пример 2

Объявление обычной переменной универсального типа, присвоение ей значений из диапазона ячеек «A1:C3», записанных кодом первого примера, и вставка этих значений из полученного двумерного массива в диапазон «D10:F12»:

Sub Test2()

Dim a As Variant

a = Range(«A1:C3»)

Range(«D10:F12») = a

End Sub

Естественно, указанные диапазоны ячеек расположены на активном листе.

Пример 3

Допустим, на рабочем листе «Лист1» в ячейках «A1:A5» записано количество какого-то товара, а в ячейках «B1:B5» — его цена. Необходимо к этой информации добавить сумму каждого товара, умножив количество на цену, и перенести данные на «Лист2».

Sub Test3()

Dim a As Variant, i As Long

  a = Лист1.Range(«A1:C5»)

    For i = 1 To 5

      a(i, 3) = a(i, 1) _

      * a(i, 2)

    Next

  Лист2.Range(«A1:C5») = a

End Sub

Массив создан сразу с размерностью 5×3 с элементами под суммы. Даже если на первом листе в ячейках «C1:C5» есть какие-то значения, в массиве они будут перезаписаны результатами вычислений.

Копирование значений из массива в массив

Этот пример показывает, как в VBA Excel можно скопировать значения из одного массива в другой:

Sub Test4()

Dim arr1, arr2

    arr1 = Range(«G7:I11»)

    arr2 = arr1

    Range(«B2:D6») = arr2

End Sub


Sub example_1() 'двумерные массивы (на выбор)
Dim x
x = Range("A1", Cells(Rows.Count, 1).End(xlUp)).Value
x = Range("A1", Cells(5, Columns.Count).End(xlToLeft)).Value
x = Range("A1").CurrentRegion.Value
With Sheets("Sheet1")
 x = .Range("A1:D" & .Cells(Rows.Count, 1).End(xlUp).Row).Value
 x = .UsedRange.Value
End With
End Sub
Sub example_2() 'одномерный массив (на выбор), индексация всегда с 1
Dim x
With Range("A1", Cells(Rows.Count, 1).End(xlUp)) 'из столбца
 x = WorksheetFunction.Transpose(.Value)
End With
With WorksheetFunction 'из строки
 x = .Transpose(.Transpose(Range("A1", Cells(1, Columns.Count).End(xlToLeft)).Value))
End With
x = Application.Index(Range("A1", Cells(1, Columns.Count).End(xlToLeft)).Value, 1, 0)
End Sub
Sub example_3() 'одномерный массив без дубликатов из столбца с заголовком
Dim x, i&
i = ActiveSheet.UsedRange.Columns(1).Rows.Count
x = Filter(Evaluate("TRANSPOSE(IF(COUNTIF(OFFSET(a2:a" & i & ",0,0,ROW(1:" & i - 1 & _
 ")),a2:a" & i & ")=1,a2:a" & i & ",CHAR(126)))"), "~", 0)
Range("B1").Resize(UBound(x) + 1).Value = WorksheetFunction.Transpose(x)
End Sub
Sub example_4() 'одномерный массив без дубликатов из столбца без заголовка
Dim x
With ActiveSheet.Cells(1).CurrentRegion.Columns(1)
 x = Filter(.Parent.Evaluate("TRANSPOSE(IF(COUNTIF(OFFSET(" & .Address & ",0,0,ROW(1:" & .Rows.Count & _
 "))," & .Address & ")=1," & .Address & ",CHAR(126)))"), "~", 0)
End With
Range("B1").Resize(UBound(x) + 1).Value = WorksheetFunction.Transpose(x)
End Sub
Sub example_5() 'одномерный массив без пустых значений из столбца
Dim x
With Range("A1", Cells(Rows.Count, 1).End(xlUp))
 x = Split(Replace(Join(Filter(Split("~" & Join(Application.Transpose(.Value), "~|~") & "~", "|"), _
 "~~", False), "|"), "~", ""), "|")
End With
Range("B1").Resize(UBound(x) + 1).Value = WorksheetFunction.Transpose(x)
End Sub
Sub example_6() 'массив из строки (только для англ. алфавита!)
Dim myStr As String, x: myStr = "AsDfghErt"
x = Split(StrConv(myStr, 64), Chr(0))
Range("B1").Resize(UBound(x)).Value = WorksheetFunction.Transpose(x)
End Sub
 

eagl69

Пользователь

Сообщений: 114
Регистрация: 08.09.2016

#1

09.11.2020 11:35:29

Добрый день!

Подскажите как сохранить в массив данные из выделенного диапазона ячеек?
Действия, 1 выделяю диапазон в столбце, 2 запускаю макрос.

Код
Dim spisok As Variant
  Sub proverka()
  spisok = Array(??)
  Debing.Print spisok
End Sub
 

Mershik

Пользователь

Сообщений: 8277
Регистрация: 03.12.2015

#2

09.11.2020 11:38:00

eagl69,  

Код
spisok = Range("A1:B100") 

точнее

Код
 spisok = selection

Изменено: Mershik09.11.2020 11:44:50

Не бойтесь совершенства. Вам его не достичь.

 

Jack Famous

Пользователь

Сообщений: 10848
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#3

09.11.2020 11:54:44

Цитата
eagl69: как сохранить в массив данные из выделенного диапазона ячеек?

здравствуйте
Если диапазон состоит из одной области, то — как показал Mershik, если из нескольких несвязанных между собой областей — то циклом по областям, а если нужно получить «прямоугольный» массив из только видимых ячеек в таблице, то можно использовать шустрый вариант со словарями и сортировкой

отсюда

Изменено: Jack Famous09.11.2020 11:56:04

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

#4

09.11.2020 15:58:37

Цитата
eagl69 написал: Debing.Print spisok

Новый оператор, который выводит в одно Immediate весь масив? :)
Я только такой знаю:

Код
Debug.Print spisok(1, 1)
 

Jack Famous

Пользователь

Сообщений: 10848
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#5

09.11.2020 17:06:21

Цитата
vikttur: Новый оператор, который выводит в одно Immediate весь массив?

приветствую
с многомерным (от 2ух) массивом не выйдет, конечно, но одномерный можно сцепить и вывести через разделитель строки Debug.Print Join(spisok,vbLf)  :D

Изменено: Jack Famous09.11.2020 17:06:36

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

Jack, упор был сделан не на вывод массива, а на новый оператор )

 

Ігор Гончаренко

Пользователь

Сообщений: 13746
Регистрация: 01.01.1970

#7

09.11.2020 21:53:18

Цитата
eagl69 написал:
Записать в массив выделенный диапазон ячеек.
Код
Sub SelectionToArray()
  Dim a
  a = Selection
End Sub

все. выделенный диапазон в массиве а

Изменено: Ігор Гончаренко09.11.2020 21:56:48

Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!

 

Jack Famous

Пользователь

Сообщений: 10848
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

Ігор Гончаренко, это Mershik ещё в #2 показал — какой смысл дублировать?…
ТСу, похоже, либо неинтересно, либо давно ответ получил

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

eagl69

Пользователь

Сообщений: 114
Регистрация: 08.09.2016

#9

10.11.2020 09:44:51

Друзья, спасибо за ответы!

Еще дополнения, допустим у нас 100 строк, я выделил в столбце А ячейки с 20 по 30 получил массив:

Код
a = Selection

далее мне нужен такой же массив но с колонки С, как его создать если у нас выделен диапазон в столбце А? В итоге у меня должно быть 2 массива с данными из одинаковых строк.

Код
Sub SelectionToArray()
Dim a, с
   a = Selection
   с = ?
End Sub

Изменено: eagl6910.11.2020 09:45:41

 

Ігор Гончаренко

Пользователь

Сообщений: 13746
Регистрация: 01.01.1970

#10

10.11.2020 10:00:10

Код
c = selection.offset(0,2)

валите в эту тему все вопросы, что накопились у вас по Excel

Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!

 

eagl69

Пользователь

Сообщений: 114
Регистрация: 08.09.2016

#11

10.11.2020 10:25:47

Большое спасибо за помощь!

0 / 0 / 0

Регистрация: 15.05.2014

Сообщений: 11

1

В одномерный массив записать данные из диапазона ячеек

15.05.2014, 20:16. Показов 4322. Ответов 2


Студворк — интернет-сервис помощи студентам

В одномерный массив записать данные из диапазона ячеек, заключенных между двумя числами, целая часть которых начинается цифрой 1, а заканчивается цифрой 9 (если второго числа нет, то выбрать все ячейки до конца столбца). Полученный массив записать во второй столбец. Найти минимальное значение положительных элементов массива и записать его в ячейку С1.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Sub Массив()
' В макросе используются следующие переменные:
' Аrr - имя массива
' N - размерность массива
' LastStr - номер.последней заполненной ячейки первого столбца
' Ml - номер строки первого максимума
' М2 - номер строки второго максимума
' Sum - сумма элементов массива
' max, пит, i, j - вспомогательные переменные
Dim Arr() As Single, N As Integer, Sum As Single
Dim LastStr As Integer
Dim Ml As Integer, M2 As Integer
Dim max As Single, num As Integer
Dim i As Integer, j As Integer
' Найдем номер последней заполненной строки
i = 1
Do         ' Цикл до тех пор, пока не встретится пустая строка
' Cells(i, 1) - обращение к ячейке в текущей строке i и в 1 колонке
If CStr(Cells(i, 1)) = Empty Then
LastStr = i - 1
Exit Do   ' Выход из цикла
Else
i = i + 1   ' Увеличение номера строки на 1
End If
Loop
' Поиск первого максимума
For i = 2 To LastStr - 1
If Cells(i -1,1)< Cells(i, 1) And Cells(i, 1) > Cells(i +1,1)_
Then Ml = i: Exit For
Next i
' Если первый максимум является предпоследним числом в столбце
If LastStr - Ml = 1 Then M2 = Ml + 2
' Поиск второго максимума
For i = Ml + 1 To LastStr - 1
If Cells(i - 1, 1) < CeIIs(i, 1) And Cells(i, 1) > Cells(i + 1, 1) Then
M2 = i: Exit For
Else
M2 = LastStr + 1   ' если второго максимума нет
End If
Next i
' Запись в массив
N = 0
Fori = Ml + 1 ToM2-l
N = N + 1
ReDim Preserve Arr(N)    ' выделить место в памяти
Arr(N) = Cells(i, 1)
Sum = Sum + Arr(N)
Next i
' Сортировка массива
For i = 1 To N - 1
max = Arr(i): num = i
Forj = i + IToN
If Arr(j) > max Then max = Arr(j): num = j
Nextj
Arr(num) = Arr(i)
Arr(i) = max
Nexti
' Запись на рабочий лист
For i = 1 То N
Cells(i, 2) = Arr(i)
Nexti
Cells(l, 3) = Sum / N
End Sub



0



Like this post? Please share to your friends:
  • Vba excel диалоговое окно выбора файла
  • Vba excel диалоговое окно ввода данных
  • Vba excel диалог да нет
  • Vba excel диалог выбора файла
  • Vba excel диалог выбора папки