現象
Microsoft Visio 2013 において、VBA のコード上で Visio.Application.AddUndoUnit を用いてIVBUndoUnit.Do メソッドをイベントに登録しているにも関わらず、[やり直し] をクリックした際に、IVBUndoUnit.Do メソッドが呼ばれません。
この現象は以下の条件をすべて満たした場合に発生します。
-
シェイプオブジェクトをグループ化する。
-
Shape.NameU プロパティを変更する。
-
上記1、2 の手順の前後に、“Visio.Application.AddUndoUnit” メソッドを用いて、イベントを登録する。
回避策
発生条件を満たさないようにすることで回避します。
例えば以下のいずれかの方法で回避します。
方法 1 : Shape.NameUプロパティを変更しない
Shape .NameU プロパティの値を変更しないことにより、現象を回避することができます。
方法 2 : シェイプオブジェクトのグループ化を解除する
シェイプオブジェクトのグループ化の処理を実行しないことにより、現象を回避することができます。
Note :
発生条件を満たさないようにする方法以外に回避策はありません。
状況
マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の問題として認識しています。
詳細
問題の再現手順
-
Visio 2013 を起動し [基本図] をクリックし、[作成] にて作成を開始します。
-
ステンシルメニューから長方形を 2 つ追加します。
-
キーボードの [Alt] + [F11] を押下し、"Microsoft Visual Basic for Applications" を起動します。
-
画面左のプロジェクトウインドウにて、"Visio Objects" を右クリックし、"標準モジュール"と "クラスモジュール" を追加します。
-
標準モジュール" および "クラスモジュールにそれぞれ以下のコードを追加します。
---------------------------
標準モジュールに追加するコード
---------------------------
Sub Sample()
Dim obj1 As Class1
Dim obj2 As Class1
Dim scopeID As Long
'"TestUndoScope"のスコープIDを持つトランザクションを開始します。
scopeID = Visio.Application.BeginUndoScope("SampleScope")
'シェイプのグループ化処理前で、"元に戻す"キューにMyUndoUnit(1)を追加します。
Set obj1 = New Class1
Visio.Application.AddUndoUnit obj1
'追加されたシェイプオブジェクトをグループ化します。
ActiveWindow.SelectAll
ActiveWindow.Selection.Group
ActiveWindow.DeselectAll
'Shape のプロパティを編集します。
ActiveWindow.Shape.Shapes(1).NameU = "MyName"
'"元に戻す"キューにMyUndoUnit(2)を追加します。
Set obj2 = New Class1
Visio.Application.AddUndoUnit obj2
Application.EndUndoScope scopeID, True
End Sub
-----------------------------
クラスモジュールに追加するコード
-----------------------------
Implements IVBUndoUnit
Private Property Get IVBUndoUnit_Description() As String
IVBUndoUnit_Description = "MySample"
End Property
' この Do が呼び出される回数が異なります
Private Sub IVBUndoUnit_Do(ByVal pMgr As IVBUndoManager)
Debug.Print "Do"
pMgr.Add Me
End Sub
Private Sub IVBUndoUnit_OnNextAdd()
End Sub
Private Property Get IVBUndoUnit_UnitSize() As Long
IVBUndoUnit_UnitSize = 0
End Property
Private Property Get IVBUndoUnit_UnitTypeCLSID() As String
IVBUndoUnit_UnitTypeCLSID = vbNullString
End Property
Private Property Get IVBUndoUnit_UnitTypeLong() As Long
IVBUndoUnit_UnitTypeLong = 0
End Property -
[表示] - [イミディエイト ウインドウ] メニューで、[イミディエイト ウインドウ] を表示します。
-
標準モジュールに追加した "Sample" を実行します。
-
Visio のウインドウに戻り、[元に戻す] を実行します。イミディエイトウインドウに、Do が 2 回表示されます。
-
Visio のウインドウで、[やり直し] を実行します。
結果
イミディエイトウインドウに、Do が 1 回しか表示されません。
関連情報
Shape.ID プロパティ (Visio)(機械翻訳)
http://msdn.microsoft.com/ja-jp/library/office/ff767467(v=office.15).aspx
Shape.NameU プロパティ (Visio)(機械翻訳)
http://msdn.microsoft.com/ja-jp/library/office/ff765535(v=office.15).aspx