Получение ошибки "метод saveas книги объектов не удалось" при попытке сохранить XLSM как CSV

Я пытаюсь сохранить книгу excel (с поддержкой макросов) в виде csv-файла через этот макрос, перезаписывая старый (ниже у меня было изменение имени папки и листа, но это, похоже, не проблема!):

 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

как ни странно, иногда, но не всегда, он терпит неудачу и сообщение об ошибке заголовка (ошибка выполнения 1004: метод saveas объекта _workbook не) выскакивает с отладчиком, указывающим мне на эту строку:

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

I погуглил его, и, по-видимому, это происходит много с людьми, и некоторые из решений, которые я пробовал, были:

  • указание того, что каталог является строкой
  • избегайте любого специального символа в имени файла или папки (см. здесь)
  • копировать вставьте лист как значение перед сохранением его как .csv (см. здесь)
  • указание FileFormat с помощью .номер кода csv (см. здесь)
  • отключение/повторное включение некоторых предупреждений
  • добавление других полей в ActiveWorkbook.Сохранить как строку, касающиеся паролей, создания резервных копий etcetc

тем не менее, он может работать правильно до 50-60 раз подряд, а затем в какой-то момент снова терпеть неудачу в строке.

любое предложение или вещи, которые я мог бы посмотреть, чтобы решить эту проблему (кроме остановки использования VBA / Excel для этой задачи, которая произойдет в ближайшее время, но я не могу для теперь.)

заранее спасибо за ваше время.

EDIT: решено благодаря предложению Degustaf. Я внес только два изменения в предложенный Degustaf код:

  • ThisWorkbook.Листы вместо CurrentWorkbook.Листы
  • FileFormat:=6 вместо FileFormat:=xlCSV (по-видимому, более надежный для разных версий 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

3 ответов


Я вообще считаю что ActiveWorkbook проблема в этих случаях. Под этим я подразумеваю, что каким-то образом у вас нет этой книги (или любой другой), и Excel не знает, что делать. К сожалению, с copy ничего не возвращает (скопированный рабочий лист был бы хорошим), это стандартный способ подхода к этой проблеме.

Итак, мы можем подойти к этому, как мы можем скопировать этот лист в новую книгу, и получить ссылку на эту книгу. Что мы можем сделать, так это создать новая книга, а затем скопируйте лист:

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

или есть еще лучший подход в такой ситуации: WorkSheet поддерживает SaveAs метод. Нет необходимости копировать.

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

я предупрежу вас, чтобы сохранить книгу в исходное имя afterwarsd, если она остается открытой, но у вас уже есть это в вашем коде.


Это год назад, но я добавлю кое-что для будущих читателей

вы не найдете много документации в справке Excel для ошибки времени выполнения 1004, поскольку Microsoft не считает ее ошибкой Excel.

ответы выше 100% действительны, но иногда это помогает узнать, что вызывает проблему, так что вы можете избежать его, исправить его раньше или исправить его более легко.

факт что это прерывистый недостаток, и он исправлен путем сохранять с полным путем и имя файла говорит мне, что ваш макрос может пытаться сохранить.xlsb-файл в каталог autorecover после автоматического восстановления файла.

кроме того, вы, возможно, отредактировали путь к файлу или имя файла самостоятельно.

вы можете проверить путь и имя файла с:- Функцию MsgBox Файл Thisworkbook.Полное имя

вы должны увидеть что-то подобное в окне сообщения.

C:\Users\Mike\AppData\Roaming\Microsoft\Excel\DIARY (Версия 1).xlxb

Если таким образом, решение (как указано выше другими), чтобы сохранить ваш файл на правильный путь и имя файла. Это можно сделать с помощью VBA или вручную.

Теперь у меня есть привычка вручную сохранять файл с его правильным путем и именем файла как само собой разумеющееся после любого действия автосохранения, поскольку это занимает секунды, и я нахожу его быстрее (если это не ежедневное явление). Таким образом, макросы не столкнутся с этой ошибкой, которую вы запустите. Помните, что в то время как моя привычка вручную экономить.файлы xlxb для .файлы xlsm сразу после восстановления не помогут новичку, которому вы даете лист.

примечание по гиперссылкам

после этой ошибки: если у вас есть гиперссылки на листе, созданных с Ctrl+k по всей вероятности, у вас будет что-то вроде "AppData\Roaming\Microsoft\", "\AppData\Roaming\", "../../ AppData / роуминг/ "или"....\Мои документы\Мои документы\ " в нескольких гиперссылках после восстановления файла. Вы можете избежать их путем прикрепление гиперссылок к текстовому полю или их генерация с помощью функции гиперссылки.

идентификация и ремонт их немного сложнее

сначала проверьте гиперссылки и определите ошибочные строки и правильную строку для каждой ошибки. Со временем я нашел несколько.

Excel не предоставляет средства в меню "перейти к специальному" для поиска гиперссылок, созданных с помощью Ctrl+k.

вы можете автоматизировать идентификацию ошибочных гиперссылок в вспомогательном столбце, скажем, столбец Z и используя формулу

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

где Link2Text является UDF

функция Link2Text (rng как диапазон) как строка - Не отключайтесь. "Находит гиперссылки, содержащие "роуминг" в столбце Z.

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

  End Function

мой VBA для исправления ошибок выглядит следующим образом

Sub Replace_roaming ()

' Выберите правильный лист Листы ("дневник").Выберите

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

Я также рекомендую вам привыкнуть делать регулярные резервные копии и не полагаться только на автосохранение. Если это не удастся, у вас ничего нет с момента последней полной резервной копии.

в то время как лист является хрупкой резервной копии часто, как каждый час или после любого значительного импорта новых данных.

следующие ярлыки будут резервное копирование рабочего листа в секундах:Ctrl+O, [выделите имя файла], Ctrl+C, Ctrl+V, [ X]. Регулярные резервные копии позволяют сразу перейти к последней резервной копии без необходимости восстановления из файла резервной копии прошлой ночи, особенно если вам нужно сделать запрос другого человека, чтобы сделать это.


попробуйте объединить путь и имя файла CSV в строковую переменную и отбросить.csv; который обрабатывается FileFormat. Путь должен быть абсолютным, начиная с буквы диска или имени сервера: Dim strFullFileName as String strFullFileName = "C:\My Folder\My_Sheet" Если на сервере, то это будет выглядеть примерно так: strFullFileName = "\ServerName\ShareName\My Folder\My_Sheet" Substiture ServerName с именем вашего сервера и замените ShareName именем вашего сетевого ресурса, например \data101\Accounting\My Folder\My_Sheet ActiveWorkbook.SaveAs Filename:=strFullFileName,FileFormat:=xlCSVMSDOS, CreateBackup:=False