I have a chunck of VBA code, which opens 2 files, copy the content in each, and paste that into a third file.
The problem is, that the two files (lets say "alm" and "fiber") often are used by other users, thus when i use Set alm = Workbooks.Open(alm_path) I get an error, since Excel cannot open it. I assume it is due to the file being opened by another user, and I then have to open it as write protected. Is there any smart way to do so? I am fairly new to VBA code
As mentioned in the comments you can open the workbook as ReadOnly, an example below:
Dim alm As Workbook
Set alm = Workbooks.Open(Filename:=alm_path, ReadOnly:=True)
Related
I have a macros that opens a file, makes changes and saves it under some other name. It does so many times. The problem is, the file has links to other files, so when my macros opens that file Excel generates a window that asks whether or not those links should be refreshed.
It interrupts macros and requires manual mouse click, which is something I'd really wish to avoid. Is there any way to ensure it wouldn't happen within macros?
I tried
Dim cn As WorkbookConnection
For Each cn In resultWorkbook.Connections
cn.Refresh
Next
But it didn't work - the windows keep appearing.
Include the UpdateLinks parameter when calling Workbooks.Open. The UpdateLinks argument (emphasis added):
Specifies the way external references (links) in the file, such as the
reference to a range in the Budget.xls workbook in the following
formula =SUM([Budget.xls]Annual!C10:C25), are updated. If this
argument is omitted, the user is prompted to specify how links will be
updated. For more information about the values used by this parameter,
see the Remarks section. If Microsoft Excel is opening a file in the
WKS, WK1, or WK3 format and the UpdateLinks argument is 0, no charts
are created; otherwise Microsoft Excel generates charts from the
graphs attached to the file.
I need to write a macro that can either pull a specific worksheet from every workbook in a folder without opening them (preferable if possible due to the size of these workbooks) or open each workbook one at a time and copy the worksheet.
Every post on this topic I have been able to find, the path has been static and is specified in the macro, but for the purposes of this macro there will be two different paths that this will need to work for, and those will change every week.
Can someone show me how to code the macro so that it asks for the path?
Is it possible to pull a worksheet from a workbook without opening the workbook?
Thanks,
Aaron
You can use Application.FileDialog(msoFileDialogFolderPicker) to prompt for the path.
I have made a Visual Basic program in Visual Studio (NOT VBA) that creates an instance of Excel and uses it throughout the program to open existing/create Workbooks. The problem I'm encountering is that any time after the instance of Excel is created, I am unable to completely open a workbook normally (from within windows explorer). I say 'completely' because Excel DOES appear open, but the menus and workbook itself don't actually populate. The Excel border just sits there and the busy cursor is shown when I hover over it.
Once the VB program is closed and that object is released, Excel returns to 'normal' functionality. Additionally, when I quit the VB program, the partially opened workbook also goes closes, almost as though it was attached to the instance of Excel I created in code.
The instance of excel created should be totally silent and the user should never even know it's being used. To that end, I'd like the user to be able to open other workbooks as though Excel isn't already being used elsewhere. This is important because other Excel workbooks might need to be opened for reference by the user during runtime.
I declare the object this way because there are many sub routines in various modules that all might want to use the instance of Excel.
Public Shared XLapp As New Excel.Application
The following code runs when the first form opens in the applicaion. Once this bit runs and the XLapp object gets set to a new Excel.Application, I lose the ability to open a workbook normally, as described above.
If IsNothing(XLapp) Then XLapp = New Excel.Application
XLapp.Visible = False
XLapp.DisplayAlerts = False
XLapp.EnableEvents = False
XLapp.ScreenUpdating = False
After creating a workbook object, I'll later in the code, and in various places throughout, open a workbook typically as below:
Dim OpenedWorkbook as Excel.Workbook = Nothing
[...]
OpenedWorkbook = XLapp.Workbooks.Open(workbook_filepath)
I've always been under the impression that if I'm opening workbooks using this particular object (XLapp) that when a workbook is opened in windows explorer that a new instance of Excel would be created. That is to say, the instance of Excel my program creates should be isolated from other instances of Excel, but that doesn't seem to be the case here.
Is there something else I need to do (or have I done something wrong?) to allow the user to use Excel normally while my program is running?
Thanks in advance for the help and for having patience with this VB newbie!
(Sorry, too long for a comment.)
You might be using the wrong tool for the job. You write:
The instance of excel created should be totally silent and the user should never even know it's being used. To that end, I'd like the user to be able to open other workbooks as though Excel isn't already being used elsewhere.
The purpose of Excel interop is to remote-control Excel, just like a user would interact with it. However, users don't interact with silent, non-visible Excel windows. It's just not what Excel interop is made for.
I suspect that you don't really want to remote-control a locally installed Excel instance. What you really want to do is to open and manipulate Excel workbooks. Then do just that: Use one of the Excel libraries for .NET and modify the Excel files directly (personally, I like SpreadsheetLight, but others are fine as well). Additional bonus: Your users don't need to have Excel installed.
You should refer to this post ... How do I properly clean up Excel interop objects?
Basically, when you create the Excel object, and don't dispose of it correctly, it hangs around sucking up legitimate Excel file open requests but not acting on them!
Fixing this type of error is time consuming, because the worksheet/cell/etc references all need to be disposed of correctly.
Furthermore, if you use more than one '.' in an instruction (eg Parent.Child.GrandChild) then you are in even more trouble since you create a reference to Child, but don't store it anywhere, and thus can't dispose of it!
As #Heinzi mentions, you could well fare better by using a different library rather than Excel interop if all you are doing is reading/writing values. I've used EPPlus with no issues so far (add via Nuget)!
It is possible to password protect an excel workbook for opening without the use of SaveAs method (without any method to save the file)?
Currently in our application, we use the SaveAs method to save and set the password after a workbook is generated and filled with data. The generation of this workbook takes a while as we use a lot of data and the resulting file is quite big (120MB).
We were searching for some ways to accelerate the workbook generation and we found that the SaveAs method takes around 3 minutes to complete because a lot of formulas needs to be calculated. After a small talk with the users, we realize that everyone make some small changes to the UI of the workbook anyway so then they need to save again and wait for another 3 minutes.
We have decided to suppress the SaveAs method and will be the users responsibility to save the workbook after they finish with their changes. And here is the problem, without the SaveAs I couldn't find a way to protect the file with a password.
I have tried the Workbook.Protect but it seems it only protects the structure and the windows from changes but not the file from opening:
ActiveWorkbook.Protect Password:=cPwd, Structure:=True, Windows:=False
I also found the Workbook.ProtectSharing method but I did not tried because the documentation says that it saves the file.
So, is there any way to set a workbook password without saving the file that will be applied when the user save it manually after his changes?
You can use the Workbook.Password property, which is read/write. The password will be applied the next time the file is saved.
All of this is being done in VB.NET using the Excel 14.0 Interop Services
I am at my wits end. I keep getting prompts from windows and excel during the middle of a batch run.
The program i have takes in a workbook with batch records, then runs simulations on each batch record, then writes the results back out to the excel file.
The steps:
Open workbook
check to see if workbook is already in use by another program.
if it is in use. we try to close the workbook. then we wait for a set amount of time before trying again.
if the workbook is not in use we continue.
Get the contents
Mark the records as being processed
save and close the file.
process the records.
do the same process above to open the workbook.
save the results to the workbook.
close the workbook.
loop these processes until all the records have been simulated.
Ok the problems that can occur:
Workbook is already in use or two programs are trying to interact with the save workbook at the same time.
Ok now for the problem that i am having.
When the workbook is being interacted with by two programs at the same time. a prompt will show saying the file is currently in use.
another problem that happens that i can't explain is excel will show a prompt saying that the file is now ready to be modified with the options read-write, notify, cancel.
I need to find a way to handle these prompts programmatically.
If any one can point me in the right direction I would be very greatful.
You can prevent the prompts from appearing by setting:
Dim xlApp As Excel.Application = New Excel.Application
xlApp.DisplayEvents = False
But I've not found a way to actually "catch" the prompts and do something useful. I've noticed that often if Interop cannot get hold of a file then it will throw an exception. The exception rarely contains any way to distinguish what the actual error is, but you can sometimes work it out based on what could happen at that point.