Object browser in vba7 does not show WebClient Object members [duplicate] - vba

This question already has answers here:
Using standard .Net libraries with VBA
(2 answers)
Closed 9 years ago.
I need to download and save a file automatically from a URI. I think I can use URLDownloadToFile from "urlmon" library but I wanted to use the WebClient.DownloadFile method.
I hoped it would be a cakewalk but for reasons beyond me, I am not able to view or use the members of the WebClient class in the VBA 7 IDE. I have already referenced the .Net 2 framework's System.tlb and am able to see the classes in the System.Net namespace but members for many of the classes are not visible and I cannot use them in my code.
I get a compilation error on trying to use a code like:
Dim Downloader as New System.WebClient
Downloader.DownloadFile("uri","filename")
Maybe I have not registered the .Net classes to be used in VBA and hence the problem but; the System.dll being referred to in my project is located at C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.tlb
which confuses me even more. Also, it will really help if someone can detail out the process to reference .Net Framework libraries in VBA 7.
Thanks in advance!

In lieu of .Net libraries, I suggest using the MSXML library. You can add it to VBA in the IDE by clicking "Tools" ---> "References..." and checking the box next to "Microsoft XML, x.x" where x.x is the most recent version.
Here is a quick test you can run:
Public Sub Downl()
Dim xhttp As MSXML2.XMLHTTP
Set xhttp = New MSXML2.XMLHTTP
Dim oFile As Integer
oFile = FreeFile()
Open CurrentProject.Path & "\test.png" For Binary Access Write As oFile
Dim bdata() As Byte
With xhttp
.Open "GET", "https://www.google.com/images/srpr/logo11w.png", False
.send
bdata = .responseBody
Put oFile, 1, bdata
End With
Close oFile
End Sub

Related

Need a vb version of DOM getElementByAttribute

I know that there are tons of versions in JavaScript out there but I need this as a vb version for use in Scripting in Exel 2010? Has anyone done this translation?
If your query is for XML DOM methods, , then in the VB Editor in Tools > References add a reference to Microsoft.MSXML2
goto 1) below!
If your query is for DHTML DOM methods, then in the VB Editor in Tools > References add a reference to Microsoft.mshtml
1) Then you can access the DOM using all the methods that you see in the Object Browser (keystroke f2 in the VB Editor, then select MSHTML in the drop down to select DHMTML DOM Library.
an example using MSXML would be:
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("title")[0]
y=x.childNodes[0]
msgbox y.nodeValue
an example (using MSHTML) would be :
Sub testDoc()
Dim xDoc As MSHTML.HTMLDocument
Dim sURL As String
Dim oElement As MSHTML.HTMLBaseElement
Set xDoc = New MSHTML.HTMLDocument
With xDoc
.Open (sURL)
Set oElement = .getElementById(idName)
MsgBox oElement.ID
End With
End Sub
I hope that gets you started in the right direction.
BTW,
Philip

Convert PDF to string using acrobat dlls

I am working on a vb.net project. I am trying to convert the content of a pdf file to string using acrobat dlls (cannot use other 3 rd party dlls). Below is my code, when I run the program I am getting the following error: "Retrieving the COM class factory for component with CLSID, failed due to the following error: 80040154 Class not registered". I did some research and found out that I have to install the full version of acrobat standard or professional version. Not only that the full version of acrobat must also be installed in all the user machines that the program runs.
Can anyone tell me if this is true and suggest how to fix the class not registered error?
Sub Main()
Dim s As String
Dim sSourceFile As String
sSourceFile = "P:\Report images\DevReports\New Folder\UM-STD-Approval_154.pdf"
Dim oSourceFileInfo As New System.IO.FileInfo(sSourceFile)
Dim st As New AcroPDDoc
st.Open(sSourceFile)
s = GetText(st)
Dim oAcroApp As Acrobat.CAcroApp = New Acrobat.AcroApp
Dim oAcroAvDoc As Acrobat.CAcroAVDoc = New Acrobat.AcroAVDoc
Dim oAcroPDDoc As Object = Nothing
If oAcroAvDoc.Open(sSourceFile, "") Then
'Set PDDoc object and save the file.
oAcroPDDoc = oAcroAvDoc.GetPDDoc()
' oAcroPDDoc.Save(1, sOutputFile)
Else ' Document FAILED to open.
MsgBox("Cannot open ")
End If
oSourceFileInfo = Nothing
oAcroApp.CloseAllDocs()
oAcroPDDoc = Nothing
oAcroAvDoc = Nothing
oAcroApp.Exit()
oAcroApp = Nothing
End Sub
Apologies for the obvious answer but you've kind of answered your own question already.
Adobe Reader is a free application with a very limited interface allowing automation; in practice it's limited to the point where you can display a PDF file and navigate through it (to some extent).
For full features automation (like what I think you are looking for) you will need to install the full Adobe Acrobat. And yes, any system you run this on will also need to have Adobe Acrobat installed.
Now, there are probably libraries out there (including libraries from Adobe or containing Adobe technology inside) that will allow you to embed the functionality you are looking for in your application, but those too will not be free...

Snapshot of data structures, VBA excel [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
What's the fastest way to export all excel add-in modules to .bas files?
Is it possible to do snapshot of all used modules and data structures in VBA Excel and recover it some time after?
The reason is reproducing error after crashes
ADDED. Yes, in essence I want to serialize classes and types.
I feel like what you kind of want is to serialize all your classes as
they are to an XML file? I know this function exists in other
languages but VBA might not have it as it is. (I'm sure you could
force something) – Brad
#Brad, yes, exactly, as one of possible ways – nikaan
Assuming that this method does not exist for VBA (although it is available for VB.NET or VB 2005: http://support.microsoft.com/kb/315703), I would probably try to make a simulation: Write the state of each object / variable (of those needed) to a txt file by using FSO.
I don't know if this is feasible for your project though and I probably wouldn't like to do this with pleasure for a huge amount of code.
dim sFile As string
Dim FSO As FileSystemObject
Dim FSOFile As TextStream
sFile = "U:/Log.txt"
Set FSO = New FileSystemObject
Set FSOFile = FSO.OpenTextFile(sFile, 2, True)
FSOFile.writeline (<Descriptions+Property/variable value>)
FSOFile.Close
set FSO = nothing
Depending on how well you input descriptions (eg. inlcuding boolean values for successful instantiation of objects, etc...), you may be able to see what has happened behind the screen up to the point where your application crashed...
I don't know if this answers your question, as I'm a little bit doubting about what you refer to with "fields" (comments).
When being the owner of a VBA project, you can create a sub routine that exports all the modules in your currenct project.
This link provides the code:
http://edndoc.esri.com/arcobjects/9.0/Samples/Application_Framework/ExportVBACode.htm
For the purpose as you describe it, I don't see a reason to do this.
Personally I would use a lame trick like this one:
Option Explicit
Sub Save_File()
Dim sCur_Path As String
Dim sCopied_Path As String
Application.DisplayAlerts = False
Application.ScreenUpdating = False
sCur_Path = ThisWorkbook.FullName
sCopied_Path = "U:/Copied_New.xlsm"
ThisWorkbook.SaveAs sCopied_Path
ThisWorkbook.SaveAs sCur_Path
End Sub

Advice on Debugging Machine-Specific Excel VBA Issue

I have an Excel workbook with dependencies on code in other other Excel workbooks (these dependent .xls's are VB-level references, i.e. via the Tools->References dialog box in the VBA editor), and some dependencies on dll's such as:
Microsoft Scripting Runtime
Microsoft Forms 2.0 Object Library
This sheet has worked for about 2 years on around 20 machines running Windows XP and Office XP. Recently we have taken delivery of 3 new machines (same OS, same office version) which refuse to run this sheet. When the sheet opens, it throws a 'Compile Error', and the session hangs.
If I open the sheet on a 'bad' machine, hold down the left shift key to stop macro's from running, and then go to VBA Editor->Debug->Complie VBAProject, it compiles fine. I am then able to save the sheet and open it normally on a 'bad' machine. However this new version of the sheet refuses to run on a 'good' machine!!
I think there must be some sort of version mismatch between certain dll's on the 'good' and 'bad' machines. How do I establish what is causing the issue? Are there any tools available for comparing versions of com components?
Two suggestions
1) First open the file with macros disabled. And then check VBA Editor | Tools | References. Check for any missing references and then let us know what are they. We will take it from there.
2) For references like "Microsoft Scripting Runtime Object Library" I never use Early Binding. Early Binding is the major cause for these kind of errors. Just FYI: Early Binding is creating references beforehand via VBA Editor | Tools | References. I would recommend changing your code to Late Binding. Here are 2 examples of the same code using "Microsoft Scripting Runtime Object Library" with Early Binding and Late Binding
EARLY BINDING EXAMPLE
'~~> Set Reference to "Microsoft Scripting Runtime Object Library"
Sub EBExample()
Dim FSO As Scripting.FileSystemObject
Dim SourceFolder As Scripting.Folder
Dim FileItem As Scripting.File
Set FSO = New Scripting.FileSystemObject
Set SourceFolder = FSO.GetFolder(SourceFolderName)
For Each FileItem In SourceFolder.Files
'~~> You code
Next FileItem
End Sub
LATE BINDING EXAMPLE
'~~> This doesn't need a reference
Sub LBExample()
Dim FSO As Object, SourceFolder As Object, FileItem As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
Set SourceFolder = FSO.GetFolder(SourceFolderName)
For Each FileItem In SourceFolder.Files
'~~> You code
Next FileItem
End Sub
As for me I use early binding to take advantage of Intellisense but then convert it to late binding to avoid version-specific code before distributing the code. That ways the code always works. :)
IMP NOTE: Late Binding fails in scenarios where the destination machine doesn't have the relevant dll registered.
RECOMMENDED LINK:
Topic: Using early binding and late binding in Automation
Link: http://support.microsoft.com/kb/245115
Hope this helps
Sid
The easiest way I've found to compare references on two different machines is to run a little macro on each pc to show me all the details.
Make sure Excel is set to trust access to the VBA project object model and run the below code on the two versions of your macro.
Sub GetReferences()
Dim r As Object
For Each r In ActiveWorkbook.VBProject.References
Debug.Print r.Name, r.Description, r.FullPath
Next r
End Sub

How do I programatically add a reference to a VBA project?

I'm deploying an early bound styled VBA module that needs Scripting.Dictionary and RegExp.
The script, predictably, fails when it runs on another computer.
The user has to go to Tools->Reference in the VBA IDE and add a reference to those two libraries manually to make it work.
Hence lies the problem. Asking the non-technical end user to go to the IDE and manually add references is asking way too much of them.
The other alternative is to rewrite the whole (very long script written by someone else) to use late binding. I rather not take this path if there are other methods.
As an altervative, some people suggest adding a reference programatically like so:
Application.VBE.ActiveVBProject.References.AddFromFile [Path to library]
Is this the correct solution and if so are there any downsides of this strategy?
If not, are there other methods that will to enable the code to remain early bound yet does not require references to be added manually by the user.
Suggestions involving direct calls to the Win32/64 API are also welcome.
Thanks.
In my own limited environment (small # of other people using spreadsheets I develop, relatively standard machine setups), if I create the file and add the references, and then give a copy to someone else, they can open it with no problems and not have to do anything, so keep that in mind with this answer. (I'm wondering why that doesn't work for you.) Also, this was with Excel.
Rather than adding a reference from a file path, you might consider using the GUID property instead.
Here is some code I once used to automatically create references in a newly created workbook. (It's part of a script that would export code, references, and unit tests on worksheets to text for use with Subversion and then later reconstitute the workbook from the text files.) You might find it useful to your situation. (EH and cleanup removed to keep it short...)
'Export refs in existing workbook to text file
Private Sub exportRefs_(srcWbk As Workbook)
Dim fs As FileSystemObject
Set fs = New FileSystemObject
Dim tsout As TextStream
Set tsout = fs.CreateTextFile(fs.BuildPath(getTargetPath_(srcWbk), "refs.refs"))
Dim ref As Reference
For Each ref In Application.ThisWorkbook.VBProject.References
Call tsout.WriteLine(ref.GUID)
Next ref
'<EH + cleanup...>
End Sub
'Add refs to newly created workbook based on previously exported text file
Private Sub importRefs_(wbk As Workbook, path As String)
Dim fs As FileSystemObject
Set fs = New FileSystemObject
Dim tsin As TextStream
Set tsin = fs.OpenTextFile(path)
Dim line As String
Dim ref As Reference
While Not tsin.AtEndOfStream
line = tsin.ReadLine()
Set ref = Nothing
On Error Resume Next
Set ref = wbk.VBProject.References.AddFromGuid(line, 0, 0)
On Error GoTo 0
If ref Is Nothing Then
Debug.Print "add failed: " & line
End If
Wend
'<EH + cleanup...>
End Sub
Like, I said, limited environment, but hopefully it helps.