Private Sub CommandButton1_Click()
'To count sheets in excel file
totalsheets = Worksheets.Count
For i = 1 To totalsheets
If Worksheets(i).Name <> "MasterSheet" Then
'cheking last filled row on each sheet
lastrow = Worksheets(i).Cells(Rows.Count, 1).End(xlUp).Row
For j = 1 To lastrow
Worksheets(i).Activate
Worksheets(i).Cells(j, 2).Select
Selection.Copy
Worksheets("MasterSheet").Activate
lastcln = Worksheets("MasterSheet").Cells(1, Columns.Count).End(xlToLeft)
Worksheets("MasterSheet").Cells(j, lastcln + 1).Select
ActiveSheet.Paste
Next
End If
Next
End Sub
Asked
Active
Viewed 69 times
1

BigBen
- 46,229
- 7
- 24
- 40

Lotfi Ronin
- 11
- 1
-
2It would be better to copy the whole column rather than a cell at a time. So `worksheets(i).columns(2).copy` What is wrong with your code can you show where youre having issues? Also, dont use activate etc, and dont put it in your row loop, this needs to be before, for example if you have 1000 rows, you're activating worksheets(i) 1000 times – Nathan_Sav Aug 16 '21 at 12:31
-
**1.** No need to select or activate. You may want to see [How to avoid using Select in Excel VBA](https://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba) **2.** No need to copy cell by cell. Simply copy the entire range and and do a pastespecial transpose. There may be a problem if you last row is more `16384` rows – Siddharth Rout Aug 16 '21 at 12:32
-
@Nathan : we I run my code it gives error at that ligne: ActiveSheet.Paste ; As you said " activate " should be out the loop, for more effciency. – Lotfi Ronin Aug 16 '21 at 15:21
-
@LotfiRonin Hi, yes, just outside the loop, so the line before the for next loop for J needs to be activate, or even just after the for next for I. – Nathan_Sav Aug 17 '21 at 07:53
2 Answers
0
Try this
For i = 1 To totalsheets
If Worksheets(i).Name <> "MasterSheet" Then
' change this according to your need
firstrow = 1
'last row of source
lastrow = Worksheets(i).Cells(Rows.Count, 1).End(xlUp).Row
'last column of destination
lastcln = Worksheets("MasterSheet").Cells(1, Columns.Count).End(xlToLeft)
'more efficient procedure as suggested by Nathan
Worksheets("MasterSheet").Cells(firstrow, lastcln + 1).Value = Worksheets(i).Range(Cells(firstrow, 2), Cells(lastrow, 2)).Value
End If
Next

Wils Mils
- 613
- 4
- 9
-
2Could even say `Worksheets("MasterSheet").Cells(firstrow, lastcln + 1).value=Worksheets(i).Range(Cells(firstrow, 2), Cells(lastrow, 2)).value` And maybe `for each ws in worksheets` and use `ws` instead of `worksheets(i)` – Nathan_Sav Aug 16 '21 at 12:51
-
1@Nathan_Sav: You are mistaken. In this way only the value of the first cell will be copied (assigned). The syntax is: `dCell.Resize(srg.Rows.Count).Value = srg.Value` for a one-column range or `dCell.Resize(srg.Rows.Count, srg.Columns.Count).Value = srg.Value` for any range. You will easily make the code more readable and avoid these mistakes by using variables. – VBasic2008 Aug 16 '21 at 13:33
-
-
You forgot the 'trailing' `.Column` in `lastcln = ...` and the more efficient part is wrong. Try `Set dCell = Worksheets("MasterSheet").Cells(firstrow, lastcln + 1)` and `Set srg = Worksheets(i).Range(Worksheets(i).Cells(firstrow, 2), Worksheets(i).Cells(lastrow, 2))`, when you can finally do: `dCell.Resize(srg.Rows.Count).Value = srg.Value`. – VBasic2008 Aug 16 '21 at 13:50
0
Copy Column From Multiple Worksheets
Option Explicit
Sub CopyColumn()
' Source
Const sfRow As Long = 1
Const sCol As String = "B"
' Destination
Const dName As String = "MasterSheet"
Const dfRow As Long = 1
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim wsrCount As Long: wsrCount = wb.Worksheets(1).Rows.Count
' Destination
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfCell As Range ' Note that the left-most column cannot be column 'A'.
Set dfCell = dws.Cells(dfRow, dws.Columns.Count).End(xlToLeft).Offset(, 1)
' Declare additional variables.
Dim sws As Worksheet ' Source Worksheet
Dim srg As Range ' Source Range
Dim slCell As Range ' Source Last Cell
Dim drg As Range ' Destination Range
' Copy.
For Each sws In wb.Worksheets
If StrComp(sws.Name, dName, vbTextCompare) <> 0 Then
Set slCell = sws.Cells(wsrCount, sCol).End(xlUp)
Set srg = sws.Range(sws.Cells(sfRow, sCol), slCell)
' Either for values only (more efficient)...
Set drg = dfCell.Resize(srg.Rows.Count)
drg.Value = srg.Value
' ... or for values, formats, formulas:
'srg.Copy dfCell ' no need for 'drg'.
' (A third, most flexible option is to use 'PasteSpecial'.)
Set dfCell = dfCell.Offset(, 1) ' next column
End If
Next sws
End Sub

VBasic2008
- 44,888
- 5
- 17
- 28