Есть такая функция, которая при попытке передачи oldPath=ActiveWorkbook.FullName выдаёт ошибку 70: Permission Denied. Дэ-юре это вроде как попытка скопировать защищённый файл, но дэ-факто, она просто не даёт скопировать Активную книгу, т.к. её же, но из другого файла копирует без проблем
Код
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' КАК СРЕДСТВАМИ VBA ПЕРЕИМЕНОВАТЬ/ПЕРЕМЕСТИТЬ/СКОПИРОВАТЬ ФАЙЛ
' https://www.excel-vba.ru/chto-umeet-excel/kak-sredstvami-vba-pereimenovatperemestitskopirovat-fajl/
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Function PRDX_Files_Copy(oldPath$, newPath$, Optional MsgIfTrue As Boolean, Optional MsgIfFalse As Boolean) As Boolean
FileCopy oldPath, newPath: PRDX_Files_Copy = True
If MsgIfTrue Then MsgBox "Файл успешно скопирован от пути «" & oldPath & "» по пути «" & newPath & "»", vbInformation, "PRDX_Files_Copy": Exit Function
If MsgIfFalse Then MsgBox "Не удалось скопировать файл от пути «" & oldPath & "» по пути «" & newPath & "»", vbCritical, "PRDX_Files_Copy"
End Function
Вопрос: как обойти это без использования ActiveWorkbook.SaveAs?
UPD: с перемещением/переименованием тоже самое, только другие номера/описание ошибок. Может можно как-то "отстраниться" от книги (кроме как создавать новую), скопировать её, и "вернуться"…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Nordheim, в качестве первой переменной передаю полное имя (путь и имя) активной книги. В качестве второй - новый путь (где должна появится копия)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Nordheim, разумеется)) все проверки проведены. Говорю же, если эту книгу из ДРУГОЙ сохранить (то есть, когда копируемая книга не является активной), то всё получается. При абсолютно таких же прочих условиях.
Цитата
Nordheim: пример с рабочей функцией без лишнего кода
Код
Sub Files_Copy(oldPath$, newPath$)
FileCopy oldPath, newPath
End Sub
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
При использовании FileCopy, на сколько я понял, файл вообще может быть закрыт. Предположу, что ошибка Permission Denied (доступ запрещен), выводится по причине того что файл активный в режиме редактирования. Могу ошибаться, но попробовал копировать вообще не открытый файл, все отработало на ура.
"Все гениальное просто, а все простое гениально!!!"
Nordheim: При использовании FileCopy, на сколько я понял, файл вообще может быть закрыт
ну разумеется. И именно поэтому мне прекрасно удаётся скопировать файл, находясь в другом, то есть файл должен быть НЕАКТИВНЫЙ. Об этом свойстве также написано в руководстве (увидел потом, ссылка в стартовом сообщении). А мне для макроса бэкапа нужно было копировать именно активную книгу…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Юрий М, искал что-то пошустрее и более точное. FileCopy отлично подходит, если бы не ограничение на активную книгу. Вот думал, как обойти. Shell прекрасно справляется, но не так просто отловить ошибку.
Nordheim, вы серьёзно? Я вам об этом и пишу. И ссылку закрепил в первом сообщении. Я искал способы обойти это с помощью каких-нибудь костылей…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Как всегда, первый кандидат для такого рода операций - объект FileSystemObject (метод CopyFile). "Родные" методы VBA не поддерживают юникод и возникают проблемы, если имена файлов (и/или папок) содержат, например, символы расширенной латиницы (подробнее здесь, пункт 3.4).
После тестов всё-таки отказался от Shell, т.к. тяжело контролировать выполнение. Функция на основе метода с FSO (по ссылке) работает отлично
Код
Function PRDX_Files_Copy(oldPath$, newPath$, Optional MsgIfTrue As Boolean, Optional MsgIfFalse As Boolean) As Boolean
On Error Resume Next
With CreateObject("Scripting.FileSystemObject"): .GetFile(oldPath).Copy newPath: End With
If Err Then GoTo er
If MsgIfTrue Then MsgBox "Файл успешно скопирован от пути «" & oldPath & "» по пути «" & newPath & "»", vbInformation, "PRDX_Files_Copy"
PRDX_Files_Copy = True: Exit Function
er: On Error GoTo 0: If MsgIfFalse Then MsgBox "Не удалось скопировать файл от пути «" & oldPath & "» по пути «" & newPath & "»", vbCritical, "PRDX_Files_Copy"
End Function
sokol92, учитывая ваши комментарии, тем более утвердился в правильности выбора - спасибо
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Успехов, Алексей! Маленькое дополнение. Создавать и удалять объекты (особенно в цикле) - недешёвое удовольствие. Следующий трюк (функция GetFSO) обходит это препятствие. Объект FileSystemObject будет создаваться однократно (и в случаях сброса проекта).
Код
' Возвращает объект FileSysTemObject
Function GetFSO() As Object
Static fso As Object
If fso Is Nothing Then
Set fso = CreateObject("Scripting.FileSystemObject")
End If
Set GetFSO = fso
End Function
Sub FileCopy2(ByVal Source, ByVal Destination)
GetFSO.CopyFile Source, Destination
End Sub
Sub test()
FileCopy2 "C:\Temp\пример.xlsm", "C:\Temp\Пример2.xlsm"
End Sub
UPD: а я немного с другой стороны хотел зайти, чтобы избежать этого - переписать функцию под массив пар "старый путь-новый путь", поскольку о том, как много "жрёт" создание объектов в цикле помню ещё с соревнований
И снова ваш приём мне кажется намного удобнее, проще и правильнее. Сделаю отдельный модуль с функциями создания объектов Большое спасибо!
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous написал: Nordheim , вы серьёзно? Я вам об этом и пишу. И ссылку закрепил в первом сообщении. Я искал способы обойти это с помощью каких-нибудь костылей…
А какой смысл искать костыли, если написано что не работает, тут нужен иной способ, а не костылями пробовать переделать. По опыту знаю, что костыли работают но не всегда корректно. А если ипользовать FSO, то это уже не костыли, а целая библиотека с кучей свойств и методов одни из которых могут справится с выполнением поставленной задачи.
PS Если бы увидел сразу ссылку, то и дискутировать на тему костылей не стал бы.
"Все гениальное просто, а все простое гениально!!!"
Nordheim, да - FSO это не костыли, а другой способ, как и Shell. Сначала он мне не очень понравился, но потом ничего - смирился))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄