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

События

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

06.08.2017  Коды событий (Visio)  Microsoft.   

06.08.2017  Метод IVisEventProc.VisEventProc (Visio)  Microsoft.   

06.08.2017  Объект IVisEventProc (Visio)  Microsoft.   

05.07.2012  Automating Page.DropLegend in Visio 2010  David Parker.   

29.12.2010  Preparing for Visio Web Access control events  David Parker.   

18.06.2007  EventXFMod can cause Visio to stop working  David Parker.   

15.11.2004  Four Best Practices When Event Handling in Visio  Mai-lan.  (англ.) Четыре совета по обработке событий в Visio 

12.10.2004  Finding the Shape That Generated the Click Event in Visio   Mai-lan.  (англ.) Поиск шейпа, сгенерировавшего Click Event в Visio 

01.01.1900  Auto-computed values in Visio diagrams with VBA  Julien.   

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

Как перехватить events в поле Value, если произошли изменения данных?

Как перехватить events в поле Value, если произошли изменения данных? 

Вот такая конструкция (после выполнения макроса ttt) срабатывает на любое изменение первого шейпа на странице и через MsgBox перечисляет все изменившиеся ячейки, в том числе и пользовательские. Остается отфильтровать их и реагировать только на нужную ячейку. 

Dim WithEvents m_shpObj As Visio.Shape
Public Sub InitWith(ByVal aShape As Visio.Shape)
Set m_shpObj = aShape
End Sub
Private Sub m_shpObj_CellChanged(ByVal Cell As Visio.IVCell)
MsgBox Cell.Shape.Name & " " & Cell.Name & " changed to =" & Cell.Formula
End Sub
Sub ttt()
Set m_shpObj = ActivePage.Shapes(1)
End Sub 

Почему срабатывает ShapeAdded при открытии файла?

Работая через VBasic с Visio Type Library,я пытался использовать обработчик события ShapeAdded в клиенте (объявлена переменная dim WithEvents app As Visio.Application)
Sub appVisio_ShapeAdded(ByVal Shape As Visio.IVShape)
...
End Sub
и пришел к неожиданному выводу - что он срабатывает при открытии файла *.WMF (не только при добавлении шейпов). При открытии стандартного *.VSD обработчик "молчит".
Почему это? Может Visio при чтении такого файла воспринимает процесс как добавление шейпов или недоработка? 

При открытии стандартного vsd обработчик молчит, потому что просто открывается пустой рисунок.
При открытии WMF Visio открывает для него пустой документ, а затем помещает на него картинку (WMF). Эта картинка является тоже шейпом, у него существует шейп-лист, полный набор атрибутов и т.д. То есть срабатывание добавления шейпа вполне закономерно и соответствует правилам Visio. 

Подскажите, можно ли отловить изменение шейпа?

Подскажите, можно ли отловить изменение шейпа? Дело в том, что необходимо написать процедуру, запрещающую некоторые изменения шейпов. Стандартной функции нет (есть только при добавлении шейпа ShapeAdded или при изменении текста шейпа, а необходимо отловить изменение геометрии шейпа). 

На изменение геометрии срабатывает EventXFMod.
Что-нибудь типа Shape.Cells("EventXFMod").Formula = "RUNADDON (""ThisDocument.ttt"")" позволит в дальнейшем при изменении геометрии шейпа выходить на макрос ttt. 

Где описывать обработчик ShapeAdded и как его вызывать?

Где описывать обработчик ShapeAdded и как его вызывать? 

Обработчик будет вызываться сам, как только на страницу упадет шейп.
Чтобы его описать, нужно вызвать Microsoft Visual Basic (Tools / Macros / Visual Basic Editor), щелкнуть слева по ThisDocument, справа в списке объектов выбрать Document, а еще правее в списке событий выбрать ShapeAdded.
При этом на листе появится заготовка типа: 

Private Sub Document_ShapeAdded(ByVal Shape As IVShape)

End Sub 

Впишите туда для проверки MsgBox, например: 

Private Sub Document_ShapeAdded(ByVal Shape As IVShape)
MsgBox "Ой, Добавилось!"
End Sub 

Теперь возвращайтесь на страницу рисунка и добавьте любой шейп или просто проведите линию и наблюдайте, как срабатывает Ваш обработчик. 

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

Подскажите, если не затруднит, как отследить изменение в выделении.
Пробовал так:
Private Sub ActiveWindow_SelectionChanged(ByVal Window As IVWindow)
MsgBox Time
End Sub
Но не работает. 

А ассоциировать с реальным источником не забыли? Типа вот так: 

Dim WithEvents tt As Visio.Window

Sub ttt()
Set tt = ActiveWindow
End Sub

Private Sub tt_SelectionChanged(ByVal Window As IVWindow)
MsgBox "Changed"
End Sub 

После выполнения ttt событие начинает срабатывать. 

есть ли возможность средствами VB отслеживать событие ShapeAdded?

А есть ли возможность средствами того же VB отслеживать это событие ShapeAdded (в VBA я знаю, как это сделать)? 

Конечно, есть.
Если приложение VB делается по технологии COM Add-in (в Visio 2002 стала поддерживаться) то все практически так же, как и в VBA. Это нужно скачать из Microsoft Visio 2002 SDK, он подсаживается в VB6 и добавляет к нему свой пример-шаблон. То есть там уже все понятно становится.
А если технология Add-on, то посложнее. Это уже два разных приложения взаимодействуют. Пример по-моему в том же SDK есть (там еще и документация прилагается, правда на английском). 

Как сделать, чтобы объект из группы исчезал и появлялся по двойному клику?

Нужно сделать так, чтобы один из объектов группы исчезал и появлялся по двойному клику. Расскажите как. 

Зайдите в ТаблицуФигур группы и вставьте раздел Другие свойства.
В ТаблицеФигур группы укажите следующие параметры: 

EventDblClick =IF(Prop.Row_1.Prompt=1;SETF(GetRef(Prop.Row_1.Prompt);0);SETF(GetRef(Prop.Row_1.Prompt);1)) 

И в фигуре, которая должна исчезнуть: 

Geometry1.NoShow =Sheet.ID!Prop.Row_1.Prompt 

где ID номер группы. Теперь при двойном нажатии эта фигура(ы) будет "исчезать" и "появляться".
Можно еще вот как поступить, если требуется убирать из группы группу.
1) Создать группу (как элемент будущей группы).
2) Скопировать в буфер.
3) Сделать специальную вставку Edit>Paste Special...
4) С этим новым элементом создать группу.
5) Зайдите в ТаблицуФигур группы и вставьте раздел Другие свойства.
В ТаблицеФигур группы укажите следующие параметры: 

EventDblClick =IF(Prop.Row_1.Prompt=1;SETF(GetRef(Prop.Row_1.Prompt);0);SETF(GetRef(Prop.Row_1.Prompt);1)) 

И в группе которая должна исчезнуть: 

ImgWidth =Width*Sheet.ID!Prop.Row_1.Prompt
ImgHeight =Height*Sheet.ID!Prop.Row_1.Prompt 

где ID номер группы. Теперь при двойном нажатии эта группа(ы) будет "исчезать" и "появляться". 

Как сделать, чтобы объект из группы исчезал и появлялся по двойному клику 2?

На строку IF(Prop.Row_1.Prompt=1;SETF(GetRef(Prop.Row_1.Prompt); 0); SETF(GetRef(Prop.Row_1.Prompt);1))
В поле EventDblClick я получаю сообщение "Error in formula". В справке 5-го Визио я не могу найти GetRef. Что это? 

Измените =IF(Prop.Row_1.Prompt=1;SETF(GetRef(Prop.Row_1.Prompt);0);SETF(GetRef(Prop.Row_1.Prompt);1))
на 

=IF(Prop.Row_1.Prompt=1;SETF("Prop.Row_1.Prompt";0);SETF("Prop.Row_1.Prompt";1)) 

Примечание: задача решилась так. 

EventDblClick=IF(Prop.Row_1.Prompt=1;SETF("Prop.Row_1.Prompt";"0");SETF("Prop.Row_1.Prompt";"1")) 

в общей группе.
В группе которая исчезает 

Width=Sheet.ID!Width*1*Sheet.ID!Prop.Row_1.Prompt
Height=Sheet.ID!Height*0,7703*Sheet.ID!Prop.Row_1.Prompt