We use the IHTMLElementCollection in an ASP.NET 2.0 application.
Sometimes- not always - it gives us a UnauthorizedAccessException. I think it only happens on our server, and not locally.
I tried searching in searchdotnet.com, and found only 2 results, but in both of them the use of IHTMLElementCollection was the solution to that exception, not the cause...
What could make the IHTMLElementCollection generate that exception?
Related
I was just wondering how do we have to declare "ie" from the following code?
Dim objShell As Object
Set objShell = CreateObject("Shell.Application")
Set ie = objShell.Windows(x)
Thank you :)
You can just use Object but it's easier if you enable the Microsoft Internet Controls library as it creates more specific objects. This allows you to use intellisense while coding which makes it much less of a guessing game of what properties and actions are available. Here's some sample code once you have it enabled.
Dim ieobject As InternetExplorer
Set ieobject = New InternetExplorer
ieobject.Visible = True
ieobject.navigate Url:="https://www.StackOverFlow.com"
'get the HTML document for the page.
Dim ieDOCUMENT As HTMLDocument
Set ieDOCUMENT = ieobject.document
This site covers it well (along with a lot of other VBA topics)
If you get the error User-defined Type not defined, you haven't enabled the Microsoft Internet Controls library.
Place a breakpoint (F9) in your procedure, then bring up the Locals toolwindow (View /> Locals) when the breakpoint is hit.
The runtime data types will appear under the "Type" column1:
If you are not referencing the type library where these classes and interfaces are defined, the type to use at the declaration site is Object, or Variant - because there is no compile-time reference to the library, the compiler cannot bind the types at compile-time, so you would get a compile error if you tried to declare the object variables otherwise.
With a reference to the appropriate type library, you can still use late binding and declare everything As Object, but that would be silly with the library right there waiting to be used.
In your particular example (as provided anyway), the type of ie is... Object, and the reference is Nothing, so expect any member call against ie to throw error 91:
1Unless user interfaces are involved... that's a bug in the VBE, unlikely to ever see a fix.
I asked a question this morning about how an object in VBA was successfully executing a method that was not listed under the possible methods for that object in the object library. Thanks to user Toby Allen I learned that I was thinking about it all wrong. The object in question was the IHTMLelement and the method was "getelementsbytagname", which I was referencing from the Microsoft HTML Object Library. However, he informed me that's it's not an object at all but rather an interface, and it was inheriting members from other interfaces (hence why it wasn't showing up in the object library) and after reading about this in depth I believe I have a good grasp on it.
However, I tried to backtrack using MSDN and find out which interfance this method is really from, so I went to the IHTMLelement help page which says it inherits an interface from the IDispatch interface which inherits from the IUnkown interface. But still none of these list the method in question - the "getelementsbytagname" method! Am I missing something else?
I figured it out. The methods are from an interface under the ihtmlelement interface, not vice-versa. It was actually an htmlbuttonelement
I have an Access app, developed in Access 2013 in multi-user env, uses Excel automation to export and format an Excel file.
The normal Office/Excel 2013 (15.0) references have been made and all works well on Office 2013 machines. Does not play nicely on 2010 machines.
Using a 2010 machine, I replaced the 15.0 references with 14.0 references, and the app is happy on 2010 and 2013 machines. Upon next edit/update on my 2013 machine the 15.0 references return.
Any suggestions to more conveniently develop/operate in this multi-version environment?
Thanks!
The overall solution to this issue is to use late binding. The downsides to late binding are
Dim xlApp As Object means that we don't get any IntelliSense for xlApp, and
related constants like xlEdgeTop are not defined without the associated Reference
These issues can be mitigated by using conditional compilation in the VBA project. For development, add the required Reference to the project and define a conditional compilation argument
which you can use in your code like this
Option Compare Database
Option Explicit
Public Sub WorkWithExcel()
#If LateBinding Then
Dim xlApp As Object
Set xlApp = CreateObject("Excel.Application")
#Else
Dim xlApp As Excel.Application
Set xlApp = New Excel.Application
#End If
Debug.Print xlEdgeTop
End Sub
To avoid clutter, I would be inclined to keep the constants in a separate Module like this
Option Compare Database
Option Explicit
#If LateBinding Then
Public Const xlEdgeTop = 8
#End If
When the code tweaking is complete, remove the Reference, set the LateBinding argument to "True" (LateBinding = -1) and compile the project. Add any constants you've missed (there always seems to be one or two) and when it compiles without the Reference you should be good to deploy.
For the next development session, set LateBinding back to "False" (LateBinding = 0) and add the Reference back in.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
So I have an MS Access application originally in a 2002-2003 format. Developed on a production network image, and when the image pushed the office upgrade, it became office 2007. So this is used in a very non traditional way...reps take it with them on company laptops enter data, and it automates complex ppt presentations, and excel worksheet for them (they love it....they need it). Data is not held in this like a database repository, just long enough to produce the automation they need and it works....saves them time. So Access is limited, and in the use case, really limited since i am using it in a way it certainly wasn't intended to be used. I get that, but like I said so far, its working pretty well.....
The one bump I have run into is if someone has to use another computer for whatever reason (doesn't happen often but it got me thinking), and say they have a version of 2002-2003 access, the tool will run, but once we get to the code routines/modules for ppt & outlook, the object libraries show MISSING because working on this tool seems to automatically cause the libraries to go up to the next available version, but not down to find the version.....
so originally when I made this....it used MS PowerPoint 11.0, and MS Outlook 11.0, and then when I had to start working in 2007 it became 12.0 for both, some instances I see it bumped up to 14.0, and none of the ups are a problem, but now since I have an image with Office 2007 out, and new files version I try to give them has the libraries defaulted to 12.0 and if they run into a scenario where they would take the file on a disc and use it on a computer that has office 2003, those libraries just come up missing and it doesn't recognize the appropriate 11.0 object libraries anymore.
So finally my question....any suggesions (save the obvious and build a real app...lol...would love to....no $) to handling this? Is there code that can/will evaluate what libraries need to be set on opening the file using vba? Is that possible?
There is Remove Method which you could use to remove a reference, then AddFromFile Method or AddFromGuid Method to add a reference.
The AddFromFile approach was offered in answers to this recent StackOverflow question: Add references programatically However, make sure to read Tony's answer ... if you're distributing your application as an MDE, you're SOL.
Consider switching to late binding for your PowerPoint and Outlook stuff. That way you won't have to fiddle with references (no reference required for late binding). A drawback from late binding is you lose the benefit of IntelliSense during development. However, you can develop with early binding, then switch to late binding for deployment. Substitute the values where you used any named constants from the referenced library ... debug will highlight any you overlook.
A frequent counter-argument is that late binding imposes a "performance penalty". However, I've yet to encounter a use case where the "slow-down" was large enough to be noticeable by a human observer.
In any case I've been using late binding for years specifically to avoid the type of deployment issue you're struggling with now.
Edit: Here is an example which uses the Excel type library. I have it set to use early binding. To convert it to late binding, comment out the declarations under '* early binding ... , and uncomment those under '* late binding ...
Also notice the 2 lines which include the named constant, xlAutomatic.
Public Sub EarlyVsLateBinding()
Dim strFullPath As String
'* early binding requires reference to Excel type library *'
Dim objExcel As Excel.Application
Set objExcel = New Excel.Application
Dim objBook As Excel.Workbook
Dim objSheet As Excel.Worksheet
'* late binding; no reference required *'
' Dim objExcel As Object '
' Dim objBook As Object '
' Dim objSheet As Object '
' Set objExcel = CreateObject("Excel.Application") '
strFullPath = CurrentProject.Path & Chr(92) & "foo.xls"
Set objBook = objExcel.Workbooks.Open(strFullPath)
Set objSheet = objBook.Worksheets("bar")
objSheet.Range("B1").Select
With objExcel.Selection.Font
.Name = "Arial"
.FontStyle = "Regular"
.Size = 10
.ColorIndex = xlAutomatic 'named constant available with reference set '
'.ColorIndex = -4105 'substitute xlAutomatic value so we drop reference
End With
objBook.Close SaveChanges:=True
objExcel.Quit
Set objSheet = Nothing
Set objBook = Nothing
Set objExcel = Nothing
End Sub
I am using VBA (in Access 2003) and I'd like to use the IFilter mechanism to extract the textual contents of files. I found some some nice C++ sample code which makes it look relatively easy, but at the moment I can't even get the DLL call to LoadIFilter to work:
Declare Function LoadIFilter Lib "query.dll" (ByVal pwcsPath As String, _
ByVal pUnkOuter As Object, ByRef ppIFilter As Object) As Integer
Public Sub DocEx()
Dim ifilter As Object
Dim hresult As Integer
hresult = LoadIFilter("C:\temp\test.txt" & Chr(0), Nothing, ifilter)
Debug.Print hresult
End Sub
hresult is always E_FAIL (= 16389).
Is it my syntax for the DLL that is incorrect, or something else?
EDITED TO ADD: In the end I didn't solve this problem. But since my only purpose is to hack up an internal script, it is sufficient for me to to just call the FiltDump.exe tool that comes bundled with the Microsoft Platform SDK and parse its output. (A bit clunky though, especially since FiltDump.exe insists on printing error messages to stdout instead of stderr!)
LoadIFilter() is meant to do a lot of work - it looks up the registry to find which IFilter to load, then loads it (most likely calls CoCreateInstance() for just found class id). Anything could go wrong - there could be no mapping in the registry from .txt extension to the class id or the COM server for that class id could fail to load.
Your best bet is to use Process Monitor to see if it finds what IFilter to load and if at least it tries to load it.