问题
During development everything was fine, early binding worked a treat, but now I've moved to late binding for production and I'm having issues with Visio Enums. As follows:
Set AppVisio = CreateObject("visio.application")
Set vsoSelection = AppVisio.ActiveWindow.Selection
Call vsoSelection.GetIDs(lngShapeIDs)
With .Shapes.ItemFromID(lngShapeIDs(0))
.CellsSRC(visSectionObject, visRowXFormOut, visXFormPinX).FormulaU = sngShapeHCenter
.CellsSRC(visSectionObject, visRowXFormOut, visXFormPinY).FormulaU = sngShapeVCenter
.CellsSRC(visSectionObject, visRowXFormOut, visXFormWidth).FormulaU = sngShapeWidth
.CellsSRC(visSectionObject, visRowXFormOut, visXFormHeight).FormulaU = sngShapeHeight
End With
In early binding
visSectionObject, visRowXFormOut, visXFormPinX etc.
all resolve, but I can't get them to resolve in Late Binding.
I've tried adding AppVisio. to prefix the parameters to no avail, can anyone help and tell me the correct way of referencing the Enums?
I've tried using the Visio VBA recorder to see what it gives, but it is not as verbose as I'd hoped (yes, I know, it is so verbose but not on this occasion).
This needs to work for Visio 2010 and 2013 etc.
回答1:
That's one of the trade-offs of late binding, or more precisely of not setting an explicit reference in Tools>References. The pre-defined enums are then no longer available.
You'll have to replace the enums with their numerical value (see e.g. this list).
For example, the numerical value of visRowXFormOut
is 1
, which you can check for yourself in the Immediate window:
?visRowXFormOut
1
So you can either replace all instances of visRowXFormOut
with 1
s, or declare visRowXFormOut
as a constant:
Const visRowXFormOut As Integer = 1
and keep the rest of your code as is.
回答2:
Defining all enumerators yourself or replacing in code with plain numbers in some cases may be a bit too challenging. There is also another way.
If you use scripting in windows (the language looks like .vbs) then you still can use these constants, by wrapping your file into .WSF (Windows Script) file.
In a .wsf file, you have a "reference" item which allows you to use constants from a type library.
<job id='my script'>
<!-- this imports enumerators from Visio typelib -->
<reference guid="{00021A98-0000-0000-C000-000000000046}" version="4.14" />
<script language="vbscript">
...
your code here which uses constants from Visio type library here, like:
...
WScript.Echo visRowXFormOut ' prints 1
...
</script>
</job>
Not 100% sure if you must specify the version explicitly in the item but anyways, Visio 2010 version is 4.14, Visio 2013 is 4.15. It may work without explicit version specification as well (please refer to the wsf docs)
You could also consider wrapping the whole .vbs file without changes like this:
<job id='my script>
<reference guid="{00021A98-0000-0000-C000-000000000046}" version="4.14"/>
<!-- you can use enumerators in that script -->
<script language="vbscript" src="code.vbs" />
</job>
来源:https://stackoverflow.com/questions/20344409/late-binding-issue-with-enums