Chris:
Do you have any samples that will inject or edit VBA via code into an existing Visio file?
Let's say that I have a VBA function that I want to add to an existing Visio file. How is this done? It is unclear how to use the VBProject object that hangs off of the ActiveDocument object.
Any light here would be helpful.
Thanks,
- Billy
I'd be very surprised if this were possible. It would break the entire security model of Visio as any "bad" file could infect any other Visio document.
Hey Pruchinator,
I've only gone as far as exporting and importing VBA modules/classes/forms programmatically, but haven't built Functions or Subs on the fly.
Looking at that code, there appear to be two pieces to the puzzle:
1. The VBA project needs a reference to MSVBA Extensibility, "Microsoft Visual Basic 6.0 Extensibility"
2. In Visio, need to check: Tools > Macros > Security > Trusted Publishers Tab > "Trust access to Visual Basic Project", or wherever it is in Visio 2010.
Those two needs might alleviate some of the security concerns that Paul voiced, since access to Visio's projects is usually turned off.
Here's some code for exporting VBA modules programmatically:
' Need reference to MSVBA Extensibility
' Microsoft Visual Basic 6.0 Extensibility
' For Visio, need to check:
' Tools > Macros > Security > Trusted Publishers Tab
' "Trust access to Visual Basic Project"
Sub ExportComponents()
Dim v As VBIDE.VBProject
Dim c As VBIDE.VBComponent
Set v = ThisDocument.VBProject
v.VBComponents.Item(1).Export (ThisDocument.Path & "ThisDocument.cls")
Exit Sub
For Each c In v.VBComponents
' Classes:
' This is an ad-hoc filter for only exporting certain class modules
' that start with "CVis". You could just export all of them.
If left(c.Name, 4) = "CVis" Then
Call exportComponent(c)
End If
' Modules:
' Specifically export only these two modules. Again, we could
' have just called exportComponent(c) for everything.
If c.Name = "ShapeSheet" Then Call exportComponent(c)
If c.Name = "LocaleInfo" Then Call exportComponent(c)
Next
End Sub
Private Sub exportComponent(vbcomp As VBIDE.VBComponent)
Dim sName As String, sExt As String
' Set the extension based on component type. Exit sub
' if type not supported.
Select Case vbcomp.Type
Case vbext_ct_ClassModule
sExt = ".cls"
Case vbext_ct_StdModule
sExt = ".bas"
Case Else
Exit Sub
End Select
' Build the name:
sName = ThisDocument.Path & vbcomp.Name & sExt
' Save the file:
Call vbcomp.Export(sName)
End Sub
Injecting lines of code seems to go something like this (I didn't try it)
Dim doc As Visio.Document
Set doc = Visio.ActiveDocument
Dim v As VBIDE.VBProject
Dim c As VBIDE.VBComponent
' Get the project:
Set v = doc.VBProject
' Add a class:
Set c = v.VBComponents.Add(vbext_ct_ClassModule)
c.Name = "CBilly"
' Blast some lines of code into the class:
Call c.CodeModule.InsertLines( lngNumLines, sCode )
I remember folks at Visio Corp. doing this sort of thing for good reason (at least for a good demo), so it is definitely possible, but I'm sure Microsoft is embarrassed about it now! :)
Ah! So this is what "Trust access to Visual Basic Project" is for!
The checksum of your VBA code will fail. (assuming you signed your code, otherwise you have to disable your macro security)
Next time you open the file the VBA code will be disabled due to an invalid checksum or missing certificate.
Obviously if you can sign it again on that PC, it is no problem.
I'have already explain how to do this in the following post :
http://visguy.com/vgforum/index.php?topic=1330.msg6417#msg6417 (http://visguy.com/vgforum/index.php?topic=1330.msg6417#msg6417)