I have a vba macro to open Excel files, including Read-only files.
I use the following code to do this:
Workbooks.Open((FileName:=MyFileName, UpdateLinks:=0, IgnoreReadOnlyRecommended:=True)
Up until June 2013 this never failed. As of now this no longer works. Now when the macro encounters a read-only file the file appears in a separate window and a Save As prompt also appears (never happened before).
If I click Cancel I get a Path not found error. If I click Save the file gets saved to its original location. This is completely new. There is no Save As command in this part of my code.
It appears to be something new associated with Microsoft’s File > Protect Workbook > Mark as final stuff. Anyone seeing this? I can’t find a way to prevent it. I simply want to be able to open the read only file without further prompts.
I haven't used VBA with excel much, but is it possible that the macro security settings within excel were reset so that it no longer trusts macros or VBA script attempting to use it.
Thanks for the input. I did find a work-around. In newer versions of Excel there is a new ReadOnly designation: Final, i.e. File > Protect workbook > Mark as Final. This is the same as ReadOnly, just by another name, and it does not show up as an option in WorkBooks.Open(FileName:= ...). If I set the Workbook.Final property = False, then I can open the file w/o the SaveAs prompt.
If wbName.Final = True Then
wbName.Final = False
End If
Related
I'm encountering an issue trying to get some macros and VBA scripts working on a new coworker's computer. I've been using the same code for years on my machine and several others without issue, but when my new analyst tries to run it, it throws an error stating it couldn't save the file. He can manually save the file without issue, but running the script throws the error. The really weird part is that it lists the file path, but replaces the filename with a seemingly random hex byte.
On another file, if he opens it, closes with or without saving, then I open the file and try to save it using a macro, it fails saying "cannot access file...". If I copy and paste the file, open and run the macro again, it saves over the offending file no problem.
We've checked permissions and settings and haven't found anything that was different between the two systems. We're both on VMs. His hardware allowance is less than mine but otherwise they're both IT-managed and identical. I'm at my wits' end... Any advice on what may be the source of my grief would be helpful, even if not a solution.
A couple of things I'd check before trying to step through debugger mode.
Coworker does not have write access to the directory (I think you said you checked already)
The new users' Trust Center Settings are not correct
File > Options > Trust Center > Trust Center Settings... > Macro Settings > Ensure the box is checked to trust the VBA model and that macros are not disabled
The new user does not have the same libraries referenced.
Alt + F11 > Tools > References... > Check if coworkers' libs match yours
Is he using a new/different version of Excel that you? A lot of older code got bojangled when Office 365 hit the scene.
After checking settings, I would ask the following:
What error is thrown when coworker attempts to run the macro?
When does the error get thrown? It could be that you have code that is attempting to edit the file (or has another file stuck in an edit) at the same time you're trying to save it.
I would see why the file name is getting corrupted. It sounds like coworkers' machine is looking to a bit of memory or memory address that is somehow getting forgotten. Like the code is referencing a variable that is out of scope.
User Access Control has been enabled on his VM that is somehow preventing him from saving the file correctly.
Your code does not properly Quit the Excel application, so its still running in the background on coworkers' machine. Have them open/close without saving a file and check Task Manager to see if Excel is still up to confirm
My issue with the unsaved file is if I clear the clipboard with:
Globals.ThisAddIn.Application.CutCopyMode = False
The errors I get for the clipboard code is:
System.Runtime.InteropServices.COMException
HResult=0x800A03EC
Message=Exception from HRESULT: 0x800A03EC
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
The code works ok but this issue with the clipboard happens when I change anything in the draft excel sheet and work on it while being unsaved. So a work-around I found is to save the excel file whenever I change values, but unfortunately, that is not what I want.
Is there a way to work on the unsaved excel file with VSTO, do I need to open an xls/worksheet from Temp?
Edit1: Another good observation, if the app changes the saved excel file, I have the option to save the file so that means its unsaved, but if I run the app again it works on the unsaved file. But any manual changes on the excel triggers the error. Observation 2, any changes made by the app cannot be undone with the undo operation. There is no option on the gui and ctrl-z doesn't do anything.
Edit2: It is as if Globals cant fetch the excel file if it's modified by the user manually.
I have a workbook that runs every x minutes with Application.OnTime.
The problem is that if I open a different workbook and get the yellow ribbon thing asking if I want to edit the file (or macro safety warning) the Application.OnTime stops working.
There is another question quite similar to mine here:
Application.ontime failes, when another workbook is open in "safe mode"
But the answer is not really an answer since that will just skip the line and make the code not run OnTime.
Is there anything that can be done to still allow Application.OnTime to run even if I have another file open in safe mode?
I think the solution here is opening that conflictive workbook in a different instance of Excel, so it won't be affected by other files.
To manually open a new instance of Excel, hold key ALT and click on the Excel icon. But in your case, if several people are using the file, then everybody needs to do that.
I've been looking around about creating a BAT file that opens that file in a new instance, but I'm totally noob about ms-dos commands so I'm posting this answer and hoping somebody can help.
To create a BAT FILE is really easy: just create a TXT, type the commands, save it and change file extension to BAT.
Be aware that I'm using my PC paths, so you need to adapt it to your paths. I've tried a lot of things but can't manage it to work it out:
"C:\Program Files (x86)\Microsoft Office\Office12\EXCEL.EXE" will open Excel in a new instance.
start "excel.exe" "C:\filepath\yourfile.xlsx" will open the file but in active instance. IF there is no instance, it will create a new one, but this does not work as you need it
"filepath\yourfile.xlsm" will do the same than step 2
So I've been not able to find the exact commands. But I'm pretty sure there must be a way that a BAT file opens a new Excel instance (like in step 1) and opens the file in that instance.
About your macro, another shot in the dark, but you posted I have a workbook that runs every x minutes with Application.OnTime don't know how many times do you need to execute it, but maybe with Task Scheduler you could automate the process, because Task Scheduler got an option to open files in new instances.
Sorry, but could not find the exact commands. I'm able to open Excel in a new instance, (step 1) and I'm able to open a specific file, but I'm not able to combine both of them.
Hope somebody can help with that part, so you can create a BAT file to execute that conflictive workbook in a different instance just by double clicking on that BAT file (so everybody won't need to remember about the ALT thing)
WORKAROUND 2: Other way would be executing that Excel file but from a different APP, so you can create a new instance of Excel from VBA. I made a simple Word file that creates and opens an Excel file in a new instance, so you can work with rest of Excel files. The code must be in the event Document_Open.
Private Sub Document_Open()
Application.ScreenUpdating = False
Application.Visible = False
Dim ExcelAPP As Object
Dim ThisWB As Object
Set ExcelAPP = CreateObject("Excel.Application")
ExcelAPP.Visible = False
Set ThisWB = ExcelAPP.Workbooks.Open("filepath\yourfile.xlsm")
ThisWB.Close False
DoEvents
ExcelAPP.Quit
Application.ScreenUpdating = True
Application.Visible = True
Application.Quit False
End Sub
So just by opening this word file, your Excel File would be executed in a new instance and not visible.
KNOWN FAILS: This way is good if you already have an Excel instance opened, but if there is no Excel file opened (you close all of them), you execute this code, and then open an Excel File, the Excel file will be opened in that invisible instance, so it's not perfect.
I have a macro that imports a spreadsheet as follows: (this spreadsheet is an export from a web-based application, and during the initial export the chosen format is 97-2003)
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12, "d2s_safety_tbl", _
"\\company.com\dfsroot$\Share\office_public\D2S\D2S\D2S_Scorecard\Source Data\D2S\D2S Safety.xls", True
When importing to Access, I get:
Run-time Error '3274': External table is not in the expected format.
When I open this Excel file, I get a dialog
"The file you are trying to open is in a different format than specified by the file extension..."
So the file name is .xls, my computer tells me its the 97-2003 Format, but once I open the file and click save, it defaults to save it as a Web Page format with the option to save as .xls. What gives?
UPDATE: If I open the file, then Save As .xls format (seemingly redundant, but apparently not), it asks me if I want to overwrite the existing file, so I do. Once I go through this, the VBA import is successful. I can't have the clerk go through this process every week--any way to avoidd this? Possibly the initial export from the web-based application?
DoCmd.TransferSpreadsheet is refusing to import your .xls file because it is not really an .xls file, it is an HTML file that has been given an .xls file extension. Providing a "fake" file extension is a trick that I've seen other "developers" use, and it really is a Bad Idea (for the reasons we've seen here).
If the keepers of the upstream system balk at doing The Right Thing and fixing their code to produce a real .xls file then try renaming the ".xls" file to .htm and importing it using
DoCmd.TransferText acImportHTML, ...
I also got a 3274 error when importing a spreadsheet into Access. I have been using this macro for a while now.
The solution was to compact and repair the Access database.
I had the same problem along with another problem (office 2016 x64): Pasting from excel to access raised 'Data on the Clipboard is damaged,...' error. I found a workaround by clicking on the lower right button in paste section of home tab of access, opening the clipboard pane.
After opening Clipborad Pane as stated above, my DoCmd.TransferSpreadsheet surprisingly worked fine.
I don't know why but it may help those having the same problem and those trying to find a real solution.
I've just upgraded to Excel 2010 from 2003. An internal add-in that is heavily used uses the Application.GetSaveAsFilename method to prompt for file names to be used for an export process (exporting information from the current Excel file into an xml configuration file).
In 2003, even if they selected a Read Only file, I didn't get any prompts (which is what I want) leaving it up to me to handle read-only issues (which I do...e.g. I check the file out of source control). However, after upgrading to 2010, I can't select a filename if that file exists and is readonly, forcing me to manually go checkout files first (which is a major downer in terms of proficiency when I'm exporting ~60 files per day).
Does anyone know of any settings/workarounds so that Excel 2010 doesn't prevent (or even prompt hopefully) selecting a filename of a previously existing/readonly file?
Thanks in advance.
Does it help if you use Application.GetOpenFilename instead?
Sub PromptForFilename()
ret = Application.GetOpenFilename
MsgBox ret
End Sub
This doesn't give me any errors for a read-only file.