Creating a macro to Unhide worksheets and Clear Used Rows, Resetting the workbook - excel

I have a 52 sheet workbook that needs to be reset after the file is saved as a copy.
I have the UnHide part figured out, but I can't seem to figure out the Clearcontents.
On many Worksheets, not all, in row A there is a string "State Requires All License Verifications"
It is in a variable row, between 6 and 12. Starting with ws2 I want to find the string and clear the rows below it. Column range A:H
Then Check the next worksheet.
I have this so far..
Sub UnhideAllSheets()
Dim ws As Worksheet
Dim rowNum As Long
Dim stateReg As String
For Each ws In ActiveWorkbook.Worksheets
ws.Visible = xlSheetVisible
If ws.Visible Then
'Activate sheet
ws.Activate
'Look for String "State Requires All License Verifications"
Set stateReq = .Find(what:="State Requires All License Verifications")
'Null find quits loop
If Not stateReq Is Nothing Then
rowNum = stateReq.Row
End If
'Clear all Used rows after String(stateReq)
With Sheets(ws)
Intersect(.Range(.Rows(rowNum + 1), .UsedRange.Rows(.UsedRange.Rows.Count)), .Range("A:H")).ClearContents
End With
'Select and Zoom to A1 upon leaving the worksheet
Range("A1").Select
ActiveWindow.ScrollRow = 1
ActiveWindow.ScrollColumn = 1
End If
Next ws
'Jump back to the first worksheet "Information"
Sheets("Information").Select
Range("E2").Select
End Sub

Try this. Not sure where you got stuck.
I have assumed the string is in column A and that A is also a reliable indicator of the last used row (so may need changing).
Also no need to activate the sheet.
Sub UnhideAllSheets()
Dim ws As Worksheet
Dim rowNum As Long
Dim stateReg As Range
For Each ws In ActiveWorkbook.Worksheets
ws.Visible = xlSheetVisible
Set stateReg = ws.Columns(1).Find(what:="State Requires All License Verifications", Lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)
If Not stateReg Is Nothing Then
Range(stateReg.Offset(1), ws.Range("A" & Rows.Count).End(xlUp)).Resize(, 8).ClearContents
End If
Next ws
'Jump back to the first worksheet "Information"
Application.Goto Sheets("Information").Range("E2")
End Sub

Maybe something like:
Sub Fresh_Slate()
Dim ws As Worksheet
Dim Found As Range
Dim Target As String
Dim lr As Long
Target = "State Requires All License Verifications"
For Each ws In ThisWorkbook.Sheets
If ws.Name <> "Sheet1" Then 'You can add sheets to ignore here
ws.Visible = xlSheetVisible
Set Found = ws.Cells.Find(Target)
If Not Found Is Nothing Then
'Assuming Column A on each sheet is a good indicator of the last used row in range
lr = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
ws.Range(ws.Cells(Found.Row + 1, 1), ws.Cells(lr, 8)).ClearContents
End If
Set Found = Nothing
End If
Next ws
End Sub

Related

Copy and paste data between workbooks depending on drop-down choice

Just a quick one, I have coded a piece of VBA that copies and pastes data between two workbooks. However, I would like to be able to copy specific data across rather than the entire table. So workbook "x" I would like to filter column 'L' by a choice of a drop down box in workbook "y" - field "P14".
how would I do this, so that whatever the user chooses it filters and pastes that data into workbook y.
Code below for what I've done so far:
Private Sub CommandButton1_Click()
Dim x As Workbook
Dim y As Workbook
Dim p As String
Set p = y.Worksheets("Title").Cells(14, "P").Value
Set x = Workbooks.Open("C:\Users\name\Desktop\Project
Autonetics\CoreData")
'x.Worksheets("Xero").Range("L1").AutoFilter Field:=1, Criteria:="p"
With Xero
.AutoFilterMode = False
With .Range("L:L")
.AutoFilter Field:=1, Criteria:="p"
.SpecialCells (xlCellTypeVisible)
End With
End With
Set y = ThisWorkbook
x.Worksheets("Xero").Range("A1:L100000").Copy
Application.DisplayAlerts = False
y.Worksheets("Costings").Range("A1").PasteSpecial
x.Close
End Sub
Here is something for you to work with. Personally I'm not such a On Error fan, but it would be legitimate use inside to check for a returned error when using SpecialCells.
Private Sub CommandButton1_Click()
Dim wb1 As Workbook, wb2 As Workbook
Dim sht1 As Worksheet, sht2 As Worksheet
Dim lc As Long, lr As Long
Dim rng As Range, str As String
'Set your two workbooks
Set wb1 = ThisWorkbook
Set wb2 = Workbooks.Open("C:\Users\name\Desktop\ProjectAutonetics\CoreData")
'Set your two worksheets
Set sht1 = wb1.Worksheets("Title")
Set sht2 = wb2.Worksheets("Xero")
'Get your criteria ready
str = sht1.Range("P14").Value
'Get your range to filter ready
With sht2
lr = .Cells(.Rows.Count, 12).End(xlUp).Row
lc = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set rng = .Range(.Cells(1, 1), .Cells(lr, lc))
End With
'Apply filter and act if any hits
rng.AutoFilter 12, str
If rng.SpecialCells(12).Cells.Count > rng.Rows(1).Cells.Count Then
rng.SpecialCells(12).Copy sht1.Cells(1, 1)
End If
'Close your second workbook
wb2.Close False
End Sub
I been quite extensive in the hope you can clearly see what is going on in this code.
Good luck.

How to Copy and Append filtered data sourced from multiple sheets into a single destination sheet using a loop?

EDIT: I've pasted some revised code below in the Sub(Copyinternal) section. Still doesn't work but maybe I'm on the right track?
I have a workbook with 6 tabs. Sheets are set up as follows:
Controls
Forecast
Financial Update
Board Goals
Internal Calendar
External Calendar
Sheets 2-4 contain data tables that I would like to filter in two different ways and copy/paste to both tabs 5 & 6 without overwriting.
Sheets 5 & 6 have headers in row 1 that I would like to maintain.
Trying to:
First delete any existing information in "Internal Calendar" sheet and "External Calendar" sheet from Row 2 down without deleting the headers.
In "Forecast" sheet, filter column H on selections "Both" and "Internal" in and then copy/paste that information into "Internal Calendar" sheet starting in column C. I'm then trying to do the same for "Financial Update" and "Board Goals" sheets, but Copy/Pasting the filtered information after the content that's already been pasted into "Internal Calendar", as to not overwrite information.
Repeat step 2 except Filter H on "Both" and "External" and Copy/Paste the filtered info into "External Calendar" starting in column C.
Controls sheet can be ignored.
Loop begins to run correctly only if I run the macro while my active sheet is "Forecast", but then it stops after pasting that data and doesn't move onto the following two sheets. I'm also not entirely sure the existing code I have will identify the first empty row to append data to in the destination sheets.
I'm pretty new to using VBA, so a guide in the right direction would be very appreciated.
Sub CalendarAutomation()
ClearSheets
CopyInternal
CopyExternal
End Sub
Sub ClearSheets()
'Clear out Contents
Sheets("Internal Calendar").Select
activesheet.Range("C2:G250").Select
Selection.ClearContents
Sheets("External Calendar").Select
Range("C2:G250").Select
Selection.ClearContents
End Sub
Sub CopyInternal()
Dim ws As Variant
Dim starting_ws As Worksheet
Dim ending_ws As Worksheet
Dim rng As range
Set starting_ws = ThisWorkbook.Worksheets("Forecast")
Set ending_ws = ThisWorkbook.Worksheets("Internal Calendar")
Set rng = ActiveRange
For ws = 2 To 4
If Selection.AutoFilter = OFF Then Selection.AutoFilter
ws.rng.AutoFilter Field:=6, Criteria1:="=Both", _
Operator:=xlOr, Criteria2:="=Internal"
UsedRange.Copy
ending_ws.range(Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).Row).Paste
Next ws
End Sub
Sub CopyExternal()
Dim ws As Worksheet
Dim unusedRow As Long
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name = "Controls" _
And Not ws.Name = "Internal Calendar" _
And Not ws.Name = "External Calendar" Then
Range("$C$3:$H$14").AutoFilter Field:=6, Criteria1:="=Both", _
Operator:=xlOr, Criteria2:="=External"
Range("C4:G14").Select
Selection.Copy
Sheets("External Calendar").Select
activesheet.Paste
unusedRow = Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).Row
End If
Next ws
End Sub
Try this:
Sub tst()
Dim ctrl As Worksheet: Set ctrl = ThisWorkbook.Sheets("Controls")
Dim fcast As Worksheet: Set fcast = ThisWorkbook.Sheets("Forecast")
Dim fu As Worksheet: Set fu = ThisWorkbook.Sheets("Financial Update")
Dim bg As Worksheet: Set bg = ThisWorkbook.Sheets("Board Goals")
Dim ic As Worksheet: Set ic = ThisWorkbook.Sheets("Internal Calendar")
Dim ec As Worksheet: Set ec = ThisWorkbook.Sheets("External Calendar")
Dim ic_last_r As Long
Dim ec_last_r As Long
ic_last_r = ic.Cells(ic.Rows.Count, 3).End(xlUp).Row
ec_last_r = ec.Cells(ec.Rows.Count, 3).End(xlUp).Row
If ic_last_r < 2 Then ic_last_r = 2 'avoid deleting 1st row
If ec_last_r < 2 Then ec_last_r = 2
ic.Rows("2:" & ic_last_r).ClearContents
ec.Rows("2:" & ec_last_r).ClearContents
copy_paste fcast, ic, "Both", "Internal", Array("Controls", "Forecast", "External Calendar")
copy_paste fcast, ec, "Both", "External", Array("Controls", "Forecast", "Internal Calendar")
End Sub
Sub copy_paste(ws1 As Worksheet, ws2 As Worksheet, c1 As String, c2 As String, wsheets)
Dim ws As Worksheet
Dim ws2_last_r As Long
For Each ws In ThisWorkbook.Worksheets
For i = LBound(wsheets) To UBound(wsheets)
If ws.Name = wsheets(i) Then GoTo n_ext
Next
ws2_last_r = ws2.Cells(ws2.Rows.Count, 3).End(xlUp).Row
ws1.Range("A1").AutoFilter 8, c1, xlOr, c2
ws1.Range("A1").CurrentRegion.Columns("C:G").Copy
ws2.Range("C" & ws2_last_r).PasteSpecial xlPasteAll
ws1.Range("A1").AutoFilter
n_ext:
Next
End Sub
Your code after changes (I hope it will work for you but there is a space for improvement):
Sub CalendarAutomation()
ClearSheets
CopyInternal
CopyExternal
End Sub
Sub ClearSheets()
'Clear out Contents
Sheets("Internal Calendar").Range("C2:G250").ClearContents
Sheets("External Calendar").Range("C2:G250").ClearContents
End Sub
Sub CopyInternal()
Dim ws As Variant
Dim starting_ws As Worksheet
Dim ending_ws As Worksheet
Dim rng As Range
Set starting_ws = ThisWorkbook.Worksheets("Forecast")
Set ending_ws = ThisWorkbook.Worksheets("Internal Calendar")
For ws = 2 To 4
If Sheets(ws).AutoFilterMode Then Sheets(ws).Range("A1").AutoFilter
Sheets(ws).Range("A1").AutoFilter 6, "Both", xlOr, "Internal"
Sheets(ws).UsedRange.Copy
ending_ws.Cells(ending_ws.Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).Row, 3).PasteSpecial xlPasteAll 'pasting into "C" column
Next ws
End Sub
Sub CopyExternal()
Dim ws As Worksheet
Dim unusedRow As Long
Dim external As Worksheet: Set external = ThisWorkbook.Worksheets("External Calendar")
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name = "Controls" _
And Not ws.Name = "Internal Calendar" _
And Not ws.Name = "External Calendar" Then
unusedRow = external.Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).Row 'if you want to find last filled row i suggest to change to: external.cells(external.rows.count, [column number]).end(xlup).row
ws.Range("A1").AutoFilter Field:=6, Criteria1:="=Both", _
Operator:=xlOr, Criteria2:="=External"
ws.UsedRange.Copy
external.Cells(unusedRow, 1).PasteSpecial xlPasteAll 'paste into "A" column
End If
Next ws
End Sub

Copy-Paste range (inc. entirerow) from Min to Max

(1) I´d appreciate if somebody could help me briefly. I can not really figure out how to include the formula "entire row" into the code below, so that the macro copies from min to max in column F but also the entire row of each data point...
Sub Enter_Formula()
Dim sht As Worksheet, summarySht As Worksheet
Set summarySht = Worksheets("SummarySheet") '<--| change "Summary" to your actual "Summary" sheet name
For Each sht In Worksheets
If sht.Name <> summarySht.Name Then
With sht.Range("F15000:F20000")
.Parent.Range(.Find(what:=WorksheetFunction.Min(.Cells), lookat:=xlWhole, LookIn:=xlValues), .EntireColumn.Find(what:=WorksheetFunction.Max(.EntireColumn), lookat:=xlWhole, LookIn:=xlValues)).Copy summarySht.Cells(1, Columns.Count).End(xlToLeft).Offset(, 1)
End With
End If
Next
End Sub
(2) The other question is, how to modify the code, so that excel creates an extra "summary" sheet for each sheet the macro runs over. I do not want one summarysheet for all the found ranges because that is too confusing for the reader.
Thank you very much!
Try this (not sure you really need to copy the whole row though do you?) The summary sheet name is just the sheet name preceded by "Summary".
Sub x()
Dim sht As Worksheet, summarySht As Worksheet
Dim rMin As Range, rMax As Range
For Each sht In Worksheets
If Not sht.Name Like "Summary*" Then
Set summarySht = Sheets.Add(after:=Sheets(Sheets.Count))
summarySht.Name = "Summary " & sht.Name
With sht.Range("F15000:F20000")
Set rMin = .Find(what:=WorksheetFunction.Min(.Cells), lookat:=xlWhole, LookIn:=xlValues)
Set rMax = .EntireColumn.Find(what:=WorksheetFunction.Max(.EntireColumn))
.Parent.Range(rMin, rMax).EntireRow.Copy summarySht.Range("A1")
End With
End If
Next sht
End Sub

Remove Entire Row if Column Contains $0.00 Value [duplicate]

I have an excel workbook, in worksheet1 in Column A, IF the value of that column = ERR I want it to be deleted (the entire row), how is that possible?
PS: keep in mind that I have never used VBA or Macros before, so detailed description is much appreciated.
Using an autofilter either manually or with VBA (as below) is a very efficient way to remove rows
The code below
Works on the entire usedrange, ie will handle blanks
Can be readily adpated to other sheets by changing strSheets = Array(1, 4). ie this code currently runs on the first and fourth sheets
Option Explicit
Sub KillErr()
Dim ws As Worksheet
Dim lRow As Long
Dim lngCol As Long
Dim rng1 As Range
Dim strSheets()
Dim strws As Variant
strSheets = Array(1, 4)
For Each strws In strSheets
Set ws = Sheets(strws)
lRow = ws.Cells.Find("*", , xlValues, , xlByRows, xlPrevious).Row
lngCol = ws.Cells.Find("*", , xlValues, , xlByColumns, xlPrevious).Column
Application.ScreenUpdating = False
ws.Rows(1).Insert
Set rng1 = ws.Range(ws.Cells(1, lngCol), ws.Cells(lRow + 1, lngCol))
With rng1.Offset(0, 1)
.FormulaR1C1 = "=RC1=""ERR"""
.AutoFilter Field:=1, Criteria1:="TRUE"
.EntireRow.Delete
On Error Resume Next
.EntireColumn.Delete
On Error GoTo 0
End With
Next
Application.ScreenUpdating = True
End Sub
sub delete_err_rows()
Dim Wbk as Excel.workbook 'create excel workbook object
Dim Wsh as worksheet ' create excel worksheet object
Dim Last_row as long
Dim i as long
Set Wbk = Thisworkbook ' im using thisworkbook, assuming current workbook
' if you want any other workbook just give the name
' in invited comma as "workbook_name"
Set Wsh ="sheetname" ' give the sheet name here
Wbk.Wsh.activate
' it means Thisworkbook.sheets("sheetname").activate
' here the sheetname of thisworkbook is activated
' or if you want looping between sheets use thisworkbook.sheets(i).activate
' put it in loop , to loop through the worksheets
' use thisworkbook.worksheets.count to find number of sheets in workbook
Last_row = ActiveSheet.Cells(Rows.count, 1).End(xlUp).Row 'to find the lastrow of the activated sheet
For i = lastrow To 1 step -1
if activesheet.cells(i,"A").value = "yourDesiredvalue"
activesheet.cells(i,"A").select ' select the row
selection.entirerow.delete ' now delete the entire row
end if
Next i
end sub
Note any operations that you do using activesheet , will be affected on the currently activated sheet
As your saying your a begginner, why dont you record a macro and check out, Thats the greatest way to automate your process by seeing the background code
Just find the macros tab on the sheet and click record new macro , then select any one of the row and do what you wanted to do , say deleting the entire row, just delete the entire row and now go back to macros tab and click stop recording .
Now click alt+F11 , this would take you to the VBA editor there you find some worksheets and modules in the vba project explorer field , if you dont find it search it using the view tab of the VBA editor, Now click on module1 and see the recorded macro , you will find something like these
selection.entirerow.delete
I hope i helped you a bit , and if you need any more help please let me know, Thanks
Fastest method:
Sub DeleteUsingAutoFilter()
Application.ScreenUpdating = False
With ActiveSheet
.AutoFilterMode = False
.Columns("A").AutoFilter Field:=1, Criteria1:="ERR"
.AutoFilter.Range.Offset(1, 0).EntireRow.Delete
.AutoFilterMode = False
End With
Application.ScreenUpdating = True
End Sub
Second fastest method (lots of variations to this one too):
Sub DeleteWithFind()
Dim rFound As Range, rDelete As Range
Dim sAddress As String
Application.ScreenUpdating = False
With Columns("A")
Set rFound = .Find(What:="ERR", After:=.Resize(1, 1), SearchOrder:=xlByRows)
If Not rFound Is Nothing Then
Set rDelete = rFound
Do
Set rDelete = Union(rDelete, rFound)
Set rFound = .FindNext(rFound)
Loop While rFound.Row > rDelete.Row
End If
If Not rDelete Is Nothing Then rDelete.EntireRow.Delete
End With
Application.ScreenUpdating = True
End Sub
Autofilter method for multiple sheets:
Sub DeleteUsingAutoFilter()
Dim vSheets As Variant
Dim wsLoop As Worksheet
Application.ScreenUpdating = False
'// Define worksheet names here
vSheets = Array("Sheet1", "Sheet2")
For Each wsLoop In Sheets(vSheets)
With wsLoop
.AutoFilterMode = False
.Columns("A").AutoFilter Field:=1, Criteria1:="ERR"
.AutoFilter.Range.Offset(1, 0).EntireRow.Delete
.AutoFilterMode = False
End With
Next wsLoop
Application.ScreenUpdating = True
End Sub
Assuming there are always values in the cells in column A and that the data is in the first sheet, then something like this should do what you want:
Sub deleteErrRows()
Dim rowIdx As Integer
rowIdx = 1
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)
While ws.Cells(rowIdx, 1).Value <> ""
If ws.Cells(rowIdx, 1).Value = "ERR" Then
ws.Cells(rowIdx, 1).EntireRow.Delete
Else
rowIdx = rowIdx + 1
End If
Wend
End Sub

Extracting Data from Excel Database

I've got a database with a long list of names, and unique values associated with the names. What I want to do is create one worksheet for each individual, and then copy only their data to a specified range in their worksheet, then proceed to the next individual, copy their data to their worksheet etc.
Here is a link to an example worksheet (in google docs form, note - I am actually using Excel 2010, not google docs).
I've been able to create all the worksheets through using the following code in a new sheet I called "Employee". All I did to this sheet was remove the duplicate name values so I could have a list of all the names for the worksheets.
Any help is much appreciated. Thanks in advance.
Sub CreateSheetsFromAList()
Dim nameSource As String 'sheet name where to read names
Dim nameColumn As String 'column where the names are located
Dim nameStartRow As Long 'row from where name starts
Dim nameEndRow As Long 'row where name ends
Dim employeeName As String 'employee name
Dim newSheet As Worksheet
nameSource = "Employee"
nameColumn = "A"
nameStartRow = 1
'find the last cell in use
nameEndRow = Sheets(nameSource).Cells(Rows.Count, nameColumn).End(xlUp).Row
'loop till last row
Do While (nameStartRow <= nameEndRow)
'get the name
employeeName = Sheets(nameSource).Cells(nameStartRow, nameColumn)
'remove any white space
employeeName = Trim(employeeName)
' if name is not equal to ""
If (employeeName <> vbNullString) Then
On Error Resume Next 'do not throw error
Err.Clear 'clear any existing error
'if sheet name is not present this will cause error that we are going to leverage
Sheets(employeeName).Name = employeeName
If (Err.Number > 0) Then
'sheet was not there, so it create error, so we can create this sheet
Err.Clear
On Error GoTo -1 'disable exception so to reuse in loop
'add new sheet
Set newSheet = Sheets.Add(After:=Sheets(Sheets.Count))
'rename sheet
newSheet.Name = employeeName
'paste training material
Sheets(employeeName).Cells(1, "A").PasteSpecial
Application.CutCopyMode = False
End If
End If
nameStartRow = nameStartRow + 1 'increment row
Loop
End Sub
Bare bones approach - could be optimized for better performance, but it will do the job.
Sub SplitToSheets()
Dim c As Range, ws As Worksheet, rngNames
With ThisWorkbook.Sheets("EmployeeData")
Set rngNames = .Range(.Range("A1"), .Cells(Rows.Count, 1).End(xlUp))
End With
For Each c In rngNames.Cells
Set ws = GetSheet(ThisWorkbook, c.Value)
c.EntireRow.Copy ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Next c
End Sub
Function GetSheet(wb As Workbook, wsName As String, _
Optional CreateIfMissing As Boolean = True) As Worksheet
Dim ws As Worksheet
On Error Resume Next
Set ws = wb.Sheets(wsName)
On Error GoTo 0
If ws Is Nothing And CreateIfMissing Then
Set ws = wb.Sheets.Add(after:=wb.Sheets(wb.Sheets.Count))
ws.Name = wsName
End If
Set GetSheet = ws
End Function

Resources