Страницы: 1
RSS
Копирование активной книги/файла
 
Доброго времени суток, Планетяне!

Есть такая функция, которая при попытке передачи 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: с перемещением/переименованием тоже самое, только другие номера/описание ошибок. Может можно как-то "отстраниться" от книги (кроме как создавать новую), скопировать её, и "вернуться"…
Изменено: Jack Famous - 14.06.2019 11:15:52
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Что-то не понял, вы в переменную пытаетесь запихнуть полное имя вновь созданной книги?
"Все гениальное просто, а все простое гениально!!!"
 
Nordheim, в качестве первой переменной передаю полное имя (путь и имя) активной книги. В качестве второй - новый путь (где должна появится копия)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Активная книга сохранена на жестком диске? Путь по которому хотите сохранить существует?
Изменено: Nordheim - 14.06.2019 11:06:29
"Все гениальное просто, а все простое гениально!!!"
 
Можно пример с рабочей функцией, только без лишнего кода плиз, а то глаза разбегаются от кодирования))
"Все гениальное просто, а все простое гениально!!!"
 
Nordheim, разумеется)) все проверки проведены. Говорю же, если эту книгу из ДРУГОЙ сохранить (то есть, когда копируемая книга не является активной), то всё получается. При абсолютно таких же прочих условиях.
Цитата
Nordheim: пример с рабочей функцией без лишнего кода
Код
Sub Files_Copy(oldPath$, newPath$)
FileCopy oldPath, newPath
End Sub
Изменено: Jack Famous - 14.06.2019 11:14:05
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Короче, решил использовать для любых книг метод через Shell от ZVI. Очень шустрая штука :idea:
Изменено: Jack Famous - 14.06.2019 11:42:14
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
При использовании FileCopy, на сколько я понял, файл вообще может быть закрыт. Предположу, что ошибка Permission Denied (доступ запрещен), выводится по причине того что файл активный в режиме редактирования. Могу ошибаться, но попробовал копировать вообще не открытый файл, все отработало на ура.
"Все гениальное просто, а все простое гениально!!!"
 
Цитата
Nordheim: При использовании FileCopy, на сколько я понял, файл вообще может быть закрыт
ну разумеется. И именно поэтому мне прекрасно удаётся скопировать файл, находясь в другом, то есть файл должен быть НЕАКТИВНЫЙ. Об этом свойстве также написано в руководстве (увидел потом, ссылка в стартовом сообщении). А мне для макроса бэкапа нужно было копировать именно активную книгу…
Изменено: Jack Famous - 14.06.2019 12:37:02
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
как обойти это без использования ActiveWorkbook.SaveAs?
Джек, а почему бы не использовать тогда .SaveCopyAs?
 
Вот тут прямо написано -
Примечания
Если вы попытаетесь использовать оператор FileCopy для открытого в данный момент файла, возникнет ошибка.
"Все гениальное просто, а все простое гениально!!!"
 
Юрий М, искал что-то пошустрее и более точное. FileCopy отлично подходит, если бы не ограничение на активную книгу. Вот думал, как обойти. Shell прекрасно справляется, но не так просто отловить ошибку.

Nordheim, вы серьёзно? Я вам об этом и пишу. И ссылку закрепил в первом сообщении. Я искал способы обойти это с помощью каких-нибудь костылей…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Как всегда, первый кандидат для такого рода операций - объект FileSystemObject (метод CopyFile).
"Родные" методы VBA не поддерживают юникод и возникают проблемы, если имена файлов (и/или папок) содержат, например, символы расширенной латиницы (подробнее здесь, пункт 3.4).
Изменено: sokol92 - 14.06.2019 13:04:52
Владимир
 
После тестов всё-таки отказался от 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, учитывая ваши комментарии, тем более утвердился в правильности выбора - спасибо  ;)
Изменено: Jack Famous - 14.06.2019 13:24:40
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Успехов, Алексей!
Маленькое дополнение. Создавать и удалять объекты (особенно в цикле) - недешёвое удовольствие. Следующий трюк (функция 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
Изменено: sokol92 - 14.06.2019 13:30:53
Владимир
 
sokol92, благодарю)) и вам  :)

UPD: а я немного с другой стороны хотел зайти, чтобы избежать этого - переписать функцию под массив пар "старый путь-новый путь", поскольку о том, как много "жрёт" создание объектов в цикле помню ещё с соревнований   :D

И снова ваш приём мне кажется намного удобнее, проще и правильнее. Сделаю отдельный модуль с функциями создания объектов  :idea: Большое спасибо!
Изменено: Jack Famous - 14.06.2019 13:41:20
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
Nordheim , вы серьёзно? Я вам об этом и пишу. И ссылку закрепил в первом сообщении. Я искал способы обойти это с помощью каких-нибудь костылей…
А какой смысл искать костыли, если написано что не работает, тут нужен иной способ, а не костылями пробовать переделать. По опыту знаю, что костыли работают но не всегда корректно. А если ипользовать FSO, то это уже не костыли, а целая библиотека с кучей свойств и методов одни из которых могут справится с  выполнением поставленной задачи.

PS
Если бы увидел сразу ссылку, то и дискутировать на тему костылей не стал бы.
"Все гениальное просто, а все простое гениально!!!"
 
Nordheim, да - FSO это не костыли, а другой способ, как и Shell. Сначала он мне не очень понравился, но потом ничего - смирился))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх