copy from sheet1 cols A,B,C,G,F,R,S,T to sheet 2 in colums A,B,C,D,E,F,G,H

后端 未结 5 645
粉色の甜心
粉色の甜心 2021-01-16 02:25

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...

相关标签:
5条回答
  • 2021-01-16 03:01

    Use an array to collect, reshape then return the values.

    A,B,C,G,F,R,S,T to sheet TMP in columns A,B,C,D,E,F,G,H

    Sub Button1_Click()
    
        Dim i As Long, arr as variant
    
        with workSheets("Validation by rules")
    
            'collect
            i= .Cells(.Rows.Count, 1).End(xlUp).Row
            arr = .range(.cells(1,"A"), .cells(i, "T")).value
    
            'reshape part 1
            for i=lbound(arr, 1) to ubound(arr, 1)
                arr(i, 4) = arr(i, 7)
                arr(i, 5) = arr(i, 6)
                arr(i, 6) = arr(i, 18)
                arr(i, 7) = arr(i, 19)
                arr(i, 8) = arr(i, 20)
            next i
    
        end with
    
        'reshape part 2
        redim preserve arr(lbound(arr, 1) to ubound(arr, 1), lbound(arr, 2) to 8)
    
        'return
        workSheets("TMP").cells(1,1).resize(ubound(arr, 1), ubound(arr, 2)) = arr
    
    end sub
    
    0 讨论(0)
  • 2021-01-16 03:06

    I think that this code is self explanatory and easy to modify.

    Sub Button1_Click()
        Application.Calculation = xlCalculationManual
        Application.ScreenUpdating = False
    
        Const CopyDataOnly As Boolean = False
        Dim c As Long
        Dim c1 As String, c2 As String
        Dim source As Range, target As Range
        With Sheets("Validation by rules")
            For c = 0 To 7
                c1 = Split("A,B,C,G,F,R,S,T", ",")(c)
                c2 = Split("A,B,C,D,E,F,G,H", ",")(c)
    
                Set source = .Range(.Cells(1, c1), .Cells(.Rows.Count, c1).End(xlUp))
                Set target = Sheets("TMP").Cells(1, c2)
                If CopyDataOnly Then
                    target.Resize(source.Rows.Count).Value = source.Value
                Else
                    source.Copy target
                End If
            Next
        End With
    
        Application.Calculation = xlCalculationAutomatic
        Application.ScreenUpdating = True
    End Sub
    
    0 讨论(0)
  • 2021-01-16 03:07

    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
    
    0 讨论(0)
  • 2021-01-16 03:21

    If:

    1. Your data is stored in a file on disk (and not in-memory in an open Excel workbook with unsaved changes), and
    2. You only want to copy and paste the data, not formatting

    then you can read the relevant columns in the appropriate order into an ADODB Recordset, and then copy the recordset data into the destination using the CopyFromRecordset method.

    Add a reference to Microsoft ActiveX Data Objects 6.1 Library (via Tools -> References...). There may be versions other than 6.1; choose the highest.

    Then, you can use the following code:

    Dim excelPath As String
    excelPath = "C:\path\to\excel\file.xlsx" ' Replace with the path to the Excel file
    
    Dim connectionString As String
    connectionString = _
        "Provider=Microsoft.ACE.OLEDB.12.0;" & _
        "Data Source=""" & excelPath & """;" & _
        "Extended Properties=""Excel 12.0;HDR=No"""            
    
    Dim sql As String
    sql = _
        "SELECT F1, F2, F3, F4, F6, F18, F19, F20 " & _
        "FROM [Validation by rules$] "
    ' When setting the HDR=No option in the connection string, column names are
    ' automatically generated -- Column A -> F1, Column B -> F2 etc.
    ' If the first row of your column is the column header, you could specify HDR=Yes
    ' and use those column headers in SQL
    
    Dim rs As New ADODB.Recordset
    rs.Open sql, connectionString
    
    Worksheets("TMP").Range("A1").CopyFromRecordset rs
    
    0 讨论(0)
  • 2021-01-16 03:24

    You are not telling the code where to paste with: Sheets("TMP").Paste. You only name the sheet but not the column.

    Also use a loop so you do not need to keep retyping the same thing:

    Sub Button1_Click()
    
    Dim ultima_fila As Long
    Dim columnOrd As Variant
    columnOrd = Array("A", "B", "C", "G", "F", "R", "S", "T")
    
    With Sheets("Validation by rules")
        ultima_fila = .Cells(.Rows.Count, 1).End(xlUp).Row
    
        Dim i As Long
        For i = 1 To 8
            MsgBox .Range(.Cells(1, columnord(i - 1)), .Cells(ultima_fila, columnord(i - 1))).Address
            .Range(.Cells(1, columnord(i - 1)), .Cells(ultima_fila, columnord(i - 1))).Copy Destination:=Sheets("TMP").Cells(1, i)
        Next i
    End With
    
    End Sub
    
    0 讨论(0)
提交回复
热议问题