Close Excel associated with a particular file name - excel

After a bunch of processing, I save my Excel spreadsheet with a script-defined name and a user-chosen path. In other words, I know exactly where the file is.
I want to close down Excel. If I do
Workbook.Close
...the instance of Excel will hang around. If I do
Excel.Application.quit
...it might affect other instances of Excel I have open.
Given I know exactly which Excel I want to close, can I close the workbook AND the associated instance in a single step, without a lot of testing for other workbooks or instances? TIA

If you already have the Workbook Object, you can access the Application that it is running within using Workbook.Application. The .Parent property also returns the object that the current object is a member of, which for Workbooks, is also the Application.
So either of the following will close the specific Excel App that is running the target workbook:
'Given that TargetWorkbook is a valid Workbook Object
TargetWorkbook.Application.Quit
TargetWorkbook.Parent.Quit

Related

In Excel, how do I a call a user-defined function stored in another workbook without having to have the other workbook open?

I have some VBA user-defined functions that I'd like to store in their own workbook so that they can be accessed by multiple other workbooks. I saw that an easy way to do it is to make the workbook with the commonly-used functions, then reference this common workbook using Tools > References (VBA window).
However, I now find that when I use that function in the calling workbook, it wants me to have the common-function workbook open. I don't want to do this, since that seems likely to create some confusion with my users.
What is best practice for sharing VBA functions between workbooks, without having to have the function "repository" open in Excel?
the workbook should be open, but you can make it invisible
Dim commonWB as Workbook
Set commonWB = Workbooks.Open("path/file.name")
commonWB .Windows(1).Visible = False
Don't forget to close it when you leave the macro

Error when setting workbook variable - 2147352565

I have a simple code that runs upon initialization of a userform that sets a few workbook and worksheet variables so they can be used easily throughout the rest of my modules, and the references can be easily changed in one place if the file moves. I recently migrated my workbooks from my desktop to a separate server/drive, and accordingly updated the file pathways; however, when I try to run the code now I immediately get the message:
"Run-time error '-2147352565 (8002000b)': Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus."
This error occurs on the line
Set ReportWkbk = Workbooks("N:\ rest of file pathway here\QuaRT_Template.xlsm")
Is there anything that can be happening on the server/drive that is causing this issue? If so, is there anything I can do to fix it? I do work with other excel workbooks saved in the same location that seem to have no issue being referenced, though their references are in the workbook itself, not through Visual Basic.
The Subscript Out of Range error occurs because the Excel workbook being referenced is not open (or opening) in the same instance of Excel. You can easily reproduce the error by creating two workbooks (name one WorkBook2.xlsx) and ensuring they open in separate instances of Excel. Then run this code:
Sub OpenWkbkNames()
Dim wbk As Workbook
For Each wbk In Workbooks
Debug.Print wbk.Name
Next
'Hmm. Workbook 2 is not listed, but lets activate it and see what happens.
Workbooks("workbook2.xlsx").Activate
End Sub
You could avoid the issue by looping through the names of the workbooks open in THIS instance of Excel to ensure its available.
I've been researching Run-time error '-2147352565 (8002000b)' and found this: https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.vsconstants.disp_e_badindex.aspx
Apparently, that is VS's way of saying Subscript Out of Range too. I suspect (but have no solid proof) that since the code worked locally but the issue appeared after the file was migrated to a shared drive that Windows is taking a long time to open the file so opens it in a new instance of Excel. Essentially, Excel gets impatient and decides to move on while Windows completes its task. I base this assumption on the detection logic that was added to Excel 2013 (https://blogs.office.com/2013/06/03/opening-workbooks-by-running-separate-instances-of-excel/).

Excel/VBA workbook.activesheet returns wrong sheet

I have a workbook (we'll call it "AAA") that is based on a template and refers to code modules in a second workbook. The second workbook (we'll call it "CodeStorage") is a repository for code modules so that any saved versions of the template will be able to access modified/updates code without a change to the saved workbook.
My problem arises when I have multiple windows open in "AAA" and try to get the activesheet when a module is running in "CodeStorage". In code, I create an object ("oWorkbook") that is a reference to the workbook "AAA" When "AAA" has focus, oWorkbook.Activesheet returns the sheet for the active window. When "CodeStorage" is running a module and thus has focus, oWorkbook.Activesheet returns the sheet that is selected in window #1 regardless of what window (#2, 3, etc) was active when the code module in "CodeStorage" was called.
Has anyone run into this and have you found a work around?
ActiveSheet is confusing the way you are using it.
You need to explicitly activate a sheet for it to be considered the ActiveSheet. Running code in another workbook does not activate it.
Selecting cells in a worksheet will activate it. Or specifically calling Activate.
You could do something like:
oWorkbook.Activate
oWorkbook.Activesheet
Alternatively, and preferably, you could do something like the following:
oWorkbook.Worksheets("Sheet1")
oWorkbook.Worksheets(1)
Both these are better. If your user selects a different workbook during runtime execution or you select something in a different sheet, ActiveSheet will return something different.
It's better to fully qualify you workbook paths when using multiple workbooks. This will save you a ton of headache in the future for dealing with "what is activated?" or "what is selected?" This answer is worth reading, too.
To rephrase my question, I was looking for a way to reference the last active worksheet in a workbook that had multiple windows open. If window 1 was selected, I wanted the sheet from window 1, same for window 2, 3, or ???. I also needed the reference when a code module in a different workbook was running and the code module had a variable that was an object reference to the calling workbook.
The solution is Workbook.Windows.Item(1).ActiveSheetView.Sheet. When called from the running code module, even in a different workbook, it returns the same as workbook.activesheet when that is called from the workbook itself. My tests show that Workbook.Windows.Item(1) is the last active window when a workbook loses focus.
Thank you enderland. You got me pointed in the right direction.

Excel VBA file open by same vs other user

I am writing a bit of code for a company who will be using it on their network. I'm not on a network like theirs to be able to test, so I'm checking in to try and make sure the code is right first time!
The workbook will interact with other worksheets on their network in various ways, and essentially I need to be able to check if:
The target workbook is already open on their own system, and
ideally:
Whether it is open in the same Excel instance, or
Whether is is open in a separate instance (I believe this could
require different actions for copying and pasting ranges, saving etc
which I need to learn more about)
The target workbook is open by another network user (so presume it would only open as read-only)
I've come across lots of stuff about checking if a workbook is already open, eg: http://support.microsoft.com/kb/291295
But I haven't found anything that clearly differentiates between the two scenarios I explained above.
Thank you
Update
I am now using:
Function IsFileOpenInInstance(FileName As String)
Dim ShortFileName As String
Dim ValidOpenFile As Boolean
Dim ErrNum As Integer
On Error Resume Next
ShortFileName = Dir(FileName)
If FileName = Workbooks(ShortFileName).FullName Then ValidOpenFile = True
ErrNum = Err
On Error GoTo 0
If ErrNum <> 0 Then
IsFileOpenInInstance = False
Else
IsFileOpenInInstance = ValidOpenFile
End If
End Function
Because of how Excel macros are resolved, Excel workbooks within a single instance are distinguished by unqualified name (file name without full path).
Try accessing Workbooks("File Name.xls") to see if the workbook is loaded within current instance, and if it is, check FullName to see if it is indeed the right one.
It does not make a difference, operation-wise, whether or not two workbooks are opened in different instances. Getting a pointer to another instance, however, may be problematic and I don't recommend this (e.g. if you call GetObject("File Name.xls"), it can return your instance of Excel, not the other one, even if you don't have the file opened). You should work on assumption that all required workbooks are opened in the same instance.
It does not make a difference whether you or another user has opened a workbook. If you try to open the same workbook in another instance of Excel, it will tell you it is blocked same way as if it was opened by someone else.

NOW() in Excel 2010

I am just wondering if there is an easy way to make the function "now()", in Excel, just to work when a modification is done on the workbook, and not when the workbook is opened.
take a look at this:
http://www.extendoffice.com/documents/excel/954-excel-created-last-modified-time.html#three
and try using the second macro from:
Sub Workbook_Open()
Range("A2").Value = Format(ThisWorkbook.BuiltinDocumentProperties("Last Save Time"), "short date")
End Sub
Replace A2 with the cell you want to put that last modified time in.
you can also add:
Public Function ModDate()
ModDate = Format(FileDateTime(ThisWorkbook.FullName), "m/d/yy h:n ampm")
End Function
and then call:
=ModDate()
EDIT:
You can also use:
FileDateTime()
http://www.techonthenet.com/excel/formulas/filedatetime.php
You'd have to figure out how to get the file to refer to itself.
Bear in mind though, that a file is changed by being opened, so it might as well be the current time. For more on this, see:
http://support.microsoft.com/kb/826741
So NOW() might be all you have. Also, you can search Excel's components in program files, but if NOW is written in its binary, it might not be changeable.
However...
According to microsoft,
Making your custom functions available anywhere
To use a custom function, the workbook containing the module in which
you create the function must be open. If that workbook is not open,
you get a #NAME? error when you try to use the function. Even if the
workbook is open, if you use the function in a different workbook, you
must precede the function name with the name of the workbook in which
the function resides. For example, if you create a function called
Discount in a workbook called Personal.xls, and you call that function
from another workbook, you must write =personal.xls!Discount(), not
simply =Discount().
You can save yourself some keystrokes (and possible typing errors) by
selecting your custom functions from the Insert Function dialog box.
(Your custom functions appear in the User Defined category.) An easier
way to make your custom functions available at all times is to store
them in a separate workbook and then save that workbook as an add-in
(an XLA file) in your XLStart folder. (The XLStart folder is a
subfolder of the folder containing your Excel files. When you start
Excel, the program opens any documents it finds in XLStart.) To save a
workbook as an add-in, choose File, Save As (or File, Save). Then
choose Microsoft Excel Add-in from the Files Of Type list.
If your user-defined functions are stored in an XLA file that is
present in memory, you don't have to specify the name of that file
when you call a function. If the XLA file is saved in your XLStart
folder, it will be present in memory whenever you run Excel.
http://office.microsoft.com/en-us/excel-help/creating-custom-functions-HA001111701.aspx
So it seems implied that, provided user defined functions are in that workbook, they should work just fine wherever the file is.
Hope that gives you your answer.

Resources