Простая альтернатива с использованием расширенных возможностей Application.Index()
Этот подход демонстрирует расширенные возможности реструктуризации функции ► Application.Index()
, чьи строка и аргументы столбца передаются массивами вместо отдельных числовых индексов.
Основная процедура RedoubleCols
Эта процедура выполняется в два этапа:
- присваивает данные 2-димному массиву на основе 1
v
одной строкой кода, - реструктурирует весь массив через
Application.Index
, где строки и аргументы столбца являются массивами, возвращаемыми вспомогательными функциями AllRows()
и RDC()
;результирующий массив записывается обратно в заданную цель.
Sub RedoubleCols(rng As Range, rng2 As Range)
' Purpose: get column values and write them back in pairs
' Param.: 1-rng: source range, 2-rng2: target range
' Method: uses the advanced features of the Application.Index function
Dim v ' declare variant (array)
' [1] get data
v = rng.Value2
' [2] rearrange data by redoubling columns (RDC) and write them to a given target range
rng2.Value2 = Application.Index(v, AllRows(UBound(v)), RDC(UBound(v, 2)))
End Sub
Вспомогательные функции, используемые главной процедурой выше
Function AllRows(ByVal n&) As Variant
' Purpose: create transposed Array(1,2,...n)
Dim i&: ReDim tmp(n - 1)
For i = 0 To n - 1
tmp(i) = i + 1
Next i
AllRows = Application.Transpose(tmp)
End Function
Function RDC(ByVal n&) As Variant()
' Purpose: create Array(1,1,2,2,...n,n) containing pairs of each column number
Dim i&: ReDim tmp(2 * n - 1) ' declare counter and zero based counter array
For i = 0 To n - 1 ' redouble column counters
tmp(i * 2) = i + 1
tmp(i * 2 + 1) = i + 1
Next i
RDC = tmp ' return counter array
End Function
Пример вызова
Необходимыестрока кода в разделе [3]
просто вызывает основную процедуру RedoubleCols
:
RedoubleCols src, target
, где диапазон источника и целевой диапазон могут быть определены в соответствии с вашими потребностями - ср. разделы [1]
и [2]
.
Sub ExampleCall()
' [1] Identify source range
Dim src As Range
Set src = ThisWorkbook.Worksheets("MySheet").Range("A1:D2")
' [2] define any target, e.g. 1 column to the right of source data
Dim target As Range, r&, c&
r = src.Rows.Count: c = src.Columns.Count
Set target = src.Offset(0, c + 1).Resize(r, c * 2) ' reserve double space for columns
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' [3] write redoubled source range columns back to target
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RedoubleCols src, target
End Sub
Рекомендуемая ссылка
Лечение Некоторые особенности функции Application.Index