web-dev-qa-db-fra.com

Obtention de l'erreur "La sauvegarde des méthodes de l'objet _travail a échoué" lors de la tentative d'enregistrement d'un fichier XLSM au format CSV

J'essaie d'enregistrer un classeur Excel compatible avec les macros en tant que fichier csv, en écrasant l'ancien (ci-dessous, j'ai dû changer le nom du dossier et de la feuille, mais cela ne semble pas être le problème).

 Sub SaveWorksheetsAsCsv()

 Dim SaveToDirectory As String
 Dim CurrentWorkbook As String
 Dim CurrentFormat As Long

 CurrentWorkbook = ThisWorkbook.FullName
 CurrentFormat = ThisWorkbook.FileFormat
 SaveToDirectory = "\MyFolder\"

 Application.DisplayAlerts = False
 Application.AlertBeforeOverwriting = False

 Sheets("My_Sheet").Copy

 ActiveWorkbook.SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=xlCSV
 ActiveWorkbook.Close SaveChanges:=False
 ThisWorkbook.Activate

 ThisWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat

 Application.DisplayAlerts = True
 Application.AlertBeforeOverwriting = True

 End Sub

Parfois, il échoue avec

Erreur d'exécution 1004: les sauvegardes de la méthode de l'objet _workbook ont ​​échoué **)

Le débogueur souligne:

 ActiveWorkbook.SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=xlCSV

J'ai googlé et certaines des solutions que j'ai essayées étaient:

  • Spécifier que le répertoire est une chaîne
  • Évitez tout caractère spécial dans le nom de fichier ou le dossier (vu ici )
  • Copiez collez la feuille de calcul en tant que valeur avant de l'enregistrer au format .csv (vu ici )
  • Spécification du FileFormat avec le numéro de code .csv (vu ici )
  • Désactiver/réactiver certaines des alertes
  • Ajout d'autres champs dans la ligne ActiveWorkbook.SaveAs, concernant les mots de passe, la création de sauvegardes, etc.

Pourtant, il peut fonctionner correctement jusqu'à 50 à 60 fois de suite, puis à un moment donné échouer à nouveau.

Toute suggestion, sauf arrêter d'utiliser VBA/Excel pour cette tâche, ce qui arrivera bientôt, mais je ne peux pas pour l'instant.

EDIT: Résolu grâce à la suggestion de Degustaf. Je n'ai apporté que deux modifications au code suggéré par Degustaf:

  • ThisWorkbook.Sheets au lieu de CurrentWorkbook.Sheets
  • FileFormat:=6 au lieu de FileFormat:=xlCSV (est apparemment plus robuste pour différentes versions d'Excel)

Sub SaveWorksheetsAsCsv()

Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
Dim TempWB As Workbook

Set TempWB = Workbooks.Add

CurrentWorkbook = ThisWorkbook.FullName
CurrentFormat = ThisWorkbook.FileFormat
SaveToDirectory = "\\MyFolder\"

Application.DisplayAlerts = False
Application.AlertBeforeOverwriting = False

ThisWorkbook.Sheets("My_Sheet").Copy Before:=TempWB.Sheets(1)
ThisWorkbook.Sheets("My_Sheet").SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=6
TempWB.Close SaveChanges:=False

ThisWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
ActiveWorkbook.Close SaveChanges:=False

Application.DisplayAlerts = True
Application.AlertBeforeOverwriting = True
End Sub
9
Riccardo

Je trouve généralement que ActiveWorkbook est le problème dans ces cas. J'entends par là que vous n'avez pas sélectionné ce classeur (ou tout autre) et Excel ne sait pas quoi faire. Malheureusement, puisque copy ne renvoie rien (la feuille de calcul copiée serait bien), c'est une façon standard d'aborder ce problème.

Donc, nous pouvons aborder cela comme comment pouvons-nous copier cette feuille dans un nouveau classeur et obtenir une référence à ce classeur. Ce que nous pouvons faire, c'est créer le nouveau classeur, puis copier la feuille:

Dim wkbk as Workbook

Set Wkbk = Workbooks.Add
CurrentWorkbook.Sheets("My_Sheet").Copy Before:=Wkbk.Sheets(1)
Wkbk.SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=xlCSV
Wkbk.Close SaveChanges:=False

Ou, il existe une approche encore meilleure dans une situation comme celle-ci: WorkSheet prend en charge la méthode SaveAs. Aucune copie nécessaire.

CurrentWorkbook.Sheets("My_Sheet").SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=xlCSV

Je vous avertirai de réenregistrer le classeur à son nom d'origine par la suite, s'il reste ouvert, mais vous l'avez déjà dans votre code.

5
Degustaf

Ceci a un an, mais je vais ajouter quelque chose pour les futurs lecteurs

Vous ne trouverez pas beaucoup de documentation dans l'aide d'Excel pour l'erreur d'exécution 1004, car Microsoft ne considère pas qu'il s'agit d'une erreur Excel.

Les réponses ci-dessus sont valides à 100%, mais il est parfois utile de savoir ce qui cause le problème afin que vous puissiez l'éviter, le résoudre plus tôt ou le résoudre plus facilement.

Le fait qu'il s'agisse d'une erreur intermittente et qu'elle soit corrigée en enregistrant avec le chemin d'accès complet et le nom de fichier m'indique que votre macro peut essayer d'enregistrer un fichier .xlsb dans le répertoire de récupération automatique après une récupération automatique de fichier.

Vous pouvez également avoir modifié vous-même le chemin d'accès ou le nom du fichier.

Vous pouvez vérifier le chemin et le nom de fichier avec: - MsgBox ThisWorkbook.FullName

Vous devriez voir quelque chose comme ça dans la boîte de message.

C:\Users\Mike\AppData\Roaming\Microsoft\Excel\DIARY (version 1) .xlxb

Si c'est le cas, la solution consiste (comme indiqué ci-dessus par d'autres) à enregistrer votre fichier dans son chemin d'accès et son nom de fichier corrects. Cela peut être fait avec VBA ou manuellement.

J'ai maintenant l'habitude de sauvegarder manuellement le fichier avec son chemin et son nom de fichier corrects bien sûr après toute action de récupération automatique car cela prend quelques secondes et je le trouve plus rapide (si ce n'est pas une occurrence quotidienne). Ainsi, les macros ne rencontreront pas ce défaut si vous l'exécutez. N'oubliez pas que même si mon habitude de sauvegarder manuellement les fichiers .xlxb dans des fichiers .xlsm immédiatement après une récupération n'aidera pas un novice à qui vous donnez la feuille de calcul.

Une note sur les hyperliens

Après cette erreur: si vous avez des hyperliens dans votre feuille de calcul créés avec Ctrl+k selon toute vraisemblance, vous aurez quelque chose comme "AppData\Roaming\Microsoft \", "\ AppData\Roaming \", "../../AppData/Roaming/"or" ....\Mes documents\Mes documents\"dans plusieurs hyperliens après la récupération du fichier. Vous pouvez les éviter en attachant vos hyperliens à une zone de texte ou en les générant avec la fonction HYPERLINK.

Les identifier et les réparer est un peu plus compliqué

Tout d'abord, examinez les liens hypertexte et déterminez les chaînes erronées et la chaîne correcte pour chaque erreur. Au fil du temps, j'en ai trouvé plusieurs.

Excel ne fournit pas de fonctionnalité dans le menu "Aller à spécial" pour rechercher des hyperliens créés avec Ctrl+k.

Vous pouvez automatiser l'identification des hyperliens erronés dans une colonne d'assistance, par exemple la colonne Z et en utilisant la formule

=OR(ISNUMBER(SEARCH("Roaming", Link2Text($C2),1)),ISNUMBER(SEARCH("Roaming", Link2Text($D2),1)))

où Link2Text est l'UDF

Fonction Link2Text (rng As Range) As String 'NE PAS désactiver. "Localise les hyperliens contenant" itinérance "dans la colonne Z.

' Identify affected hyperlinks
    If rng(1).Hyperlinks.Count Then
    Link2Text = rng.Hyperlinks(1).Address
    End If

  End Function

Mon VBA pour corriger les erreurs est le suivant

Sub Replace_roaming ()

'Sélectionnez les feuilles de feuille appropriées ("JOURNAL").

Dim hl As Hyperlink
For Each hl In ActiveSheet.Hyperlinks
    hl.Address = Replace(hl.Address, "AppData\Roaming\Microsoft\", "")
Next
    For Each hl In ActiveSheet.Hyperlinks
    hl.Address = Replace(hl.Address, "AppData\Roaming\", "")
Next

    For Each hl In ActiveSheet.Hyperlinks
    hl.Address = Replace(hl.Address, "../../AppData/Roaming/", "..\..\My documents\")
Next
    For Each hl In ActiveSheet.Hyperlinks
    hl.Address = Replace(hl.Address, "..\..\My documents\My documents\", "..\..\My documents\")
Next

Application.Run "Recalc_BT"

' Move down one active row to get off the heading
    ActiveCell.Offset(1, 0).Select

' Check active row location
    If ActiveCell.Row = 1 Then
    ActiveCell.Offset(1, 0).Select
    End If

' Recalc active row
   ActiveCell.EntireRow.Calculate

' Notify
    MsgBox "Replace roaming is now complete."

End Sub

Je vous recommande également de prendre l'habitude de faire des sauvegardes régulières et de ne pas compter uniquement sur la récupération automatique. En cas d'échec, vous n'avez plus rien depuis votre dernière sauvegarde complète.

Bien que la feuille de calcul soit souvent fragile, la sauvegarde, comme toutes les heures ou après toute importation importante de nouvelles données.

Les raccourcis suivants sauvegarderont votre feuille de calcul en quelques secondes: Ctrl+O, [mettez en surbrillance le nom du fichier], Ctrl+CCtrl+V, [ X ]. Les sauvegardes régulières vous permettent d'accéder immédiatement à votre sauvegarde la plus récente sans avoir à restaurer à partir du fichier de sauvegarde de la nuit dernière, surtout si vous devez faire la demande d'une autre personne pour ce faire.

3
Mike Benstead

Essayez de combiner le chemin et le nom du fichier CSV dans une variable de chaîne et supprimez le .csv; qui est géré par le FileFormat. Le chemin doit être absolu en commençant par une lettre de lecteur ou un nom de serveur: Dim strFullFileName as StringstrFullFileName = "C:\My Folder\My_Sheet" Si sur un serveur, cela ressemblerait à ceci: strFullFileName = "\\ServerName\ShareName\My Folder\My_Sheet" Remplacez ServerName par votre nom de serveur et remplacez ShareName par votre nom de partage réseau, par exemple \\data101\Accounting\My Folder\My_SheetActiveWorkbook.SaveAs Filename:=strFullFileName,FileFormat:=xlCSVMSDOS, CreateBackup:=False

0
JMMach