Для русскоязычных пользователей Visio. Начинающих и профессионалов. Где взять, как сделать, что купить и т.д.

VBA

Перечень литературы

06.11.2015  Simple Macros in Microsoft Visio with the Macro Recorder  David Parker.   

Ответы на вопросы

Как вызвать макрос из трафарета макросом из документа?

Сначала код был в документе (в шаблоне) и был связан с клавишами быстрого доступа. Потом я перенес его в трафарет, но не смог использовать клавиши. Постоянно вызывать макросы через меню слишком долго и раздражает.
Я пытался использовать CallThis, но не получилось. 

Если в трафарете будет такой макрос: 

Public Sub RunMe()
MsgBox ("test")
End Sub 

то вы можете вызвать его из документа так: 

Sub Run()
Dim nSencil As Integer
Dim i As Integer
For i = 1 To Application.Documents.Count
If Application.Documents(i).Name = "Stencil1" Then
nStencil = i
End If
Next i
Call Application.Documents(nStencil).RunMe
End Sub 

Первоначально нужная программа находилась в модуле NewMacros и такой вызов давал ошибку 438. Я перенес код в ThisDocument трафарета и все заработало.
Можно ли вызвать макрос, находящийся в модуле трафарета? 

Можно через ExcuteLine. 

Call Application.Documents(nStencil).ExecuteLine("Module1.RunMe") 

Клавиши быстрого вызова для макроса в трафарете

У меня есть макрос в трафарете. Он отлично запускается из редактора. Я назначил сочетание клавиш (Ctl + m). Но когда я нажимаю клавишу быстрого вызова, макрос не вызывается.
Любые идеи по поводу альтернатив приветствуются. 

Скорее всего клавишами можно вызвать макрос только из активного документа. Но внешний трафарет не является активным документом.
Я использую такую комбинацию:
"Рабочий" код находится в трафарете с именем code.vss, который не содержит шейпов, только код и распространяется среди всех пользователей.
В шаблоне есть ссылка на этот трафарет в проекте VBA, поэтому код трафарета "известен" в шаблоне / чертеже. Этот трафарет не отображается в шаблоне. Он открыт только из-за ссылки в проекте VBA.
Код в шаблоне может быть запущен с помощью клавиш и ничего не делает кроме запуска "рабочего" кода в трафарете.
Таким образом, я могу вносить изменения в код в трафарете, и остается только распространять этот трафарет, чтобы сделать изменения доступными для всех пользователей.
Проблемы:
Если я хочу создать полностью новый макрос, я могу распространить его с помощью трафарета, чтобы он был доступен для всех, но не могу вызвать этот макрос из более старых чертежей, потому что пока нет доступных клавиш быстрого доступа. Клавиши имеются только в новом шаблоне / чертеже.
Так что способ помогает при изменении кода, но недостаточно хорош для нового кода.
(Источник - http://visguy.com/vgforum/index.php?topic=5424.0) 

Внедрение VBA в существующий файл Visio

Injecting VBA into an existing Visio file
http://visguy.com/vgforum/index.php?topic=2349.msg10436#msg10436 

Есть ли у вас примеры, которые могут вставлять или редактировать VBA в существующем файле Visio?
Допустим, у меня есть функция VBA, которую я хочу добавить в существующий файл Visio. Как это сделать? Неясно, как использовать объект VBProject, зависящий от объекта ActiveDocument. 

Я только дошел до того, что экспортировал и импортировал модули / классы / формы VBA программно, но не создавал функции или вспомогательные модули на лету.
На мой взгляд, проблема состоит из двух частей:
1. Проект VBA нуждается в ссылке на MSVBA Extensibility, "Microsoft Visual Basic 6.0 Extensibility".
2. В Visio необходимо проверить: Tools > Macros > Security > Trusted Publishers Tab > Trust access to Visual Basic Project.
Эти две вещи могут облегчить некоторые проблемы безопасности, поскольку доступ к проектам Visio обычно отключен.
Вот код для программного экспорта модулей VBA: 

' 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 

Внедрение строк кода выглядит примерно так (я не пробовал) 

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 ) 

Однако, контрольная сумма вашего кода VBA исказится. (при условии, что вы подписали свой код, в противном случае вы должны отключить защиту макросов).
При следующем открытии файла код VBA будет отключен из-за неверной контрольной суммы или отсутствующего сертификата.
Очевидно, что если вы сможете снова подписать его на этом компьютере, это не проблема.