VBA Error 1004 - ChangeFileAccess Method Failed - File on Sharepoint - excel

I'm fixing some code written by a colleague and I've come across this hurdle where an Excel document is opened from a Sharepoint and the ChangeFileAccess method is run to change it to Read/Write. The method fails with error code 1004. The file opens so everything up to that point is working.
I can't see why it won't work, I'm hoping someone more knowledgeable than I can!
I've removed the file path and document name for the sake of anonymity.
I'm using Office 365, code in question below:
Dim ObjFileA, ObjfileB As File
FilePathA = "filepath" & fileName
Set FSO = CreateObject("Scripting.FileSystemObject")
Set App = CreateObject("Excel.Application")
Set ObjFileA = FSO.GetFile(FilePathA)
Set wbA = Workbooks.Open(ObjFileA, False, False)
wbA.Activate
wbA.ChangeFileAccess (xlReadWrite)
Set wbA = Workbooks(fileName)

Is your file already being opened as Read-Write?
I just encountered a similar problem to what you describe (Err 1004 when changing the access method, though in my case I was attempting to change the access to Read-Only on a file that was already Read-Only.)
After some testing, I get the error every time if I try to invoke wkbk.ChangeFileAccess to "change" the access type to be the same as the current access type.
If you find that the workbook might already be Read-Write, then I suggest a change to :
If wbA.ReadOnly then wbA.ChangeFileAccess (xlReadWrite)

Related

How to SaveAs with OneDrive while offline?

I use VBA to create copies (Excel and PDF) of an Excel document.
I save in the OneDrive folder (C:\Users\XXX\OneDrive) so I can access the document from every device later. I use this folder so I can save while I am connected to internet or not.
When I am connected to internet and OneDrive everything works.
When I am not connected to internet I get
error 1004 method saveas of object _workbook failed
My macro stops but when I go to the folder the files are there.
I get the error on:
ActiveWorkbook.SaveAs Filename:=Fname, FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
(Fname="C:\Users\XXX\OneDrive\YYY\ZZZ.xlsm")
I couldn't find anything related to this function not working on OneDrive while not connected to internet.
If your file is in OneDrive, I would first make sure to deactivate the AutoSave feature. I've personally had some bugs with it in the past, so it might help.
I'm not aware of this particular bug that you are experiencing, but since you are saying that the file is actually saved properly even if an error is triggered, there is a way to ignore the error and check if the file was actually saved. It would look a little like this:
Const RETRY_LIMIT = 2
Dim DoesFileExist As Boolean
dim RetryCounter as Integer
Do While RetryCounter < RETRY_LIMIT And DoesFileExist = False
On Error Resume Next
ActiveWorkbook.SaveAs Filename:=Fname, FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
On Error GoTo 0
DoesFileExist = FileExists(Fname)
RetryCounter = RetryCounter + 1
Loop
If DoesFileExist = False Then
MsgBox "Error: File couldn't be saved."
Exit Sub
End If
Note that I've added a retry limit of 2 to make sure that we don't go into an infinite loop.
Also make sure to add the following function in the module you are working on to make sure the code above works.
Function FileExists(ByVal FullFileName As String) As Boolean
If Dir(FullFileName) <> vbNullString Then FileExists = True
End Function
Some explanations and caveats
If you have never used error handling statements such as : On Error Resume Next or On Error GoTo 0, I would strongly advise you to have a look at C. Pearson's Error Handling In VBA article.
To summarize, what On Error Resume Next does is simply ignore the error and let the code handle the error. In our case, the DoesFileExist does the job of making sure that the code ran without error and the if statement after the loop will make sure to stop the code if all tentative to save the file failed. This does the job, but you could also check Err.Number to handle different type of error as well.
Regarding On Error GoTo 0, to put it simply, it resets the VBA error handling to its normal state where any error will launch the usual run-time error dialog box
I ended up saving the file on my desktop and then using FileSystemObject to move the file. It works fine except that if I try to open the file right away (using VBA or directly in windows explorer) I get a network error. If I wait about 1 min I don't get that error anymore. So I decided to live with it for now.
here is an example:
Dim FSO as Object
Set FSO = CreateObject("Scripting.Filesystemobject")
FSO.MoveFile("SourceFileName", "TargetFileName")
Thank you very much for your help

Fix with code : "Parts of your document may include personal information that cannot be removed by the document inspector"

I have the following script "MyTest.vbs" :
Dim objXLApp
Set objXLApp = CreateObject("Excel.Application")
objXLApp.visible= True
objXLApp.DisplayAlerts = false
objXLApp.Workbooks.Open "F:MyFolder\test.xlsm"
objXLApp.Run "test.xlsm!Module1.main"
objXLApp.Workbooks("test.xlsm").Save
objXLApp.Workbooks("test.xlsm").Close
When I run the script, the following error appear :
Be careful! Parts of your document may include personal information that cannot be removed by the document inspector.
I know that I can fix this error manually, but I would like disable this error with code.
Someone knows how ?
There's a VBA (not vbs) method called Workbook.RemoveDocumentinformation(xlRDIAll). Take a look at this https://learn.microsoft.com/office/vba/api/excel.workbook.removedocumentinformation
You should just add this to your Module1.main.

Constantly getting Err 1004 when trying to using Application.AddIns.Add

I'm trying to implement a bootstrap installer for my add-ins workbook, such that I can easily install the add-in for new users and send out updates. It works fine on my machine, but when having others test it, I get a runtime error when I try to call Set AI = Application.AddIns.Add(fileName:=fullPath, copyfile:=True). Specifically, the error is "1004: Unable to get the Add property of the AddIns class". I thought this was because the user needed to have "Trust access to the VBA project object model" enabled, but the error seems to occur even after they've toggled that box.
Other things I've checked:
The fullPath to the add-in is valid and the user can access the directory and the file
The user has the folder located at Application.UserLibraryPath
Any ideas?
Figured it out. It appears that the issue isn't one of permissions, but rather of whether a workbook is already open. Opening any workbook before running the Addins.Add prevented the error from occurring so I've simply added that into the program:
If Application.Workbooks.Count = 0 then Set wb = Application.Workbooks.Add()
Set AI = Application.AddIns.Add(fileName:=fullPath, copyfile:=True)
If not wb is nothing then wb.Close
Duke, perhaps it's the Trust Center settings on the recipients' machines. I have found this and may be helpful.
Best,
Danny
Check out VBA videos on ExcelVBADude on YouTube.

Excel fails to throw errors on Workbooks.Open or Workbook.Save methods on files that are in use

Our code essentially does the following:
1) It creates an Excel.Application object, and invokes .Workbooks.Open to open a file from a network location
2) It makes a minor change to the open Workbook
3) It invokes the .Save() method to save the workbook
This is causing a problem when the file is currently in use because
1) NO error is raised on .Workbooks.Open - The workbook simply gets opened in ReadOnly mode, but no messages or nothin' are shown to the user. So unless the user pays close attention and looks at the Title Bar, he or she will have NO idea that the document has actually been opened in ReadOnly mode
BUT the worst thing is
2) The .Save() method on the WorkBook object raises NO error WHATSOEVER. Instead it just goes ahead and saves the document to the %UserProfile%\Documents folder. Not only does it raise no error that WE can catch in code, it shows no message or warning to the USER either, so they remain blissfully unaware of the fact that they are no longer working on the original document in the Network Location, but on a local copy of same instead.
So the questions are:
1) Can we either force Excel to show a message to the END USER or raise an error on the .Workbooks.Open method so we can handle it in code? At the moment all I can do is check the workbook's .ReadOnly property, but that will give me no clue as to whether the workbook is ACTUALLY Read Only, or whether it was open in Read Only mode because it is in use by another user, let alone tell us in code, or the user through a message box, by WHOM the workbook might be in use.
2) Can we force Excel to raise an error or prompt the user on the workbook's .Save method, rather than simply saving it somewhere local without any indication to anyone!?!?
Sorry if I sound exasperated.... you should have heard the customer....
'Please note that oXApp is a Microsoft.Office.Interop.Excel.Application that has been instantiated correctly.
Dim oWBS As Microsoft.Office.Interop.Excel.Workbooks = Nothing
Dim oWBK As Microsoft.Office.Interop.Excel.Workbook = Nothing
oWBS = oXApp.Workbooks
oWBK = oWBS.Open(sFile) 'No error raised here, nothing. Document is opened in ReadOnly mode. sFile contains a UNC path to a file that is in use by another user.
oWBK.Save() 'Again, no error raised, but while oWBK.FullName points at the UNC path BEFORE the Save, it now refers to a local path in %UserProfile%\Documents

Injecting module into excel and run it

In VBScript I'm injecting a module into excel files and then I want to run them. The injection goes fine but when I run it says it can't find it. I've put the location in the trust center so it should trust it just fine. The module has a public sub named Run as well.
Dim XL
Set XL = CreateObject("Excel.Application")
Dim book
Set book = XL.Workbooks.Open(wkpath + "\" + wkname, 0, false)
book.VBProject.VBComponents.Import "C:\MyModule.bas"
XL.Application.Run("'" + wkname + "'!Run")
The paths and names all work out. Am I doing something wrong with this? What are my next debugging steps here.
[EDIT]
Actually it looks like some references aren't being selected now so it's getting an error about user-defined type not defined, but that's not the error that I get from VBScript. I had to do what is happening manually and then I saw that error.
So I was missing a reference but the error was pretty bogus. I figured this out by stopping my process once the excel file was open and adding in the module manually and trying to run the function. So I added the following in vbscript and it worked:
book.VBProject.References.AddFromFile "path to my xlam that has the type I use"

Resources