Transposing a Range (Multiple Columns and Rows) to a Single Row

Vertigoe

New Member
Joined
Jul 26, 2017
Messages
9
Hi all,

I am trying to transpose multiple data from multiple columns into a single row in a new workbook. My original data simplifies to what is seen below.

Before
Col1 | Col2 | Col3
1 | 2 | 3
1 | 2 | 3
1 | 2 | 3
After
Row1 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 3 So far, I am able to grab Column 1 and do that correctly, however I cannot seem to grab Column 2.

Also, when I try to add in a LastRow lookup, to run the macro again and have it paste to Row 2, it send my Row 1 to Row 43, anyone know what might be causing this?

Here is the code I have so far.

Code:
Sub PartSum()
'  Dim workbook import
    Dim SummarySheet As Worksheet
    Dim FolderPath As String
    Dim SelectedFiles() As Variant
    Dim NRow As Long
    Dim NColumn As Long
    Dim Filename As String
    Dim NFile As Long
    Dim Workbk As Workbook
    Dim SourceRange As Range
    Dim DestRange As Range
    Dim Worksht As Worksheet
    Dim C As Range
        
    'Creating and naming worksheets
    Set Worksht = ThisWorkbook.Sheets("Part Summary")
    'Worksht.Name = Application.InputBox(prompt:="Type Worksheet Name, Include Date of Test", Title:="Worksheet Title", Default:="Enter Here", Type:=2)
      
    'Create a new workbook and set a variable to the first sheet.
    Set SummarySheet = Worksht
    
    'Modify this folder path to point to the files to be used.
    Dim vFileToOpen As Variant
    Dim strCurDir As String


    'Keep Original Dir
    strCurDir = CurDir
    
    'Open the file dialog box and filter on Excel files, allowing multiple files to be selected.
    SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.xl*), *.xl*", MultiSelect:=True)
    
    'NRow keeps track of where to insert new rows in the destination workbook.
    NRow = 1
    NColumn = 0
    
    'Loop through the list of returned file names
    For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
    
        'Set FileName to be the current workbook file name to open.
        Filename = SelectedFiles(NFile)
        
        'Open the current workbook.
        Set Workbk = Workbooks.Open(Filename)
                       
        'Set the source range to be D through O.
        'Modify this range for your workbooks. It can span multiple rows.
        Set SourceRange = Workbk.Worksheets(1).UsedRange.Range("D7:D19")
                
        'Set the destination range to start at column B and be the same size as the source range.
        Dim LastRow As Long
        LastRow = ThisWorkbook.Sheets("Part Summary").Cells(Rows.Count).End(xlUp).Row + 1
        
        Set DestRange = ThisWorkbook.Sheets("Part Summary").Range("C4" & LastRow)
        
        'Copy over the values from the source to the destination.
        For Each C In SourceRange
            
            If Len(C.Value) > 0 Then
                C.Copy
                DestRange.PasteSpecial Paste:=xlPasteValues, Transpose:=False
                Set DestRange = DestRange.Offset(0, 1)
            End If
        Next C
        
        Application.CutCopyMode = False
                           
        'Increase NRow so that we know where to copy data next.
        'NRow = NRow + DestRange.Rows.Count + 1
        'NColumn = NColumn + DestRange.Columns.Count + 1
        
        'Close the source workbook without saving changes.
        Workbk.Close savechanges:=False
        
    Next NFile
    
' End by resetting to last/original Dir
ChDir strCurDir


End Sub
 

Excel Facts

What is the last column in Excel?
Excel columns run from A to Z, AA to AZ, AAA to XFD. The last column is XFD.
See if this will work for you. I didn't test it, so post back if it hiccups.

Code:
Sub PartSum2()
'  Dim workbook import
    Dim SummarySheet As Worksheet
    Dim FolderPath As String
    Dim SelectedFiles() As Variant
    Dim NRow As Long
    Dim NColumn As Long
    Dim Filename As String
    Dim NFile As Long
    Dim Workbk As Workbook
    'Dim SourceRange As Range
    'Dim DestRange As Range
    Dim Worksht As Worksheet
    Dim c As Range
    Dim vFileToOpen As Variant
    Dim strCurDir As String, i As Long
    'Creating and naming worksheets
    Set Worksht = ThisWorkbook.Sheets("Part Summary")
    'Worksht.Name = Application.InputBox(prompt:="Type Worksheet Name, Include Date of Test", Title:="Worksheet Title", Default:="Enter Here", Type:=2)
      
    'Create a new workbook and set a variable to the first sheet.
    Set SummarySheet = Worksht
    
    'Modify this folder path to point to the files to be used.
    

    'Keep Original Dir
    strCurDir = CurDir
    
    'Open the file dialog box and filter on Excel files, allowing multiple files to be selected.
    SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.xl*), *.xl*", MultiSelect:=True)
    
    'NRow keeps track of where to insert new rows in the destination workbook.
    NRow = 1
    NColumn = 0
    'Loop through the list of returned file names
    For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
        'Set FileName to be the current workbook file name to open.
        Filename = SelectedFiles(NFile)
        'Open the current workbook.
        Set Workbk = Workbooks.Open(Filename)
                       
        'Set the source range to be D through O.
        'Modify this range for your workbooks. It can span multiple rows.
        'Set SourceRange = Workbk.Worksheets(1).UsedRange.Range("D7:D19")
        'Set the destination range to start at column B and be the same size as the source range.
        'Dim LastRow As Long
        'LastRow = ThisWorkbook.Sheets("Part Summary").Cells(Rows.Count).End(xlUp).Row + 1
        'Set DestRange = ThisWorkbook.Sheets("Part Summary").Range("C4" & LastRow)
                'Copy over the values from the source to the destination.
        For i = 4 To 15
            With Sheets("Part Summary")
                For Each c In .Range(.Cells(7, i), .Cells(Rows.Count, i).End(xlUp))
                    If Len(c.Value) > 0 Then
                        c.Copy
                            If Sheets("Part Summary").Range("C4") = "" Then
                                Sheets("Part Summary").Range("C4").PasteSpecial xlPasteValues, Transpose:=True
                            Else
                                Sheets("Part Summary").Cells(4, Columns.Count).End(xlToLeft).Offset(, 1). _
                                PasteSpecial Paste:=xlPasteValues, Transpose:=True
                            End If
                    End If
                Next c
            End With
        Next
        Application.CutCopyMode = False
        'Increase NRow so that we know where to copy data next.
        'NRow = NRow + DestRange.Rows.Count + 1
        'NColumn = NColumn + DestRange.Columns.Count + 1
        'Close the source workbook without saving changes.
        Workbk.Close savechanges:=False
    Next NFile
' End by resetting to last/original Dir
ChDir strCurDir
End Sub
 
Upvote 0
Hi JLGWhiz,

Thank you for the help, however your provided code isn't quite doing what I'd like it to. It is currently taking from the Part Summary sheet (the destination sheet) and placing information already in there into a new location.

I have the code where I want it to be for the most part, however I am still having a transposing problem.

As before, I am still looking for the following:

Before
Col1 | Col2 | Col3
1 | 2 | 3
1 | 2 | 3
1 | 2 | 3

After

Row1 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 3


However all I am getting is:

Before
Col1 | Col2 | Col3
1 | 2 | 3
1 | 2 | 3
1 | 2 | 3

After

Row1 1 | 2 | 3 | 1 | 2 | 3 | 1 | 2 | 3
 
Upvote 0
Hi JLGWhiz,

Thank you for the help, however your provided code isn't quite doing what I'd like it to. It is currently taking from the Part Summary sheet (the destination sheet) and placing information already in there into a new location.

I have the code where I want it to be for the most part, however I am still having a transposing problem.

As before, I am still looking for the following:

Before
Col1 | Col2 | Col3
1 | 2 | 3
1 | 2 | 3
1 | 2 | 3

After

Row1 1 | 1 | 1 | 2 | 2 | 2 | 3 | 3 | 3


However all I am getting is:

Before
Col1 | Col2 | Col3
1 | 2 | 3
1 | 2 | 3
1 | 2 | 3

After

Row1 1 | 2 | 3 | 1 | 2 | 3 | 1 | 2 | 3
 
Upvote 0
I have no idea what I was thinking last night when I posted that code. But it is difficult to try and edit someone else's code and keep their syntax intact. Anyhow, try this modified version.

Code:
Sub PartSum2()
'  Dim workbook import
    Dim SummarySheet As Worksheet
    Dim FolderPath As String
    Dim SelectedFiles() As Variant
    Dim NRow As Long
    Dim NColumn As Long
    Dim Filename As String
    Dim NFile As Long
    Dim Workbk As Workbook
    'Dim SourceRange As Range
    'Dim DestRange As Range
    Dim Worksht As Worksheet
    Dim c As Range
    Dim vFileToOpen As Variant
    Dim strCurDir As String, i As Long
    'Creating and naming worksheets
    Set Worksht = ThisWorkbook.Sheets("Part Summary")
    'Worksht.Name = Application.InputBox(prompt:="Type Worksheet Name, Include Date of Test", Title:="Worksheet Title", Default:="Enter Here", Type:=2)
      
    'Create a new workbook and set a variable to the first sheet.
    Set SummarySheet = Worksht
    
    'Modify this folder path to point to the files to be used.
    
    'Keep Original Dir
    strCurDir = CurDir
    
    'Open the file dialog box and filter on Excel files, allowing multiple files to be selected.
    SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.xl*), *.xl*", MultiSelect:=True)
    
    'NRow keeps track of where to insert new rows in the destination workbook.
    NRow = 1
    NColumn = 0
    'Loop through the list of returned file names
    For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
        'Set FileName to be the current workbook file name to open.
        Filename = SelectedFiles(NFile)
        'Open the current workbook.
        Set Workbk = Workbooks.Open(Filename)
                       
        'Set the source range to be D through O.
        'Modify this range for your workbooks. It can span multiple rows.
        .Set SourceRange = Workbk.Worksheets(1).UsedRange.Range("D7:D19")
        'Set the destination range to start at column B and be the same size as the source range.
        'Dim LastRow As Long
        'LastRow = ThisWorkbook.Sheets("Part Summary").Cells(Rows.Count).End(xlUp).Row + 1
        'Set DestRange = ThisWorkbook.Sheets("Part Summary").Range("C4" & LastRow)
                'Copy over the values from the source to the destination.
        For i = 4 To 15
            With Workbk.Sheets(1)
                .Range(.Cells(7, i), .Cells(Rows.Count, i).End(xlUp)).Copy
                            If Sheets("Part Summary").Range("C4") = "" Then
                                Sheets("Part Summary").Range("C4").PasteSpecial xlPasteValues, Transpose:=True
                            Else
                                Sheets("Part Summary").Cells(4, Columns.Count).End(xlToLeft).Offset(, 1). _
                                PasteSpecial Paste:=xlPasteValues, Transpose:=True
                            End If
                    End If
                Next c
            End With
        Next
        Application.CutCopyMode = False
        'Increase NRow so that we know where to copy data next.
        'NRow = NRow + DestRange.Rows.Count + 1
        'NColumn = NColumn + DestRange.Columns.Count + 1
        'Close the source workbook without saving changes.
        Workbk.Close savechanges:=False
    Next NFile
' End by resetting to last/original Dir
ChDir strCurDir
End Sub
 
Upvote 0
Disregard post 5, try this.

Code:
Sub PartSum2()
'  Dim workbook import
    Dim SummarySheet As Worksheet
    Dim FolderPath As String
    Dim SelectedFiles() As Variant
    Dim NRow As Long
    Dim NColumn As Long
    Dim Filename As String
    Dim NFile As Long
    Dim Workbk As Workbook
    'Dim SourceRange As Range
    'Dim DestRange As Range
    Dim Worksht As Worksheet
    Dim c As Range
    Dim vFileToOpen As Variant
    Dim strCurDir As String, i As Long
    'Creating and naming worksheets
    Set Worksht = ThisWorkbook.Sheets("Part Summary")
    'Worksht.Name = Application.InputBox(prompt:="Type Worksheet Name, Include Date of Test", Title:="Worksheet Title", Default:="Enter Here", Type:=2)
      
    'Create a new workbook and set a variable to the first sheet.
    Set SummarySheet = Worksht
    
    'Modify this folder path to point to the files to be used.
    
    'Keep Original Dir
    strCurDir = CurDir
    
    'Open the file dialog box and filter on Excel files, allowing multiple files to be selected.
    SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.xl*), *.xl*", MultiSelect:=True)
    
    'NRow keeps track of where to insert new rows in the destination workbook.
    NRow = 1
    NColumn = 0
    'Loop through the list of returned file names
    For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
        'Set FileName to be the current workbook file name to open.
        Filename = SelectedFiles(NFile)
        'Open the current workbook.
        Set Workbk = Workbooks.Open(Filename)
                       
        'Set the source range to be D through O.
        'Modify this range for your workbooks. It can span multiple rows.
        'Set SourceRange = Workbk.Worksheets(1).UsedRange.Range("D7:D19")
        'Set the destination range to start at column B and be the same size as the source range.
        'Dim LastRow As Long
        'LastRow = ThisWorkbook.Sheets("Part Summary").Cells(Rows.Count).End(xlUp).Row + 1
        'Set DestRange = ThisWorkbook.Sheets("Part Summary").Range("C4" & LastRow)
                'Copy over the values from the source to the destination.
        For i = 4 To 15
            With Workbk.Sheets(1)
                .Range(.Cells(7, i), .Cells(Rows.Count, i).End(xlUp)).Copy
                    If Sheets("Part Summary").Range("C4") = "" Then
                        Sheets("Part Summary").Range("C4").PasteSpecial xlPasteValues, Transpose:=True
                    Else
                        Sheets("Part Summary").Cells(4, Columns.Count).End(xlToLeft).Offset(, 1). _
                        PasteSpecial Paste:=xlPasteValues, Transpose:=True
                    End If
            End With
        Next
        Application.CutCopyMode = False
        'Increase NRow so that we know where to copy data next.
        'NRow = NRow + DestRange.Rows.Count + 1
        'NColumn = NColumn + DestRange.Columns.Count + 1
        'Close the source workbook without saving changes.
        Workbk.Close savechanges:=False
    Next NFile
' End by resetting to last/original Dir
ChDir strCurDir
End Sub

If this don't work, I will just redo the whole thing.
 
Upvote 0
I took a little more time with this to eliminate the superfluous code and comments. This code should allow you to select one or more files to be opened by placing the file names and their paths in an array variable named SelectedFiles. The For NFile loop will then open each of the SelecteFiles workbooks in turn and the destination row number will increment on each iteration of that loop, allowing the copied columns of each workbook the be one destination row per workbook. The For i loop will iterate from column D to column O copying the contents of each column, transposing them from verical to horizontal and posting them consecutively on the same row. As each workbook is completed it will close without saving until all workbooks in the SelectedFiles array are exhausted. Again this is untested, so any glitches should be reported back for a fix.
Code:
Sub PartSum()
    Dim SummarySheet As Worksheet, Filename As String, NFile As Long
    Dim Workbk As Workbook, SourceRange As Range, DestRange As Range
    Dim SelectedFiles As Variant, Worksht As Worksheet
    'Creating and naming worksheets
    Set SummarySheet = ThisWorkbook.Sheets("Part Summary")
    'Open the file dialog box and filter on Excel files, allowing multiple files to be selected.
    SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.xl*), *.xl*", MultiSelect:=True)
    'NRow keeps track of where to insert new rows in the destination workbook.
    'Loop through the list of returned file names
    NRow = 4
    For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
        'Set FileName to be the current workbook file name to open.
        Filename = SelectedFiles(NFile)
        'Open the current workbook.
        Set Workbk = Workbooks.Open(Filename)
        'Set the source range to be D through O.
        'Modify this range for your workbooks. It can span multiple rows.
        For i = 4 To 15
            With Workbk.Sheets(1)
            .Range(.Cells(7, i), .Cells(Rows.Count, i).End(xlUp)).Copy
                If SummarySheet.Range("C" & NRow) = "" Then
                    SummarySheet.Range("C" & NRow).PasteSpecial xlPasteValues, Transpose:=True
                Else
                    SummarySheet.Cells(NRow, Columns.Count).End(xlToLeft).Offset(, 1).PasteSpecial xlPasteValues, _
                    Transpose:=True
                End If
            End With
        Next
        Application.CutCopyMode = False
        'Increase NRow so that we know where to copy data next.
        NRow = NRow + 1
        'Close the source workbook without saving changes.
        Workbk.Close savechanges:=False
    Next NFile
End Sub
 
Upvote 0
Can you use this? Assume my data range is A1:C4. This is a crazy complicated formula. However, it is very robust! You need to use Cntrl+Shift+Enter. Copy across.


=INDEX($A$1:$C$4,MOD(SMALL(IF($A$1:$C$4<>"",(COLUMN($A$1:$C$4)-COLUMN($A$1)+1)*10^9+ROW($A$1:$C$4)-ROW($A$1)+1),COLUMNS($A$6:A6)),10^9),INT(SMALL(IF($A$1:$C$4<>"",(COLUMN($A$1:$C$4)-COLUMN($A$1)+1)*10^9+ROW($A$1:$C$4)-ROW($A$1)+1),COLUMNS($A$6:A6))/10^9))

123
567
91011
131415
15913261014371115

<colgroup><col width="64" span="12" style="width:48pt"> </colgroup><tbody>
</tbody>

<tbody>
</tbody>
 
Upvote 0
JLGWhiz and Mike,

Thank you so much for your help, it is much appreciated.

Mike, your formula works, however doesn't allow me to pull information from a random (selected by user) workbook and use it, it need to be in the same workbook the get the formula to work, unless I am missing something.

JLG, this is so close, however I am having a hard time deciphering the code you wrote. For clarification purposes, D7 through O19 have data that I want to pull in each workbook. This data in the first selected workbook needs its columns transposed into the first row on the new worksheet in the summary workbook (C4). The next selected workbook needs its D:O put into the second row of the summary workbook (C5). This all needs to be done while deleting any empty rows that were in the in the originally selected workbook.

The code I currently have does all of this, however the transposing is giving me a real headache. Is there any way to set an object to be a specified column (say D7:D19), and within an "if" statement move that column to the next column (E7:E19) until it reaches the end (O7:O19)? Right now my object "C" is just selecting a cell, which is why my transpose isn't working.

Also, I apologize for the delayed response. I was pulled of off this project for something more urgent, and am just now getting back to it. Thank you all again.
 
Upvote 0
Finalized code is below, for those who may need it. Again, thanks for the help JLG, got the gears turning!

Code:
Sub PartSum()
    'Dim workbook import
    Dim SummarySheet As Worksheet
    Dim FolderPath, Filename As String
    Dim SelectedFiles() As Variant
    Dim NRow, NColumn, NFile As Long
    Dim Workbk As Workbook
    Dim Worksht As Worksheet
    Dim C As Range
    Dim SourceDate, DestDate, SourceTest, DestTest, SourceMeas, DestMeas, SourceRange, DestRange As Range
    Dim vFileToOpen As Variant
    Dim strCurDir As String
    Dim i As Long
    Dim SourceColInd, SourceRowInd, DestColInd As Integer 'Source range row and column indexer; destination range row indexer
    
    'Creating and naming worksheets
    Set Worksht = ThisWorkbook.Sheets("Part Summary")
    'Worksht.Name = Application.InputBox(prompt:="Type Worksheet Name, Include Date of Test", Title:="Worksheet Title", Default:="Enter Here", Type:=2)
      
    'Create a new workbook and set a variable to the first sheet.
    Set SummarySheet = Worksht


    'Keep Original Dir
    strCurDir = CurDir
   
    'Open the file dialog box and filter on Excel files, allowing multiple files to be selected.
    SelectedFiles = Application.GetOpenFilename(filefilter:="Excel Files (*.xl*), *.xl*", MultiSelect:=True)
    
    'NRow keeps track of where to insert new rows in the destination workbook.
    NRow = 4
    NColumn = 0
    
    'Loop through the list of returned file names
    For NFile = LBound(SelectedFiles) To UBound(SelectedFiles)
    
        'Set FileName to be the current workbook file name to open.
        Filename = SelectedFiles(NFile)
        
        'Open the current workbook.
        Set Workbk = Workbooks.Open(Filename)
                                           
        'Set the destination range to start at column B and be the same size as the source range.
        Dim LastRow As Long
        LastRow = ThisWorkbook.Sheets("Part Summary").Cells(ActiveSheet.Rows.Count, 1).End(xlUp).Row + 1
                                   
        'Set Date and Test Name
        Set SourceDate = Workbk.Worksheets(1).UsedRange.Range("B5")
        Set SourceTest = Workbk.Worksheets(1).UsedRange.Range("B1")
        Set SourceMeas = Workbk.Worksheets(1).UsedRange.Range("P8:S8")


        Set DestDate = SummarySheet.Range("A" & LastRow)
        Set DestTest = SummarySheet.Range("B" & LastRow)
        Set DestMeas = SummarySheet.Range("AI" & LastRow, "AL" & LastRow)
        DestDate.Value = SourceDate.Value
        DestTest.Value = SourceTest.Value
        DestMeas.Value = SourceMeas.Value
        
        'Set the source range to be D through O.
        Set SourceRange = Workbk.Worksheets(1).UsedRange.Range("D7:O19")
        
        Set DestRange = ThisWorkbook.Sheets("Part Summary").Range("C" & LastRow)
        
        'Indexer/Counter for the destination range's columns
        DestColInd = 1
        
        'Loop through each column in the Source Range
        '@SourceColInd: Indexer for the source range's columns
        '@SourceRowInd: Indexer for the source range's rows
        'inner if statement checks cell content; ignores if blank
        For SourceColInd = 1 To SourceRange.Columns.Count
            For SourceRowInd = 1 To SourceRange.Rows.Count
                If Not IsEmpty(SourceRange.Cells(SourceRowInd, SourceColInd)) Or Not IsNumeric(SourceRange.Cells(SourceRowInd, SourceColInd)) Then
                    DestRange(1, DestColInd) = SourceRange.Cells(SourceRowInd, SourceColInd)
                    DestColInd = DestColInd + 1
                End If
            Next
        Next
        End
            
        Application.CutCopyMode = False
        
        'Close the source workbook without saving changes.
        Workbk.Close SaveChanges:=False
        
    Next NFile
    
'End by resetting to last/original Dir
'ChDir strCurDir


    
End Sub
 
Upvote 0

Forum statistics

Threads
1,215,425
Messages
6,124,824
Members
449,190
Latest member
rscraig11

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top