C# 有没有办法在Excel工作簿对象上设置临时标志?
我有一个C#helper类(C# 有没有办法在Excel工作簿对象上设置临时标志?,c#,excel,vba,interop,C#,Excel,Vba,Interop,我有一个C#helper类(ExcelMacroHelper),它帮助将VBA宏代码注入打开的Excel工作簿并运行生成的宏。我刚刚意识到以下步骤会破坏我的代码: C#应用程序将宏代码注入活动工作簿,这会导致ExcelMacroHelper将其状态标记为准备运行宏 用户切换到Excel中的其他工作簿 C#应用程序尝试运行宏。ExcelMacroHelper将认为它已准备好运行宏,但VBA代码已插入到其他工作簿中,因此调用将失败 为了解决这个问题,我想我需要在工作簿对象上设置一个临时属性,表明我的
ExcelMacroHelper
),它帮助将VBA宏代码注入打开的Excel工作簿并运行生成的宏。我刚刚意识到以下步骤会破坏我的代码:
ExcelMacroHelper
将其状态标记为准备运行宏ExcelMacroHelper
将认为它已准备好运行宏,但VBA代码已插入到其他工作簿中,因此调用将失败工作簿
对象上设置一个临时属性,表明我的宏代码已被注入该对象,或者至少需要一种方法来维护已处理的工作簿
列表。有什么想法吗?您可以使用的属性
在注入代码时,可以执行以下操作:
public class ExcelMacroHelper
{
public static void Inject(Workbook workbook)
{
if ((workbook.Tag as String != "Injected"))
{
//Inject the code
workbook.Tag = "Injected";
}
}
}
private bool needToInjectMacroCode() {
// Get custom document property with name tagPropertyName
object properties, property, propertyValue;
properties = excel.ActiveWorkbook.GetType().InvokeMember(
"CustomDocumentProperties",
BindingFlags.Default | BindingFlags.GetProperty,
null, excel.ActiveWorkbook, null);
try {
property = properties.GetType().InvokeMember(
"Item",
BindingFlags.Default | BindingFlags.GetProperty,
null, properties, new object[] { tagPropertyName });
} catch (TargetInvocationException) {
return true;
}
propertyValue = property.GetType().InvokeMember(
"Value",
BindingFlags.Default | BindingFlags.GetProperty,
null, property, null);
return (tagString != (propertyValue as string));
}
// ...
private void setMacroCodeInjected() {
// Set custom property with name tagPropertyName to value tagString
object properties = excel.ActiveWorkbook.GetType().InvokeMember(
"CustomDocumentProperties",
BindingFlags.Default | BindingFlags.GetProperty,
null, excel.ActiveWorkbook, null);
try {
properties.GetType().InvokeMember(
"Add",
BindingFlags.Default | BindingFlags.InvokeMethod,
null, properties, new object[] {
tagPropertyName, false,
Office.MsoDocProperties.msoPropertyTypeString,
tagString
});
} catch (TargetInvocationException) {
object property = properties.GetType().InvokeMember(
"Item",
BindingFlags.Default | BindingFlags.GetProperty,
null, properties, new object[] { tagPropertyName });
property.GetType().InvokeMember(
"Value",
BindingFlags.Default | BindingFlags.SetProperty,
null, property, new object[] { tagString });
}
}
您可以使用名称来保存值(以及范围引用等) 伪码
if not (name already exists) then
Set nm = workbook.Names.add("Injected")
nm.Value = False
nm.Visable = False
end if
if nm.value = False
//Inject Code
nm.value = true
endif
注意:测试名称是否存在的最简单方法是尝试访问该名称,如果名称不存在,则处理错误。大概是这样的:
public class ExcelMacroHelper
{
public static void Inject(Workbook workbook)
{
if ((workbook.Tag as String != "Injected"))
{
//Inject the code
workbook.Tag = "Injected";
}
}
}
private bool needToInjectMacroCode() {
// Get custom document property with name tagPropertyName
object properties, property, propertyValue;
properties = excel.ActiveWorkbook.GetType().InvokeMember(
"CustomDocumentProperties",
BindingFlags.Default | BindingFlags.GetProperty,
null, excel.ActiveWorkbook, null);
try {
property = properties.GetType().InvokeMember(
"Item",
BindingFlags.Default | BindingFlags.GetProperty,
null, properties, new object[] { tagPropertyName });
} catch (TargetInvocationException) {
return true;
}
propertyValue = property.GetType().InvokeMember(
"Value",
BindingFlags.Default | BindingFlags.GetProperty,
null, property, null);
return (tagString != (propertyValue as string));
}
// ...
private void setMacroCodeInjected() {
// Set custom property with name tagPropertyName to value tagString
object properties = excel.ActiveWorkbook.GetType().InvokeMember(
"CustomDocumentProperties",
BindingFlags.Default | BindingFlags.GetProperty,
null, excel.ActiveWorkbook, null);
try {
properties.GetType().InvokeMember(
"Add",
BindingFlags.Default | BindingFlags.InvokeMethod,
null, properties, new object[] {
tagPropertyName, false,
Office.MsoDocProperties.msoPropertyTypeString,
tagString
});
} catch (TargetInvocationException) {
object property = properties.GetType().InvokeMember(
"Item",
BindingFlags.Default | BindingFlags.GetProperty,
null, properties, new object[] { tagPropertyName });
property.GetType().InvokeMember(
"Value",
BindingFlags.Default | BindingFlags.SetProperty,
null, property, new object[] { tagString });
}
}
这似乎正是我想要的,除了
工作簿
对象没有标记
属性(使用Office 2007)。@jnylen-这很奇怪。。。我刚刚启动了一个Office 2007工作簿项目(Visual Studio 2008),它有一个标记属性。我正在使用Microsoft.Office.Interop.Excel库和命名空间。似乎您正在使用VSTO Excel库。