continue if the workbook is already open - vba

Hello I am working on "Packing list Form (PL)" have a set of codes which opens a "Tracing Form", and copy whatever that is on there to "Packing list Form (PL)"
but when I run the code the second time, "Tracing Form" is already open,
so it prompts me saying
""Tracing Form" is already open. reopening will cause any changes you made to be discarded. do you want to reopen "Tracing Form"?"
I want it to say No and continue with the rest of the code !!
please help...
here's part of the code that's relevant
Set PL = Workbooks("PACKING LIST FORM").ActiveSheet
userprofile = Environ$("userprofile")
Workbooks.Open userprofile & "\Dropbox\Tissue Tracing Form"
Set tracingform = Workbooks("Tissue Tracing Form.xlsx").Worksheets("2018_1")
ActiveWindow.WindowState = xlMinimized
'execution
from_lastrow = ActiveSheet.Cells(Rows.Count, 3).End(xlUp).row
.
.
.
.

The function below allows you to check if a workbook is already open and assign xRet a boolean value, you can then use that within a case to run the rest of your code or open the workbook and then run the rest of your code. This will avoid you trying to open the workbook when it is already open and so you wont get that pop up message.
Sub CheckExcelOpen()
Dim myPath As String
Dim xRet As Boolean
xRet = IsWorkBookOpen(Tissue Tracing Form.xlsx)
If xRet Then
'YOUR CODE WHEN ALREADY OPEN
Else
Workbooks.Open (TissueTracingFullFilePath) 'action needs the full file path to open
'YOUR CODE ONCE OPEN
End If
End Sub
The function-
Function IsWorkBookOpen(Name As String) As Boolean
Dim xWb As Workbook
On Error Resume Next
Set xWb = Application.Workbooks.Item(Name)
IsWorkBookOpen = (Not xWb Is Nothing)
End Function
I hope this helps

Related

How to save a workbook using InputBox in VBA?

I am trying to open and save a workbook based on what the use decides to name the file. I am able to open and save the workbook but I cannot figure out how to give the user the option to change the name of the save file. Here is my code:
Sub Sheets()
Dim wb1 As Workbook
wb1save = Application.InputBox("What would you like to save this file as?")
Set wb1 = Workbooks.Add
wb1.SaveAs ("e:\excel\"Filename:=wb1save")
End Sub
Any help would be greatly appreciated.
Thanks,
G
I don't see a reason to use Excel.Application.InputBox over plain old VBA.Interaction.InputBox here. The function returns a null string pointer (kind of undocumented behavior though) if the user cancels the prompt, so you should handle that.
Dim result As String
result = InputBox(prompt, default)
If StrPtr(result) = 0 Then Exit Sub
wb1.SaveAs result
But don't use an InputBox for this (whether Excel.Application.InputBox or VBA.Interaction.InputBox - neither is meant for this kind of user input). Use Application.GetSaveAsFileName instead, and get an actual "SaveAs" dialog propmt the user for a filename, and let them browse folders and not make typos.
The function returns a Boolean value (False) if the user cancels the prompt, so you should handle that.
Dim result As Variant
result = Application.GetSaveAsFileName
If VarType(result) = vbBoolean Then Exit Sub
wb1.SaveAs result
With that you're pretty much guaranteed to have a valid file/path. With InputBox, not so much.
The dialog will open on whatever the CurDir is, so you can use ChDrive and ChDir to control the default directory.
Here you go:
Sub Sheets()
Dim wb1 As Workbook
wb1save = Application.InputBox("What would you like to save this file as?")
Set wb1 = ActiveWorkbook
wb1.SaveAs ("e:\excel\" & wb1save)
End Sub

Issues with detecting open file

I have literally copied and pasted and tested every bit of code from may BBs and the same thing happens with all of them. they all either tell me that that the file is open if it's open or closed or they tell me that the file is closed when it is open or closed. The code never gets it correct. Here is the last thing I tried and it was telling me it was not open when it was and when it wasn't
Can someone tell me if this is due to the file being located on the network
Sub Is_WorkBook_Open()
Dim wBook As Workbook
On Error Resume Next
Set wBook = Workbooks("X:\Audit Tracking\Team_Larry\DailyReports\Larry_Blank.xlsm")
'Not open
If wBook Is Nothing Then
MsgBox "Larry's Workbook is not open, Proceed to posting", vbCritical
Set wBook = Nothing
On Error GoTo 0
'It is open
Else
MsgBox "Yes it is open, Notify Supervisor to close file", vbInformation
Set wBook = Nothing
On Error GoTo 0
End If
End Sub
it was telling me it was not open when it was and when it wasn't
The Application.Workbooks collection contains all the workbooks opened in this instance of Excel.Application; if the workbook is opened by someone else on another machine, it's not in the collection and you can't use that method to know this.
If you're using the latest & greatest Excel 2016 on Office 365, see how you can dismiss that concern altogether using co-authoring features.
Otherwise, you can try sharing the workbook and then Excel can tell you exactly who has it opened, but then shared workbooks has a number of issues, including but not limited to, the inability to edit VBA code.
Using a hard-coded path is a good way to get false negatives, too. Open the file, verify its actual FullName and use that.
Dim i As Long
For i = 1 To Application.Workbooks.Count
Debug.Print Application.Workbooks(i).FullName
Next
If the file's location doesn't really matter, only its file name, you can iterate the opened files and see if one has a matching file name:
Dim i As Long
For i = 1 To Application.Workbooks.Count
If Application.Workbooks(i).Name = "Larry_Blank.xlsm" Then
MsgBox "File is opened."
Exit For
End If
Next
When you open an Excel workbook a hidden temporary copy of the workbook will be created. This is presumably used to recovery crashed files. Notice that the temporary workbook's name and path is the same as the actual workbook but has ~$ prefixed to the filename. Since the file path remains the same, we can assume that the ↓`isWorkbookOpen()↓ will work even with mapped and shared folders.
Function isWorkbookOpen(Path As String) As Boolean
Dim values() As String
values = Split(Path, "\")
values(UBound(values)) = "~$" & values(UBound(values))
Path = Join(values, "\")
isWorkbookOpen = Len(Dir(Path, vbHidden)) > 0
End Function
I believe your code will test if you have it open, on the computer your running the code from.
This code will open the workbook, if it opens in a read only state then someone else has it open. Note: If you open it on your computer, and then run this code on the same computer it will report that it's not in a read only state.
Sub Test()
Dim oWB As Workbook
Set oWB = Application.Workbooks.Open("C:\Temp\test.xlsx")
If oWB.ReadOnly Then
MsgBox "Open"
Else
MsgBox "Closed"
End If
oWB.Close
End Sub

Excel vba, Opening new Application: Microsoft Excel is waiting for another application to complete an OLE action

I have the following vba code. It creates new Excel application and uses it to open a file. Then it MsgBoxes some cell's value in this file.
Sub TestInvis()
Dim ExcelApp As Object
Set ExcelApp = CreateObject("Excel.Application")
Dim WB As Workbook
Set WB = ExcelApp.Application.Workbooks.Open("Y:\vba\test_reserves\test_data\0503317-3_FO_001-2582480.XLS")
Dim title As String
title = WB.Worksheets(1).Cells(5, 4).Value
MsgBox (title)
WB.Save
WB.Close
ExcelApp.Quit
Set ExcelApp = Nothing
End Sub
The problem is that after MsgBoxing it slows down and eventually gives a Microsoft Excel is waiting for another application to complete an OLE action window. Why does it do this? It's not like there are any hard commands being implemented. And how should I deal with it?
This happens because the Excel instance in ExcelApp is waiting for User Input, most likely.
You can try to add ExcelApp.DisplayAlerts = False to skip any pop-ups that might be there.
Also, while troubleshooting add the line ExcelApp.Visible = True so you can see what's going on in the second instance and troubleshoot there.
I encountered this problem in the following situations:
An alert was opened by the Application Instance and it was awaiting user input.
While opening a file, it was coming up with some message about a crash when the file was previously opened and whether I wanted to open the saved version or the in memory version (although this should happen before the msgBox)
If you run the code multiple times and it crashes, it might have the file open as read only since there's another hidden instance of Excel that locked it (check your task manager for other Excel processes)
Rest assured that in any case the problem is not with your code itself - It runs fine here.
Code that works for me.
You can select the file from FileDialog. In comments You have code that close the workbook without saving changes. Hope it helps.
Option Explicit
Sub Import(Control As IRibbonControl)
Dim fPath As Variant
Dim WB As Workbook
Dim CW As Workbook
On Error GoTo ErrorHandl
Set CW = Application.ActiveWorkbook
fPath = Application.GetOpenFilename(FileFilter:="Excel file, *.xl; *.xlsx; *.xlsm; *.xlsb; *.xlam; *.xltx; *.xls; *.xlt ", Title:="Choose file You want to openn")
If fPath = False Then Exit Sub
Application.ScreenUpdating = False
Set WB = Workbooks.Open(FileName:=fPath, UpdateLinks:=0, IgnoreReadOnlyRecommended:=True)
Set WB = ActiveWorkbook
MsgBox("File was opened.")
'Application.DisplayAlerts = False
'WB.Close SaveChanges:=False
'Application.DisplayAlerts = True
'MsgBox ("File was closed")
Exit Sub
ErrorHandl:
MsgBox ("Error occured. It is probable that the file that You want to open is already opened.")
Exit Sub
End Sub
None of these methods worked for me. I was calling a DLL for MATLAB from VBA and a long simulation would pop up that Excel was waiting on another application OLE action, requiring me to click it off for the routine to continue, sometimes quite a few times. Finally this code worked (saved in a new module): https://techisours.com/microsoft-excel-is-waiting-for-another-application-to-complete-an-ole-action/
The way I used it is a little tricky, as the directions don't tell you (here and elsewhere) which causes various VBA errors, so I add to the description for what works in Excel 365:
Create a new module called "ToggleOLEWarning" (or in any new module, important!) which only contains the following code:
Private Declare Function CoRegisterMessageFilter Lib "ole32" (ByVal IFilterIn As Long, ByRef PreviousFilter) As Long
Public Sub KillOLEWaitMsg()
Dim IMsgFilter As Long
CoRegisterMessageFilter 0&, IMsgFilter
End Sub
Public Sub RestoreOLEwaitMsg()
Dim IMsgFilter As Long
CoRegisterMessageFilter IMsgFilter, IMsgFilter
End Sub
Then in your main function, just decorate the long running OLE action with a couple lines:
Call KillOLEWaitMsg
'call your OLE function here'
Call RestoreOLEwaitMsg
And it finally worked. Hope I can save someone the hour or two it took for me to get it working on my project.

How to check if a workbook is open and use it

I've made a macro to open two workbooks and do some stuff with them. This macro runs from a third workbook that calls any other two user selected workbooks for which, before they're opened, I don't know their name.
So! I know Excel 2010 doesn't have a built in function to check if a workbook is open so, I've been trying to compare the workbook against Nothing but it doesn't work and every workaround I find in different sites tend to use the name of the workbook.
Is there another way of doing this?
The idea is to run a macro with the two user defined workbooks and then, maybe, re-running it in the same workbooks but Excel warms me of discarding changes.
Maybe a workaround could be to tell excel when it prompts for reopening, not to reopen and handle that error to just use the same workbooks, for which at least, I know how part or the names will be. For example, one will have the text "cluster" in it, and the other the word "translation" so, maybe in a loop like the next one, I could find and use the workbook I need but just If I already checked if it's open. Or, does this way works to see if it's opened already?
For each wbk in Application.Workbooks
If wbk.Name Like "*cluster*" Then
WorkingWorkbook = wbk.Name
End If
next
My code is as follows:
Sub structure()
Application.ScreenUpdating = False
Dim translationWorkbook As Worksheet
Dim clusterWorkbook As Workbook
If Not clusterWorkbook Is Nothing Then
Set clusterWorkbook = Application.Workbooks.Open(ThisWorkbook.Sheets(1).Range("E5").Value2)
Else
Set clusterWorkbook = Application.Workbooks(parseFilePath(ThisWorkbook.Sheets(1).Range("E5")))
End If
Set translationWorkbook = Application.Workbooks.Open(ThisWorkbook.Sheets(1).Range("E6").Value2).Worksheets("String_IDs_Cluster") 'Translation table target for completing
End Sub
The parameter passed to Workbooks.Open is the one written in the sheet by my next function:
Private Sub MS_Select_Click()
Dim File As Variant
Dim Filt As String
Filt = "Excel 97-2003 File(*.xls), *.xls," & "Excel File(*.xlsx),*.xlsx," & "Excel Macro File (*.xlsm),*.xlsm"
File = Application.GetOpenFilename(FileFilter:=Filt, FilterIndex:=2, Title:="Select Menu Structure File")
If File = False Or File = "" Then
MsgBox "No File Selected"
Exit Sub
End If
ThisWorkbook.ActiveSheet.Range("E5").Value2 = File
End Sub
Same for translationWorkbook but in a different cell and also, I was trying to create a function to parse and use the filename in a full path(Then I discovered the command Dir lol) but when I pass the filename, without the xls extension to Application.Workbooks(file) it sends me a "subscript range error". Why could that be?
Basically my questions are:
How can I check for an open workbook and use it? Either by handling the
error for excel's prompt or by not trying to reopen the same file.
Why does trying to open a workbook with Application.Workbooks() with the return of my function fails? And here my question splits in two... First: with my function, wouldn't it work if I give a string as an argument? Or maybe, before passing it as an argument, I need to assign the result of my function to a variable?
Second: If I try to open a workbook like this Application.Workbooks("clusterworkbook") it sends me another "subscript error" but, before I used the File Dialog prompt, I made it this way and worked fine.
Any help will be appreciated.
EDIT
Function ParseFilePath added:
Function parseFilePath(fullpath As Range) As String
Dim found As Boolean
Dim contStart As Integer
Dim contEnd As Integer
contEnd = InStr(fullpath, ".") - 1
contStart = contEnd
found = False
Do While found = False
If fullpath.Characters(contStart, 1).Text = "\" Then
found = True
Else
contStart = contStart - 1
End If
Loop
parseFilePath = fullpath.Characters(contStart + 1, (contEnd - contStart)).Text
End Function
How can I check for an open workbook and use it? Either by handling the error for excel's prompt or by not trying to reopen the same file.
Have done some small modifications to your procedure structure. Similar to what you were trying testing for the workbook variable to be nothing, only that you have to first attempt to set the variable, the way you were doing it will always return empty as you did not try to set it before. I have also tested for the translation workbook, as it mightt be open as well.
I'm assuming the values in E5 and E6 contain the FullName of the workbook (i.e. path + filename) and that parseFilePath is a function to extract the filename from the FullName.
Sub structure()
Application.ScreenUpdating = False
Dim clusterWorkbook As Workbook
Dim translationWorkbook As Workbook
Dim translationWorksheet As Worksheet
With ThisWorkbook.Sheets(1)
On Error Resume Next
Set clusterWorkbook = Application.Workbooks(parseFilePath(.Range("E5").Value2))
On Error GoTo 0
If clusterWorkbook Is Nothing Then Set clusterWorkbook = Application.Workbooks.Open(.Range("E5").Value2)
'Set Translation table target for completing
On Error Resume Next
Set translationWorkbook = Application.Workbooks(parseFilePath(.Range("E6").Value2))
On Error GoTo 0
If translationWorkbook Is Nothing Then
Set translationWorksheet = Application.Workbooks.Open(.Range("E6").Value2).Sheets("String_IDs_Cluster")
Else
Set translationWorksheet = translationWorkbook.Sheets("String_IDs_Cluster")
End If
End With
End Sub
Why does trying to open a workbook with Application.Workbooks() with
the return of my function fails? And here my question splits in two...
First: with my function, wouldn't it work if I give a string as an
argument? Or maybe, before passing it as an argument, I need to assign
the result of my function to a variable?
Not sure why it did not work, change the prodedure as indicated.
I tested the procedure above using this function to extract the Filename from the Fullname and it worked:
Function parseFilePath(sFullName As String) As String
parseFilePath = Right(sFullName, Len(sFullName) - InStrRev(sFullName, "\"))
End Function
Second: If I try to open a workbook like this Application.Workbooks("clusterworkbook") it sends me another
"subscript error" but, before I used the File Dialog prompt, I made it
this way and worked fine.
Bear in mind that you did not used that line alone, it most probably has something like:
set Workbook = Application.Workbooks("clusterworkbook")
So the command was to set a variable, not to open the workbook, as such the only situation in which this works is that the workbook is already open so the variable gets set. The times when it failed was when the workbook was not open and you tried to set the variable, given you an error.
Suggest to visit these pages
Excel Objects, On Error Statement
I have been using the below code to identify if the excel workbook is open. If yes, then i activate it and do some stuff. If not, i open it and do some stuff.
sub test()
Dim Ret
Ret = IsWorkBookOpen("Your excel workbook full path")
If Ret = False Then
Workbooks.Open FileName:="Your excel workbook full path", UpdateLinks:=False
Else
Workbooks("Workbook name").Activate
End If
end sub
Function IsWorkBookOpen(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: IsWorkBookOpen = False
Case 70: IsWorkBookOpen = True
Case Else: Error ErrNo
End Select
End Function

Excel VBA: Waiting for another application to complete an OLE action when macro tries to open another workbook

A little background to the title: I've written a macro that gets called on workbook open. It opens a [shared] workbook on a shared directory and pulls in some information to the workbook the user is using.
Any user working with this sheet already has the shared directory mapped to their computer (and the macro finds the correct drive letter).
I've tested this worksheet multiple times with users in my office. I've also tested it and had two people open the workbooks simultaneously to confirm that the macros for both users are able to pull data from the shared workbook concurrently.
So far, I've had no issues.
This sheet then got rolled out to multiple other users in my company. All in all, about 40 people are expected to use this sheet (not necessarily at the same time.. just in total).
One of the users is located in Poland (I'm located in London).
When he opens the workbook, he gets a 'Microsoft Excel is waiting for another application to complete an OLE action' notification. The notification comes with an 'OK' button. Pressing this button seems to have no effect and the workbook effectively hangs on this notification.
I'm having a lot of trouble resolving this problem as I have not been able to replicate it. Does anyone have an idea why this would come up? Code below:
Sub PreliminaryDataImport()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim x As Variant
Dim usename As String
usename = Environ("USERNAME")
Dim xlo As New Excel.Application
Dim xlw As New Excel.Workbook, wkbk As New Excel.Workbook
Dim xlz As String, regions As String
Dim LRow As Long, LCell As Long, LRow2 As Long
Dim RegionList As String
RegionList = ""
xlz = Sheet1.Range("o1").Value & "\Region Planning\TestDB.xlsx"
Set xlw = xlo.Workbooks.Open(xlz)
If Not Sheet11.Range("S1").Value = xlw.Worksheets("validation") _
.Range("N1").Value Then
MsgBox "YOU ARE USING AN OUT OF DATE VERSION" & vbLf & _
"Please check your inbox or contact xxxx for the current version."
xlw.Close False
Set xlo = Nothing
Set xlw = Nothing
Call Module7.ProtectSheets
End
End If
x = CheckValidation(usename, xlw)
'~~ Check to see if User has access to view/modify.
'~~ If they have access, return regions
On Error Resume Next
For i = LBound(x) To UBound(x)
regions = regions + " --- " & x(i)
RegionList = RegionList + x(i) & ", "
Sheet1.Cells(i + 2, 33).Value = x(i)
Next
If Err.Number <> 0 Then
MsgBox "You do not have access to view or modify any regions."
xlw.Close False
Set xlo = Nothing
Set xlw = Nothing
End
Else
MsgBox "You have access to view and modify the following regions:" & vbLf _
& vbLf & regions & "---"
I believe the issue occurs somewhere within this section of the code as the msgbox on the last line doesn't show up prior to the notification. I haven't been able to run in debug from his machine as he's located remotely and that would be a large effort (should only be done if absolutely necessary).
Anyone have ideas on why this one user is getting this error? I'm particularly confused because it's only him having the issue.
One thing that looks a bit suspicious is that you're creating a new instance of Excel
Dim xlo As New Excel.Application
Normally this is done so that a hidden instance of Excel can be used to open a workbook that you don't want to show to the user, but I don't see any code to hide this second instance, i.e.:
xlo.Visible = False
Since you open and close the shared workbook quickly, and you have ScreenUpdating = False in your main Excel instance, you may be able to do this in your main Excel instance without the overhead of creating a new Excel instance.
Also you aren't calling xlo.Quit to close the second Excel instance, so it may hang around in the background...
An alternative approach would be to use OleDb to read from the shared workbook, in which case you don't need to open it at all.