How to use VBA SaveAs without closing calling workbook?Excel SaveAs changes active workbook - How to SaveAs and keep active workbook active?return to workbookSuppress dialog when using VBA to save a macro containing Excel file (.xlsm) as a non macro containing file (.xlsx)Execute a .exe file from ExcelAntivirus False positive in my VBA Excel MacroExcel VBA SaveAs csv return to xlsxChange links to new workbookHow do I create an Excel (.XLS and .XLSX) file in C# without installing Microsoft Office?Referencing different types of cells-(ie. strings, doubles)-multiple workbooksHow to avoid using Select in Excel VBAExport multiple (specific) worksheets to CSV files in a specified directoryVBA: Error when savings as CSV: Run-time error '424': Object requiredDetect when password is used for opened or closed Excel workbookSaving embedded OLE Object (Excel workbook) to file in Excel 2010MS VBA - Running Macro w/o Changing File typeExcel VBA 2010: Data validation breaks when workbook saved by VBA, but not when saved manually
May I use a railway velocipede on actively-used British railways?
How to not confuse readers with simultaneous events?
How to belay quickly ascending top-rope climbers?
Three Subway Escalators
Why is Google approaching my VPS machine?
Changing iteration variable in Do loop
Why aren't there any women super GMs?
Why do the digits of a number squared follow a similar quotient?
Why is the Intel 8086 CPU called a 16-bit CPU?
Differentiable functions and existence of limits
In this iconic lunar orbit rendezvous photo of John Houbolt, why do arrows #5 and #6 point the "wrong" way?
Why doesn't Venus have a magnetic field? How does the speed of rotation affect the magnetic field of a planet?
Which modern firearm should a time traveler bring to be easily reproducible for a historic civilization?
"This used to be my phone number"
Diagram of Methods to Solve Differential Equations
Why didn't Doctor Strange restore Tony Stark after he used the Stones?
How to interpret a promising preprint that was never published in peer-review?
Improving an O(N^2) function (all entities iterating over all other entities)
What's a German word for »Sandbagger«?
"Je suis petite, moi?", purpose of the "moi"?
Why do jet engines sound louder on the ground than inside the aircraft?
Are there any satellites in geosynchronous but not geostationary orbits?
How do I reproduce this layout and typography?
Wait or be waiting?
How to use VBA SaveAs without closing calling workbook?
Excel SaveAs changes active workbook - How to SaveAs and keep active workbook active?return to workbookSuppress dialog when using VBA to save a macro containing Excel file (.xlsm) as a non macro containing file (.xlsx)Execute a .exe file from ExcelAntivirus False positive in my VBA Excel MacroExcel VBA SaveAs csv return to xlsxChange links to new workbookHow do I create an Excel (.XLS and .XLSX) file in C# without installing Microsoft Office?Referencing different types of cells-(ie. strings, doubles)-multiple workbooksHow to avoid using Select in Excel VBAExport multiple (specific) worksheets to CSV files in a specified directoryVBA: Error when savings as CSV: Run-time error '424': Object requiredDetect when password is used for opened or closed Excel workbookSaving embedded OLE Object (Excel workbook) to file in Excel 2010MS VBA - Running Macro w/o Changing File typeExcel VBA 2010: Data validation breaks when workbook saved by VBA, but not when saved manually
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I want to:
- Do data manipulation using a Template workbook
- Save a copy of this work book as .xlsx (SaveCopyAs doesn't let you change filetypes, otherwise this would be great)
- Continue showing original template (not the "saved as" one)
Using SaveAs
does exactly what is expected - it saves the workbook while removing the macros and presents me the view of the newly created SavedAs workbook.
This unfortunately means:
- I no longer am viewing my macro enabled workbook unless I reopen it
- Code execution stops at this point because
- Any macro changes are discarded if I forget to save (note: for a production environment this is ok, but, for development, it's a huge pain)
Is there a way I can do this?
'current code
Application.DisplayAlerts = False
templateWb.SaveAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
templateWb.Activate
Application.DisplayAlerts = True
'I don't really want to make something like this work (this fails, anyways)
Dim myTempStr As String
myTempStr = ThisWorkbook.Path & "" & ThisWorkbook.Name
ThisWorkbook.Save
templateWb.SaveAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWorkbook.Close
Workbooks.Open (myTempStr)
'I want to do something like:
templateWb.SaveCopyAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False 'SaveCopyAs only takes one argument, that being FileName
Also note while SaveCopyAs
will let me save it as a different type (ie templateWb.SaveCopyAs FileName:="myXlsx.xlsx"
) this gives an error when opening it because it now has an invalid file format.
excel vba excel-vba save
|
show 5 more comments
I want to:
- Do data manipulation using a Template workbook
- Save a copy of this work book as .xlsx (SaveCopyAs doesn't let you change filetypes, otherwise this would be great)
- Continue showing original template (not the "saved as" one)
Using SaveAs
does exactly what is expected - it saves the workbook while removing the macros and presents me the view of the newly created SavedAs workbook.
This unfortunately means:
- I no longer am viewing my macro enabled workbook unless I reopen it
- Code execution stops at this point because
- Any macro changes are discarded if I forget to save (note: for a production environment this is ok, but, for development, it's a huge pain)
Is there a way I can do this?
'current code
Application.DisplayAlerts = False
templateWb.SaveAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
templateWb.Activate
Application.DisplayAlerts = True
'I don't really want to make something like this work (this fails, anyways)
Dim myTempStr As String
myTempStr = ThisWorkbook.Path & "" & ThisWorkbook.Name
ThisWorkbook.Save
templateWb.SaveAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWorkbook.Close
Workbooks.Open (myTempStr)
'I want to do something like:
templateWb.SaveCopyAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False 'SaveCopyAs only takes one argument, that being FileName
Also note while SaveCopyAs
will let me save it as a different type (ie templateWb.SaveCopyAs FileName:="myXlsx.xlsx"
) this gives an error when opening it because it now has an invalid file format.
excel vba excel-vba save
1
a lame workaround I can think of is to SaveCopyAs, open the copy, save it as your desired format, delete the copy. If you shove it into a sub then it won't clutter up your main procedures.
– Cor_Blimey
Sep 19 '13 at 16:14
1
UseSaveCopyAs
to create a copy then, open that copy and do a save as?
– Siddharth Rout
Sep 19 '13 at 16:20
@Cor_Blimey: Sorry didn't see your comment
– Siddharth Rout
Sep 19 '13 at 16:21
Or create a new workbook, copy all your sheets in that and then save it as an xlsx?
– Siddharth Rout
Sep 19 '13 at 16:22
Both those options make me die a little on the inside (ok a lot). @Cor_Blimey I definitely thought of doing that as well initially but it just seems there should be a better way. I'm working with network drives so minimizing saving on them multiple times is ideal.
– enderland
Sep 19 '13 at 16:25
|
show 5 more comments
I want to:
- Do data manipulation using a Template workbook
- Save a copy of this work book as .xlsx (SaveCopyAs doesn't let you change filetypes, otherwise this would be great)
- Continue showing original template (not the "saved as" one)
Using SaveAs
does exactly what is expected - it saves the workbook while removing the macros and presents me the view of the newly created SavedAs workbook.
This unfortunately means:
- I no longer am viewing my macro enabled workbook unless I reopen it
- Code execution stops at this point because
- Any macro changes are discarded if I forget to save (note: for a production environment this is ok, but, for development, it's a huge pain)
Is there a way I can do this?
'current code
Application.DisplayAlerts = False
templateWb.SaveAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
templateWb.Activate
Application.DisplayAlerts = True
'I don't really want to make something like this work (this fails, anyways)
Dim myTempStr As String
myTempStr = ThisWorkbook.Path & "" & ThisWorkbook.Name
ThisWorkbook.Save
templateWb.SaveAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWorkbook.Close
Workbooks.Open (myTempStr)
'I want to do something like:
templateWb.SaveCopyAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False 'SaveCopyAs only takes one argument, that being FileName
Also note while SaveCopyAs
will let me save it as a different type (ie templateWb.SaveCopyAs FileName:="myXlsx.xlsx"
) this gives an error when opening it because it now has an invalid file format.
excel vba excel-vba save
I want to:
- Do data manipulation using a Template workbook
- Save a copy of this work book as .xlsx (SaveCopyAs doesn't let you change filetypes, otherwise this would be great)
- Continue showing original template (not the "saved as" one)
Using SaveAs
does exactly what is expected - it saves the workbook while removing the macros and presents me the view of the newly created SavedAs workbook.
This unfortunately means:
- I no longer am viewing my macro enabled workbook unless I reopen it
- Code execution stops at this point because
- Any macro changes are discarded if I forget to save (note: for a production environment this is ok, but, for development, it's a huge pain)
Is there a way I can do this?
'current code
Application.DisplayAlerts = False
templateWb.SaveAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
templateWb.Activate
Application.DisplayAlerts = True
'I don't really want to make something like this work (this fails, anyways)
Dim myTempStr As String
myTempStr = ThisWorkbook.Path & "" & ThisWorkbook.Name
ThisWorkbook.Save
templateWb.SaveAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWorkbook.Close
Workbooks.Open (myTempStr)
'I want to do something like:
templateWb.SaveCopyAs FileName:=savePath, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False 'SaveCopyAs only takes one argument, that being FileName
Also note while SaveCopyAs
will let me save it as a different type (ie templateWb.SaveCopyAs FileName:="myXlsx.xlsx"
) this gives an error when opening it because it now has an invalid file format.
excel vba excel-vba save
excel vba excel-vba save
edited Sep 19 '13 at 16:22
enderland
asked Sep 19 '13 at 16:10
enderlandenderland
8,84712 gold badges64 silver badges122 bronze badges
8,84712 gold badges64 silver badges122 bronze badges
1
a lame workaround I can think of is to SaveCopyAs, open the copy, save it as your desired format, delete the copy. If you shove it into a sub then it won't clutter up your main procedures.
– Cor_Blimey
Sep 19 '13 at 16:14
1
UseSaveCopyAs
to create a copy then, open that copy and do a save as?
– Siddharth Rout
Sep 19 '13 at 16:20
@Cor_Blimey: Sorry didn't see your comment
– Siddharth Rout
Sep 19 '13 at 16:21
Or create a new workbook, copy all your sheets in that and then save it as an xlsx?
– Siddharth Rout
Sep 19 '13 at 16:22
Both those options make me die a little on the inside (ok a lot). @Cor_Blimey I definitely thought of doing that as well initially but it just seems there should be a better way. I'm working with network drives so minimizing saving on them multiple times is ideal.
– enderland
Sep 19 '13 at 16:25
|
show 5 more comments
1
a lame workaround I can think of is to SaveCopyAs, open the copy, save it as your desired format, delete the copy. If you shove it into a sub then it won't clutter up your main procedures.
– Cor_Blimey
Sep 19 '13 at 16:14
1
UseSaveCopyAs
to create a copy then, open that copy and do a save as?
– Siddharth Rout
Sep 19 '13 at 16:20
@Cor_Blimey: Sorry didn't see your comment
– Siddharth Rout
Sep 19 '13 at 16:21
Or create a new workbook, copy all your sheets in that and then save it as an xlsx?
– Siddharth Rout
Sep 19 '13 at 16:22
Both those options make me die a little on the inside (ok a lot). @Cor_Blimey I definitely thought of doing that as well initially but it just seems there should be a better way. I'm working with network drives so minimizing saving on them multiple times is ideal.
– enderland
Sep 19 '13 at 16:25
1
1
a lame workaround I can think of is to SaveCopyAs, open the copy, save it as your desired format, delete the copy. If you shove it into a sub then it won't clutter up your main procedures.
– Cor_Blimey
Sep 19 '13 at 16:14
a lame workaround I can think of is to SaveCopyAs, open the copy, save it as your desired format, delete the copy. If you shove it into a sub then it won't clutter up your main procedures.
– Cor_Blimey
Sep 19 '13 at 16:14
1
1
Use
SaveCopyAs
to create a copy then, open that copy and do a save as?– Siddharth Rout
Sep 19 '13 at 16:20
Use
SaveCopyAs
to create a copy then, open that copy and do a save as?– Siddharth Rout
Sep 19 '13 at 16:20
@Cor_Blimey: Sorry didn't see your comment
– Siddharth Rout
Sep 19 '13 at 16:21
@Cor_Blimey: Sorry didn't see your comment
– Siddharth Rout
Sep 19 '13 at 16:21
Or create a new workbook, copy all your sheets in that and then save it as an xlsx?
– Siddharth Rout
Sep 19 '13 at 16:22
Or create a new workbook, copy all your sheets in that and then save it as an xlsx?
– Siddharth Rout
Sep 19 '13 at 16:22
Both those options make me die a little on the inside (ok a lot). @Cor_Blimey I definitely thought of doing that as well initially but it just seems there should be a better way. I'm working with network drives so minimizing saving on them multiple times is ideal.
– enderland
Sep 19 '13 at 16:25
Both those options make me die a little on the inside (ok a lot). @Cor_Blimey I definitely thought of doing that as well initially but it just seems there should be a better way. I'm working with network drives so minimizing saving on them multiple times is ideal.
– enderland
Sep 19 '13 at 16:25
|
show 5 more comments
5 Answers
5
active
oldest
votes
Here is a much faster method than using .SaveCopyAs
to create a copy an then open that copy and do a save as...
As mentioned in my comments, this process takes approx 1 second to create an xlsx copy from a workbook which has 10 worksheets (Each with 100 rows * 20 Cols of data)
Sub Sample()
Dim thisWb As Workbook, wbTemp As Workbook
Dim ws As Worksheet
On Error GoTo Whoa
Application.DisplayAlerts = False
Set thisWb = ThisWorkbook
Set wbTemp = Workbooks.Add
On Error Resume Next
For Each ws In wbTemp.Worksheets
ws.Delete
Next
On Error GoTo 0
For Each ws In thisWb.Sheets
ws.Copy After:=wbTemp.Sheets(1)
Next
wbTemp.Sheets(1).Delete
wbTemp.SaveAs "C:Blah Blah.xlsx", 51
LetsContinue:
Application.DisplayAlerts = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
+1, this is pretty similar to what I ended up with here - I made it a bit more robust and into a function.
– enderland
Sep 19 '13 at 17:45
2
AlsoFor Each... ws.Delete
is such a hack ;)
– enderland
Sep 19 '13 at 17:50
It depends on what version of Excel you use. With Excel 2003 copying sheets is not a safe operation and can result in data loss.
– AndASM
Sep 19 '13 at 19:20
@AndASM: Hmm, that is news to me. Where did you read it?
– Siddharth Rout
Sep 19 '13 at 19:20
1
@SiddharthRout IIRC there are a few errors that can occur. For example, a quick Google search turns up the 255 character limit.
– AndASM
Sep 19 '13 at 19:30
|
show 5 more comments
I did something similar to what Siddharth suggested and wrote a function to do it as well as handle some of the annoyances and offer some more flexibility.
Sub saveExample()
Application.ScreenUpdating = False
mySaveCopyAs ThisWorkbook, "C:Temptestfile2", xlOpenXMLWorkbook
Application.ScreenUpdating = True
End Sub
Private Function mySaveCopyAs(pWorkbookToBeSaved As Workbook, pNewFileName As String, pFileFormat As XlFileFormat) As Boolean
'returns false on errors
On Error GoTo errHandler
If pFileFormat = xlOpenXMLWorkbookMacroEnabled Then
'no macros can be saved on this
mySaveCopyAs = False
Exit Function
End If
'create new workbook
Dim mSaveWorkbook As Workbook
Set mSaveWorkbook = Workbooks.Add
Dim initialSheets As Integer
initialSheets = mSaveWorkbook.Sheets.Count
'note: sheet names will be 'Sheet1 (2)' in copy otherwise if
'they are not renamed
Dim sheetNames() As String
Dim activeSheetIndex As Integer
activeSheetIndex = pWorkbookToBeSaved.ActiveSheet.Index
Dim i As Integer
'copy each sheet
For i = 1 To pWorkbookToBeSaved.Sheets.Count
pWorkbookToBeSaved.Sheets(i).Copy After:=mSaveWorkbook.Sheets(mSaveWorkbook.Sheets.Count)
ReDim Preserve sheetNames(1 To i) As String
sheetNames(i) = pWorkbookToBeSaved.Sheets(i).Name
Next i
'clear sheets from new workbook
Application.DisplayAlerts = False
For i = 1 To initialSheets
mSaveWorkbook.Sheets(1).Delete
Next i
'rename stuff
For i = 1 To UBound(sheetNames)
mSaveWorkbook.Sheets(i).Name = sheetNames(i)
Next i
'reset view
mSaveWorkbook.Sheets(activeSheetIndex).Activate
'save and close
mSaveWorkbook.SaveAs FileName:=pNewFileName, FileFormat:=pFileFormat, CreateBackup:=False
mSaveWorkbook.Close
mySaveCopyAs = True
Application.DisplayAlerts = True
Exit Function
errHandler:
'whatever else you want to do with error handling
mySaveCopyAs = False
Exit Function
End Function
1
out of curiosity, is there a reason why you copy the sheets and not move them from the temp file? Moving closes the workbook automatically. Anyway, I can see this being quicker than saving a copy, opening etc, but it probably wouldn't be great if you intend to use this method with worksheets with tables, formulae, defined names etc (though as you are using this with a template you control, I suppose you know this isn't an issue).
– Cor_Blimey
Sep 19 '13 at 21:05
1
@Cor_Blimey I want to keep the template intact and use this functionality basically like "SaveCopyAs" - if I move the sheets I lose them from the template workbook.
– enderland
Sep 20 '13 at 13:06
whoops - I lost sight of that objective. Thanks.
– Cor_Blimey
Sep 20 '13 at 16:46
add a comment |
There is nothing pretty or nice about this process in Excel VBA, but something like the below.
This code doesn't handle errors very well, is ugly, but should work.
We copy the workbook, open and resave the copy, then delete the copy. The temporary copy is stored in your local temp directory, and deleted from there as well.
Option Explicit
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Public Sub SaveCopyAs(TargetBook As Workbook, Filename, FileFormat, CreateBackup)
Dim sTempPath As String * 512
Dim lPathLength As Long
Dim sFileName As String
Dim TempBook As Workbook
Dim bOldDisplayAlerts As Boolean
bOldDisplayAlerts = Application.DisplayAlerts
Application.DisplayAlerts = False
lPathLength = GetTempPath(512, sTempPath)
sFileName = Left$(sTempPath, lPathLength) & "tempDelete_" & TargetBook.Name
TargetBook.SaveCopyAs sFileName
Set TempBook = Application.Workbooks.Open(sFileName)
TempBook.SaveAs Filename, FileFormat, CreateBackup:=CreateBackup
TempBook.Close False
Kill sFileName
Application.DisplayAlerts = bOldDisplayAlerts
End Sub
add a comment |
I have a similar process, here's the solution I use. It allows the user to open a template, perform manipulation, save the template somewhere, and then have the original template open
- user opens macro-enabled template file
- do manipulation
- save ActiveWorkbook's file path (template file)
- execute a SaveAs
- set ActiveWorkbook (now the saveas'd file) as a variable
- open template file path in step 3
- close the variable in step 5
the code looks something like this:
'stores file path of activeworkbook BEFORE the SaveAs is executed
getExprterFilePath = Application.ActiveWorkbook.FullName
'executes a SaveAs
ActiveWorkbook.SaveAs Filename:=filepathHere, _
FileFormat:=51, _
Password:="", _
WriteResPassword:="", _
ReadOnlyRecommended:=False, _
CreateBackup:=False
'reenables alerts
Application.DisplayAlerts = True
'announces completion to user
MsgBox "Export Complete", vbOKOnly, "List Exporter"
'sets open file (newly created file) as variable
Set wbBLE = ActiveWorkbook
'opens original template file
Workbooks.Open (getExprterFilePath)
'turns screen updating, calculation, and events back on
With Excel.Application
.ScreenUpdating = True
.Calculation = Excel.xlAutomatic
.EnableEvents = True
End With
'closes saved export file
wbBLE.Close
add a comment |
Another option (only tested on latest versions of excel).
The Macros are not deleted until the workbook is closed after a SaveAs
.xlsx
so you can do two SaveAs
in quick succession without closing the workbook.
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False, ConflictResolution:=xlLocalSessionChanges
Application.DisplayAlerts = True
Note: you need to turn off the DisplayAlerts
to avoid getting the warning that the workbook already exists on the second save.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18899824%2fhow-to-use-vba-saveas-without-closing-calling-workbook%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here is a much faster method than using .SaveCopyAs
to create a copy an then open that copy and do a save as...
As mentioned in my comments, this process takes approx 1 second to create an xlsx copy from a workbook which has 10 worksheets (Each with 100 rows * 20 Cols of data)
Sub Sample()
Dim thisWb As Workbook, wbTemp As Workbook
Dim ws As Worksheet
On Error GoTo Whoa
Application.DisplayAlerts = False
Set thisWb = ThisWorkbook
Set wbTemp = Workbooks.Add
On Error Resume Next
For Each ws In wbTemp.Worksheets
ws.Delete
Next
On Error GoTo 0
For Each ws In thisWb.Sheets
ws.Copy After:=wbTemp.Sheets(1)
Next
wbTemp.Sheets(1).Delete
wbTemp.SaveAs "C:Blah Blah.xlsx", 51
LetsContinue:
Application.DisplayAlerts = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
+1, this is pretty similar to what I ended up with here - I made it a bit more robust and into a function.
– enderland
Sep 19 '13 at 17:45
2
AlsoFor Each... ws.Delete
is such a hack ;)
– enderland
Sep 19 '13 at 17:50
It depends on what version of Excel you use. With Excel 2003 copying sheets is not a safe operation and can result in data loss.
– AndASM
Sep 19 '13 at 19:20
@AndASM: Hmm, that is news to me. Where did you read it?
– Siddharth Rout
Sep 19 '13 at 19:20
1
@SiddharthRout IIRC there are a few errors that can occur. For example, a quick Google search turns up the 255 character limit.
– AndASM
Sep 19 '13 at 19:30
|
show 5 more comments
Here is a much faster method than using .SaveCopyAs
to create a copy an then open that copy and do a save as...
As mentioned in my comments, this process takes approx 1 second to create an xlsx copy from a workbook which has 10 worksheets (Each with 100 rows * 20 Cols of data)
Sub Sample()
Dim thisWb As Workbook, wbTemp As Workbook
Dim ws As Worksheet
On Error GoTo Whoa
Application.DisplayAlerts = False
Set thisWb = ThisWorkbook
Set wbTemp = Workbooks.Add
On Error Resume Next
For Each ws In wbTemp.Worksheets
ws.Delete
Next
On Error GoTo 0
For Each ws In thisWb.Sheets
ws.Copy After:=wbTemp.Sheets(1)
Next
wbTemp.Sheets(1).Delete
wbTemp.SaveAs "C:Blah Blah.xlsx", 51
LetsContinue:
Application.DisplayAlerts = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
+1, this is pretty similar to what I ended up with here - I made it a bit more robust and into a function.
– enderland
Sep 19 '13 at 17:45
2
AlsoFor Each... ws.Delete
is such a hack ;)
– enderland
Sep 19 '13 at 17:50
It depends on what version of Excel you use. With Excel 2003 copying sheets is not a safe operation and can result in data loss.
– AndASM
Sep 19 '13 at 19:20
@AndASM: Hmm, that is news to me. Where did you read it?
– Siddharth Rout
Sep 19 '13 at 19:20
1
@SiddharthRout IIRC there are a few errors that can occur. For example, a quick Google search turns up the 255 character limit.
– AndASM
Sep 19 '13 at 19:30
|
show 5 more comments
Here is a much faster method than using .SaveCopyAs
to create a copy an then open that copy and do a save as...
As mentioned in my comments, this process takes approx 1 second to create an xlsx copy from a workbook which has 10 worksheets (Each with 100 rows * 20 Cols of data)
Sub Sample()
Dim thisWb As Workbook, wbTemp As Workbook
Dim ws As Worksheet
On Error GoTo Whoa
Application.DisplayAlerts = False
Set thisWb = ThisWorkbook
Set wbTemp = Workbooks.Add
On Error Resume Next
For Each ws In wbTemp.Worksheets
ws.Delete
Next
On Error GoTo 0
For Each ws In thisWb.Sheets
ws.Copy After:=wbTemp.Sheets(1)
Next
wbTemp.Sheets(1).Delete
wbTemp.SaveAs "C:Blah Blah.xlsx", 51
LetsContinue:
Application.DisplayAlerts = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
Here is a much faster method than using .SaveCopyAs
to create a copy an then open that copy and do a save as...
As mentioned in my comments, this process takes approx 1 second to create an xlsx copy from a workbook which has 10 worksheets (Each with 100 rows * 20 Cols of data)
Sub Sample()
Dim thisWb As Workbook, wbTemp As Workbook
Dim ws As Worksheet
On Error GoTo Whoa
Application.DisplayAlerts = False
Set thisWb = ThisWorkbook
Set wbTemp = Workbooks.Add
On Error Resume Next
For Each ws In wbTemp.Worksheets
ws.Delete
Next
On Error GoTo 0
For Each ws In thisWb.Sheets
ws.Copy After:=wbTemp.Sheets(1)
Next
wbTemp.Sheets(1).Delete
wbTemp.SaveAs "C:Blah Blah.xlsx", 51
LetsContinue:
Application.DisplayAlerts = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
answered Sep 19 '13 at 17:24
Siddharth RoutSiddharth Rout
120k14 gold badges162 silver badges218 bronze badges
120k14 gold badges162 silver badges218 bronze badges
+1, this is pretty similar to what I ended up with here - I made it a bit more robust and into a function.
– enderland
Sep 19 '13 at 17:45
2
AlsoFor Each... ws.Delete
is such a hack ;)
– enderland
Sep 19 '13 at 17:50
It depends on what version of Excel you use. With Excel 2003 copying sheets is not a safe operation and can result in data loss.
– AndASM
Sep 19 '13 at 19:20
@AndASM: Hmm, that is news to me. Where did you read it?
– Siddharth Rout
Sep 19 '13 at 19:20
1
@SiddharthRout IIRC there are a few errors that can occur. For example, a quick Google search turns up the 255 character limit.
– AndASM
Sep 19 '13 at 19:30
|
show 5 more comments
+1, this is pretty similar to what I ended up with here - I made it a bit more robust and into a function.
– enderland
Sep 19 '13 at 17:45
2
AlsoFor Each... ws.Delete
is such a hack ;)
– enderland
Sep 19 '13 at 17:50
It depends on what version of Excel you use. With Excel 2003 copying sheets is not a safe operation and can result in data loss.
– AndASM
Sep 19 '13 at 19:20
@AndASM: Hmm, that is news to me. Where did you read it?
– Siddharth Rout
Sep 19 '13 at 19:20
1
@SiddharthRout IIRC there are a few errors that can occur. For example, a quick Google search turns up the 255 character limit.
– AndASM
Sep 19 '13 at 19:30
+1, this is pretty similar to what I ended up with here - I made it a bit more robust and into a function.
– enderland
Sep 19 '13 at 17:45
+1, this is pretty similar to what I ended up with here - I made it a bit more robust and into a function.
– enderland
Sep 19 '13 at 17:45
2
2
Also
For Each... ws.Delete
is such a hack ;)– enderland
Sep 19 '13 at 17:50
Also
For Each... ws.Delete
is such a hack ;)– enderland
Sep 19 '13 at 17:50
It depends on what version of Excel you use. With Excel 2003 copying sheets is not a safe operation and can result in data loss.
– AndASM
Sep 19 '13 at 19:20
It depends on what version of Excel you use. With Excel 2003 copying sheets is not a safe operation and can result in data loss.
– AndASM
Sep 19 '13 at 19:20
@AndASM: Hmm, that is news to me. Where did you read it?
– Siddharth Rout
Sep 19 '13 at 19:20
@AndASM: Hmm, that is news to me. Where did you read it?
– Siddharth Rout
Sep 19 '13 at 19:20
1
1
@SiddharthRout IIRC there are a few errors that can occur. For example, a quick Google search turns up the 255 character limit.
– AndASM
Sep 19 '13 at 19:30
@SiddharthRout IIRC there are a few errors that can occur. For example, a quick Google search turns up the 255 character limit.
– AndASM
Sep 19 '13 at 19:30
|
show 5 more comments
I did something similar to what Siddharth suggested and wrote a function to do it as well as handle some of the annoyances and offer some more flexibility.
Sub saveExample()
Application.ScreenUpdating = False
mySaveCopyAs ThisWorkbook, "C:Temptestfile2", xlOpenXMLWorkbook
Application.ScreenUpdating = True
End Sub
Private Function mySaveCopyAs(pWorkbookToBeSaved As Workbook, pNewFileName As String, pFileFormat As XlFileFormat) As Boolean
'returns false on errors
On Error GoTo errHandler
If pFileFormat = xlOpenXMLWorkbookMacroEnabled Then
'no macros can be saved on this
mySaveCopyAs = False
Exit Function
End If
'create new workbook
Dim mSaveWorkbook As Workbook
Set mSaveWorkbook = Workbooks.Add
Dim initialSheets As Integer
initialSheets = mSaveWorkbook.Sheets.Count
'note: sheet names will be 'Sheet1 (2)' in copy otherwise if
'they are not renamed
Dim sheetNames() As String
Dim activeSheetIndex As Integer
activeSheetIndex = pWorkbookToBeSaved.ActiveSheet.Index
Dim i As Integer
'copy each sheet
For i = 1 To pWorkbookToBeSaved.Sheets.Count
pWorkbookToBeSaved.Sheets(i).Copy After:=mSaveWorkbook.Sheets(mSaveWorkbook.Sheets.Count)
ReDim Preserve sheetNames(1 To i) As String
sheetNames(i) = pWorkbookToBeSaved.Sheets(i).Name
Next i
'clear sheets from new workbook
Application.DisplayAlerts = False
For i = 1 To initialSheets
mSaveWorkbook.Sheets(1).Delete
Next i
'rename stuff
For i = 1 To UBound(sheetNames)
mSaveWorkbook.Sheets(i).Name = sheetNames(i)
Next i
'reset view
mSaveWorkbook.Sheets(activeSheetIndex).Activate
'save and close
mSaveWorkbook.SaveAs FileName:=pNewFileName, FileFormat:=pFileFormat, CreateBackup:=False
mSaveWorkbook.Close
mySaveCopyAs = True
Application.DisplayAlerts = True
Exit Function
errHandler:
'whatever else you want to do with error handling
mySaveCopyAs = False
Exit Function
End Function
1
out of curiosity, is there a reason why you copy the sheets and not move them from the temp file? Moving closes the workbook automatically. Anyway, I can see this being quicker than saving a copy, opening etc, but it probably wouldn't be great if you intend to use this method with worksheets with tables, formulae, defined names etc (though as you are using this with a template you control, I suppose you know this isn't an issue).
– Cor_Blimey
Sep 19 '13 at 21:05
1
@Cor_Blimey I want to keep the template intact and use this functionality basically like "SaveCopyAs" - if I move the sheets I lose them from the template workbook.
– enderland
Sep 20 '13 at 13:06
whoops - I lost sight of that objective. Thanks.
– Cor_Blimey
Sep 20 '13 at 16:46
add a comment |
I did something similar to what Siddharth suggested and wrote a function to do it as well as handle some of the annoyances and offer some more flexibility.
Sub saveExample()
Application.ScreenUpdating = False
mySaveCopyAs ThisWorkbook, "C:Temptestfile2", xlOpenXMLWorkbook
Application.ScreenUpdating = True
End Sub
Private Function mySaveCopyAs(pWorkbookToBeSaved As Workbook, pNewFileName As String, pFileFormat As XlFileFormat) As Boolean
'returns false on errors
On Error GoTo errHandler
If pFileFormat = xlOpenXMLWorkbookMacroEnabled Then
'no macros can be saved on this
mySaveCopyAs = False
Exit Function
End If
'create new workbook
Dim mSaveWorkbook As Workbook
Set mSaveWorkbook = Workbooks.Add
Dim initialSheets As Integer
initialSheets = mSaveWorkbook.Sheets.Count
'note: sheet names will be 'Sheet1 (2)' in copy otherwise if
'they are not renamed
Dim sheetNames() As String
Dim activeSheetIndex As Integer
activeSheetIndex = pWorkbookToBeSaved.ActiveSheet.Index
Dim i As Integer
'copy each sheet
For i = 1 To pWorkbookToBeSaved.Sheets.Count
pWorkbookToBeSaved.Sheets(i).Copy After:=mSaveWorkbook.Sheets(mSaveWorkbook.Sheets.Count)
ReDim Preserve sheetNames(1 To i) As String
sheetNames(i) = pWorkbookToBeSaved.Sheets(i).Name
Next i
'clear sheets from new workbook
Application.DisplayAlerts = False
For i = 1 To initialSheets
mSaveWorkbook.Sheets(1).Delete
Next i
'rename stuff
For i = 1 To UBound(sheetNames)
mSaveWorkbook.Sheets(i).Name = sheetNames(i)
Next i
'reset view
mSaveWorkbook.Sheets(activeSheetIndex).Activate
'save and close
mSaveWorkbook.SaveAs FileName:=pNewFileName, FileFormat:=pFileFormat, CreateBackup:=False
mSaveWorkbook.Close
mySaveCopyAs = True
Application.DisplayAlerts = True
Exit Function
errHandler:
'whatever else you want to do with error handling
mySaveCopyAs = False
Exit Function
End Function
1
out of curiosity, is there a reason why you copy the sheets and not move them from the temp file? Moving closes the workbook automatically. Anyway, I can see this being quicker than saving a copy, opening etc, but it probably wouldn't be great if you intend to use this method with worksheets with tables, formulae, defined names etc (though as you are using this with a template you control, I suppose you know this isn't an issue).
– Cor_Blimey
Sep 19 '13 at 21:05
1
@Cor_Blimey I want to keep the template intact and use this functionality basically like "SaveCopyAs" - if I move the sheets I lose them from the template workbook.
– enderland
Sep 20 '13 at 13:06
whoops - I lost sight of that objective. Thanks.
– Cor_Blimey
Sep 20 '13 at 16:46
add a comment |
I did something similar to what Siddharth suggested and wrote a function to do it as well as handle some of the annoyances and offer some more flexibility.
Sub saveExample()
Application.ScreenUpdating = False
mySaveCopyAs ThisWorkbook, "C:Temptestfile2", xlOpenXMLWorkbook
Application.ScreenUpdating = True
End Sub
Private Function mySaveCopyAs(pWorkbookToBeSaved As Workbook, pNewFileName As String, pFileFormat As XlFileFormat) As Boolean
'returns false on errors
On Error GoTo errHandler
If pFileFormat = xlOpenXMLWorkbookMacroEnabled Then
'no macros can be saved on this
mySaveCopyAs = False
Exit Function
End If
'create new workbook
Dim mSaveWorkbook As Workbook
Set mSaveWorkbook = Workbooks.Add
Dim initialSheets As Integer
initialSheets = mSaveWorkbook.Sheets.Count
'note: sheet names will be 'Sheet1 (2)' in copy otherwise if
'they are not renamed
Dim sheetNames() As String
Dim activeSheetIndex As Integer
activeSheetIndex = pWorkbookToBeSaved.ActiveSheet.Index
Dim i As Integer
'copy each sheet
For i = 1 To pWorkbookToBeSaved.Sheets.Count
pWorkbookToBeSaved.Sheets(i).Copy After:=mSaveWorkbook.Sheets(mSaveWorkbook.Sheets.Count)
ReDim Preserve sheetNames(1 To i) As String
sheetNames(i) = pWorkbookToBeSaved.Sheets(i).Name
Next i
'clear sheets from new workbook
Application.DisplayAlerts = False
For i = 1 To initialSheets
mSaveWorkbook.Sheets(1).Delete
Next i
'rename stuff
For i = 1 To UBound(sheetNames)
mSaveWorkbook.Sheets(i).Name = sheetNames(i)
Next i
'reset view
mSaveWorkbook.Sheets(activeSheetIndex).Activate
'save and close
mSaveWorkbook.SaveAs FileName:=pNewFileName, FileFormat:=pFileFormat, CreateBackup:=False
mSaveWorkbook.Close
mySaveCopyAs = True
Application.DisplayAlerts = True
Exit Function
errHandler:
'whatever else you want to do with error handling
mySaveCopyAs = False
Exit Function
End Function
I did something similar to what Siddharth suggested and wrote a function to do it as well as handle some of the annoyances and offer some more flexibility.
Sub saveExample()
Application.ScreenUpdating = False
mySaveCopyAs ThisWorkbook, "C:Temptestfile2", xlOpenXMLWorkbook
Application.ScreenUpdating = True
End Sub
Private Function mySaveCopyAs(pWorkbookToBeSaved As Workbook, pNewFileName As String, pFileFormat As XlFileFormat) As Boolean
'returns false on errors
On Error GoTo errHandler
If pFileFormat = xlOpenXMLWorkbookMacroEnabled Then
'no macros can be saved on this
mySaveCopyAs = False
Exit Function
End If
'create new workbook
Dim mSaveWorkbook As Workbook
Set mSaveWorkbook = Workbooks.Add
Dim initialSheets As Integer
initialSheets = mSaveWorkbook.Sheets.Count
'note: sheet names will be 'Sheet1 (2)' in copy otherwise if
'they are not renamed
Dim sheetNames() As String
Dim activeSheetIndex As Integer
activeSheetIndex = pWorkbookToBeSaved.ActiveSheet.Index
Dim i As Integer
'copy each sheet
For i = 1 To pWorkbookToBeSaved.Sheets.Count
pWorkbookToBeSaved.Sheets(i).Copy After:=mSaveWorkbook.Sheets(mSaveWorkbook.Sheets.Count)
ReDim Preserve sheetNames(1 To i) As String
sheetNames(i) = pWorkbookToBeSaved.Sheets(i).Name
Next i
'clear sheets from new workbook
Application.DisplayAlerts = False
For i = 1 To initialSheets
mSaveWorkbook.Sheets(1).Delete
Next i
'rename stuff
For i = 1 To UBound(sheetNames)
mSaveWorkbook.Sheets(i).Name = sheetNames(i)
Next i
'reset view
mSaveWorkbook.Sheets(activeSheetIndex).Activate
'save and close
mSaveWorkbook.SaveAs FileName:=pNewFileName, FileFormat:=pFileFormat, CreateBackup:=False
mSaveWorkbook.Close
mySaveCopyAs = True
Application.DisplayAlerts = True
Exit Function
errHandler:
'whatever else you want to do with error handling
mySaveCopyAs = False
Exit Function
End Function
edited Sep 19 '13 at 17:51
answered Sep 19 '13 at 17:44
enderlandenderland
8,84712 gold badges64 silver badges122 bronze badges
8,84712 gold badges64 silver badges122 bronze badges
1
out of curiosity, is there a reason why you copy the sheets and not move them from the temp file? Moving closes the workbook automatically. Anyway, I can see this being quicker than saving a copy, opening etc, but it probably wouldn't be great if you intend to use this method with worksheets with tables, formulae, defined names etc (though as you are using this with a template you control, I suppose you know this isn't an issue).
– Cor_Blimey
Sep 19 '13 at 21:05
1
@Cor_Blimey I want to keep the template intact and use this functionality basically like "SaveCopyAs" - if I move the sheets I lose them from the template workbook.
– enderland
Sep 20 '13 at 13:06
whoops - I lost sight of that objective. Thanks.
– Cor_Blimey
Sep 20 '13 at 16:46
add a comment |
1
out of curiosity, is there a reason why you copy the sheets and not move them from the temp file? Moving closes the workbook automatically. Anyway, I can see this being quicker than saving a copy, opening etc, but it probably wouldn't be great if you intend to use this method with worksheets with tables, formulae, defined names etc (though as you are using this with a template you control, I suppose you know this isn't an issue).
– Cor_Blimey
Sep 19 '13 at 21:05
1
@Cor_Blimey I want to keep the template intact and use this functionality basically like "SaveCopyAs" - if I move the sheets I lose them from the template workbook.
– enderland
Sep 20 '13 at 13:06
whoops - I lost sight of that objective. Thanks.
– Cor_Blimey
Sep 20 '13 at 16:46
1
1
out of curiosity, is there a reason why you copy the sheets and not move them from the temp file? Moving closes the workbook automatically. Anyway, I can see this being quicker than saving a copy, opening etc, but it probably wouldn't be great if you intend to use this method with worksheets with tables, formulae, defined names etc (though as you are using this with a template you control, I suppose you know this isn't an issue).
– Cor_Blimey
Sep 19 '13 at 21:05
out of curiosity, is there a reason why you copy the sheets and not move them from the temp file? Moving closes the workbook automatically. Anyway, I can see this being quicker than saving a copy, opening etc, but it probably wouldn't be great if you intend to use this method with worksheets with tables, formulae, defined names etc (though as you are using this with a template you control, I suppose you know this isn't an issue).
– Cor_Blimey
Sep 19 '13 at 21:05
1
1
@Cor_Blimey I want to keep the template intact and use this functionality basically like "SaveCopyAs" - if I move the sheets I lose them from the template workbook.
– enderland
Sep 20 '13 at 13:06
@Cor_Blimey I want to keep the template intact and use this functionality basically like "SaveCopyAs" - if I move the sheets I lose them from the template workbook.
– enderland
Sep 20 '13 at 13:06
whoops - I lost sight of that objective. Thanks.
– Cor_Blimey
Sep 20 '13 at 16:46
whoops - I lost sight of that objective. Thanks.
– Cor_Blimey
Sep 20 '13 at 16:46
add a comment |
There is nothing pretty or nice about this process in Excel VBA, but something like the below.
This code doesn't handle errors very well, is ugly, but should work.
We copy the workbook, open and resave the copy, then delete the copy. The temporary copy is stored in your local temp directory, and deleted from there as well.
Option Explicit
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Public Sub SaveCopyAs(TargetBook As Workbook, Filename, FileFormat, CreateBackup)
Dim sTempPath As String * 512
Dim lPathLength As Long
Dim sFileName As String
Dim TempBook As Workbook
Dim bOldDisplayAlerts As Boolean
bOldDisplayAlerts = Application.DisplayAlerts
Application.DisplayAlerts = False
lPathLength = GetTempPath(512, sTempPath)
sFileName = Left$(sTempPath, lPathLength) & "tempDelete_" & TargetBook.Name
TargetBook.SaveCopyAs sFileName
Set TempBook = Application.Workbooks.Open(sFileName)
TempBook.SaveAs Filename, FileFormat, CreateBackup:=CreateBackup
TempBook.Close False
Kill sFileName
Application.DisplayAlerts = bOldDisplayAlerts
End Sub
add a comment |
There is nothing pretty or nice about this process in Excel VBA, but something like the below.
This code doesn't handle errors very well, is ugly, but should work.
We copy the workbook, open and resave the copy, then delete the copy. The temporary copy is stored in your local temp directory, and deleted from there as well.
Option Explicit
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Public Sub SaveCopyAs(TargetBook As Workbook, Filename, FileFormat, CreateBackup)
Dim sTempPath As String * 512
Dim lPathLength As Long
Dim sFileName As String
Dim TempBook As Workbook
Dim bOldDisplayAlerts As Boolean
bOldDisplayAlerts = Application.DisplayAlerts
Application.DisplayAlerts = False
lPathLength = GetTempPath(512, sTempPath)
sFileName = Left$(sTempPath, lPathLength) & "tempDelete_" & TargetBook.Name
TargetBook.SaveCopyAs sFileName
Set TempBook = Application.Workbooks.Open(sFileName)
TempBook.SaveAs Filename, FileFormat, CreateBackup:=CreateBackup
TempBook.Close False
Kill sFileName
Application.DisplayAlerts = bOldDisplayAlerts
End Sub
add a comment |
There is nothing pretty or nice about this process in Excel VBA, but something like the below.
This code doesn't handle errors very well, is ugly, but should work.
We copy the workbook, open and resave the copy, then delete the copy. The temporary copy is stored in your local temp directory, and deleted from there as well.
Option Explicit
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Public Sub SaveCopyAs(TargetBook As Workbook, Filename, FileFormat, CreateBackup)
Dim sTempPath As String * 512
Dim lPathLength As Long
Dim sFileName As String
Dim TempBook As Workbook
Dim bOldDisplayAlerts As Boolean
bOldDisplayAlerts = Application.DisplayAlerts
Application.DisplayAlerts = False
lPathLength = GetTempPath(512, sTempPath)
sFileName = Left$(sTempPath, lPathLength) & "tempDelete_" & TargetBook.Name
TargetBook.SaveCopyAs sFileName
Set TempBook = Application.Workbooks.Open(sFileName)
TempBook.SaveAs Filename, FileFormat, CreateBackup:=CreateBackup
TempBook.Close False
Kill sFileName
Application.DisplayAlerts = bOldDisplayAlerts
End Sub
There is nothing pretty or nice about this process in Excel VBA, but something like the below.
This code doesn't handle errors very well, is ugly, but should work.
We copy the workbook, open and resave the copy, then delete the copy. The temporary copy is stored in your local temp directory, and deleted from there as well.
Option Explicit
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Public Sub SaveCopyAs(TargetBook As Workbook, Filename, FileFormat, CreateBackup)
Dim sTempPath As String * 512
Dim lPathLength As Long
Dim sFileName As String
Dim TempBook As Workbook
Dim bOldDisplayAlerts As Boolean
bOldDisplayAlerts = Application.DisplayAlerts
Application.DisplayAlerts = False
lPathLength = GetTempPath(512, sTempPath)
sFileName = Left$(sTempPath, lPathLength) & "tempDelete_" & TargetBook.Name
TargetBook.SaveCopyAs sFileName
Set TempBook = Application.Workbooks.Open(sFileName)
TempBook.SaveAs Filename, FileFormat, CreateBackup:=CreateBackup
TempBook.Close False
Kill sFileName
Application.DisplayAlerts = bOldDisplayAlerts
End Sub
answered Sep 19 '13 at 17:06
AndASMAndASM
4,9971 gold badge16 silver badges31 bronze badges
4,9971 gold badge16 silver badges31 bronze badges
add a comment |
add a comment |
I have a similar process, here's the solution I use. It allows the user to open a template, perform manipulation, save the template somewhere, and then have the original template open
- user opens macro-enabled template file
- do manipulation
- save ActiveWorkbook's file path (template file)
- execute a SaveAs
- set ActiveWorkbook (now the saveas'd file) as a variable
- open template file path in step 3
- close the variable in step 5
the code looks something like this:
'stores file path of activeworkbook BEFORE the SaveAs is executed
getExprterFilePath = Application.ActiveWorkbook.FullName
'executes a SaveAs
ActiveWorkbook.SaveAs Filename:=filepathHere, _
FileFormat:=51, _
Password:="", _
WriteResPassword:="", _
ReadOnlyRecommended:=False, _
CreateBackup:=False
'reenables alerts
Application.DisplayAlerts = True
'announces completion to user
MsgBox "Export Complete", vbOKOnly, "List Exporter"
'sets open file (newly created file) as variable
Set wbBLE = ActiveWorkbook
'opens original template file
Workbooks.Open (getExprterFilePath)
'turns screen updating, calculation, and events back on
With Excel.Application
.ScreenUpdating = True
.Calculation = Excel.xlAutomatic
.EnableEvents = True
End With
'closes saved export file
wbBLE.Close
add a comment |
I have a similar process, here's the solution I use. It allows the user to open a template, perform manipulation, save the template somewhere, and then have the original template open
- user opens macro-enabled template file
- do manipulation
- save ActiveWorkbook's file path (template file)
- execute a SaveAs
- set ActiveWorkbook (now the saveas'd file) as a variable
- open template file path in step 3
- close the variable in step 5
the code looks something like this:
'stores file path of activeworkbook BEFORE the SaveAs is executed
getExprterFilePath = Application.ActiveWorkbook.FullName
'executes a SaveAs
ActiveWorkbook.SaveAs Filename:=filepathHere, _
FileFormat:=51, _
Password:="", _
WriteResPassword:="", _
ReadOnlyRecommended:=False, _
CreateBackup:=False
'reenables alerts
Application.DisplayAlerts = True
'announces completion to user
MsgBox "Export Complete", vbOKOnly, "List Exporter"
'sets open file (newly created file) as variable
Set wbBLE = ActiveWorkbook
'opens original template file
Workbooks.Open (getExprterFilePath)
'turns screen updating, calculation, and events back on
With Excel.Application
.ScreenUpdating = True
.Calculation = Excel.xlAutomatic
.EnableEvents = True
End With
'closes saved export file
wbBLE.Close
add a comment |
I have a similar process, here's the solution I use. It allows the user to open a template, perform manipulation, save the template somewhere, and then have the original template open
- user opens macro-enabled template file
- do manipulation
- save ActiveWorkbook's file path (template file)
- execute a SaveAs
- set ActiveWorkbook (now the saveas'd file) as a variable
- open template file path in step 3
- close the variable in step 5
the code looks something like this:
'stores file path of activeworkbook BEFORE the SaveAs is executed
getExprterFilePath = Application.ActiveWorkbook.FullName
'executes a SaveAs
ActiveWorkbook.SaveAs Filename:=filepathHere, _
FileFormat:=51, _
Password:="", _
WriteResPassword:="", _
ReadOnlyRecommended:=False, _
CreateBackup:=False
'reenables alerts
Application.DisplayAlerts = True
'announces completion to user
MsgBox "Export Complete", vbOKOnly, "List Exporter"
'sets open file (newly created file) as variable
Set wbBLE = ActiveWorkbook
'opens original template file
Workbooks.Open (getExprterFilePath)
'turns screen updating, calculation, and events back on
With Excel.Application
.ScreenUpdating = True
.Calculation = Excel.xlAutomatic
.EnableEvents = True
End With
'closes saved export file
wbBLE.Close
I have a similar process, here's the solution I use. It allows the user to open a template, perform manipulation, save the template somewhere, and then have the original template open
- user opens macro-enabled template file
- do manipulation
- save ActiveWorkbook's file path (template file)
- execute a SaveAs
- set ActiveWorkbook (now the saveas'd file) as a variable
- open template file path in step 3
- close the variable in step 5
the code looks something like this:
'stores file path of activeworkbook BEFORE the SaveAs is executed
getExprterFilePath = Application.ActiveWorkbook.FullName
'executes a SaveAs
ActiveWorkbook.SaveAs Filename:=filepathHere, _
FileFormat:=51, _
Password:="", _
WriteResPassword:="", _
ReadOnlyRecommended:=False, _
CreateBackup:=False
'reenables alerts
Application.DisplayAlerts = True
'announces completion to user
MsgBox "Export Complete", vbOKOnly, "List Exporter"
'sets open file (newly created file) as variable
Set wbBLE = ActiveWorkbook
'opens original template file
Workbooks.Open (getExprterFilePath)
'turns screen updating, calculation, and events back on
With Excel.Application
.ScreenUpdating = True
.Calculation = Excel.xlAutomatic
.EnableEvents = True
End With
'closes saved export file
wbBLE.Close
answered Jan 5 '16 at 16:45
arbitelarbitel
1713 silver badges21 bronze badges
1713 silver badges21 bronze badges
add a comment |
add a comment |
Another option (only tested on latest versions of excel).
The Macros are not deleted until the workbook is closed after a SaveAs
.xlsx
so you can do two SaveAs
in quick succession without closing the workbook.
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False, ConflictResolution:=xlLocalSessionChanges
Application.DisplayAlerts = True
Note: you need to turn off the DisplayAlerts
to avoid getting the warning that the workbook already exists on the second save.
add a comment |
Another option (only tested on latest versions of excel).
The Macros are not deleted until the workbook is closed after a SaveAs
.xlsx
so you can do two SaveAs
in quick succession without closing the workbook.
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False, ConflictResolution:=xlLocalSessionChanges
Application.DisplayAlerts = True
Note: you need to turn off the DisplayAlerts
to avoid getting the warning that the workbook already exists on the second save.
add a comment |
Another option (only tested on latest versions of excel).
The Macros are not deleted until the workbook is closed after a SaveAs
.xlsx
so you can do two SaveAs
in quick succession without closing the workbook.
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False, ConflictResolution:=xlLocalSessionChanges
Application.DisplayAlerts = True
Note: you need to turn off the DisplayAlerts
to avoid getting the warning that the workbook already exists on the second save.
Another option (only tested on latest versions of excel).
The Macros are not deleted until the workbook is closed after a SaveAs
.xlsx
so you can do two SaveAs
in quick succession without closing the workbook.
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False, ConflictResolution:=xlLocalSessionChanges
Application.DisplayAlerts = True
Note: you need to turn off the DisplayAlerts
to avoid getting the warning that the workbook already exists on the second save.
answered Jul 14 '17 at 9:21
OSKMOSKM
69713 silver badges23 bronze badges
69713 silver badges23 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18899824%2fhow-to-use-vba-saveas-without-closing-calling-workbook%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
a lame workaround I can think of is to SaveCopyAs, open the copy, save it as your desired format, delete the copy. If you shove it into a sub then it won't clutter up your main procedures.
– Cor_Blimey
Sep 19 '13 at 16:14
1
Use
SaveCopyAs
to create a copy then, open that copy and do a save as?– Siddharth Rout
Sep 19 '13 at 16:20
@Cor_Blimey: Sorry didn't see your comment
– Siddharth Rout
Sep 19 '13 at 16:21
Or create a new workbook, copy all your sheets in that and then save it as an xlsx?
– Siddharth Rout
Sep 19 '13 at 16:22
Both those options make me die a little on the inside (ok a lot). @Cor_Blimey I definitely thought of doing that as well initially but it just seems there should be a better way. I'm working with network drives so minimizing saving on them multiple times is ideal.
– enderland
Sep 19 '13 at 16:25