C#进行Visio二次开发的常见问题处理
1. Visio属性值的转换问题
做过Visio开发的人知道,Visio中的属性值也就是Cell.Formula的值通常包含两对双引号的(如""XX""), 如果要将属性的值转换正常的字符串值,那么需要去除双引号。因此从Visio的Cell的Formula值中得到的字符串需要经过下面方法处理一下:

public
static
string
FormulaStringToString(
string
formula)

{

const
string
OneQuote
=
"
\
""
;

const
string
TwoQuotes
=
"
\
"
\
""
;

string
convertedFormula
=
""
;


try

{

convertedFormula
=
formula;

if
(convertedFormula.StartsWith(OneQuote)
&&
convertedFormula.EndsWith(OneQuote))

{

convertedFormula
=
convertedFormula.Substring(
1
, (convertedFormula.Length
-
2
));

convertedFormula
=
convertedFormula.Replace(TwoQuotes, OneQuote);

}

}

catch
(Exception err)

{

convertedFormula
=
""
;

}


return
convertedFormula;

}
如果是写入到Visio的Cell的Formula中,那么要经过反过程,如下所示:

public
static
string
StringToFormulaForString(
string
input)

{

const
string
quote
=
"
\
""
;

string
result
=
""
;


if
(input
==
null
)

{

return
null
;

}


result
=
input.Replace(quote, (quote
+
quote));

result
=
quote
+
result
+
quote;


return
result;

}
2、获取指定形状指定Cell的值
。除了方法1,还有下面一种方法可以获取Cell的Value值。这种方法比使用Formula获取字符串的方式要好,是因为在Visio2007中下拉列表“资产归属”.对应的Cell的Value可能是INDEX(0,Prop.资产归属.Format),但是如果使用下面的方法就可以正常获取到它具体的值了。

public
static
string
GetShapeCellValue(Shape shapeTarget,
string
strCellType)

{

const
string
CUST_PROP_PREFIX
=
"
Prop.
"
;

string
shapeCellValue
=
string
.Empty;


if
(shapeTarget.get_CellExistsU(CUST_PROP_PREFIX
+
strCellType, (
short
)VisExistsFlags.visExistsAnywhere)
!=
0
)

{

shapeCellValue
=
FormulaStringToString(shapeTarget.get_CellsU(CUST_PROP_PREFIX
+
strCellType).get_ResultStr(VisUnitCodes.visNoCast));

}


return
shapeCellValue;

}
3、给指定的Shape赋值。
方法2是读取,当然还需要写入到指定Shape,指定Cell的值

public
static
bool
SetShapeCellValue(Shape shapeTarget,
string
strCellType,
string
cellValue)

{

const
string
CUST_PROP_PREFIX
=
"
Prop.
"
;

bool
breturn
=
false
;

if
(shapeTarget.get_CellExistsU(CUST_PROP_PREFIX
+
strCellType, (
short
)VisExistsFlags.visExistsAnywhere)
!=
0
)

{

shapeTarget.get_CellsU(CUST_PROP_PREFIX
+
strCellType
+
"
.Value
"
).Formula
=
StringToFormulaForString(cellValue);

}

return
true
;

}
4、判断形状某个属性是否存在。
有时候在做一些操作前,需要判断某个属性是否存在,以免访问指定的Cell不存在而抛出异常。

public
static
bool
ShapeCellExist(Shape shapeTarget,
string
strCellType)

{

const
string
CUST_PROP_PREFIX
=
"
Prop.
"
;

bool
breturn
=
false
;

if
(shapeTarget.get_CellExistsU(CUST_PROP_PREFIX
+
strCellType, (
short
)VisExistsFlags.visExistsAnywhere)
!=
0
)

{

breturn
=
true
;

}


return
breturn;

}
5、取当前操作属性所在的行。
Cell的行号有时候非常重要,因此有必要提供一个函数获取对应Cell在ShapeData中的行号。

public
static
int
GetCustomPropRow(Shape shapeTarget,
string
propName)

{

const
string
CUST_PROP_PREFIX
=
"
Prop.
"
;

int
intCustomRow
=
-
1
;

if
(shapeTarget.get_CellExistsU(CUST_PROP_PREFIX
+
propName, (
short
)VisExistsFlags.visExistsAnywhere)
!=
0
)

{

intCustomRow
=
shapeTarget.get_CellsRowIndexU(CUST_PROP_PREFIX
+
propName);

}


return
intCustomRow;
6、判断Visio图纸上是否有形状图元存在。
如果图纸上没有形状图元,你进行操作的时候可能会抛出“请求被禁用”的异常,因此可以操作前先判断有设备在图纸上为妙。

public
static
bool
HasShapeInWindow(Window window)

{

bool
result
=
false
;

try

{

window.SelectAll();

result
=
(window.Selection.Count
>
0
);

window.DeselectAll();

}

catch

{ ;}


return
result;

}
7、其他的一些功能设置

//
Visio2007的形状窗口中去除搜索形状功能

VisApplication.Settings.ShowShapeSearchPane
=
false
;


Visio2003的ShowShapeSearchPane实现方式


//
屏蔽Visio2007中的动态连接的功能(默认有)

VisApplication.Settings.EnableAutoConnect
=
false
;

VisApplication.Settings.StencilBackgroundColor
=
10070188
;
8、Name和NameU属性的差别
Visio中很多属性都有一个同名+U的属性名称,一般情况下最好使用这个名称如NameU,因此这个是一个唯一的名字,有时候你会发现Name相同,但他们就是不一样,因为他们的NameU名称不一样的。
9、遇到不明白的操作或者属性,多用Visio文档的宏记录功能,然后对VBA代码进行分析和调试。