А есть способ отдельно записать ряд значений для первого "столбца" двумерного массива (1, 2, 3, 4), и отдельно для второго (10, 20, 30, 40)?
Такого способа не припомню. Но знаю, что решаема обратная задача - из двухмерного массива вырезать (тоже в виде массива) целиком отдельные строки или столбцы: [vba]
Код
Sub io3()
Dim SuperMassiv(1 To 4, 1 To 2) Dim arrCol1, arrCol2 Dim arrRow3, arrRow4 Dim i, j
А есть способ отдельно записать ряд значений для первого "столбца" двумерного массива (1, 2, 3, 4), и отдельно для второго (10, 20, 30, 40)?
Такого способа не припомню. Но знаю, что решаема обратная задача - из двухмерного массива вырезать (тоже в виде массива) целиком отдельные строки или столбцы: [vba]
Код
Sub io3()
Dim SuperMassiv(1 To 4, 1 To 2) Dim arrCol1, arrCol2 Dim arrRow3, arrRow4 Dim i, j
Gustav, есть ещё copymemory для этого дела - но не освоил А экселевский index медленный - быстрее в цикле переложить. Как-то замеряли, можете повторить.
Если использовать не в Экселе - то я бы вероятно заполнял небольшие прямо явно в коде, большие - парсингом текста с списком. Перекладывая в цикле по строкам/массиву_строк.
Gustav, есть ещё copymemory для этого дела - но не освоил А экселевский index медленный - быстрее в цикле переложить. Как-то замеряли, можете повторить.
Если использовать не в Экселе - то я бы вероятно заполнял небольшие прямо явно в коде, большие - парсингом текста с списком. Перекладывая в цикле по строкам/массиву_строк.Hugo
Протестировал, и обалдел! a1 26,1406 a2 0,0156 [vba]
Код
Sub qq() Dim arr, a1(), a2(), a3() Dim i&, j&, t! arr = Range("A1").CurrentRegion.Value t = Timer ReDim a1(1 To UBound(arr)) For i = 1 To UBound(arr) a1(i) = Application.Index(arr, i, 0) Next Debug.Print "a1 " & Format(Timer - t, "0.0000") t = Timer
ReDim a2(1 To UBound(arr)) For i = 1 To UBound(arr) ReDim a3(1 To UBound(arr, 2)) For j = 1 To UBound(arr, 2) a3(j) = arr(i, j) Next a2(i) = a3
Next Debug.Print "a2 " & Format(Timer - t, "0.0000")
End Sub
[/vba]
Протестировал, и обалдел! a1 26,1406 a2 0,0156 [vba]
Код
Sub qq() Dim arr, a1(), a2(), a3() Dim i&, j&, t! arr = Range("A1").CurrentRegion.Value t = Timer ReDim a1(1 To UBound(arr)) For i = 1 To UBound(arr) a1(i) = Application.Index(arr, i, 0) Next Debug.Print "a1 " & Format(Timer - t, "0.0000") t = Timer
ReDim a2(1 To UBound(arr)) For i = 1 To UBound(arr) ReDim a3(1 To UBound(arr, 2)) For j = 1 To UBound(arr, 2) a3(j) = arr(i, j) Next a2(i) = a3
Next Debug.Print "a2 " & Format(Timer - t, "0.0000")
Надежда всё ещё живёт, поэтому снова напомню, что тема посвящена живому общению и обмену опытом =)
Пока разбираюсь с вариантом RAN, хотел бы кинуть затравку. Я слышал, что есть массивы, где по ключу подбираются уникальные записи. Давайте рассмотрим также подробно и классно, как Gustav и SkyPro делали в этой теме?
Надежда всё ещё живёт, поэтому снова напомню, что тема посвящена живому общению и обмену опытом =)
Пока разбираюсь с вариантом RAN, хотел бы кинуть затравку. Я слышал, что есть массивы, где по ключу подбираются уникальные записи. Давайте рассмотрим также подробно и классно, как Gustav и SkyPro делали в этой теме?Rioran
Роман, Москва, voronov_rv@mail.ru Яндекс-Деньги: 41001312674279
Сообщение отредактировал Rioran - Среда, 11.06.2014, 14:39
Public Declare Sub CopyMemory Lib _ "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, _ ByVal Length As Long)
Sub testCopyMemory() Dim i& Dim arFrom1#(1000), arFrom2#(1000), arTo#(1000, 1 To 2) ' обьявили 3 массива _ 2 откуда будем копировать (одномерные) _ 1 куда будем копировать (двумерный) Randomize ' заполним случайными числами с запятой (мы ведь массивы дабл обьявили) For i = LBound(arFrom1) To UBound(arFrom1) arFrom1(i) = Rnd arFrom2(i) = Rnd Next 'выведем на лист для последующей проверки [a2].Resize(UBound(arFrom1)) = Application.Transpose(arFrom1) [b2].Resize(UBound(arFrom2)) = Application.Transpose(arFrom2)
'А теперь копируем два одномерных массива в один двумерный ' Куда, Откуда, Длинна (в байтах) CopyMemory arTo(0, 1), arFrom1(0), 1000 * 8 CopyMemory arTo(0, 2), arFrom2(0), 1000 * 8 'Так как у нас даблы, то один дабл весит 8 байт. Соответственно умножаем на количество элементов.
'и выводим на лист для сверки :-) [d2].Resize(UBound(arTo), 2) = arTo End Sub
[/vba]
Точно так же из двумерного можно разложить на одномерные.
По CopyMemory накидал пример: [vba]
Код
Public Declare Sub CopyMemory Lib _ "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, _ ByVal Length As Long)
Sub testCopyMemory() Dim i& Dim arFrom1#(1000), arFrom2#(1000), arTo#(1000, 1 To 2) ' обьявили 3 массива _ 2 откуда будем копировать (одномерные) _ 1 куда будем копировать (двумерный) Randomize ' заполним случайными числами с запятой (мы ведь массивы дабл обьявили) For i = LBound(arFrom1) To UBound(arFrom1) arFrom1(i) = Rnd arFrom2(i) = Rnd Next 'выведем на лист для последующей проверки [a2].Resize(UBound(arFrom1)) = Application.Transpose(arFrom1) [b2].Resize(UBound(arFrom2)) = Application.Transpose(arFrom2)
'А теперь копируем два одномерных массива в один двумерный ' Куда, Откуда, Длинна (в байтах) CopyMemory arTo(0, 1), arFrom1(0), 1000 * 8 CopyMemory arTo(0, 2), arFrom2(0), 1000 * 8 'Так как у нас даблы, то один дабл весит 8 байт. Соответственно умножаем на количество элементов.
'и выводим на лист для сверки :-) [d2].Resize(UBound(arTo), 2) = arTo End Sub
[/vba]
Точно так же из двумерного можно разложить на одномерные.SkyPro
skypro1111@gmail.com
Сообщение отредактировал SkyPro - Среда, 11.06.2014, 15:22
Так если берём с листа неизвестно что (variant) - определить длину нужно перебором? В общем я узнал давно - но не применял, т.к. такие гарантированные числа бывают редко. Попробовал воткнуть в пример empty и строку - в результате перенеслось всё в нулях... Видать к массивам вариант нужны другие числа...
Так если берём с листа неизвестно что (variant) - определить длину нужно перебором? В общем я узнал давно - но не применял, т.к. такие гарантированные числа бывают редко. Попробовал воткнуть в пример empty и строку - в результате перенеслось всё в нулях... Видать к массивам вариант нужны другие числа...Hugo
Каждый элемент массива Variant может содержать не только данные, но и ссылки на размещённые в других участках памяти объекты и массивы (понятно-дело, на то он и Variant). При копировании массива подобным "пиратским" способом VBA остаётся в неведении, о копировании ссылки на объект, следовательно указываемый участок памяти в любой момент может оказаться очищен. Таким образом применять CopyMemory можно только для данных фиксированной длины. Ну или отслеживать все ссылки и дублировать их вручную.
Каждый элемент массива Variant может содержать не только данные, но и ссылки на размещённые в других участках памяти объекты и массивы (понятно-дело, на то он и Variant). При копировании массива подобным "пиратским" способом VBA остаётся в неведении, о копировании ссылки на объект, следовательно указываемый участок памяти в любой момент может оказаться очищен. Таким образом применять CopyMemory можно только для данных фиксированной длины. Ну или отслеживать все ссылки и дублировать их вручную. Формуляр
Excel 2003 EN, 2013 EN
Сообщение отредактировал Формуляр - Понедельник, 16.06.2014, 10:52
Т.е. CopyMemory в работе с данными листа практически неприменим... Или сперва взять данные в массив, его циклом перебрать и преобразовать что можно/нужно в определённый тип в другой массив, затем уже CopyMemory, что уже и не нужно.
Т.е. CopyMemory в работе с данными листа практически неприменим... Или сперва взять данные в массив, его циклом перебрать и преобразовать что можно/нужно в определённый тип в другой массив, затем уже CopyMemory, что уже и не нужно.Hugo