Je veux:
Utiliser SaveAs
fait exactement ce qui est attendu - il enregistre le classeur tout en supprimant les macros et me présente la vue du classeur SavedAs nouvellement créé.
Cela signifie malheureusement:
Est-ce qu'il y a un moyen de faire ça?
'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
Notez également que SaveCopyAs
me permettra de le sauvegarder sous un type différent (c.-à-d. templateWb.SaveCopyAs FileName:="myXlsx.xlsx"
). Cela produira une erreur lors de son ouverture car il a maintenant un format de fichier non valide.
J'ai fait quelque chose de similaire à ce que Siddharth avait suggéré et écrit une fonction pour le faire, ainsi que pour gérer certains désagréments et offrir plus de flexibilité.
Sub saveExample()
Application.ScreenUpdating = False
mySaveCopyAs ThisWorkbook, "C:\Temp\testfile2", 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
Voici une méthode beaucoup plus rapide que d'utiliser .SaveCopyAs
pour créer une copie, puis l'ouvrir et faire une sauvegarde sous ...
Comme mentionné dans mes commentaires, ce processus prend environ 1 seconde pour créer une copie xlsx à partir d'un classeur comportant 10 feuilles de calcul (chacune contenant 100 lignes * 20 colonnes).
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
J'ai un processus similaire, voici la solution que j'utilise. Il permet à l'utilisateur d'ouvrir un modèle, d'effectuer des manipulations, de sauvegarder le modèle quelque part, puis d'ouvrir le modèle d'origine.
le code ressemble à ceci:
'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
Ce processus dans Excel VBA n’a rien de joli ni de sympa, mais quelque chose comme l’observation ci-dessous… .. Ce code ne traite pas très bien les erreurs, est moche, mais devrait fonctionner.
Nous copions le classeur, ouvrons et enregistrez la copie, puis supprimons la copie. La copie temporaire est stockée dans votre répertoire temporaire local et également supprimée.
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
Une autre option (testé uniquement sur les dernières versions d'Excel).
Les macros ne sont pas supprimées tant que le classeur n'est pas fermé après une SaveAs
.xlsx
. Vous pouvez ainsi exécuter deux SaveAs
successives sans fermer le classeur.
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False, ConflictResolution:=xlLocalSessionChanges
Application.DisplayAlerts = True
Remarque: vous devez désactiver la DisplayAlerts
pour éviter de recevoir l'avertissement que le classeur existe déjà lors de la deuxième sauvegarde.