ようこそ 屋根裏部屋 mkII へ ログイン | 登録 | ヘルプ

Technological

ちょっとしたTIPSや私がはまったこと、調べたことなんかを書いていきます。

Visio 2003のオブジェクトにC#からアクセスする

 PIAを使ってVisio 2003のドキュメントのステンシルを列挙する方法。すごく苦労しました…Visual BASIC 6.0なんかが楽ですね。get_CellsU()なんかわからないってCrying

 WordやExcelならサンプルがあるのですが、Visioは軽く探しただけではまったくみつからず。ちなみにこれは完全ではありません。Pageコレクションの中にはLayerコレクションがあります。従って、もう一段階増えるはずです。私が扱うvsdファイルはLayerがないので省略しています。MSDN Libararyのオブジェクトモデルで確認してください。

 変数名、べたな名前ですいません…。それにしてもこんなにtry~catchというか、階層化されるってかなりいや。ちなみにこれは悪い例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using Microsoft.Office.Interop.Visio;
using System.Runtime.InteropServices;
using Visio = Microsoft.Office.Interop.Visio;

public void EnumObjectsVisio(string p_vsdFullPath)
m_visioApp = new Visio.Application();
try {
using (StreamWriter ws = new StreamWriter(VisioLog, false, Encoding.Unicode)) {
uint ShapeCount = 0;
Document oVsdDocument = m_visioApp.Documents.Open(p_vsdFullPath);
try {
Pages oPages = oVsdDocument.Pages;
try {
foreach (Page oPage in oPages) {
Shapes oShapes = oPage.Shapes;
try {
if (oPage.Type == VisPageTypes.visTypeForeground) {
double shapeHeight,shapeWidth, shapePinX, shapePinY;
ws.WriteLine(@"{0}のページ:{1}", p_vsdFullPath, oPage.Document.Name);
foreach (Shape oShape in oShapes) {
ShapeCount++;
//inch to millimeter
shapeWidth = oShape.get_CellsU("Width").ResultIU;
shapeHeight = oShape.get_CellsU("Height").ResultIU;
shapePinX = oShape.get_CellsU("PinX").ResultIU;
shapePinY = oShape.get_CellsU("PinY").ResultIU;

ws.WriteLine(@"No.{0} {1}, {2}, {3}, width:{4}, Height:{5}", ShapeCount, oShape.Name, oShape.Text, oShape.Type, shapeWidth, shapeHeight);
ws.WriteLine(@" PinX:{0}, PinY:{1}", shapePinX, shapePinY);
}
}
} finally {
if (oShapes != null) {
System.Runtime.InteropServices.Marshal.ReleaseComObject(oShapes);
}

}
}
} finally {
if (oPages != null) {
System.Runtime.InteropServices.Marshal.ReleaseComObject(oPages);
}
}
} finally {
if (oVsdDocument != null) {
System.Runtime.InteropServices.Marshal.ReleaseComObject(oVsdDocument);
}
}
}
} finally {
m_visioApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(m_visioApp);
m_visioApp = null;
}
}

修正後(渋木さん、あきひろさん、ご指摘感謝)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  Document oVsdDocument = m_visioApp.Documents.Open(p_vsdFullPath);
try {
Page oPage = null;
for (int i = 1; i <= oVsdDocument.Pages.Count; i++) {
if (oVsdDocument.Pages[ i ].Type == VisPageTypes.visTypeForeground) {
oPage = oVsdDocument.Pages[ i ];
break;
}
}
if (oPage == null) {
return false;
}
try {
Shape oShape = null;
Cell oCustomPropCell = null;
double shapeHeight, shapeWidth, shapePinX, shapePinY;

for (int i = 1; i <= oPage.Shapes.Count; i++) {
try {
oShape = oPage.Shapes[ i ];
shapeWidth = oShape.get_CellsU("Width").ResultIU;
shapeHeight = oShape.get_CellsU("Height").ResultIU;
shapePinX = oShape.get_CellsU("PinX").ResultIU;
shapePinY = oShape.get_CellsU("PinY").ResultIU;
} finally {
if (oShape != null) {
System.Runtime.InteropServices.Marshal.ReleaseComObject(oShape);
}
if (customPropCell != null) {
System.Runtime.InteropServices.Marshal.ReleaseComObject(customPropCell);
}
}
} finally {
if (oPage != null) {
System.Runtime.InteropServices.Marshal.ReleaseComObject(oPage);
}
}
} finally {
if (oVsdDocument != null) {
System.Runtime.InteropServices.Marshal.ReleaseComObject(oVsdDocument);
}
}

ちゃんと勉強していなかったためなんだけれど、foreach使うと参照が開放されないそうな。おかげで前時代的な(?)コードに逆戻り。まだ変なところがあったら指摘してください(^^;。

公開 2006年11月22日 19:59 投稿者 kkamegawa
タグ , , ,

コメントの通知

この投稿にコメントが付いた場合にメールを受信するには、登録してください。ここ

また次のフィードから、お気に入りのRSSリーダーを使って最新の状態を知ることもできます。 コメントのRSSフィード

コメント

# re: Visio 2003のオブジェクトにC#からアクセスする @ 2006年11月24日 13:03

書くのも大変なんですけど、動作確認がまた泣きそう。

どこで例外投げられても解放忘れがないかを調べるのが超面倒。

あとforeachでまわしてるoShapeが指すやつらはReleaseComObjectしなくても大丈夫ですか?

自分そこんとこよく理解できてなくて配列で回してるんですけど。。。

http://aki-itou.cocolog-nifty.com/diary/2006/11/cexcel_2676.html

あきひろ

# re: Visio 2003のオブジェクトにC#からアクセスする @ 2006年11月24日 19:16

はてなダイアリーの方で渋木(ひどり)さんにコメントいただいてしまいました…foreach使うと開放されないんだそうで(;-;)。ああ勉強不足。

#道理でサンプルがどれもこれも使っていなかったわけだ…。

というわけで、このエントリは大幅に書き換えます(汗)。

kkamegawa

どのような感想ですか?

(必須) 
必須 
(必須) 
Powered by Community Server, by Telligent Systems