如何使用 Excel Interop (VB.net) 获取 CustomDocumentProperties?
How to get CustomDocumentProperties using Excel Interop (VB.net)?
我有一个 Excel 文档,它是使用 Excel Interop 创建的,用 VB.net 编写。 Adapting information from this post,我能够成功创建工作簿并使用以下方法编写其 CustomDocumentProperties:
Dim objNewApp As Excel.Application
Dim objNewBook As Excel._Workbook
Dim objNewBooks As Excel.Workbooks
objNewApp = New Excel.Application With {
.DisplayAlerts = True,
.Visible = True,
.UserControl = True,
.ScreenUpdating = True
}
objNewBooks = objNewApp.Workbooks
objNewBook = objNewBooks.Add
Dim properties As Object = objNewBook.CustomDocumentProperties
Dim propertiesType As Type = properties.[GetType]()
Dim documentClient As Object() = {"Client", False, Core.MsoDocProperties.msoPropertyTypeString, "In-Progress"}
propertiesType.InvokeMember("Add", BindingFlags.InvokeMethod, Nothing, properties, documentClient)
但是,这个属性设置后我一直没能成功读取。在进行彻底搜索后,SO 以及 MSDN 上有关该主题的大多数帖子建议阅读 this missing MSDN article 以了解有关如何执行此操作的更多信息,并注意在 Interop 中这样做通常是多么愚蠢。但是,我在程序的其余部分使用 Interop,因此我想找到一个特定于 Interop 的解决方案(而不是 VSTO)。
Adapting from this post,我相信我目前的代码是在正确的轨道上:
Dim ReadClient As String = "Client"
Dim ObjReadClient = propertiesType.InvokeMember("Item", BindingFlags.GetProperty, Nothing, properties, New Object() {ReadClient})
Dim TypeReadClient As Type = ObjReadClient.GetType
Dim ClientString As String
ClientString = TypeReadClient.InvokeMember("Value", BindingFlags.GetProperty, Nothing, properties, New Object() {})
然而,当我 运行 收到一个 System.Runtime.InteropServices.COMException:
"Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))"
做更多的研究,这似乎是由于最后一行代码中的 "Value" 部分所致。我无法弄清楚从那里去哪里。
有人知道最后一块拼图吗?如果需要,我很乐意澄清任何事情!
这是针对我的特定问题的解决方案:
Dim ReadClientIndex As String = "Client"
Dim ReadClientValue As String
Dim ObjReadClient As Object = propertiesType.InvokeMember("Item", BindingFlags.GetProperty, Nothing, properties, New Object() {ReadClientIndex})
Dim TypeReadClient As Type = ObjReadClient.GetType()
ReadClientValue = TypeReadClient.InvokeMember("Value", BindingFlags.GetProperty, Nothing, ObjReadClient, New Object() {})
除了清理代码之外,问题是我应该在最后一行引用 "ObjReadClient" 作为参数——而不是之前设置的 "properties" 变量。
但是,由于在 VB.net 或 C# 中明显缺乏关于此主题的文档,以下是一些可能对未来用户有所帮助的资源:
Link 1: 原先在缺失的 MSKB 文章中提供的代码(用 C# 编写,在下面再次复制以供保存。):
Word.Application oWord;
Word._Document oDoc;
object oMissing = Missing.Value;
object oDocBuiltInProps;
object oDocCustomProps;
//Create an instance of Microsoft Word and make it visible.
oWord = new Word.Application();
oWord.Visible = true;
//Create a new Document and get the BuiltInDocumentProperties collection.
oDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing,
ref oMissing);
oDocBuiltInProps = oDoc.BuiltInDocumentProperties;
Type typeDocBuiltInProps = oDocBuiltInProps.GetType();
//Get the Author property and display it.
string strIndex = "Author";
string strValue;
object oDocAuthorProp = typeDocBuiltInProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.GetProperty,
null,oDocBuiltInProps,
new object[] {strIndex} );
Type typeDocAuthorProp = oDocAuthorProp.GetType();
strValue = typeDocAuthorProp.InvokeMember("Value",
BindingFlags.Default |
BindingFlags.GetProperty,
null,oDocAuthorProp,
new object[] {} ).ToString();
MessageBox.Show( "The Author is: " + strValue,"Author" );
//Set the Subject property.
strIndex = "Subject";
strValue = "The Subject";
typeDocAuthorProp.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.SetProperty,
null,oDocBuiltInProps,
new object[] {strIndex,strValue} );
//Add a property/value pair to the CustomDocumentProperties collection.
oDocCustomProps = oDoc.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
strIndex = "Knowledge Base Article";
strValue = "Q303296";
object[] oArgs = {strIndex,false,
MsoDocProperties.msoPropertyTypeString,
strValue};
typeDocCustomProps.InvokeMember("Add",BindingFlags.Default |
BindingFlags.InvokeMethod, null,
oDocCustomProps, oArgs );
MessageBox.Show("Select \"Properties\" from the File menu "
+ "to view the changes.\nSelect the Summary tab to view "
+ "the Subject property and the Custom tab to view the Knowledge"
+ "Base Article property.", "Check File Properties",
MessageBoxButtons.OK,MessageBoxIcon.Information);
Link 2:请注意,在 VB.net 中更容易完成,但 C# 将很快支持使用 "Dynamic"(10 年前编写)的后期绑定。我在某个地方找到了另一个 post,它解释了 "Dynamic" 作为 C# 答案的重要性,但无法再次找到它 link 到
Link 3:此信息是 Excel 所特有的,但我相信它可能对专门寻找它的人有所帮助。
Link 4:这给出了一个误认为VTSO和Interop的例子,可以帮助用户区分两者。
使用 C# 获取自定义属性是一种不同的方法。请检查这些 2.
没有为去重复制整个代码。
我有一个 Excel 文档,它是使用 Excel Interop 创建的,用 VB.net 编写。 Adapting information from this post,我能够成功创建工作簿并使用以下方法编写其 CustomDocumentProperties:
Dim objNewApp As Excel.Application
Dim objNewBook As Excel._Workbook
Dim objNewBooks As Excel.Workbooks
objNewApp = New Excel.Application With {
.DisplayAlerts = True,
.Visible = True,
.UserControl = True,
.ScreenUpdating = True
}
objNewBooks = objNewApp.Workbooks
objNewBook = objNewBooks.Add
Dim properties As Object = objNewBook.CustomDocumentProperties
Dim propertiesType As Type = properties.[GetType]()
Dim documentClient As Object() = {"Client", False, Core.MsoDocProperties.msoPropertyTypeString, "In-Progress"}
propertiesType.InvokeMember("Add", BindingFlags.InvokeMethod, Nothing, properties, documentClient)
但是,这个属性设置后我一直没能成功读取。在进行彻底搜索后,SO 以及 MSDN 上有关该主题的大多数帖子建议阅读 this missing MSDN article 以了解有关如何执行此操作的更多信息,并注意在 Interop 中这样做通常是多么愚蠢。但是,我在程序的其余部分使用 Interop,因此我想找到一个特定于 Interop 的解决方案(而不是 VSTO)。
Adapting from this post,我相信我目前的代码是在正确的轨道上:
Dim ReadClient As String = "Client"
Dim ObjReadClient = propertiesType.InvokeMember("Item", BindingFlags.GetProperty, Nothing, properties, New Object() {ReadClient})
Dim TypeReadClient As Type = ObjReadClient.GetType
Dim ClientString As String
ClientString = TypeReadClient.InvokeMember("Value", BindingFlags.GetProperty, Nothing, properties, New Object() {})
然而,当我 运行 收到一个 System.Runtime.InteropServices.COMException:
"Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))"
做更多的研究,这似乎是由于最后一行代码中的 "Value" 部分所致。我无法弄清楚从那里去哪里。
有人知道最后一块拼图吗?如果需要,我很乐意澄清任何事情!
这是针对我的特定问题的解决方案:
Dim ReadClientIndex As String = "Client"
Dim ReadClientValue As String
Dim ObjReadClient As Object = propertiesType.InvokeMember("Item", BindingFlags.GetProperty, Nothing, properties, New Object() {ReadClientIndex})
Dim TypeReadClient As Type = ObjReadClient.GetType()
ReadClientValue = TypeReadClient.InvokeMember("Value", BindingFlags.GetProperty, Nothing, ObjReadClient, New Object() {})
除了清理代码之外,问题是我应该在最后一行引用 "ObjReadClient" 作为参数——而不是之前设置的 "properties" 变量。
但是,由于在 VB.net 或 C# 中明显缺乏关于此主题的文档,以下是一些可能对未来用户有所帮助的资源:
Link 1: 原先在缺失的 MSKB 文章中提供的代码(用 C# 编写,在下面再次复制以供保存。):
Word.Application oWord;
Word._Document oDoc;
object oMissing = Missing.Value;
object oDocBuiltInProps;
object oDocCustomProps;
//Create an instance of Microsoft Word and make it visible.
oWord = new Word.Application();
oWord.Visible = true;
//Create a new Document and get the BuiltInDocumentProperties collection.
oDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing,
ref oMissing);
oDocBuiltInProps = oDoc.BuiltInDocumentProperties;
Type typeDocBuiltInProps = oDocBuiltInProps.GetType();
//Get the Author property and display it.
string strIndex = "Author";
string strValue;
object oDocAuthorProp = typeDocBuiltInProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.GetProperty,
null,oDocBuiltInProps,
new object[] {strIndex} );
Type typeDocAuthorProp = oDocAuthorProp.GetType();
strValue = typeDocAuthorProp.InvokeMember("Value",
BindingFlags.Default |
BindingFlags.GetProperty,
null,oDocAuthorProp,
new object[] {} ).ToString();
MessageBox.Show( "The Author is: " + strValue,"Author" );
//Set the Subject property.
strIndex = "Subject";
strValue = "The Subject";
typeDocAuthorProp.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.SetProperty,
null,oDocBuiltInProps,
new object[] {strIndex,strValue} );
//Add a property/value pair to the CustomDocumentProperties collection.
oDocCustomProps = oDoc.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
strIndex = "Knowledge Base Article";
strValue = "Q303296";
object[] oArgs = {strIndex,false,
MsoDocProperties.msoPropertyTypeString,
strValue};
typeDocCustomProps.InvokeMember("Add",BindingFlags.Default |
BindingFlags.InvokeMethod, null,
oDocCustomProps, oArgs );
MessageBox.Show("Select \"Properties\" from the File menu "
+ "to view the changes.\nSelect the Summary tab to view "
+ "the Subject property and the Custom tab to view the Knowledge"
+ "Base Article property.", "Check File Properties",
MessageBoxButtons.OK,MessageBoxIcon.Information);
Link 2:请注意,在 VB.net 中更容易完成,但 C# 将很快支持使用 "Dynamic"(10 年前编写)的后期绑定。我在某个地方找到了另一个 post,它解释了 "Dynamic" 作为 C# 答案的重要性,但无法再次找到它 link 到
Link 3:此信息是 Excel 所特有的,但我相信它可能对专门寻找它的人有所帮助。
Link 4:这给出了一个误认为VTSO和Interop的例子,可以帮助用户区分两者。
使用 C# 获取自定义属性是一种不同的方法。请检查这些 2.
没有为去重复制整个代码。