Excel macro 2016 in VBA. Need to copy from 8 separated columns from one sheet to another, in different order. Tried but the Paste is done always in same column A...
Approach via Application.Index
This solution demonstrates relatively unknown possibilities of the Application.Index
function and allows to restructure the whole array set in one single code line thus avoiding further loops or ReDim
(cf. section [3]
):
v = Application.Index(v, _
Application.Evaluate("row(1:" & n - FIRSTROW + 1 & ")"), _
a)
Calling procedure
Option Explicit ' declaration head of your code module
Sub CopyColumns()
' Purpose: copy defined columns to target sheet
Const FIRSTROW& = 2 ' <<~~ change to first data row
Dim i&, j&, n& ' row or column counters
Dim a, v ' variant arrays
Dim ws As Worksheet, ws2 As Worksheet ' declare and set fully qualified references
Set ws = ThisWorkbook.Worksheets("Validation by rules")
Set ws2 = ThisWorkbook.Worksheets("TMP")
' [1] Get data from A1:T{n}
n = ws.Range("A" & Rows.Count).End(xlUp).Row ' find last row number n
v = ws.Range("A" & FIRSTROW & ":T" & n) ' get data cols A:T and omit header row(s)
' [2] build columns array (type Long)
a = buildColAr("A,B,C,F,G,R,S,T") ' << get wanted column numbers via helper function
' [3] Column Filter A,B,C,F,G,R,S,T
v = Application.Index(v, _
Application.Evaluate("row(1:" & n - FIRSTROW + 1 & ")"), _
a) ' column array
' [4] Copy results array to target sheet, e.g. starting at A2
ws2.Range("A2").Offset(0, 0).Resize(UBound(v), UBound(v, 2)) = v
End Sub
Helper function buildColAr()
The helper function only offers some further convenience by translating the column names "A,B,C,F,G,R,S,T"
to a numbered array 1|2|3|6|7|18|19|20 instead of counting the columns by yourself and assigning values directly, e.g. via parameter Array(1,2,3,6,7,18,19,20)
Function buildColAr(ByVal v As Variant) As Variant
' Purpose: return column number array from splitted string values
' Example: a = buildColAr("A,B,C,F,G,R,S,T") returns 1|2|3|6|7|18|19|20
Dim i&, temp
v = Split(v, ","): ReDim temp(LBound(v) To UBound(v))
For i = LBound(v) To UBound(v)
temp(i) = Cells(1, v(i)).Column ' get column numbers
Next i
buildColAr = temp
End Function