I have checked similar issues, but the solutions I have seen don't really address this problem. I am trying to temporarily change the file access of a linked Excel sheet for a supervisor on a network drive. After doing some testing, I was able to validate that 2 directories I was testing are recognized. However, when trying to set a workbook object to a particular .xlsx file in those folders, I kept getting an error indicating Excel couldn't find the file (note the exact Excel name was copied and pasted in). Here is a sample of the code:
Dim wb As Excel.Application
Dim s As String
If Me.Check9.Value = False Then
s = CurrentPath & "\OurFile.xlsx"
Else
s = "\\--UserProfile---Data\My%20Documents\Access%20Database%20Work"
End If
If Dir(s, vbDirectory) = "" Then
MsgBox ("Good")
Excel.Application.EnableEvents = False
s = s & "\DummyQueryTested.xlsx"
'*** Here is where the error is; we disabled macros above ***'
Set wb = Workbooks.Open(s)
wb.ChangeFileAccess Mode:=xlReadWrite
Else
MsgBox ("Bad")
Set wb = Workbooks.Open(s)
End If
Excel.Application.EnableEvents = True
A few last notes:
There are On_Open macros, so that is why I tried using the EnableEvents=False command. The thought was those were preventing the files from opening
I can't just move the file to another location because this is a file that is opened by an Access database as a link, and the company needs these files to be in the locations they are currently residing in.
Finally, you can see I tested the network as well as local file paths and that is what the "Check9.Value" test was for...to test 2 different filepaths.
Any help would be appreciated. I have seen similar issues, but not exactly like this one. Is there any way to test further if there is some permission, or some setting these files have that might be causing problems?
Related
So I have this problem with my app. It is supposed to take user inputs and archive them in Excel files. All of that would work just fine, if I didn't need to access said Excel files as a special user due to the company's safety restrictions.
I have a working piece of code that opens said restricted files just fine through creating a new process (it is pretty much the same as the one here).
I use the code as such:
Sub RunAsUser_Main()
Dim ExeCommand As String
ExeCommand = "C:\Program Files\Microsoft Office\Office16\EXCEL.EXE \\192.168.88.3\share\public\Workbook.xlsm"
RunAsUser "username", "password", "domain", ExeCommand, "C:\Windows"
'-------------------- OPEN WORKBOOK --------------------
Dim ret As Integer
Dim ExcelApp As Object
Dim WorkbookPath As String
Dim MyWorkbook As Object
On Error Resume Next
Set ExcelApp = GetObject("Excel.Application").Application
If ExcelApp Is Nothing Then
ret = MsgBox("error!", vbCritical + vbOKOnly, title)
Exit Sub
End If
...
All goes good right until the GetObject statement. The new process starts, Excel opens the workbook as it should and I have verified that it is run by the special user.
After this though, I am unable to reference the running ExcelApp object. It just returns nothing.
What is wrong with this code? I have very little experience with creation and management of processes, so I might be failing to see the obvious.
Thanks in advance!
Edit: After some more trying, I believe that there is no way to reference the workbook using standard commands (GetObject etc.). I will need some special code to make this work, and have no idea for where to look for it. Any advice on this?
I've also used the code from this thread that is supposed to list all current instances of excel. It does list the ones running under my current user, but does't register the one under my special user, same as with my previous attempts.
I have an app I coded in Excel that suits the needs of my project; it serves the purpose of keeping track of quite a lengthy process and prerequisites and such.
It feeds off of a certain number of tables in my file.
The thing is, only one user can currently work on that file; and since we have multiple teams working on different parts in parallel, it would be nice to host that somehow in a way that would remove the single-user restriction.
Do any of you have an idea of how I could work around this?
I worked on a solution for a very similar project of keeping track of a hospital's labor utilization (nursing employee census, if you will) on a day-to-day basis across every nursing-based department in the hospital system. This solution relies on a couple conditions:
That it will be unlikely two or more people will need to save data to the final file at the same time (meaning within seconds of each other).
All the various users of the file will have access to at least one commonly-shared network drive or location.
In our case, we created a new file each day, but it wouldn't be difficult to adjust the data-writing code to append data, rather than create a new file and dump data into that new file.
The rough outline of the process is this:
Create a read-only destination file (.xlsx in our case) in a network location that contains tables of data split between n worksheets.
Create an interactive form (.xlsm) that allows user input and then on form submission, opens the destination .xlsx file and saves the form data to it, then closes it. This interactive .xlsm file can be placed in the same network location, with shortcuts created on as many peoples' desktops (or departmental shares, for example) as necessary.
With the speed of Excel and VBA, this means you're only "opening" the destination file for a second or two to write the form data, no matter how long one user may have a copy of the form open.
One thing that will be necessary is to check if the file is open, and gracefully alert the user if they need to try again, which you can do with a function covering the related error codes, for example:
Function IsFileOpen(FileName As String)
Dim iFilenum As Long
Dim iError As Long
On Error Resume Next
iFilenum = FreeFile()
Open FileName For Input Lock Read As #iFilenum
Close iFilenum
iError = Err
On Error GoTo 0
Select Case iError
Case 0: IsFileOpen = False
Case 70: IsFileOpen = True
Case 53: IsFileOpen = "Not Found"
Case Else: Error iError
End Select
End Function
which can be called via some code like (pseudo code):
Private Sub UpdateData(ByVal thesheet As String)
Dim xlApp As New Excel.Application
Dim xlWkbk As New Excel.Workbook
If Not IsFileOpen(FileName) Then
Set xlWkbk = xlApp.Workbooks.Open(filename)
xlWkbk.Worksheets(theSheet).Activate
Else
MsgBox "Sorry, the file is currently in use. Please try again", vbOKOnly
Exit Sub
End If
End Sub
Or you could have it simply wait a few seconds (e.g. Wait 5) or more if the writing process doesn't cover that much data. The specific amount of seconds to wait would depend on testing write times based on your scenario and your data. That would be added as a nested If Not statement inside the previous one.
Then, when the result is that the file is not in use, simply write a series of subroutines to write the form data (stored as variables) to the destination sheet. End with something like
xlWkbk.Save
xlWkbk.Close
Set xlWkbk = Nothing
Set xlApp = Nothing
to save and close the workbook and clear your variables (memory cleanup and all that).
You may already be aware of this practice, but while you'll want to keep Excel visible during development, you'll definitely want to set Application.Visible = False on the production files for two reasons:
This will prevent users from getting confused by a lot of automation
It covers Application.Updating as well, which will really speed up data processing.
This is my first time using such forum.
I have exactly the same question as here:
How to release an object and clear memory in VBA
In this thread, the question was unfortunately not solved...
With Excel VBA I connect to another program (namely Aspen EDR). For that purpose I have an according Add-In installed. To access Aspen EDR I need to add an object. After I'm done I want to release the object to save some memory. First thing I tried is this:
Dim ObjEDR As BJACApp
Dim Path As String
Path = 'assume this is the correct path to the file i want to open
Set ObjEDR = New BJACApp ' Create the BJAC object
If Not ObjEDR.FileOpen(Path) Then
MsgBox "Can't open file!"
End If
'...
Set ObjEDR = Nothing
After I set the object nothing, Excel does not release the memory (as I can see in my task manager). Of course after a few hundred iterations (I have to open a lot of these files) I get an error message, that Excel is out of memory. I read a few threads and apparently nothing only deletes some kind of reference to the object but not the object itself, so I tried adding fileclose
'...
ObjEDR.FileClose
Set ObjEDR = Nothing
When executing the FileClose I can see that a little memory is released (0.5 of 3MB) but still there is a lot of memory accumulating.
Also when not using the "Now" it is not working and I get "runtime error'424': Object required" when executing Set ObjEDR = BJACApp
I also read about "pointers" that might cause the staying memory increase, but how can I find and clear/delete them?
Does anyone has an idea?
I would really appreciate it!
If .Quit (or the object's equivalent) and setting the object to Nothing is not working for you, then you could try relying on VBA's garbage collector to do the job.
Essentially what this means is that you would need to split the sub in two, have the main sub, and within that sub call the sub that will open and close your object. Hopefully, upon the second sub exiting, VBA will clean up those objects.
Sub Main()
Dim filePath As String
For Each [..] In [..] ' Or use a Do...Loop
filePath = 'assume this is the correct path to the file i want to open
openObj filePath 'call the sub below
Next [..]
End Sub
Sub openObj(ByVal Path As String)
Dim ObjEDR As BJACApp
Set ObjEDR = New BJACApp ' Create the BJAC object
If Not ObjEDR.FileOpen(Path) Then
MsgBox "Can't open file!"
End If
[...] 'your code to perform the needed actions with your obj
ObjEDR.FileClose
Set ObjEDR = Nothing
End Sub
I don't know anything about this object, but you should also try .Quit and .Close
Another method is to not create a new object for each path. Place the Set ObjEDR on the outside of your loop, and utilize the same object every time you open the new file.
Ok, to those who are interested:
The support of Aspen Tech told me that
ObjEDR.dispose()
should work, but just for versions above V8.4.
So this did not solved my problem and I built a workaround using MATLAB which opens and closes Excel after each run. So I loose time opening and closing the Excel file, but the memory of excel is not increasing until it stops working.
Every time I open this Excel file I get this error which is in screenshot 1 and screenshot 2.
When I click OK it takes me to code windows and asks me to select library.
I tried everything to make it work but no luck.
Screenshot one and screenshot two:
Make sure that these references are in this Priority order.
HTML and Internet Controls need to be above OLE Automation.
If you are still having this issue after this, run a Repair on the Office install and it refreshes the .DLL files that may have been corrupted.
Update: 7/6/2017
The pervious answer above will re-associate the references and allow the script to compile.
However, there is a better way.
This issue occurs when the VBA script is shared to other computers that are not identical platforms(OS and MS Office versions) and use early binding. Early binding reduces latency and is the correct way when only intended for one computer.
The answer is to use late binding format in the script and not select any references. Change any data type objects other than object back to object and use the following format:
Sub Late_Binding()
Dim IE_App_obj As Object
Dim MyShell_obj As Object
Dim IE_Window_obj As Object
Dim Windows_cnt As Long
Dim x_cnt As Variant
Dim HTML_Element_obj As Object
Set IE_App_obj = CreateObject("InternetExplorer.Application")
'Use IE_App_obj to Navigate to webpage and control it.'
Set MyShell_obj = CreateObject("Shell.Application")
'Use MyShell_obj to find an existing webpage and control it.'
Let Windows_cnt = MyShell.Windows.Count
For x_cnt = Windows_cnt - 1 To 0 Step -1
On Error Resume Next
If Instr(MyShell_obj.Windows(x_cnt).Document.Title,"WebPage_Title") > 0 Then
Set IE_Window_obj = MyShell_obj.Windows(x_cnt)
Exit For
End If
Next
Set HTML_Element_obj = IE_Window_obj.Document.getElementByID("ID_text")
End Sub
Latency will increase but so will stability.
I have seen several questions relating to Object variable not set when using Activeworkbook, but none for my particular scenario. I use some code in workbook_open that tests a condition to decide if the user should be shown a form
If Len(ActiveWorkbook.Names("DCStype_Selected").RefersToRange.Value) = 0 Then
This works fine for most users 99% of the time. However some users have reported error 91 - Object Variable or with block variable not set, and it is on the activeworkbook line.
I believe I have tracked the scenario where this happens and it is always for users who do not have my excel workbook in a trusted location, and so are prompted to enable macros and this error occurs when they click the "enable" button.
Once I have talked them through setting a folder as a trusted location, and moving the workbook to that folder, this issue does not occur.
Could anyone tell me a more defensive way to code my line, so that it works regardless of a users security settings?
Could some one explain why this error only occurs in this specific scenario?
I would set ActiveWorkbook.Names("DCStype_Selected").RefersToRange.Value as a variable and on error
either set a message box to tell them to move the file to a trusted folder
or set the variable to 0 to avert further damage and debug mode
Sub ert()
On Error GoTo Err
... 'your code
If False Then
Err:
... 'MsgBox or setting the var to 0
End If
End Sub
A little late to the party but I had the exact same problem... eventually got around it like this:
Dim wBook As Workbook
Do While wBook Is Nothing
Set wBook = ActiveWorkbook
DoEvents
' Prob. put a counter in here to prevent infinite looping...
Loop