1

I'm relatively new to VBA and I'm trying to move data from one workbook to another. Specifically I'm trying to move row elements from the first workbook which can be selected using the code I have and move it to Book1 in a specific way. My current goal is to move elements from the 3rd row of the selected file and copy each cell of that row 358 times down column C and then move to the next cell in the row and copy it 358 times as well. The row contains 62 elements which each have to be copied 358 times down a column. The row starts from column 2.

The code I'm using is :

Dim SelectedBook As Workbook
Dim lastRow As String
Dim i As Long
Dim j As Long
Dim n As Long

i = 1
j = 1
n = 2

FileToOpen = Application.GetOpenFilename(Filefilter:="Excel Files (*.xls*), *.xls*", Title:="Select FIles")

Do While n <= 62
    Do While j <= 358

        Set OpenBook = Application.Workbooks.Open(FileToOpen)
        Cells(3, n).Select
        Selection.Copy
        Windows("Book1").Activate
        lastRow = ActiveSheet.Cells(Rows.Count, "C").End(xlUp).Row + 1
        Range("C" & lastRow).Select
        Selection.PasteSpecial
        ActiveSheet.Paste
        j = j + 1
        Loop
        j = 1
        n = n + 1
        Loop

End Sub



The copying happens but because it is happening cell by cell its taking forever due to there being so many cells and the repetition as well. Is there anyway to speed this up in such a way that it can run faster? Any help would be appreciated, thanks in advance!

  • Read https://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba – SJR Jan 10 '23 at 13:14
  • `range("A1").Resize(50).Value=range("B1")` will put the value of B1 in A1:A50 so no need to loop (or copy and paste). – SJR Jan 10 '23 at 13:14
  • Thank you for replying. How does it work between different workbooks the way you have mentioned it? Also won't I need a loop to choose the next row element? – Varun Alankrith Jan 10 '23 at 14:03
  • What is the result? 358 rows of `B3:BK3` or one single column with thousands of rows (cells)? – VBasic2008 Jan 10 '23 at 14:07
  • The result should have the cell C2 in the selected workbook which should be copied 358 times down the column C. After this cell D2 should be copied 358 times in column C under the previously copied data and this should go on till cell BK3. So its pretty much 358x62 elements in column C of Book1. – Varun Alankrith Jan 10 '23 at 14:26

2 Answers2

0

Transpose Headers Repeatedly

  • It will open the selected file and copy the data to a newly created single-worksheet workbook. First, test it as-is and adjust the numbers. If you have a preceding code not posted here, move the lines, creating the workbook, to the beginning of the code and use dwb (and dws) instead of (activating) Windows("Book1").
Sub TransposeHeaders()
     
    Const dReps As Long = 358

    ' Open the source file.
    Dim sPath: sPath = Application.GetOpenFilename( _
        Filefilter:="Excel Files (*.xls*), *.xls*", Title:="Select FIles")
    If VarType(sPath) = vbBoolean Then
        MsgBox "No file selected.", vbExclamation
        Exit Sub
    End If

    ' Write the values from the source worksheet to the source array.
    Dim swb As Workbook: Set swb = Workbooks.Open(sPath)
    Dim sws As Worksheet: Set sws = swb.Worksheets(1) ' adjust e.g. "Sheet1"
    Dim srg As Range
    Set srg = sws.Range("B3", sws.Cells(3, sws.Columns.Count).End(xlToLeft))
    Dim sData(): sData = srg.Value
    
    ' Write the values from the source to the destination array.
    
    Dim scCount As Long: scCount = srg.Columns.Count
    Dim dData(): ReDim dData(1 To scCount * dReps, 1 To 1)
    
    Dim sValue, sc As Long, dRep As Long, dr As Long
    
    For sc = 1 To scCount
        sValue = sData(1, sc)
        For dRep = 1 To dReps
            dr = dr + 1
            dData(dr, 1) = sValue
        Next dRep
    Next sc
    
    ' Write the values from the destination array to the destination range.
    
    ' Add and reference a new single-worksheet workbook.
    Dim dwb As Workbook: Set dwb = Workbooks.Add(xlWBATWorksheet)
    ' Reference its only worksheet.
    Dim dws As Worksheet: Set dws = dwb.Sheets(1) ' the one and only
    ' Reference the destination range.
    Dim dfCell As Range: Set dfCell = dws.Range("C2")
    Dim drg As Range: Set drg = dfCell.Resize(dr)
    ' Write the values from the destination array to the destination range.
    drg.Value = dData
    
    ' Close the source workbook.
    swb.Close SaveChanges:=False

End Sub
VBasic2008
  • 44,888
  • 5
  • 17
  • 28
  • Thank you for responding and helping me understand the code. The only issue I think I might have is that the source workbook from where I'm copying the data, the code you have provided needs me to mention the name of the worksheet. I want to append data from multiple workbooks and the worksheet name is not the same in all of the documents. Is there anyway to deal with different worksheet name problem? – Varun Alankrith Jan 11 '23 at 10:35
  • If you're saying that your solution would have worked, instead of `.Worksheets(1)`, you can use `.Activesheet`. Otherwise, I need more information. – VBasic2008 Jan 11 '23 at 12:50
0

Here's some commented code that should help you understand how to write what you're looking for:

Sub ImportData()
    
    'Import data from StartCol to FinalCol, from CopyRow, a total of CopyTimes
    Const sStartCol As String = "B"
    Const sFinalCol As String = "BK"
    Const lCopyRow As Long = 3
    Const lCopyTimes As Long = 358
    
    'Data imported will be placed in DestCol
    Const sDestCol As String = "C"
    
    'Option to clear previous data before importing
    'Set this to false if you want to keep prior data
    Const bClearPrevious As Boolean = True
    
    'Declare and define destination variables
    Dim wbDest As Workbook:     Set wbDest = ThisWorkbook
    Dim wsDest As Worksheet:    Set wsDest = wbDest.Worksheets("Sheet1")    'Set this to correct worksheet in destination workbook
    
    'Prompt for source file
    Dim sSourceFile As String
    sSourceFile = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*", , "Select Import File", MultiSelect:=False)
    If sSourceFile = "False" Then Exit Sub  'Pressed cancel
    
    'Clear previous results if option is set to true
    If bClearPrevious = True Then wsDest.Range(sDestCol & 2, wsDest.Cells(wsDest.Rows.Count, sDestCol).End(xlUp)).ClearContents
    
    Dim lColIndex As Long
    Dim sSourceSheet as String
    With Workbooks.Open(sSourceFile)
        'Specify correct worksheet for the source workbook names here
        Select Case .Name
            Case "Book1.xlsx": sSourceSheet = "Sheet1"
            Case "Book2.xlsx": sSourceSheet = "Sheet10"
            Case "Book3.xlsx", "Book4.xlsx": sSourceSheet = "DataSheet"
            Case Else: sSourceSheet = "Sheet1" 'If the other cases aren't found, it will default to the Case Else
        End Select
        With .Worksheets(sSourceSheet)
        
            For lColIndex = .Columns(sStartCol).Column To .Columns(sFinalCol).Column
                wsDest.Cells(wsDest.Rows.Count, sDestCol).End(xlUp).Offset(1).Resize(lCopyTimes).Value = .Cells(lCopyRow, lColIndex).Value
            Next lColIndex
            
        End With
        .Close False    'Close source file, don't save changes
    End With
    
End Sub
tigeravatar
  • 26,199
  • 5
  • 30
  • 38
  • Thank you for your help and helping me understand the code. I really appreciate the help but the only issue I have with this is that my aim is to append similar data from multiple workbooks in the manner that I explained. Due to this, the worksheet name is different in athe different workbooks but the data needs to be copied in the same way. Is there a workaround to deal with the name of the worksheet? – Varun Alankrith Jan 11 '23 at 10:47
  • @VarunAlankrith Can do a `Select Case` on the opened workbook name and set the worksheet based on that. Would need more info to be able to accurately assist. – tigeravatar Jan 11 '23 at 14:46