Want to add two more conditions in my excel VBA coding - excel

What I want to add is.. Macro should delete the old from "Master"sheet and refresh the sheet1,sheet2 and sheet3
Sub Combine3Sheet()
Dim Ary As Variant
Dim Ws As Worksheet
Ary = Array("Sheet1", "Sheet2", "Sheet3")
Sheets("Master").Name = "Master"
For Each Ws In Worksheets(Ary)
Ws.UsedRange.Offset(1).Copy Sheets("Master") _
.Range("A" & Rows.Count).End(xlUp).Offset(1)
Application.DisplayAlerts = False
Application.DisplayAlerts = True
Call Formatting
Next Ws
End Sub

You mean this? Delete the data on Master before pasting it?
(Also stop changing the edits on your post)
Sub Combine3Sheet()
Dim Ary As Variant
Dim Ws As Worksheet
Ary = Array("Sheet1", "Sheet2", "Sheet3")
'Refresh all sources/Tables
ThisWorkbook.RefreshAll
'Clear All but first Row
Sheets("Master").Rows("2:" & Rows.Count).ClearContents
'Loop sheets
For Each Ws In Worksheets(Ary)
Ws.UsedRange.Offset(1).Copy
Sheets("Master").Range("A" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlPasteValues
Call Formatting
Next Ws
End Sub

Related

SCript does not generate a new workbook for each filtered value

This script loops through each value within a filtered column with the aim of filtering one by one, copy the data, create a new workbook, paste it and save it.
It it now creating a signle new workbook with all the worksheets, instead of one workbook per worksheet.
Can someone point out how can I mend the code to create one workbook per value filtered?
On the other hand, the workbook is also keeping the original sheet1. I am also looking on how to remove it, but thought it would be importat to let you know.
Sub test()
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
' -------------------
Dim x As Range
Dim rng As Range
Dim rng1 As Range
Dim last As Long
Dim sht As String
Dim newBook As Excel.Workbook
Dim Workbk As Excel.Workbook
Dim ws As Worksheet
'Specify sheet name in which the data is stored
sht = "Report"
'Workbook where VBA code resides
Set Workbk = ThisWorkbook
'New Workbook
Set newBook = Workbooks.Add(xlWBATWorksheet)
Workbk.Activate
Set ws = Workbk.Worksheets(sht)
'change filter column in the following code
last = ws.Cells(Rows.Count, "BR").End(xlUp).Row
With ws
Set rng = .Range("A1:BR" & last)
End With
ws.Range("G1:G" & last).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("BT1"), Unique:=True
For Each x In ws.Range([BT2], Cells(Rows.Count, "BT").End(xlUp))
With rng
.AutoFilter
.AutoFilter Field:=7, Criteria1:=x.Value
.SpecialCells(xlCellTypeVisible).Copy
newBook.Sheets.Add(After:=newBook.Sheets(newBook.Sheets.Count)).Name = x.Value
newBook.Activate
ActiveSheet.Paste
End With
Next x
' Turn off filter
ws.AutoFilterMode = False
With Application
.CutCopyMode = False
.ScreenUpdating = True
End With
' -------------------
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
MsgBox "Check."
End Sub ```
Put the Workbooks.Add line inside the loop.
Option Explicit
Sub test()
Dim wb As Workbook, wbNew As Workbook
Dim ws As Worksheet, wsNew As Worksheet
Dim rng As Range, cel As Range
Dim iLastRow As Long, iLastRowBT As Long
Dim folder As String
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
'Workbook where VBA code resides
Set wb = ThisWorkbook
Set ws = wb.Sheets("Report")
folder = wb.Path & "\"
With ws
'change filter column in the following code
iLastRow = .Cells(Rows.Count, "BR").End(xlUp).Row
.Range("BT:BT").Clear
.Range("G1:G" & iLastRow).AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=Range("BT1"), Unique:=True
Set rng = .Range("A1:BR" & iLastRow)
iLastRowBT = .Cells(Rows.Count, "BT").End(xlUp).Row
End With
' create workbooks
For Each cel In ws.Range("BT2:BT" & iLastRowBT)
' Open New Workbook
Set wbNew = Workbooks.Add(xlWBATWorksheet)
Set wsNew = wbNew.Sheets(1)
wsNew.Name = cel.Value
' filter and copy data
With rng
.AutoFilter
.AutoFilter Field:=7, Criteria1:=cel.Value
.SpecialCells(xlCellTypeVisible).Copy
End With
' paste and save
wsNew.Paste
wbNew.SaveAs folder & cel.Value & ".xlsx"
wbNew.Close SaveChanges:=False
Next
' Turn off filter
ws.AutoFilterMode = False
With Application
.CutCopyMode = False
.ScreenUpdating = True
.DisplayAlerts = True
.EnableEvents = True
End With
MsgBox iLastRowBT - 1 & " Workbooks created in " & folder, vbInformation
End Sub

How do I get my VBA Code to loop through all sheets in workbook?

I am currently using the following code to remove classifications I do not require in my tables:
Sub RemoveOldPlatforms()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("RAW")
ws.Range("$A$1:$J$100000").AutoFilter Field:=2, Criteria1:=Array("Coniferous", "Broafleaf", "Mixedwood", "Water", "Exposed Land / Barren", "Urban / Developed", "Greenhouses", "Shrubland", "Wetland", "Grassland"), Operator:=xlFilterValues
ws.Range("$A$2:$J$100000").SpecialCells(xlCellTypeVisible).EntireRow.Delete
ws.Range("$A$1:$J$100000").AutoFilter
End Sub
As is, I am specifying a single identified worksheet, but how do I loop it through all worksheets in my workbook (20+)?
Hi pretty simple code to check every worksheets in a workbook,
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
'called once per worsheet
Next ws
Here I loop trough all the worksheet to find all tables availiable in ANOTHER workbook and display it inside a ComboBox
Private Sub UpdateTablesFromFile()
Dim wb As Workbook
Dim ws As Worksheet
Dim tbl As ListObject
Dim text As String
Dim I As Integer
Dim FileToOpen As String
FolderPath = Application.ActiveWorkbook.Path
FilePath = FolderPath & "\" & ComboBox1.Value
Application.ScreenUpdating = False
Workbooks.Open Filename:=FilePath
For Each ws In Workbooks(ComboBox1.Value).Worksheets
For Each tbl In ws.ListObjects
text = ws.Name & "\" & tbl.Name
ImportForm1.ComboBox2.AddItem text 'add every tables in my entire workbook inside the ComboBox2
Next tbl
Next ws
Workbooks(ComboBox1.Value).Close SaveChanges:=False
Application.ScreenUpdating = True
End Sub
You should do something like this:
Sub EnteringAllSheetsOneByOne()
For Each ws In Excel.Workbooks("YourWorkbook.xlsx").Worksheets
ws.Select
Call RemoveOldPlatforms(ws) 'must to be called here and use ws as parameter
Next ws
MsgBox "Done!"
End Sub
' Just add the "ws" parameter to your current sub
Sub RemoveOldPlatforms(ws As Object)
'Dim ws As Worksheet
'Set ws = ThisWorkbook.Worksheets("RAW")
ws.Range("$A$1:$J$100000").AutoFilter Field:=2, Criteria1:=Array("Coniferous", "Broafleaf", "Mixedwood", "Water", "Exposed Land / Barren", "Urban / Developed", "Greenhouses", "Shrubland", "Wetland", "Grassland"), Operator:=xlFilterValues
ws.Range("$A$2:$J$100000").SpecialCells(xlCellTypeVisible).EntireRow.Delete
ws.Range("$A$1:$J$100000").AutoFilter
End Sub
Note: Please pay atention to all I've commented, Dim and Set in this case are not necessary

Get error message "expected end of line" when using PasteSpecial

I am copying a range from all open workbooks with the goal of pasting the copied cells into a consolidated sheet in the master (active) workbook. I need to paste the values only but get an "end of line" error message with this code
Spent pretty much all day googling my problem to no avail
Sub Consolidate()
Dim oBook As Workbook, ws As Worksheet, wb As Workbook, bk As Workbook
Dim copyFrom As Range
'Disable Screen Updating - stop screen flickering
' And Disable Events to avoid inturupted dialogs / popups
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the Consolidate_Data WorkSheet if it exists
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Sheets("Consolidate_Data").Delete
Application.DisplayAlerts = True
'Add a new WorkSheet and name as 'Consolidate_Data'
With ActiveWorkbook
Set DstSht = .Sheets.Add(After:=.Sheets(.Sheets.Count))
DstSht.Name = "Consolidate_Data"
End With
'Loop through each WorkBook in the folder and copy the data to the 'Consolidate_Data' WorkSheet in the ActiveWorkBook
Set wb = ActiveWorkbook
For Each oBook In Application.Workbooks
If Not oBook.Name = wb.Name Then
'Find the last row on the 'Consolidate_Data' sheet
DstRow = fn_LastRow(DstSht) + 1
'Determine Input data range
Set copyFrom = oBook.Worksheets(1).Range("A6:C8")
'Copy data to the 'consolidated_data' WorkSheet
copyFrom.Copy _
DstSht.Range("A" & DstRow).PasteSpecial xlPasteValues
End If
Next
IfError:
'Enable Screen Updating and Events
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
'Find the last Row of specified Sheet
Function fn_LastRow(ByVal Sht As Worksheet)
Dim lastRow As Long
lastRow = Sht.Cells.SpecialCells(xlLastCell).Row
lRow = Sht.Cells.SpecialCells(xlLastCell).Row
Do While Application.CountA(Sht.Rows(lRow)) = 0 And lRow <> 1
lRow = lRow - 1
Loop
fn_LastRow = lRow
End Function
Consolidate()
Dim oBook As Workbook, ws As Worksheet, wb As Workbook, bk As Workbook
Dim copyFrom As Range
'Disable Screen Updating - stop screen flickering
' And Disable Events to avoid inturupted dialogs / popups
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the Consolidate_Data WorkSheet if it exists
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Sheets("Consolidate_Data").Delete
Application.DisplayAlerts = True
'Add a new WorkSheet and name as 'Consolidate_Data'
With ActiveWorkbook
Set DstSht = .Sheets.Add(After:=.Sheets(.Sheets.Count))
DstSht.Name = "Consolidate_Data"
End With
'Loop through each WorkBook in the folder and copy the data to the 'Consolidate_Data' WorkSheet in the ActiveWorkBook
Set wb = ActiveWorkbook
For Each oBook In Application.Workbooks
If Not oBook.Name = wb.Name Then
'Find the last row on the 'Consolidate_Data' sheet
DstRow = fn_LastRow(DstSht) + 1
'Determine Input data range
Set copyFrom = oBook.Worksheets(1).Range("A6:C8")
'Copy data to the 'consolidated_data' WorkSheet
copyFrom.Copy _
DstSht.Range("A" & DstRow).PasteSpecial xlPasteValues
End If
Next
IfError:
'Enable Screen Updating and Events
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
'Find the last Row of specified Sheet
Function fn_LastRow(ByVal Sht As Worksheet)
Dim lastRow As Long
lastRow = Sht.Cells.SpecialCells(xlLastCell).Row
lRow = Sht.Cells.SpecialCells(xlLastCell).Row
Do While Application.CountA(Sht.Rows(lRow)) = 0 And lRow <> 1
lRow = lRow - 1
Loop
fn_LastRow = lRow
End Function
Get an error message at the PasteSpecial line. Everything works fine without the paste special but, as the copied range includes formulas, I do not get the values which is what I need.
.Copy and .PasteSpecial have to be done in 2 different lines but you concatenated the lines with _
copyFrom.Copy _
DstSht.Range("A" & DstRow).PasteSpecial xlPasteValues
Change it to:
copyFrom.Copy 'no line concatenation here !
DstSht.Range("A" & DstRow).PasteSpecial xlPasteValues
For more information see the documentation:
Range.Copy method
Range.PasteSpecial method / Worksheet.PasteSpecial method

VBA Looping & Filtering Issue

I'm running into an issue with looping through tabs in my workbook. The code I am working on is supposed to perform the following:
Loop through all worksheets except the ones titled "BOAT" & "Data"
Select cell "A2" (A2 contains the value to filter)in each worksheet that it is looping through and use it as the autofilter value for the "Data" tab
Then copy and paste the filtered data into the respective tab that is looping through.
The issue I am running into is my code isn't picking up on the active sheet in the loop. Is there a way to create a variable to for the worksheet currently being looped through?
Code below. Thank you!
Sub updatedata()
Dim ws As Worksheet
Dim wsheet2 As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If ws.name <> "BOAT" And ws.name <> "Data" Then
Call filter1
End If
Next ws
End Sub
Sub filter1()
Dim lastrow As Long
Dim lastrow2 As Long
Dim wSheet As Worksheet
Dim rInput As String
Application.DisplayAlerts = False
Set wSheet = ActiveSheet
rInput = wSheet.Range("A2").Value
Sheets("Data").Activate
lastrow = Range("A" & Rows.Count).End(xlUp).Row
ActiveSheet.Range("A1:Y" & lastrow).AutoFilter field:=4, Criteria1:="=*" & rInput & "*"
lastrow2 = Range("G" & Rows.Count).End(xlUp).Row
Range("G1:G" & lastrow2).Copy
wSheet.Activate
Range("A4").PasteSpecial xlPasteValues
Rows(4).EntireRow.Delete
Application.DisplayAlerts = True
End Sub
"Is there a way to create a variable to for the worksheet currently being looped through?"
Yes, using a Worksheet variable as an argument in filter1.
Avoid using Activate or making Range calls without specifying the Worksheet.
Sub updateData()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> "BOAT" And ws.Name <> "Data" Then
filter1 ws 'no need to use Call
End If
Next ws
End Sub
By passing ws as an Argument to filter1, all Range calls are fully qualified with the Worksheet in question. This is easily accomplished with a With...End With block - note the period . in front of .Range("A2").Value, .Range("A4"), etc - equivalent to myWs.Range("A2").Value, myWs.Range("A4")..., etc.
Sub filter1(myWs As Worksheet)
Dim lastRow As Long, lastRow2 As Long
Dim rInput As String
Application.DisplayAlerts = False
With myWs
rInput = .Range("A2").Value
With .Parent.Sheets("Data")
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A1:Y" & lastRow).AutoFilter field:=4, Criteria1:="=*" & rInput & "*"
lastRow2 = .Range("G" & .Rows.Count).End(xlUp).Row
.Range("G1:G" & lastRow2).Copy
End With
.Range("A4").PasteSpecial xlPasteValues
.Rows(4).EntireRow.Delete
End With
Application.DisplayAlerts = True
End Sub

Edit VBA to paste multiple sheets as values into new workbook

The code from this forum is what I used as a starting point. I am trying to modify it to copy multiple sheets and paste them all as values, instead of just one sheet.
I copied multiple sheets using worksheets(array(1,2,3)).copy. I think the problem is With ActiveSheet.UsedRange because it is only replacing the first sheet as values and leaving the remaining sheets as formulas.
What do I need to change so that all the sheets paste as values?
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.DisplayAlerts = False
Worksheets(Array("Sheet 1","Sheet 2","Sheet 3").Copy
With ActiveSheet.UsedRange
.Value = .Value
End With
Set wbNew = ActiveWorkbook
wbNew.SaveAs "L:\Performance Data\UK Sales\Sales (Latest).xlsx"
wbNew.Close True
Application.DisplayAlerts = True
End Sub
You need to loop through the sheets:
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.UsedRange.Value = ws.UsedRange.Value
Next ws
So, with your code, you could do it like this:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim wbOld As Workbook, wbNew As Workbook
Dim ws As Worksheet, delWS As Worksheet
Dim i As Long, lastRow As Long, lastCol As Long
Dim shts() As Variant
Dim rng As Range
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set wbOld = ActiveWorkbook
shts() = Array("Sheet 1", "Sheet 2", "Sheet 3")
Set wbNew = Workbooks.Add
Set delWS = ActiveSheet
wbOld.Worksheets(Array("Sheet 1", "Sheet 2", "Sheet 3")).Copy wbNew.Worksheets(1)
delWS.Delete
For i = LBound(shts) To UBound(shts)
With wbNew.Worksheets(shts(i))
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set rng = .Range(.Cells(1, 1), .Cells(lastRow, lastCol))
rng.Value = rng.Value
End With
Next i
wbNew.SaveAs "L:\Performance Data\UK Sales\Sales (Latest).xlsx"
wbNew.Close True
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Note: I am not sure which workbook you want to paste the values in. As it is above, it does this in the COPIED workbook, not original.

Resources