Auto Filter a sheet list and delete marked sheets and create new updated sheet from a sample sheet - excel

I am taking a shot at VBA for the first time so hoping someone can help. I have a large model with lots of sheets which are from a template sample worksheet and with value set to the serial number of the sheet on each one and the name of the worksheet set to on the master sheet list.
The master sheet list has three columns
Sheet Number--Sheet Name--Delete Flag
1-- Baby_24-- Yes
2-- Baby_36-- No
3-- Baby_48-- No
4-- Baby_60-- Yes
Trying to write a macro that goes through the master sheet list (Columns A through C), filters for Delete Flag "Yes", deletes all the sheets in the filtered dataset.
After it does that then it should go through the same list and recreate the sheets again by copying the sheet and renaming to in the master list and updating cell value B$2$ on that sheet to the sheet number in the master list. This is what I have so far.
The code generates a debug error and deletes only the first filtered sheet market "Yes" in the set and never goes to the next sheet.
Sub DeleteSheets()
' Delete Sheets Marked as Yes on SkuGroup Worksheet
Dim rRange As Range, filRange As Range, Rng As Range
' Turn off Alerts
Application.DisplayAlerts = False
'Remove any filters
ActiveSheet.AutoFilterMode = False
'~~> Set your range
Set rRange = Sheets("SKU_Groups").Range("A1:C999")
With rRange
'~~> Set your criteria and filter
.AutoFilter Field:=3, Criteria1:="=Yes"
'~~> Filter, offset(to exclude headers)
Set filRange = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
Debug.Print filRange.Address
For Each Rng In filRange
'~~> Your Code
ActiveCell.Value2 = Range("B" & .Offset(1, 0).SpecialCells(xlCellTypeVisible)(1).Row).Value2
Sheets(ActiveCell.Value2).Delete
Next
End With
'Remove any filters
ActiveSheet.AutoFilterMode = False
' Turn on Alerts
Application.DisplayAlerts = True
End Sub

No need to filter . try this :
Sub DeleteSelectedSheets()
Dim masterSheetName
Dim sh As Worksheet
masterSheetName = "master"
Sheets(masterSheetName).Select
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim rowNum
rowNum = 1
Do Until Cells(rowNum, "B").Value = ""
If Cells(rowNum, "C").Value = "Yes" Then
For Each sh In Worksheets
If sh.Name = Cells(rowNum, "B").Value Then
sh.Delete
Rows(rowNum).Delete Shift:=xlUp
rowNum = rowNum - 1
Exit For
End If
Next
End If
rowNum = rowNum + 1
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

Related

Copying columns from multiple sheets into one sheet in the same workbook using VBA

My goal is to automatically copy a range of columns (A:C) from 40+ Excel Sheet into one Sheet located in the same workbook.
The structure of all sheets is identical. Columns consist of numeric values. I want the columns to be added to the right at each iteration (so the target sheet will be enriched horizontally with the data)
My attempt (see the code below) is not automated as if I have to specify Sheet Names and Target Cell where it is possible to copy the columns
Sub macro()
Sheets("Top").Select
Columns("A:C").Select
Selection.Copy
Sheets("Low").Select
Range("D1").Select
ActiveSheet.Paste
End Sub
Any help is appreciated! Thank you
Please, try the next code. It will iterate between all existing sheets and copy all rows of columns "D:K" from all sheets in one named "Destination" (starting from "A1"). If you need it to start from "D1" it would be easy to adapt the code:
Sub copyAllSheetsInOne()
Dim ws As Worksheet, sh As Worksheet, lastRow As Long, lastEmptyCol As Long, i As Long
Set sh = Worksheets("Destination") 'a sheet named "Destination" must exist in the workbook to be processed
sh.cells.ClearContents 'clear its content (for cases when code run before)
'some optimization to make the code faster:
Application.DisplayAlerts = False: Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'iterate between all existing sheets:
For Each ws In ActiveWorkbook.Worksheets
If ws.name <> "Destination" Then
lastEmptyCol = sh.cells(1, sh.Columns.count).End(xlToLeft).Column + 1
lastRow = ws.Range("D" & ws.rows.count).End(xlUp).row
If lastEmptyCol = 2 Then lastEmptyCol = 1 'for the first sheet
ws.Range("D1", ws.Range("K" & lastRow)).Copy sh.cells(1, lastEmptyCol)
End If
Next ws
Application.DisplayAlerts = True: Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub

VBA - Combine Tables to Add Unique Rows

I have a workbook that is being updated regularly by third parties. Let's call each update WB1, WB2... The data in WB is formatted as a table in columns A:F, and there are approx. 2000 rows. There is one sheet of data. In my copy of WB, I called it "Master." In WB1, WB2..., it is "Indexes." Column A has a unique identifier for each row, and the rest of the data is text.
I'm adding notes next to each row, in columns G:H. I need to be able to merge the unique entries from WB 1 into my copy of WB, while preserving my notes in G:H, and the conditional formatting I added to WB. I want to use VBA, and I do not have Microsoft Access.
I found a partial solution here: Find Duplicate Values In Excel and Export Rows to another sheet using VBA
I made the following changes to the solution linked above:
Option Explicit
Sub MergeTables()
Dim wstSource As Worksheet, _
wstOutput As Worksheet
Dim rngMyData As Range, _
helperRng As Range, _
unionRng As Range
Dim i As Long, iOld As Long
Set wstSource = Worksheets("Indexes")
Set wstOutput = Worksheets("Master")
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With wstSource
Set rngMyData = .Range("A1:J" & .Range("A" & .Rows.Count).End(xlUp).Row)
End With
With rngMyData
Set helperRng = .Offset(, rngMyData.Columns.Count - 1).Resize(, 1)
Set unionRng = .Cells(3000, 3000) 'set a "helper" cell to be used with Union method, to prevent it from failing the first time
End With
With helperRng
.FormulaR1C1 = "=row()" 'mark rows with ad ascending number (its own row number)
.Value = .Value
End With
With rngMyData.Resize(, rngMyData.Columns.Count + 1) 'enclose "helper" column
i = .Rows(1).Row 'start loop from data first row
Do While i < .Rows(.Rows.Count).Row
iOld = i 'set current row as starting row
Do While .Cells(iOld + 1, 1) = .Cells(iOld, 1) 'loop till first cell with different value
iOld = iOld + 1
Loop
If iOld - i = 0 Then Set unionRng = Union(unionRng, .Cells(i, 1).Resize(iOld - i + 1)) 'if more than one cell found with "current" value, then add them to "UnionRng" range
i = iOld + 1
Loop
Intersect(unionRng, rngMyData).Range("A:F").Copy Destination:=wstOutput.Cells(1, 1) 'get rid of the "helper" cell via Intersect method
wstOutput.Columns(helperRng.Column).Clear 'delete "Helper" column pasted in wstOutput sheet
.Sort key1:=.Columns(6), Order1:=xlAscending, Orientation:=xlTopToBottom, Header:=xlYes ' sort data in wstSource back
End With
helperRng.Clear 'delete "helper" column, not needed anymore
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
This macro successfully adds in the new rows, but my notes in G:H do not line up with the original data anymore.
Can you please suggest alternative approaches, or revisions to this macro?
Thanks
Edit 1:
#dwirony I've attached three photos: A sample version of WB before using the macro, a sample of an updated WB1, and a sample version of WB after using the macro.

How to match columns and count the matches using vba

I am working on one scenario where I have two sheets. Sheet1 is the master sheet and sheet2 which I am creating.
Column1 of Sheet1 is Object which has duplicate objects as well. So, what I have done is I have created a macro which will produce the unique Objects and will paste it in sheet2.
Now, from Sheet2, each of the objects should be matched with Sheet1 column1 and based on the matching results, it should also count the corresponding entries from other columns in sheet1 to sheet2.
Below are the snapshots of my two sheets
Sheet1
Sheet2
here is my macro code which will first copy and paste the unique objects from sheet1 to sheet2 Column1.
Sub UniqueObj()
Dim Sh1 As Worksheet
Dim Rng As Range
Dim Sh2 As Worksheet
Set Sh1 = Worksheets("Sheet1")
Set Rng = Sh1.Range("A1:A" & Sh1.Range("A65536").End(xlUp).Row)
Set Sh2 = Worksheets("Sheet1")
Rng.Cells(1, 1).Copy Sh2.Cells(1, 1)
Rng.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Sh2.Range("A1"), Unique:=True
End Sub
But, I am unable to move forward from there. I am pretty new and any help would be very greatful.
Thanks
If I'm understanding what you want correctly, you're just counting matching columns from Sheet1 where the value in the corresponding column isn't blank? If so this should do the trick.
Option Explicit
Sub GetStuffFromSheet1()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim lastRow1 As Long, lastRow2 As Long
Dim x As Long
'turn on error handling
On Error GoTo error_handler
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Sheet2")
'determine last row with data in sheet 1
lastRow1 = ws1.Cells(ws1.Rows.Count, 1).End(xlUp).Row
'determine last row with data in sheet 2
lastRow2 = ws2.Cells(ws2.Rows.Count, 1).End(xlUp).Row
'define columns in sheet 1
Const objCol1 As Long = 1
Const rProdCol1 As Long = 3
Const keysCol1 As Long = 4
Const addKeysCol1 As Long = 5
'define columns in sheet 2
Const objCol2 As Long = 1
Const rProdCol2 As Long = 2
Const keysCol2 As Long = 3
Const addKeysCol2 As Long = 4
'turn off screen updating + calculation for speed
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'loop through all rows of sheet 2
For x = 2 To lastRow2
'formula counts # of cells with matching obj where value isn't blank
ws2.Cells(x, rProdCol2) = WorksheetFunction.CountIfs(ws1.Columns(objCol1), ws2.Cells(x, objCol2), ws1.Columns(rProdCol1), "<>" & "")
ws2.Cells(x, keysCol2) = WorksheetFunction.CountIfs(ws1.Columns(objCol1), ws2.Cells(x, objCol2), ws1.Columns(keysCol1), "<>" & "")
ws2.Cells(x, addKeysCol2) = WorksheetFunction.CountIfs(ws1.Columns(objCol1), ws2.Cells(x, objCol2), ws1.Columns(addKeysCol1), "<>" & "")
Next x
'turn screen updating + calculation back on
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Exit Sub
error_handler:
'display error message
MsgBox "Error # " & Err.Number & " - " & Err.Description, vbCritical, "Error"
'turn screen updating + calculation back on
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Exit Sub
End Sub
In case a non VBA solution works for you, you can resume your data with a Pivot Table, take field Object into rows section and rest of fields into values section (choose Count)
This returns the exact output you are looking for. Easy to update and easy to create.
In case you want a VBA solution, because your design is tabular and you are counting values, you can use CONSOLIDATE:
Consolidate data in multiple worksheets
'change K1 with cell where to paste data.
Range("K1").Consolidate Range("A1").CurrentRegion.Address(True, True, xlR1C1, True), xlCount, True, True, False
'we delete column relation type and column value. This columns depends on where you paste data, in this case, K1
Range("L:L,P:P").Delete Shift:=xlToLeft
After executing code i get this:
Hope this helps

Excel: search for a word in the column and copy it to another column on the same sheet

I have an excel table with rows of data. The column J contains various descriptions of goods. I need to search all the rows in this column for the word LATEX and when it is found, copy ONLY this word to the column A on the same sheet on the same row. I was trying to find a solution and came up with this macro using Autofilter, but it is not working properly. Can you please help me?
Sub FilterAndCopy()
Dim dataWs As Worksheet
Dim copyWs As Worksheet
Dim totRows As Long
Dim lastRow As Long
Set dataWs = Worksheets("Massiv")
Set copyWs = Worksheets("Massiv")
With dataWs
.AutoFilterMode = False
With .Range("J:J")
.AutoFilter Field:=1, Criteria1:="LATEX"
End With
End With
totRows = dataWs.Range("J:J").Rows.count
lastRow = dataWs.Range("J" & totRows).End(xlUp).Row
dataWs.Range("J:J" & lastRow).Copy
copyWs.Range("A6").PasteSpecial Paste:=xlPasteValues
dataWs.AutoFilterMode = False
With the following changes, your code should work. I've noted the changes in the comments in the code.
With dataWs
.AutoFilterMode = False
With .Range("J:J")
'Use wildcard to search for word LATEX within contents of column J cells
.AutoFilter Field:=1, Criteria1:="*LATEX*"
End With
End With
totRows = dataWs.Range("J:J").Rows.Count
lastRow = dataWs.Range("J" & totRows).End(xlUp).Row
'After filtering, select the visible cells in column A...
Set rng = dataWs.Range("A2:A" & lastRow).SpecialCells(xlCellTypeVisible)
'... and set their values to "LATEX"
rng.Value = "LATEX"
dataWs.AutoFilterMode = False

Copy and paste between sheets in a workbook with VBA code

Trying to write a macro in VBA for Excel to look at the value in a certain column from each row of data in a list and if that value is "yes" then it copies and pastes the entire row onto a different sheet in the same workbook. Let's name the two sheets "Data" and "Final". I want to have the sheets referenced so it does not matter which sheet I have open when it runs the code. I was going to use a Do loop to cycle through the rows on the one data sheet until it finds there are no more entries, and if statements to check the values.
I am confused about how to switch from one sheet to the next.
How do I specifically reference cells in different sheets?
Here is the pseudocode I had in mind:
Do while DataCells(x,1).Value <> " "
for each DataCells(x,1).Value="NO"
if DataCells(x,2).Value > DataCells(x,3).Value or _
DataCells(x,4).Value < DataCells(x,5).Value
'Copy and paste/insert row x from Data to Final sheet adding a new
'row for each qualifying row
else
x=x+1
end
else if DataCells(x,1).Value="YES"
Loop
'copy and paste entire row to a third sheet
'continue this cycle until all rows in the data sheet are examined
Sub FilterAndCopy()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Dim sh As Worksheet, sh2 As Worksheet
Dim lastrow1 As Long
Dim lastcolumn1 As Long
Set sh = ThisWorkbook.Sheets("Data")
Set sh2 = ThisWorkbook.Sheets("Final")
lastrow1 = sh.Cells(Rows.Count, "A").End(xlUp).Row ' Replace "A" With column that has the most Rows
lastcolumn1 = sh.Cells(1, Columns.Count).End(xlToLeft).Column
With sh.Range(.Cells(1, 1), .Cells(lastrow1, lastcolumn1))
'Replace the number in the field section with your Columns number
.AutoFilter , _
Field:=1, _
Criteria1:="yes"
.Copy sh2.Range("A1")
End With
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub

Resources