Merging 3 Sheets Into 1 Sheet - vba

I want a script that pulls 3 different worksheets from another workbook and just stack the data in a new blank sheet.
This seems like it should work but it's not:
Sub CombineSheets()
Set NewSheet = Worksheets("Sheet2")
Set MC = Workbooks.Open("S:\OtherWorkBook.xlsm")
Set T1 = MC.Worksheets("T1")
Set T2 = MC.Worksheets("T2")
Set T3 = MC.Worksheets("T3")
With T1
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A5:I" & lastrow).Copy NewSheet.Range("A" & wks.Rows.Count).End(xlUp)
End With
With T2
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A5:I" & lastrow).Copy NewSheet.Range("A" & wks.Rows.Count).End(xlUp)
End With
With T3
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A5:I" & lastrow).Copy NewSheet.Range("A" & wks.Rows.Count).End(xlUp)
End With
Workbooks("OtherWorkBook.xlsm").Close SaveChanges:=False
End Sub
The script runs but nothing is dumped into NewSheet? What am I missing. Thank you!

You are missing Destination:= after your .Copy call.
With T1
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A5:I" & lastrow).Copy Destination:=NewSheet.Range("A" & NewSheet.Rows.Count).End(xlUp)
End With
This worked for me. I also changed wks to NewSheet. because your code doesn't clarify what wks exactly is.

Related

VBA to populate names

I need help to create one VBA for below issue -
column C should be updated based on column A and B values.
in below example if column A=Unit1 and column B=IND then Person 1 and so on.. it should loop till end.
Thank you in adv. please refer picture for sample data
enter image description here
Here you go. Just change the sheet name since I don't know what you're working with.
Sub AddPerson()
Dim i As Long, ws As Worksheet, lRow As Long
Set ws = Sheets("Sheet1") 'Change to your sheet name
lRow = ws.Range("A" & Rows.Count).End(xlUp).Row
With ws
.Range("C2:C" & lRow + 1).ClearContents
For i = 2 To lRow
If .Range("B" & i) = "IND" Then
.Range("C" & i) = "Person1"
ElseIf .Range("A" & i) = "Unit5" And .Range("B" & i) = "OTR" Then
.Range("C" & i) = "Person3"
Else
.Range("C" & i) = "Person2"
End If
Next i
End With
End Sub

VBA copy data from one sheet to another (to the blank cells)

I would like to copy data from sheet INV_LEDGERSinto Ready to uploadsheet, but the sheet Ready to upload already contains some data and therefore I want to loop through the column A in Ready to upload sheet until it will find the blank cell and then paste the data from INV_LEDGERS.
Sub CopyLedgers()
Dim ws As Worksheet, ws1 As Worksheet
Dim LastRow As Long
Set ws = Sheets("INV_LEDGERS")
Set ws1 = Sheets("Ready to upload")
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
For i = 4 To LastRow
If ws.Range("A" & i) > "" And ws1.Range("A" & i + 1) = "" Then
ws.Range("A" & i & ":AE" & i).Copy
ws1.Range("A" & i + 1).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Else
End If
Next
End Sub
It doesnt show the error msg anymore, but now it copies the data from INV_LEDGERSfrom the row, where data on sheet Ready to upload ends. I mean, that if data on Ready to upload has the end on row 82, the code will take the data from INV_LEDGERS from 82. row, so basically there are missing 81 rows.
Could you advise me, please?
Thanks a lot!
Given the comments from braX, here is my code.
Since you are always starting on the 4th row of the ledger data, you can just copy the entire section and then paste it to your last row + 1 on your upload sheet.
Sub CopyLedgers()
Dim ws As Worksheet, ws1 As Worksheet
Dim LastRow, LRow As Long
Set ws = Sheets("INV_LEDGERS")
Set ws1 = Sheets("Ready to upload")
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
LRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
ws.Range("A4:AE" & LastRow).Copy
ws1.Range("A" & LRow + 1).PasteSpecial xlPasteValues
End Sub
Couple things... have used a With statement, and instead of copy/paste, I'm just making ws1.Value=ws.Value:
Sub CopyLedgers()
Dim ws As Worksheet, ws1 As Worksheet, LastRow As Long
Set ws = Sheets("INV_LEDGERS")
Set ws1 = Sheets("Ready to upload")
With ws
LastRow = .Cells( .Rows.Count, 1).End(xlUp).Row
For i = 4 To LastRow
If .Range("A" & i) > "" And ws1.Range("A" & i + 1) = "" Then
ws1.Range("A" & i + 1 & ":AE" & i + 1).Value = .Range("A" & i & ":AE" & i).Value
End If
Next
End With
End Sub
Edit
Sub CopyLedgers()
Dim ws As Worksheet, ws1 As Worksheet, LastRow As Long
Set ws = Sheets("INV_LEDGERS")
Set ws1 = Sheets("Ready to upload")
With ws
LastRow = .Cells( .Rows.Count, 1).End(xlUp).Row
For i = 4 To LastRow
If IsEmpty(ws1.Range("A" & i + 1)) Then
ws1.Range("A" & i + 1 & ":AE" & i + 1).Value = .Range("A" & i & ":AE" & i).Value
End If
Next
End With
End Sub

copy lastrow of masterfile to multiple created worksheets then perform a Subtotal formula in a column lastrow

I have a master file which is (JV501) where I filter through column AB (currency) then copy those to createdsheets, my problem now is the lastrow from master file which I need to include to every created worksheets since it starts in column R and from there under column AD (which is all null) lastrow is where I shall perform a subtotal of AC2 up to lastrow so the subtotal shall inline with the lastrow copied.
Option Explicit
Sub SortCurrency()
Dim currRng As Range, dataRng As Range, currCell As Range
Dim LastCol As Long, lastRow As Long, lastrow2 As Long, TheLastRow As Long
Call DeleteSheets
With Worksheets("JV501")
Set currRng = .Range("AB1", .Cells(.Rows.Count, "AB").End(xlUp))
Set dataRng = Intersect(.UsedRange, currRng.EntireRow)
LastCol = Range("A1").End(xlToRight).Column
TheLastRow = Range("A1").End(xlDown).Row
lastRow = Range("AB2").End(xlDown).Row
Range("AB2:AB" & lastRow).sort key1:=Range("AB2" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("AF:XFD").EntireColumn.Delete
With .UsedRange
With .Resize(1, 1).Offset(, .Columns.Count)
With .Resize(currRng.Rows.Count)
.Value = currRng.Value
.RemoveDuplicates Array(1), Header:=xlYes
For Each currCell In .SpecialCells(xlCellTypeConstants)
currRng.AutoFilter field:=1, Criteria1:=currCell.Value
If Application.WorksheetFunction.Subtotal(103, currRng) - 1 > 0 Then
dataRng.SpecialCells(xlCellTypeVisible).Copy Destination:=GetOrCreateWorksheet(currCell.Value).Range("A1")
Range("J:Q").EntireColumn.Delete
Range("A:A").EntireColumn.Delete
Columns("A:AE").Select
Selection.EntireColumn.AutoFit
End If
Next currCell
.ClearContents
End With
End With
End With
.AutoFilterMode = False
End With
Call checklist
End Sub
Function GetOrCreateWorksheet(shtName As String) As Worksheet
On Error Resume Next
Set GetOrCreateWorksheet = Worksheets(shtName)
If GetOrCreateWorksheet Is Nothing Then
Set GetOrCreateWorksheet = Worksheets.Add(After:=Sheets(Sheets.Count))
GetOrCreateWorksheet.Name = shtName
End If
End Function
this is my code so far. I'm confused if how I shall do this.
Every help is appreciated!
In trying to compute for a a column range i've come up and got it working by adding this in my loop in creating sheets.
'subtotal of debit
lastrowSrc = Range("AC" & Rows.Count).End(xlUp).Row + 1
Range("AC" & lastrowSrc & ":AC" & lastrowSrc).Formula = "=SUBTOTAL(9,AC2:AC" & lastrowSrc - 1 & ")"
'copy ac to ad
Range("AC" & lastrowSrc & ":AC" & lastrowSrc).Cut Destination:=Range("AC" & lastrowSrc).Offset(0, 1)
in column AC is where I will compute the subtotal of debit then copy it to another column which is AD which is null I've pasted it by column AC then offset
For copying the columns not included in criteria of extracting I've done it one by one
dim internalS as long, 'and so on
internalR = Range("R" & Rows.Count).End(xlUp).Row + 1
copyR.Copy Destination:=Range("R" & internalR)
internalS = Range("S" & Rows.Count).End(xlUp).Row + 1
copyS.Copy Destination:=Range("S" & internalS)
internalT = Range("T" & Rows.Count).End(xlUp).Row + 1
copyT.Copy Destination:=Range("T" & internalT)
internalU = Range("U" & Rows.Count).End(xlUp).Row + 1
copyU.Copy Destination:=Range("U" & internalU)
internalV = Range("V" & Rows.Count).End(xlUp).Row + 1
copyV.Copy Destination:=Range("V" & internalV)
internalW = Range("W" & Rows.Count).End(xlUp).Row + 1
copyW.Copy Destination:=Range("W" & internalW)
internalX = Range("X" & Rows.Count).End(xlUp).Row + 1
copyX.Copy Destination:=Range("X" & internalX)
internalY = Range("Y" & Rows.Count).End(xlUp).Row + 1
copyY.Copy Destination:=Range("Y" & internalY)
internalZ = Range("Z" & Rows.Count).End(xlUp).Row + 1
copyZ.Copy Destination:=Range("Z" & internalZ)
internalAE = Range("AE" & Rows.Count).End(xlUp).Row + 1
copyAE.Copy Destination:=Range("AE" & internalAE)
also inserted this in my loop in creating new worksheets

Ignore empty cells in for each VBA

I am having a problem with my loop(i go throu columns in every worksheet and copy them common column ) in VBA. And I wan't to ignore empty cells... any ideas? Bellow is my code
Application.ScreenUpdating = False
lastRowMaster = 1
For Each Ws In Sheets(Array("1L", "5L"))
lastRow = Ws.Range("A" & Rows.Count).End(xlUp).row
Ws.Range("A1:A" & lastRow).Copy Destination:=Worksheets("Podatki plana").Range("A" & lastRowMaster)
lastRowMaster = Worksheets("Podatki plana").Range("A" & Rows.Count).End(xlUp).row + 1
Next
Application.ScreenUpdating = True
MsgBox "Done!"
I altered this line of code:
Ws.Range("A1:A" & lastRow).Copy Destination:=Worksheets("Podatki plana").Range("A" & lastRowMaster)
To this:
Ws.Range("A1:A" & lastRow).SpecialCells(xlCellTypeConstants).Copy Destination:=Worksheets("Podatki plana").Range("A" & lastRowMaster)
Using the .SpecialCells(xlCellTypeConstants) qualifier selects only cells that have a value in them. You could change xlCellTypeConstants to xlCellTypeFormulas or any of the options listed on this MSDN article.
The benefit with this is that you don't have to loop through each cell, which is a perfectly good solution but comes with a performance penalty.
Tested in Excel 2013.
Maybe just set each of the destination cells to the origin cell when the cell is not empty, like so
Application.ScreenUpdating = False
lastRowMaster = 1
lastRow = Ws.Range("A" & Rows.Count).End(xlUp).row
nextRow = 1
For Each Ws In Sheets(Array("1L", "5L"))
for i = 1 to lastRow
if Not IsEmpty(Ws.Cells(i, 1)) then
Worksheets("Podatkiplana").cells(nextRow, 1) = Ws.cells(i,1)
nextRow = nextRow + 1
end if
next i
Next
Application.ScreenUpdating = True
MsgBox "Done!"
Application.ScreenUpdating = False
lastRowMaster = 1
For Each Ws In Sheets(Array("1L", "5L"))
lastRow = Ws.Range("A" & Rows.Count).End(xlUp).row
For i = 1 to lastrow
lastRowMaster = Worksheets("Podatki plana").Range("A" & rows.Count).End(xlUp).row + 1
If ws.cells(i, 1)<> "" Then Worksheets("Podatki plana").Cells(lastRowMaster, 1) = ws.cells(i,1)
next i
Next
Application.ScreenUpdating = True
MsgBox "Done!"

Merge Multiple Excel Sheets Into Summary Sheet

I wonder whether someone may be able to help me please.
I'm using the code below to allow the user to copy from multiple Excel workbooks and merge the data into a Summary sheet.
Sub Merge()
Dim DestWB As Workbook, WB As Workbook, WS As Worksheet, SourceSheet As String
Set DestWB = ActiveWorkbook
SourceSheet = "Input"
startrow = 7
FileNames = Application.GetOpenFilename( _
filefilter:="Excel Files (*.xls*),*.xls*", _
Title:="Select the workbooks to merge.", MultiSelect:=True)
If IsArray(FileNames) = False Then
If FileNames = False Then
Exit Sub
End If
End If
For n = LBound(FileNames) To UBound(FileNames)
Set WB = Workbooks.Open(Filename:=FileNames(n), ReadOnly:=True)
For Each WS In WB.Worksheets
If WS.Name = SourceSheet Then
With WS
If .UsedRange.Cells.Count > 1 Then
dr = DestWB.Worksheets("Input").Range("C" & Rows.Count).End(xlUp).Row + 1
lastrow = .Range("C" & Rows.Count).End(xlUp).Row
For j = lastrow To startrow Step -1
If Range("E" & j) <> "Requirements Manager" And Range("E" & j) <> "R & D Lead" And Range("E" & j) <> "Technical" And Range("E" & j) <> "Analyst" Then Rows(j).Delete
Next
lastrow = .Range("C" & Rows.Count).End(xlUp).Row
If lastrow >= startrow Then
.Range("A" & startrow & ":AQ" & lastrow).Copy
DestWB.Worksheets("Input").Cells(dr, "A").PasteSpecial xlValues
End If
End If
End With
Exit For
End If
Next WS
WB.Close savechanges:=False
Next n
End Sub
The code works fine but I'm stuck with a problem related to the copying of the information, which is this line of code:
.Range("A" & startrow & ":AQ" & lastrow).Copy
I need to change this so that it takes into account two ranges. These are columns "B:AD" and "AF:AQ", but I'm not sure how to do this.
I just wondered wehether someone could possibly take a look at this please and offer some guidance on how I may go about solving this.
Many thanks and kind regards
In all the following I assume that you indeed don't want column A copied to the destination workbook and sheet.
You could use Union to copy paste it in one go (then any columns in between it will not be reflected when pasting:
If lastrow >= startrow Then
Union(.Range("B" & startrow & ":AD" & lastrow), .Range("AF" & startrow & ":AQ" & lastrow).Copy
DestWB.Worksheets("Input").Cells(dr, "B").PasteSpecial xlValues
End If
If you want it pasted with room between it as well then you could simply r3epeat the copy and paste lines:
If lastrow >= startrow Then
.Range("B" & startrow & ":AD" & lastrow).Copy
DestWB.Worksheets("Input").Cells(dr, "B").PasteSpecial xlValues
.Range("AF" & startrow & ":AQ" & lastrow).Copy
DestWB.Worksheets("Input").Cells(dr, "AF").PasteSpecial xlValues
End If