VBA to copy certain columns to all worksheets - excel

Hi I'm looking to create code for copying certain columns (AH to AX) across all worksheets then skipping worksheets named "Aggregated" & "Collated Results"
I have this already
Sub FillSheets()
Dim ws As Worksheets
Dim worksheetsToSkip As Variant
Dim rng As Range
Dim sh As Sheet1
Set rng = sh.Range("AH1:AX7200")
worksheetsToSkip = Array("Aggregated", "Collated Results")
For Each ws In Worksheets
If IsError(Application.Match(ws.Name, worksheetsToSkip, 0)) Then
End Sub

This will
Loop through sheets
"Copy" data from AH1 - AX1 down to the last used row that is determined by Column AH (Update column if needed)
"Paste" data on a sheet named Sheet1 (Update if needed). The data will be pasted in Column AH on the first available blank row. It's not clear what column you want to paste the data in. You just need to change AH to Some Column to modify
"Copy" and "Paste" are in quotes because we are really just transferring values here since this is quicker. We are actually setting the values of two equal sized ranges equal to each other.
Option Explicit
Sub AH_AX()
'Update "Sheet1" to sheet where data is being pasted
Dim ms As Worksheet: Set ms = ThisWorkbook.Sheets("Sheet1")
Dim ws As Worksheet, wsLR As Long, msLR As Long
Dim CopyRange As Range, PasteRange As Range
For Each ws In Worksheets
If ws.Name <> "Aggregated" And ws.Name <> "Collated Results" Then
'Determine last rows
wsLR = ws.Range("AH" & ws.Rows.Count).End(xlUp).Row
msLR = ms.Range("AH" & ms.Rows.Count).End(xlUp).Offset(1).Row
'Set Ranges
Set CopyRange = ws.Range("AH1:AX" & LR)
Set PasteRange = ms.Range("AH" & msLR).Resize(CopyRange.Rows.Count, CopyRange.Columns.Count)
'Value Transfer (Quicker than copy/paste)
PasteRange.Value = CopyRange.Value
End If
Next ws
End Sub

Related

Use VBA to copy entire row from one excel worksheet to another if match is not found in Column A

I have been running into some issues trying to use VBA to compare 2 tables in different worksheets, and then copy any rows in the "Master" sheet that are not found in the "New" sheet. Both tables are formatted as tables. The match is based on an "ID" column in Column A of both tables. If an ID is in the "Master" sheet, but not in the "New" sheet, than that entire row should be copy and pasted to the end of the table in the "New" sheet.
I updated some code found in another forum, which is almost working. However, it only seems to paste over the ID data into Column A, and not the entire corresponding row of data which is needed.
Sub compare()
Dim i As Long
Dim lrs As Long
Dim lrd As Long
With Worksheets("Master")
lrs = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = 2 To lrs 'assumes header in row 1
If Application.IfError(Application.Match(.Cells(i, 1), Worksheets("New").Columns(1), 0), 0) = 0 Then
lrd = Worksheets("New").Cells(Worksheets("test").Rows.Count, 1).End(xlUp).Row
Worksheets("New").Cells(lrd + 1, 1).Value = .Cells(i, 1).Value
End If
Next i
End With
End Sub
I think the issue has to do with the "Cells" reference, instead of a range, but I do not know how to make that line dynamic.
Slightly different approach, but you need to use something like Resize() to capture the whole row, and not just the cell in Col A.
Sub compare()
Const NUM_COLS As Long = 10 'for example
Dim wb As Workbook, wsSrc As Worksheet, wsDest As Worksheet
Dim c As Range, cDest As Range
Set wb = ThisWorkbook 'or ActiveWorkbook for example
Set wsSrc = wb.Worksheets("Master")
Set wsDest = wb.Worksheets("New")
Set cDest = wsDest.Cells(Rows.Count, 1).End(xlUp).Offset(1) 'next empty row
For Each c In wsSrc.Range("A2:A" & wsSrc.Cells(Rows.Count, 1).End(xlUp).Row).Cells
If IsError(Application.Match(c.Value, wsDest.Columns(1), 0)) Then
cDest.Resize(1, NUM_COLS).Value = c.Resize(1, NUM_COLS).Value
Set cDest = cDest.Offset(1) 'next row
End If
Next c
End Sub

How to copy last row of data in all worksheets and paste it into one worksheet

Currently I have a lot of sheets in my Excel file but I want to get the last row of data in sheets that start with "6" as their names as the other sheets are not relevant. In the sheets that start with 6 are all in the same format but have different number of rows, I am interested in extracting the last row in all those sheets (columns D:J) and placing it into a "master sheet". Since I am quite new to VBA, how would I go about doing that? Thanks in advance!
What I have currently that can copy one sheet and paste into my master sheet "Sheet2":
With Sheets("6363")
With Range(.Cells(.Rows.Count, "D").End(xlUp), _
.Cells(.Cells(.Rows.Count, "D").End(xlUp).row, .Columns.Count).End(xlToLeft))
Worksheets("Sheet2").Range("D1").Resize(, .Columns.Count).Value = .Value
End With
End With
This will copy the last row, columns D-J, from every sheet with a name that starts with '6'.
It will put the copied data into the next empty row, starting at column D, of 'Sheet2'.
Sub CopySix()
Dim wsSrc As Worksheet
Dim wsDst As Worksheet
Dim rngSrc As Range
Dim rngDst As Range
Set wsDst = ActiveWorkbook.Sheets("Sheet2")
Set rngDst = wsDst.Range("D" & Rows.Count).End(xlUp).Offset(1)
For Each wsSrc In ActiveWorkbook.Sheets
If Left(wsSrc.Name, 1) = "6" Then
Set rngSrc = wsSrc.Range("D" & Rows.Count).End(xlUp).Resize(, 7)
rngDst.Resize(, 7).Value = rngSrc.Value
Set rngDst = rngDst.Offset(1)
End If
Next wsSrc
End Sub

Copy a range of custom colored cells

I need to write a code in order to perform the below action:
From a column, select only the colored cells (eg. in yellow) and copy them under another column already filled with values at the bottom of the list
Here the code i wrote so far however i have troubles writing the part to copy the colored cells to the other sheet:
copycolor Sub m()
Dim wk As Workbook
Dim sh As Worksheet
Dim rng As Range
Dim C As Range
Set wk = ThisWorkbook
With wk
Set sh = .Worksheets("Base Dati Old")
End With
With sh
Set rng = .Range("A:A")
For Each C In rng
If C.Interior.ColorIndex = 46 Then
C.Copy
End If
Next C
End With
End Sub
Assuming you have headers in your data I'd advise to do two things:
Don't loop all cells in column A, it will slow down things significanlty.
If headers are present, applying a filter based on color might be a more optimal way.
For example:
Sub CopyColor()
Dim wk As Workbook: Set wk = ThisWorkbook
Dim sht As Worksheet: Set sht = wk.Worksheets("Base Dati Old")
Dim lr As Long, rng As Range
'Define last used row;
lr = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
'Set range;
Set rng = sht.Range("A1:A" & lr)
'Filter your data on yellow;
rng.AutoFilter 1, RGB(255, 255, 0), xlFilterCellColor
'Copy filtered cells;
rng.SpecialCells(12).Offset.Copy wk.Worksheets("DestinationSheet").Range("A1")
'Turn off filter
rng.AutoFilter
End Sub
Don't forget to change the name of the sheet you'd want to copy your data to. You may also need to find the last used row for that sheet and make that part dynamic.
Good luck.

Print name of the sheet along with copied cell

I have this code where it loops through all the sheets in the workbook and copies the value in F9 of each sheet and pastes it in "Summary" sheet column A. How can I also print the sheet name in column B? So the value is next to the sheet name in the "Summary" sheet.
code:
Sub loopsheet()
Dim wks As Worksheet
For Each wks In ThisWorkbook.Worksheets
If Not wks.Name = "Summary" Then
wks.Range("F9:F" & wks.Cells(Rows.Count, "F").End(xlUp).Row).Copy _
Destination:=Worksheets("Summary").Cells(Rows.Count, "A").End(xlUp).Offset(1)
End If
Next
End Sub
Thank you
Create two variables to track the last rows of your sheets as you loop. This will help with readability in your code. The combination of these two variables can also help you deduce the size of the range where you need to drop your sheet name.
I believe cLR + pLR - 11 is the size of range. The offset is due to headers, LR offset, and the fact that you are starting your copy from the 9th row. After you run this, you may need to tweak it up or down one if i'm wrong.
Option Explicit
Sub LoopSheet()
Dim ws As Worksheet
Dim Summary As Worksheet: Set Summary = ThisWorkbook.Sheets("Summary")
Dim cLR As Long, pLR As Long
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> Summary.Name Then
cLR = ws.Range("F" & ws.Rows.Count).End(xlUp).Row
pLR = Summary.Range("A" & Summary.Rows.Count).End(xlUp).Offset(1).Row
ws.Range("F9:F" & cLR).Copy Summary.Range("A" & pLR)
Summary.Range(Summary.Cells(pLR, 2), Summary.Cells(cLR + pLR - 11, 2)).Value = ws.Name
End If
Next ws
End Sub

Merge Multiple Worksheets into a Single Worksheet in the Same Workbook

I currently have code for each sheet I want to move but I am wondering if there was a way to reduce this code.
This is what I currently use to move each sheet times 8 or so sheets:
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = "ONI" Then
Set RNG1 = ONI.Range("A1:AK1").EntireColumn
Set RNG2 = All.Range("A1:AK1").EntireColumn
RNG2.Value = RNG1.Value
End If
Next
This is the code I use when I want to move a single column from all sheets to a single sheet. I can't figure out how to modify it to include more columns.
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "MainSheet" Then
Set RNG1 = ws.Range("A1:A700")
Set RNG2 = Sheets ("MainSheet") _
.Cells(Rows.Count,"A").End(xlUp).Offset(1)
RNG2.Value = RNG1.Value
End If
Next
So basically is it possible to modify this code to include multiple columns?
Kudos for going for the value transfer instead of copy/paste. You just need to resize your Rng2 to match the size of Rng1.
I also modified this to work with dynamic row counts. If you need to copy a static range for each sheet, you can get rid of the LR bits and hard code the range. You need to keep nLR as this determines the next available row on your main sheet.
Sub Test()
Dim ms As Worksheet: Set ms = ThisWorkbook.Sheets("MainSheet")
Dim ws As Worksheet, Rng1 As Range, Rng2 As Range
Dim LR As Long, nLR As Long '(LR = Last Row, nLR = New Last Row for Main Sheet)
For Each ws In Worksheets
If ws.Name <> ms.Name Then
'Determine Relavent Ranges (last rows)
LR = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
nLR = ms.Range("A" & ms.Rows.Count).End(xlUp).Offset(1).Row
'Set the ranges
Set Rng1 = ws.Range("A1:L" & LR)
Set Rng2 = ms.Range("A" & nLR).Resize(Rng1.Rows.Count, Rng1.Columns.Count)
'Value Transfer
Rng2.Value = Rng1.Value
End If
Next ws
End Sub
Think you need a nested loop here, long time since i wrote vba so i give pseudo code, hope this help you on the way.
for each ws
dim rang as Range
for Each rnge In Range("A1:H1").Columns
do something
next
next

Resources