I want to delete all the sheets in the workbook except month end sheets for a given year eg of sheet names all sheet names are entered in this format dd.mm.yy
I tried other codes like case instead of If but all codes seems to stop at ws.delete
Sub Delete_Sheets
Yr = InputBox("Use YY format only.", "Which year to keep?", 18)
Dim ws As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "31.01.Yr" Or ws.Name <> "28.02.Yr" Or ws.Name <> "31.03.Yr" Or ws.Name <> "30.04.Yr" Or ws.Name <> "31.05.Yr" Or ws.Name <> "30.06.Yr" Or ws.Name <> "31.07.Yr" Or ws.Name <> "31.08.Yr" Or ws.Name <> "30.09.Yr" Or ws.Name <> "31.10.Yr" Or ws.Name <> "30.11.Yr" Or ws.Name <> "31.12.Yr" Then
ws.Delete
End If
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Use Application.InputBox method instead of InputBox only. This one has a Type:=1 parameter that forces the user to enter numbers only.
Make sure you test for ThisWorkbook.Worksheets.Count > 1 because you cannot delete the last worksheet. At least 1 worksheet must remain.
Put all the sheets you want to skip into an array SkipSheets and filter that array for your worksheet name (UBound(Filter(SkipSheets, ws.Name)) > -1)
Option Explicit
Public Sub DeleteSheets()
Dim InputYear As Variant
InputYear = Application.InputBox(Prompt:="Use YY format only.", Title:="Which year to keep?", Default:=18, Type:=1)
If VarType(InputYear) = vbBoolean And InputYear = False Then Exit Sub 'user pressed cancel
Dim SkipSheets() As Variant
SkipSheets = Array("31.01." & InputYear, "28.02." & InputYear, "31.03." & InputYear, "30.04." & InputYear, "31.05." & InputYear, "30.06." & InputYear, "31.07." & InputYear, "31.08." & InputYear, "30.09." & InputYear, "31.10." & InputYear, "30.11." & InputYear, "31.12." & InputYear)
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If Not (UBound(Filter(SkipSheets, ws.Name)) > -1) And ThisWorkbook.Worksheets.Count > 1 Then
ws.Delete
End If
Next ws
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
This is another approach. Since you don't want to delete the last day of every month and looks like all the sheets are the same:
Option Explicit
Sub Delete_Sheets()
Dim ws As Worksheet, Month As Date, DontDelete As String, Yr As Integer
StartAgain:
On Error Resume Next
Yr = InputBox("Use YY format only.", "Which year to keep?", 18)
On Error GoTo 0
If Yr = 0 Then
MsgBox "You didn't enter a valid value. Please Try Again"
GoTo StartAgain
End If
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name Like "??.??.??" And ThisWorkbook.Sheets.Count > 1 Then
ws.Delete
GoTo NextSheet
End If
Month = DateSerial(Yr, Mid(ws.Name, 4, 2), 1)
DontDelete = Format(Application.EoMonth(Month, 0), "dd.mm.yy")
If Not ws.Name = DontDelete Then
ws.Delete
End If
NextSheet:
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Edit: I've edited some code but it can't throw any error. Now it shouldn't delete some worksheet that it did. But there is no way you get an error.
Here is the result of the code:
Related
The parts not working are especially loop parts (marked as --- not working ---). Do I have to “activate” them first somehow?
The part which displays sheet “X” and freezing the screen isn't working too.
I want to display a picture on sheet “X” with a coffee image and the message: “please wait” until the macro is finished.
I tried to avoid the “Select” and “Activate” commands.
'Variables
Dim Destbook As Workbook
Dim Sourcebook As Workbook
Dim DestCell As Range
Dim xFile As String
Dim xFolder As String
Dim xFiles As New Collection
Dim xSheets As Worksheet
Dim xCount As Long
Dim xSheetCount As Long
Dim xRow As Long
Dim A As Integer
Dim I As Integer
Dim Z As Integer
Dim xMax As Double
'On a System Error go to "Troubleshooting" and display the ocurred fault code
On Error GoTo Troubleshooting
'Deactivate Alerts
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Application.UseSystemSeparators = False
'Display hidden Sheet "X", select cell "A1" and freeze screen
' ------------------------- NOT WORKING ---------------------
ActiveWorkbook.Sheets("X").Visible = xlSheetVisible
With ActiveWorkbook.Sheets("X")
Application.Goto .Range("A1")
ActiveWindow.FreezePanes = True
End With
'Deactivate Alerts
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Application.UseSystemSeparators = False
'Delete contents for each Sheet containing the name "Data" for the selected range
' ------------------------- NOT WORKING ---------------------
xSheetCount = ActiveWorkbook.Worksheets.Count
For Z = 1 To xSheetCount '
If Left(xSheets.Name, 4) = "Data" Then
With ActiveSheet
.Range("B5:K90000").ClearContents
End With
End If
Next Z
'Select the folder with the desired data to import
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select Folder"
.ButtonName = "Import Data"
.InitialView = msoFileDialogViewList
If .Show = -1 Then xFolder = .SelectedItems(1)
If Right(xFolder, 1) <> "\" Then xFolder = xFolder & "\"
End With
'On error or no files found display the following
If xFolder = "" Then
MsgBox ("No files found or selected!")
Exit Sub
End If
'Get the desired Textfiles in the selected Folder
Set FS = CreateObject("Scripting.FileSystemObject")
Set Folder = FS.Getfolder(xFolder)
For Each File In Folder.Files
If File.Name Like "*####-##-##*" Then
xFile = File.Name
If xFile <> "" Then
xCount = xCount + 1
xFiles.Add xFile, xFile
If xFile = "" Then Resume Next
End If
End If
Next
'File processing
I = 1
Set Destbook = ThisWorkbook
If xFiles.Count > 0 Then
For A = 1 To xFiles.Count
Set Sourcebook = Workbooks.Open(xFolder & xFiles.Item(A), local:=True)
'Skip files with no current values greater than 2 A
xMax = Application.WorksheetFunction.Max(Range("C2:C90000"))
If xMax < 2 Then
GoTo ContinueLoop
End If
If InStr(1, ActiveSheet.Name, "Stufe", vbTextCompare) <> 0 Then
Columns("I:Y").Delete
Rows(1).Insert
Range("D1").Value = ActiveSheet.Name
xRow = Cells(Rows.Count, 1).End(xlUp).Row
ActiveSheet.Range("A1:J" & xRow).Copy
End If
ThisWorkbook.Sheets("Data (" + CStr(I) + ")").Range("B3").PasteSpecial Paste:=xlPasteAll
Application.CutCopyMode = False
On Error Resume Next
On Error GoTo 0
I = I + 1
ContinueLoop: Sourcebook.Close False
Next
End If
'Just some formatting things...
' ------------------------- NOT WORKING ---------------------
xSheetCount = ActiveWorkbook.Worksheets.Count
For I = 1 To xSheetCount
If Left(Worksheet.Name, 4) = "Data" Then
With ActiveSheet.Range("A1:J" & xRow)
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
Range("B3:C3").Merge
Range("B3").Value = "Filename:"
Range("B3:K4").Font.Bold = True
Range("B4:K4").Borders.LineStyle = xlContinuous
End With
End If
Next I
'Delete sheet "Import data", hide sheet "X" and save file
'Sheets("Import data").Delete
ActiveWorkbook.Sheets("X").Visible = xlSheetVeryHidden
Application.DisplayAlerts = True
Application.ScreenUpdating = False
Application.UseSystemSeparators = True
'DestBook.SaveAs Filename:=CStr(Date) + "Analysis", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
'Display the occured error message and exit program
Troubleshooting: Application.DisplayAlerts = True
Application.ScreenUpdating = True
If Err.Number <> 0 Then MsgBox "Troubleshooting: " & _
Err.Number & vbLf & Err.Description: Err.Clear
Exit Sub
You should add some details about your data and/or your intention.
Using subprocedures could simplify your debugging task.
Avoid "On Error Goto xxx" during development as you need the error details while debugging.
Using "Option Explicit" as a first line simplifies your debugging.
I hope this helps a little! ;-)
Option Explicit
Sub ActivateAlerts_ShowSheetX()
'Activate Alerts
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.UseSystemSeparators = True
ActiveWorkbook.Sheets("X").Visible = xlSheetVisible
End Sub
Sub main()
'Variables
Dim Destbook As Workbook
Dim Sourcebook As Workbook
Dim DestCell As Range
Dim xFile As String
Dim xFolder As String
Dim xFiles As New Collection
Dim xSheets As Worksheet
Dim xCount As Long
Dim xSheetCount As Long
Dim xRow As Long
Dim aCt As Integer
Dim iCt As Integer
Dim zCt As Integer
Dim xMax As Double
'On a System Error go to "Troubleshooting" and
'display the ocurred fault code
'On Error GoTo Troubleshooting
'You want to show Sheet("X") first and then
'Deactivate ScreenUpdating
' 'Deactivate Alerts
' Application.DisplayAlerts = False
' Application.ScreenUpdating = False
' Application.UseSystemSeparators = False
'Display hidden Sheet "X", select cell "A1" and freeze screen
' ------------------------- NOT WORKING ---------------------
ActiveWorkbook.Sheets("X").Visible = xlSheetVisible
With ActiveWorkbook.Sheets("X")
Application.Goto .Range("A1")
ActiveWindow.FreezePanes = True
End With
'Deactivate Alerts
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Application.UseSystemSeparators = False
'Delete contents for each Sheet containing the name "Data"
'for the selected range
' ------------------------- NOT WORKING ---------------------
xSheetCount = ActiveWorkbook.Worksheets.Count
For zCt = 1 To xSheetCount '
If Left(Sheets(zCt).Name, 4) = "Data" Then
With ActiveSheet
.Range("B5:K90000").ClearContents
End With
End If
Next zCt
'Select the folder with the desired data to import
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select Folder"
.ButtonName = "Import Data"
.InitialView = msoFileDialogViewList
If .Show = -1 Then xFolder = .SelectedItems(1)
If Right(xFolder, 1) <> "\" Then xFolder = xFolder & "\"
End With
'On error or no files found display the following
If xFolder = "" Then
MsgBox ("No files found or selected!")
Exit Sub
End If
Dim FS As Object
Dim Folder As Object
Dim myFile As Object
'Get the desired Textfiles in the selected Folder
Set FS = CreateObject("Scripting.FileSystemObject")
Set Folder = FS.Getfolder(xFolder)
For Each myFile In Folder.Files
If myFile.Name Like "*####-##-##*" Then
MsgBox (myFile.Name & " found!")
xFile = myFile.Name
If xFile <> "" Then
xCount = xCount + 1
xFiles.Add xFile, xFile
If xFile = "" Then Resume Next
End If
End If
Next myFile
'File processing
iCt = 1
Set Destbook = ThisWorkbook
MsgBox "xFiles count: " & xFiles.Count
If xFiles.Count > 0 Then
For aCt = 1 To xFiles.Count
Set Sourcebook = Workbooks.Open(xFolder & xFiles.Item(aCt), local:=True)
'Skip files with no current values greater than 2 A
xMax = Application.WorksheetFunction.Max(Range("C2:C90000"))
If xMax < 2 Then
GoTo ContinueLoop
End If
If InStr(1, ActiveSheet.Name, "Stufe", vbTextCompare) <> 0 Then
Columns("I:Y").Delete
Rows(1).Insert
Range("D1").Value = ActiveSheet.Name
xRow = Cells(Rows.Count, 1).End(xlUp).Row
ActiveSheet.Range("A1:J" & xRow).Copy
End If
ThisWorkbook.Sheets("Data (" + CStr(iCt) +")").Range("B3").PasteSpecial Paste:=xlPasteAll
Application.CutCopyMode = False
On Error Resume Next
On Error GoTo 0
iCt = iCt + 1
ContinueLoop:
Sourcebook.Close False
Next aCt
End If
'Just some formatting things...
' ------------------------- NOT WORKING ---------------------
xSheetCount = ActiveWorkbook.Worksheets.Count
For iCt = 1 To xSheetCount
If Left(Worksheets(iCt).Name, 4) = "Data" Then
With ActiveSheet.Range("A1:J" & xRow)
.HorizontalAlignment = xlCenter
.VerticalAlignment = xlCenter
Range("B3:C3").Merge
Range("B3").Value = "Filename:"
Range("B3:K4").Font.Bold = True
Range("B4:K4").Borders.LineStyle = xlContinuous
End With
End If
Next iCt
'Delete sheet "Import data", hide sheet "X" and save file
'Sheets("Import data").Delete
ActiveWorkbook.Sheets("X").Visible = xlSheetVeryHidden
Application.DisplayAlerts = True
Application.ScreenUpdating = False
Application.UseSystemSeparators = True
'DestBook.SaveAs Filename:=CStr(Date) + "Analysis", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
'Display the occured error message and exit program
Troubleshooting:
Application.DisplayAlerts = True
Application.ScreenUpdating = True
If Err.Number <> 0 Then MsgBox "Troubleshooting: " & _
Err.Number & vbLf & Err.Description: Err.Clear
Exit Sub
End Sub
I'm new in Excel-VBA and I need to improve my macro performance. I have a macro that searches an excel, opens it, then goes through every sheet and copy-pastevalues for all cell with a specific color (yellow). Finally saves and closes the excel. In addition, excels sheets are locked and only those yellow cells are editable. This should be done for a list of excel that I indicate in a main template from where I call the macro. The problem is that it takes a lot of time and even gets blocked when the number of excels is more than 3.
I paste my code below and hope anyone can help. Thanks!
Sub Button1_Click()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim filePath As String
Dim rng As Range
Dim cel As Range
Dim cartera As String
Dim plantilla As String
Dim wb As Workbook
Dim ws As Worksheet
Dim obj_Cell As Range
filePath = Application.ThisWorkbook.Path
Range("B9").Select
Set rng = Application.Range(Selection, Selection.End(xlDown))
For Each cel In rng.Cells
cartera = cel.Value
plantilla = cel.Offset(0, 1).Value
If cartera = vbNullString Or plantilla = vbNullString Then
GoTo Saltar
End If
Application.StatusBar = "Ejecutando Cartera: " & cartera & ", Plantilla: " & plantilla
Set wb = Workbooks.Open(filePath & "\" & cartera & "\" & plantilla, UpdateLinks:=3)
For Each ws In wb.Worksheets
If ws.Name <> "Index" And ws.Name <> "Instructions" And ws.Name <> "Glossary" Then
Worksheets(ws.Name).Activate
For Each obj_Cell In Range("A1:DW105")
With obj_Cell
If obj_Cell.Interior.Color = RGB(255, 255, 153) Then
obj_Cell.Select
If obj_Cell.MergeCells = True Then
obj_Cell.MergeArea.Select
End If
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=True, Transpose:=False
If obj_Cell.MergeCells = True Then
If obj_Cell.MergeArea(1).Value = vbNullString Then
obj_Cell.MergeArea.Cells(1, 1).Select
Selection.ClearContents
End If
Else
If obj_Cell.Value = vbNullString Then
obj_Cell.ClearContents
End If
End If
End If
End With
Next obj_Cell
Range("A1").Select
End If
Next ws
Sheets(1).Select
wb.Close SaveChanges:=True
Saltar:
Next cel
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.StatusBar = False
End Sub
Untested- just some "start" ideas for you to use (e.g. no selections, using arrays, fix With statement, no GoTo). I don't understand the logic behind clearing vbNullstring. If it is necessary adapt the code in your way.
I would also suggest opening files with displayalerts on because of few potential problems (e.g. "serious error occur last time file was opened" would hangs your macro)
Sub Button1_Click()
With Application
.ScreenUpdating = False
.StatusBar = True
End With
' If possible change this reference
' from active sheet to sheet's name/codename/index
Dim activeWs As Worksheet
Set activeWs = ActiveSheet
Dim filePath As String
filePath = Application.ThisWorkbook.Path
Dim wb As Workbook
Dim ws As Worksheet
Dim obj_Cell As Range
' range definition
' if lastRow not working change to yours xlDown
' if possible End(xlUp) method is more reliable
Dim rng As Range
Dim lastRw As Long
With activeWs
lastRw = .Cells(.Cells.Rows.Count, "B").End(xlUp).Row
Set rng = .Range("B9:B" & lastRw)
End With
' read whole ranges at once
' instead of offset it is possible also to read
' cartera and plantilla at the same time to 2Darray
Dim cartera As Variant
cartera = Application.Transpose(rng.Value2)
Dim plantilla As Variant
plantilla = Application.Transpose(rng.Offset(, 1).Value2)
' main loop
Dim i As Long
For i = 1 To UBound(cartera)
If cartera(i) <> vbNullString Or plantilla(i) <> vbNullString Then
Application.StatusBar = "Ejecutando Cartera: " & cartera(i) & ", Plantilla: " & plantilla(i)
Set wb = Workbooks.Open(filePath & "\" & cartera(i) & "\" & plantilla(i), UpdateLinks:=3)
For Each ws In wb.Worksheets
If ws.Name <> "Index" And ws.Name <> "Instructions" And ws.Name <> "Glossary" Then
For Each obj_Cell In ws.Range("A1:DW105")
With obj_Cell
If .Interior.Color = RGB(255, 255, 153) Then
.Value2 = .Value2
' I commented this part beacuse it does not make sense for me...
' If .MergeCells Then
' If .MergeArea(1).Value = vbNullString Then _
.MergeArea.Cells(1, 1).ClearContents
' Else
' If .Value = vbNullString Then .ClearContents
' End If
End If
End With
Next obj_Cell
End If
Next ws
' I would place diplayalerts off here because of potential problems
' with opening files
' if problem occurs it can macro hangs
Application.DisplayAlerts = False
wb.Close SaveChanges:=True
Application.DisplayAlerts = True
End If
Next i
With Application
.ScreenUpdating = True
.DisplayAlerts = True
.StatusBar = False
End With
End Sub
The macro I wrote copies some data from several .dat files to a specific worksheet. It works fine as long as the number of records don't exceed the maximum 1,048,576 rows in my worksheet(excel 2016). How to modify the code to continue pasting data from the source file to the successive worksheets when the max row of 1,048,576 is exceeded?
I first tried to paste data from each source file in individual worksheets in my workbook. But that would create so many sheets in the workbook which I don't want. I want my data to be in minimum number of worksheets as possible.
Sub KLT()
Dim StartTime As Double
Dim MinutesElapsed As String
Dim wbA As Workbook, wbB As Workbook
Dim button_click As VbMsgBoxResult
Dim myPath As String, myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim count As Integer
Dim LIST As Integer
Dim xWs As Worksheet
Dim sh As Worksheet
Dim xcount As Integer
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
On Error Resume Next
'Remember time when macro starts
StartTime = Timer
'Deleting the "Start" sheet from previous macro run
For Each xWs In Application.Worksheets
If xWs.Name = "Start" Then
xWs.Delete
End If
Next
'Adding a new Sheet called "Start"
Worksheets.Add(After:=Worksheets(Worksheets.count)).Name = "Start"
Set wbA = ThisWorkbook
Set sh = wbA.Sheets("Start")
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.DAT*" 'my data is in .dat files
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension) 'Storing the actual raw file name
'Loop through each Excel file in folder
Execute:
Do While myFile <> ""
'Set variable equal to opened workbook
Set wbB = Workbooks.Open(Filename:=myPath & myFile)
'The source file range might be a continuation of a previous file, so ensuring the correct range is identified always
If wbB.ActiveSheet.Range("A1").Value = "Continuation of previous file." Then Range("A1").EntireRow.Delete
'Filtering data set and choosing data below headers
With wbB.ActiveSheet
.AutoFilterMode = False
With Range("A1", Range("A" & Rows.count).End(xlUp)) 'I am only interested in the data below the header
.AutoFilter 1, "*Cycle*"
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
.AutoFilter 1, "*Profile*"
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
End With
.AutoFilterMode = False
End With
'Choosing the desired range to be copied
Set Rng = Union _
(Range("A2", Range("A2").End(xlDown)), _
Range("D2", Range("D2").End(xlDown)), _
Range("E2", Range("E2").End(xlDown)), _
Range("AX2", Range("AX2").End(xlDown)))
'Rng.Select
'''Copying relevant information from the source file & pasting in the Start worksheet'''
lr = sh.Range("A" & Rows.count).End(xlUp).Row + 1
Rng.Copy sh.Range("A" & lr)
'Keeping the count of how many files have been worked on
If InStr(1, ActiveSheet.Name, "LifeCyc") > 0 Then xcount = xcount + 1
'Debug.Print xcount
''''''''***********''''''''
'Close Workbook
wbB.Close 'SaveChanges:=True
'Ensure Workbook has closed before moving on to next line of code
DoEvents
'Get next file name
myFile = Dir
Loop
'Creating the headers in my report sheet
With sh
.Range("A1").Value = "Date"
.Range("B1").Value = "CumSec"
.Range("C1").Value = "LifeCycleNo"
.Range("D1").Value = "dT"
End With
'Formatting the headers
With sh.Range("A1:D1")
.Interior.Color = rgbBlue
.LineStyle = xlContinuous
.Borders.Color = rgbBlack
.HorizontalAlignment = xlCenter
.Font.Bold = True
.Font.Color = rgbWhite
End With
'Formatting the actual dataset
With sh.Range("A2:D2", Range("A2:D2").End(xlDown))
.LineStyle = xlContinuous
.Borders.Color = rgbBlack
End With
Columns("A:D").AutoFit
'Determine how long the code took to run
MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss")
'Displaying a message on the screen after completion of the task
MsgBox "This code ran successfully in " & MinutesElapsed & " minutes " & "Total Raw Files Processed: " & CStr(xcount), vbInformation
'Reset Macro Optimization Settings
ResetSettings:
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = False
Application.AutomationSecurity = lSecurity
End Sub
Expected outcome is to continue pasting data in successive sheets whenever the current worksheet's row number exceeds the max limit
I am not convinced that it is a good idea to let Excel handle such an amount of data, and I am not sure how you want to deal with more than one sheet having data...
Remove On Error Resume Next. It will hide all errors and you will never recognize that your code had a problem.
Set your wbA-variable at the beginning and work with that, not with then Application.Worksheets object.
Introduce a sheet-counter variable.
Before copying the Range, check if you have enough space left, else create the next sheet.
Do the formatting for all sheets.
Code could look like this (untested, may contain syntax errors)
const SHEETNAME = "Start"
Set wbA = ThisWorkbook
For Each xWs In wbA.Worksheets
If xWs.Name like SHEETNAME & "*" Then
xWs.Delete
End If
Next xWs
dim sheetCount as Long
sheetCount = 1
set sh = wbA.Worksheets.Add(After:=wbA.Worksheets(wbA.Worksheets.count))
sh.Name = SHEETNAME & sheetCount
(...)
lr = sh.Range("A" & Rows.count).End(xlUp).row + 1
If lr + rng.rows.count > sh.Rows.count then
' Not enough space left, add new sheet.
sheetCount = sheetCount + 1
set sh = wbA.Worksheets.Add(After:=sh)
sh.Name = SHEETNAME & sheetCount
lr = 1
End if
rng.Copy sh.Range("A" & lr)
(...)
' Format all data sheets.
For Each xWs In wbA.Worksheets
with xWs
If .Name like SHEETNAME & "*" Then
.Range("A1").Value = "Date"
(...)
' Create a table
lr = .Range("A" & Rows.count).End(xlUp).row
.ListObjects.Add(xlSrcRange, .Range("$A$1:$D$" & lr), , xlYes).Name = "Table_" & .Name
End If
End With
Next xWs
I'm trying to loop through sheets, and remove row entries that are not equal to sheet name.
I've if statements to ignore particular sheets.
It will only work on one sheet and won't loop through all.
Sub CleanRegionalSheets()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim lngx As Long
With ws
For Each ws In ActiveWorkbook.Worksheets
If ActiveSheet.Name = "Raw Data" Then
ElseIf ActiveSheet.Name = "Building Status" Then
ElseIf ActiveSheet.Name = "Clean Data" Then
Else
For lngx = Cells(Rows.Count, "A").End(xlUp).Row To 3 Step -1
If Cells(lngx, "A").Value <> ActiveSheet.Name Then
Cells(lngx, "A").EntireRow.Delete Shift:=xlUp
End If
Next
End If
Next
End With
End Sub
Updated code, still not working:
Sub CleanRegionalSheets()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim lngx As Long
For Each ws In ActiveWorkbook.Worksheets
If ws.Name = "Raw Data" Then
ElseIf ws.Name = "Building Status" Then
ElseIf ws.Name = "Clean Data" Then
Else
For lngx = Cells(Rows.Count, "A").End(xlUp).Row To 3 Step -1
If Cells(lngx, "A").Value <> ws.Name Then
Cells(lngx, "A").EntireRow.Delete Shift:=xlUp
End If
Next
End If
Next
End Sub
You are missing the ws object. Try this (you also forgot to enable ScreenUpdate at the end):
Sub CleanRegionalSheets()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim lngx As Long
For Each ws In ActiveWorkbook.Worksheets
Select Case ws.Name
Case "Raw Data", "Building Status", "Clean Data"
Case Else
With ws
For lngx = .Cells(.Rows.Count, "A").End(xlUp).Row To 3 Step -1
If .Cells(lngx, "A").Value <> .Name Then
.Rows(lngx).Delete Shift:=xlUp
End If
Next
End With
End Select
Next
Application.ScreenUpdating = True
End Sub
The following macro works fine without the 1st and 3rd lines emphasised (i.e. password protection). When I add the code the macro works the first time but if I open the file again, it returns a run time error 'pastespecial method of range class failed' at the line second line emphasised. The purpose of the macro is to open a purchase order template, increment the purchase order number by one, complete a second log file with date, purchase order number and user name and re-save the purchase order template under a different file name:
Private Sub Workbook_Open()
If ThisWorkbook.ReadOnly Then
MsgBox "Please use dropdown arrow next to filename within SharePoint and select 'Edit in Microsoft Office Excel' instead."
ThisWorkbook.Close
End If
Range("L14") = Range("L14") + 1
ActiveWorkbook.Save
Range("L14").Copy
Workbooks.Open Filename:="\\ehfnp01\users\gminter\My Documents\PO Log Elite\PO Log Elite.xls"
Workbooks("PO Log Elite.xls").Activate
Dim lst As Long
With ActiveWorkbook.Sheets("Sheet1")
*.Unprotect Password:="2"*
lst = .Range("B" & Rows.Count).End(xlUp).Row + 1
**.Range("B" & lst).PasteSpecial xlPasteValuesAndNumberFormats**
End With
With ActiveWorkbook.Sheets("Sheet1")
lst = .Range("A" & Rows.Count).End(xlUp).Row + 1
.Range("A" & lst) = Now
End With
With ActiveWorkbook.Sheets("Sheet1")
lst = .Range("C" & Rows.Count).End(xlUp).Row + 1
.Range("C" & lst).Value = Environ("Username")
*.Protect Password:="2"*
End With
ActiveWorkbook.Save
ActiveWorkbook.Close
ThisFile = Application.DefaultFilePath & "\" & Range("G14").Value & Range("L14").Text
ActiveWorkbook.SaveAs Filename:=ThisFile
Range("L15") = Now
Range("E20").Value = Environ("Username")
ScreenUpdating = False
Set Rng = Intersect(ActiveSheet.UsedRange, Range("e20"))
For Each C In Rng
C.Value = StrConv(C.Value, vbUpperCase)
Next
ScreenUpdating = True
Cells.Locked = False
Range("G14:N15,E20:N20").Locked = True
ActiveSheet.Protect Password:="1"
Dim x As Integer
On Error Resume Next
With ActiveWorkbook.VBProject
For x = .VBComponents.Count To 1 Step -1
.VBComponents.Remove .VBComponents(x)
Next x
For x = .VBComponents.Count To 1 Step -1
.VBComponents(x).CodeModule.DeleteLines _
1, .VBComponents(x).CodeModule.CountOfLines
Next x
End With
On Error GoTo 0
End Sub
Any help would be greatly appreciated as I can't find any similar examples of this.
What happens when you explicitly declare your Objects/Variables and then work with them? That ways you do the copy just before you paste. This will ensure that the clipboard doesn't get cleared for any reason which Excel is unfortunately famous for...
Private Sub Workbook_Open()
Dim rng As Range
Dim newWb As Workbook, wb As Workbook
Dim lst As Long
If ThisWorkbook.ReadOnly Then
MsgBox "Please use dropdown arrow next to filename within SharePoint and select 'Edit in Microsoft Office Excel' instead."
ThisWorkbook.Close
Exit Sub '<~~ ?
End If
Set rng = ThisWorkbook.Sheets("Sheet1").Range("L14")
rng.Value = rng.Value + 1
ThisWorkbook.Save
Set newWb = Workbooks.Open(Filename:="\\ehfnp01\users\gminter\My Documents\PO Log Elite\PO Log Elite.xls")
Set wb = Workbooks("PO Log Elite.xls")
With wb.Sheets("Sheet1")
.Unprotect Password:="2"
lst = .Range("B" & .Rows.Count).End(xlUp).Row + 1
rng.Copy '<~~ Do the copy here
.Range("B" & lst).PasteSpecial xlPasteValuesAndNumberFormats
End With
'
'~~> Rest of the code
'
End Sub