I am using this code to import a worksheet from a closed file. Once the import is complete I want to delete a column from that worksheet and switch back to the primary worksheet. I tried using Columns(4).Delete and EntireColumns.Delete but there is no error and Excel takes no action. Any ideas on a better way I could do this?
'THIS CODE HANDLES THE IMPORT OF THE DATA
Sub ImportFile()
'DEFINITIONS
Dim fileImport As String
Dim srcBook As Workbook
' TURNS OFF SCREEN UPDATING
Application.ScreenUpdating = False
Application.EnableEvents = False
' THE FILE PATH
fileImport = "PATH"
'OPENS THE BOOK
Set sourceB = Application.Workbooks.Open(fileImport)
'COPYS THE SHEET
sourceB.Sheets("Miscellaneous Holds").Copy After:=ThisWorkbook.Sheets (ThisWorkbook.Sheets.Count)
' CLOSES THE BOOK
srcBook.Close True
'ENABLES SCREEN EDIT
Application.ScreenUpdating = True
Application.EnableEvents = True
Sheets("Main").Activate
End Sub
This maybe not working if you are not qualifying the sheet properly in your Columns(4).EntireColumn.Delete statement...
So use sourceB.Sheets("Miscellaneous Holds").Columns(4).EntireColumn.Delete instead....
If you don't want these changes to be saved in your source workbook then change the saveChanges parameter to false.
'THIS CODE HANDLES THE IMPORT OF THE DATA
Sub ImportFile()
'DEFINITIONS
Dim fileImport As String
Dim srcBook As Workbook
Dim srcSheet As Worksheet
' TURNS OFF SCREEN UPDATING
Application.ScreenUpdating = False
Application.EnableEvents = False
' THE FILE PATH
fileImport = "PATH"
'OPENS THE BOOK
Set srcBook = Application.Workbooks.Open(fileImport)
Set srcSheet = sourceB.Sheets("Miscellaneous Holds")
srcSheet.Columns(4).EntireColumn.Delete
'COPYS THE SHEET
srcSheet.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
' CLOSES THE BOOK
srcBook.Close False
'ENABLES SCREEN EDIT
Application.ScreenUpdating = True
Application.EnableEvents = True
ThisWorkbook.Sheets("Main").Activate
End Sub
Related
I'm writing a macro in VBA for Excel. I want it to replace all worksheets except for a few. First there is a loop which deletes the unwanted sheets, and then comes another one which creates new sheets to repace them! On a first run, the macro removes unwanted sheets. However, if it is run again it seems to be unable to delete the sheets it previously created, which causes a name duplicity error.
(The rng variable is supposed to extend across the entire row but I haven't gotten to fixing that yet.)
Hope you guys can provide some insight, much appreciated!
sub Terminator()
Dim Current As Worksheet
Application.DisplayAlerts = False
' Loop through all of the worksheets in the active workbook.
For Each Current In Worksheets
If Not Current.Name = "Data" Then
Worksheets(Current.Name).Delete
End If
Next Current
Application.DisplayAlerts = True
' Define range for loop
Dim rng As Range, cell As Range
Set rng = Sheets("Data").Range("A5:M5")
' Loop through entire row, looking for employees
For Each cell In rng
If cell.Value = "Nummer" Then
' Make new chart for employee
With Charts.Add
.ChartType = xlLineMarkers
.Name = cell.Offset(-1, 1).Value
.HasTitle = True
.ChartTitle.Text = cell.Offset(-1, 1).Value
' Set data (dynamic) and x-axis (static) for new chart
.SetSourceData Source:=Sheets("Data").Range(cell.Offset(-2, 3), cell.Offset(7, 4))
.Axes(xlValue).MajorGridlines.Select
.FullSeriesCollection(1).XValues = "=Data!E4:E12"
' Add trendlines
.FullSeriesCollection(1).Trendlines.Add Type:=xlLinear, Forward _
:=0, Backward:=0, DisplayEquation:=0, DisplayRSquared:=0, Name:= _
"Trend (DDE)"
.FullSeriesCollection(2).Trendlines.Add Type:=xlLinear, Forward _
:=0, Backward:=0, DisplayEquation:=0, DisplayRSquared:=0, Name:= _
"Trend (SDE)"
End With
' Chart is moved to end of all sheets
Sheets(cell.Offset(-1, 1).Value).Move _
after:=Sheets(Sheets.Count)
End If
Next cell
End Sub
No need to define the worksheet with the Worksheets()
Sub Terminator()
Dim Current As Worksheet
Application.DisplayAlerts = False
' Loop through all of the worksheets in the active workbook.
For Each Current In ActiveWorkbook.Worksheets
If Not Current.Name = "Data" Then
Current.Delete
End If
Next Current
Application.DisplayAlerts = True
End sub
The Following code (minor changes worked in my workbook), are you sure you have the names you put in the If in your Workbook ?
Anyway, I think it's better to use Select for multiple possible mathces
Sub Terminator()
Dim Current As Excel.Worksheet
Application.DisplayAlerts = False
' Loop through all of the worksheets in the active workbook.
For Each Current In ActiveWorkbook.Sheets
If Not (Current.Name = "Data") Then
ActiveWorkbook.Worksheets(Current.Name).Delete
End If
Next Current
Application.DisplayAlerts = True
End Sub
Solution to the deletion is supplied by RGA, but in case you want to avoid several AND statements for each sheet that you want to retain, you can utilize a function similar to the isInArray below:
Sub Terminator()
Dim Current As Variant
Application.DisplayAlerts = False
' Loop through all of the worksheets in the active workbook.
For Each Current In ThisWorkbook.Sheets
If Not isInArray(Current.Name, Array("Data")) Then
Current.Delete
End If
Next
Application.DisplayAlerts = True
End Sub
Function isInArray(theValue As String, vArr As Variant) As Boolean
Dim vVal As Variant
isInArray = False
For Each vVal In vArr
If LCase(vVal) = LCase(theValue) Then
isInArray = True
End If
Next
End Function
EDIT:
function that takes a worksheet name as argument, and returns a worksheet object of that name. If the name is allready taken, the existing sheet is deleted and a new one created:
'example of use:
'set newWorksheet = doExist("This new Sheet")
Function doExist(strSheetName) As Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook
Dim wsTest As Worksheet
Dim nWs As Worksheet
Set wsTest = Nothing
On Error Resume Next
'Set wsTest = wb.Worksheets(strSheetName) 'commented out in Edit of Edit
Set wsTest = wb.Sheets(strSheetName) 'as a comment for one of the other threads reveal, the error could be the deletion of Worksheets, which would be a subgroup to Sheets of which graph sheets are no a part
On Error GoTo 0
If Not wsTest Is Nothing Then
Application.DisplayAlerts = False
wsTest.Delete
Application.DisplayAlerts = True
End If
'Set doExist = wb.Worksheets.Add(after:=wb.Sheets(wb.Sheets.Count)) 'Edit of Edit, the later call to Charts.Add does this for you
'doExist.Name = strSheetName 'Edit of Edit, no need to return anything
End Function
My workbook A containing five sheets (Sheet1, Sheet2, Sheet3, Sheet4 and Sheet5). I protected the cells containing these formulas and now I want to save only Sheet1, Sheet2, Sheet3 and Sheet4 in the new workbook named "myfile".
Sub Protect()
Dim pwd As String, s As Long
pwd = InputBox("entrer a password", Title:="Password")
With ThisWorkbook
For s = 1 To 4
With .Worksheets("Sheet" & s)
.Copy
End With
With ActiveWorkbook
for i=1 to 4
With .Worksheets(i)
.UsedRange
On Error Resume Next
.Cells.SpecialCells(xlCellTypeBlanks).Locked = False
.Cells.SpecialCells(xlCellTypeConstants).Locked = False
.Columns("O").Hidden = True 'i want to hide it for each Sheet
.Columns("P").Hidden = True 'i want to hide it for each Sheet
.Columns("Q").Hidden = True 'i want to hide it for each Sheet
.Columns("R").Hidden = True 'i want to hide it for each Sheet
.Columns("S").Hidden = True 'i want to hide it for each Sheet
.Columns("T").Hidden = True 'i want to hide it for each Sheet
.Columns("U").Hidden = True 'i want to hide it for each Sheet
.Columns("V").Hidden = True 'i want to hide it for each Sheet
On Error GoTo 0
.protect pwd, True, True, True, True
End With
next i
End With
Next s
End With
.SaveAs Filename:="myfile" & s, FileFormat:=xlOpenXMLWorkbook
.Close SaveChanges:=False
End Sub
I add .SaveAs Filename:="myfile" ActiveWorkbook.Close at the end but it doesnt work. How can I fixe it ?
To save 4 or 5 Sheets try using .Sheets(Array("Sheet1", "Sheet2")).Copy ' Or use SheetName then save it.
Here is an example on how to save certain sheets...
Option Explicit
Sub Email_Sheets_Ali()
Dim SourceBook As Workbook
Dim Book As Workbook
Dim FilePath As String
Dim FileName As String
Dim TheActiveWindow As Window
Dim TempWindow As Window
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set SourceBook = ActiveWorkbook
' // Copy the sheets to a new workbook
' // We add a temporary Window to avoid the Copy problem
' // if there is a List or Table in one of the sheets and
' // if the sheets are grouped
With SourceBook
Set TheActiveWindow = ActiveWindow
Set TempWindow = .NewWindow
.Sheets(Array("Sheet1", "Sheet2")).Copy ' Or use SheetName
End With
' // Close temporary Window
TempWindow.Close
Set Book = ActiveWorkbook
' // Save the new workbook
FilePath = "C:\Temp\"
FileName = "MyFileName"
With Book
.SaveAs FilePath & FileName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
.Close savechanges:=False
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
See Ron de Bruin on more examples and FileFormats
Copying an existing password protected sheet to a new workbook as an unprotected sheet gives the following error when user tries to type in data in the new worksheet.
Error: "the cell or chart you're trying to change is on a protected sheet"
Click OK on the error message.
Please note that this error happens only once. click OK on the pop up error message and type again, then excel allows you to type data in the cells and save the sheet.
We have an excel (format .xls) file currently being used to create another excel spreadsheet when a button on a form in the same spreadsheet is clicked. It basically copies one password protected blank sheet (a template) to a new workbook as an unprotected sheet. The code below used to work with excel 2007(using .xls format). We recently upgraded from excel 2007 to excel 2013 and the problem appeared.
Private Sub cmd_Click()
Dim jBook As Workbook
Dim jsheet As Worksheet
CurrentWorkBook = ActiveWorkbook.Name
Workbooks(CurrentWorkBook).Unprotect jWorksheetPassword
'catch all for errors
On Error GoTo ErrEnd
Dim orginalScreenUpdating As Boolean
orginalScreenUpdating = Application.ScreenUpdating
Application.ScreenUpdating = False
If Range("Language").Value = "2" Then
'French
Set jsheet = TemplateFR
Else
'english
Set jsheet = TemplateEN
End If
jsheet.Visible = xlSheetHidden
'jSheet.Visible = xlSheetVisible
'Delete this line
jsheet.Unprotect jWorksheetPassword
Set jBook = Workbooks.Add(xlWBATWorksheet)
jsheet.Copy After:=jBook.Sheets(1)
jBook.Sheets(2).Visible = xlSheetVisible
Application.DisplayAlerts = False
jBook.Sheets(1).Delete
Application.DisplayAlerts = True
jsheet.Visible = xlSheetVeryHidden
'Delete this line
jBook.Sheets(1).Unprotect jWorksheetPassword
'Delete this line
'jsheet.Protect Password:=jWorksheetPassword
NoErrEnd:
Workbooks(CurrentWorkBook).Protect Password:=jWorksheetPassword, Structure:=True, Windows:=False
Application.ScreenUpdating = orginalScreenUpdating
Unload Me
Exit Sub
ErrEnd:
Workbooks(CurrentWorkBook).Protect Password:=jWorksheetPassword, Structure:=True, Windows:=False
Application.DisplayAlerts = True
Application.ScreenUpdating = True
MsgBox DataTable.Range("MSG4").Value, vbCritical, DataTable.Range("MSG4TITLE").Value
Unload Me
End Sub
The following lines of code activate the original workbook and this somehow clears the protection of the copied sheet with excel 2013 only. On Excel 2007 this causes the original workbook to be activated and confuses users, hence the check for 2013.
If Application.Version = "15.0" Then
Workbooks(CurrentWorkBook).Activate
'jBook.Activate
End If
This is a hack that happens to work. If some one finds a better solution please do post it here as well.
The full code listing is as follows:
Private Sub cmd_Click()
Dim jBook As Workbook
Dim jsheet As Worksheet
CurrentWorkBook = ActiveWorkbook.Name
Workbooks(CurrentWorkBook).Unprotect jWorksheetPassword
'catch all for errors
On Error GoTo ErrEnd
Dim orginalScreenUpdating As Boolean
orginalScreenUpdating = Application.ScreenUpdating
Application.ScreenUpdating = False
If Range("Language").Value = "2" Then
'French
Set jsheet = TemplateFR
Else
'english
Set jsheet = TemplateEN
End If
jsheet.Visible = xlSheetHidden
Set jBook = Workbooks.Add(xlWBATWorksheet)
jsheet.Copy After:=jBook.Sheets(1)
jBook.Sheets(2).Visible = xlSheetVisible
Application.DisplayAlerts = False
jBook.Sheets(1).Delete
Application.DisplayAlerts = True
If Application.Version = "15.0" Then
Workbooks(CurrentWorkBook).Activate
'jBook.Activate
End If
jsheet.Visible = xlSheetVeryHidden
NoErrEnd:
Workbooks(CurrentWorkBook).Protect Password:=jWorksheetPassword, Structure:=True, Windows:=False
Application.ScreenUpdating = orginalScreenUpdating
Unload Me
Exit Sub
ErrEnd:
Workbooks(CurrentWorkBook).Protect Password:=jWorksheetPassword, Structure:=True, Windows:=False
Application.DisplayAlerts = True
Application.ScreenUpdating = True
MsgBox DataTable.Range("MSG4").Value, vbCritical, DataTable.Range("MSG4TITLE").Value
Unload Me
End Sub
I want to copy data from each tab in a spreadsheet and save it as new workbooks. The original workbook has many tabs (approx 50) and one of these tabs set up for the macro to run data from, as there may be new tabs added in the future. The macro data tab contains the file location for each new workbook, the name of the tab and also some information used by another macro to e-mail these newly created workbooks to relevant parties.
The issue is getting the macro to recognize the tab names for finding the range to copy, as the tab names are listed in a cell. I am unsure if it is possible to use this list, or whether I add a sheet at the end to loop through all the sheets from a specified start location until that one with an if.
Sub Datacopy()
Dim ws As Worksheet
With Application
.ScreenUpdating = False
End With
Application.DisplayAlerts = False
Set ws = Sheets("email")
For Each Cell In ws.Columns("B").Cells
Dim file1 As String
file1 = Cell.Offset(0, 3).Text
Sheets("cell.value").Range("A1:L500").Copy
Workbooks.Add.Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteAllUsingSourceTheme)
Worksheets("Sheet1").Range("A1").PasteSpecial (xlPasteComments)
ActiveWorkbook.SaveAs Filename:=file1
ActiveWorkbook.Close
Next Cell
Application.DisplayAlerts = True
With Application
.ScreenUpdating = True
End With
MsgBox ("Finished making files!")
End Sub
Something like this should work for you. Note the following:
Code assumes that on sheet "email" it has a header row which is row 1 and the actual data starts on row 2.
It checks to see if the B column cell is a valid worksheet name in the workbook
I have verified that this code works properly and as intended based on your original post:
Sub Datacopy()
Dim wb As Workbook
Dim wsData As Worksheet
Dim wsTemp As Worksheet
Dim rSheetNames As Range
Dim rSheet As Range
Set wb = ActiveWorkbook
Set wsData = wb.Sheets("email")
Set rSheetNames = wsData.Range("B2", wsData.Cells(Rows.Count, "B").End(xlUp))
If rSheetNames.Row < 2 Then Exit Sub 'No data
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
For Each rSheet In rSheetNames
If Not Evaluate("ISERROR('" & rSheet.Text & "'!A1)") Then
Set wsTemp = Sheets.Add
Sheets(rSheet.Text).Range("A1:L500").Copy
wsTemp.Range("A1").PasteSpecial xlPasteAllUsingSourceTheme
wsTemp.Range("A1").PasteSpecial xlPasteComments
wsTemp.Move
ActiveWorkbook.SaveAs rSheet.Offset(, 3).Text
ActiveWorkbook.Close False
End If
Next rSheet
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
MsgBox "Finished making files!"
End Sub
I am running this simple macro. The goal is to create new Data sheet on a click of a userform button (deleting the old one). After making a copy from a raw data sheet, it should rename it "Data". If sheet named "Data" already exists - delete it.
Private Sub CommandButton1_Click()
Dim ws1 As Worksheet
Dim trigger As Integer
trigger = 0
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For i = 1 To Sheets.Count
If Sheets(i).Name = "Data" Then
trigger = 1
Sheets("Data").Delete
Sheets("raw_Data").Visible = True
Set ws1 = Sheets("raw_Data")
ws1.Copy Sheets(Sheets.Count)
Sheets("raw_Data").Visible = False
End If
Next i
If trigger = 0 Then
Sheets("raw_Data").Visible = True
Set ws1 = ThisWorkbook.Worksheets("raw_Data")
ws1.Copy ThisWorkbook.Sheets(Sheets.Count)
Sheets("raw_Data").Visible = False
End If
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Unload Me
ActiveSheet.Name = "Data"
End Sub
Am I running some kind of infinite loop here? If I delete:
ActiveSheet.Name = "Data"
Excel isn't crashing any more.
I am with Ron on this one. I made a little bit cleaner version of the code and maybe it will shed some light to what the problem is.
Option Explicit
Private Sub CommandButton1_Click()
Const strDATA_SHEET As String = "Data"
Const strDATA_RAW_SHEET As String = "raw_Data"
Dim shDataRaw As Worksheet
Call TurnExtrasOff
' Check if we have the sheet data if so then delete it
If DoesWorksheetExist(strDATA_SHEET, ThisWorkbook) Then
Application.DisplayAlerts = False
ThisWorkbook.Sheets(strDATA_SHEET).Delete
Application.DisplayAlerts = True
End If
' Lets copy the raw data sheet.
Set shDataRaw = ThisWorkbook.Sheets(strDATA_RAW_SHEET)
shDataRaw.Visible = xlSheetVisible
shDataRaw.Copy ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
' Rename the sheet and hide raw data
ActiveSheet.Name = strDATA_SHEET
shDataRaw.Visible = xlSheetHidden
Call TurnExtrasOn
' Unload the user form
Unload Me
End Sub
' Procedure to turn extra features on
Sub TurnExtrasOn()
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = xlCalculationAutomatic
End With
End Sub
' Procedure to turn extra features oFF
Sub TurnExtrasOff()
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationAutomatic
End With
End Sub
' Function to check if a sheet exists
Function DoesWorksheetExist(ByVal sheetname As String, aWorkbook As Workbook) As Boolean
On Error Resume Next
DoesWorksheetExist = (Not aWorkbook.Sheets(sheetname) Is Nothing)
On Error GoTo 0
End Function
I hope this helps