适用于:
Microsoft Visual Basic 2005
Microsoft Visual Basic for Applications
Microsoft Visual C# 2005
Microsoft Visual Studio 2005
Microsoft Visual Studio 2005 Tools for Microsoft Office System
Microsoft Office Excel 2003
Microsoft Office Word 2003
摘要:了解 C# 开发人员在使用 Visual Studio 2005 Tools for Office 创建 Word 和 Excel 应用程序时必须知晓的问题,包括如何使用以 VBA 为核心的方法和属性。参阅示例 — 比较 Visual Basic 与 C# 的代码。
注 本文是预发布版本的文档,在将来的版本中可能会有所更改。 Microsoft Visual Studio 2005 Tools for Microsoft Office System 测试版包含 Microsoft Visual Studio 2005 测试版。
简介 | |
向 Word 传递参数 | |
使用 Excel 处理可选参数 | |
使用 Word 处理可选参数 | |
使用 Excel 处理参数化属性 | |
在 Word 中使用访问器方法 | |
Word 中的晚期绑定 | |
小结 | |
其他资源 | |
关于作者 |
Microsoft Visual Studio 2005 Tools for Microsoft Office System (Visual Studio 2005 Tools for Office) 使您能够在 Microsoft Visual Studio 2005 中利用 Microsoft Office Word 2003 和 Microsoft Office Excel 2003 的强大功能来创建丰富的、基于 Microsoft Office 2003 的应用程序。您可以在 Microsoft Visual Basic 2005 或 Microsoft Visual C# 中利用 Word 和 Excel 对象模型提供的所有功能。尽管 Visual Basic 开发人员可以轻松使用由对象模型公开的对象,但 C# 开发人员还是可能会遇到困难。由于 Office 对象模型的历史和原始设计,创建其对象成员的意图在于,它们将由 Microsoft Visual Basic for Applications (VBA) 代码调用。因此,不同的属性和方法利用由 VBA 提供但不响应 C# 功能的功能。本文讨论的问题包括使用 Word 和 Excel 的以 VBA 为核心的方法和属性,并提供比较 Visual Basic 代码和相应的 Visual C# 代码的示例。
使用 Visual Studio 2005 Tools for Office 时,C# 开发人员必须了解 VBA 或 Visual Basic 开发人员无需考虑的问题。下表详细描述了本文中讨论的问题:
• | 传递参数。默认情况下,VBA 希望通过引用传递参数。默认情况下,Visual Basic 和 C# 均通过值传递参数。VBA 和 Visual Basic 对这一区别不作具体要求,Excel 的主 interop 程序集接受通过值传递的参数,尽管它最初接受通过引用从 VBA 代码传递的所有值。Word 的主 interop 程序集要求比较高;其参数(有几个例外)必须通过引用传递。Visual Basic 无需额外的工作即可处理此情况,但 C# 不能。 |
• | 可选参数。VBA 和 Visual Basic 支持方法调用的可选参数,但 C# 不支持。许多 Office 方法允许 20、30 或更多个可选参数,因此,C# 开发人员必须比 Visual Basic 开发人员编写更多的代码才能获得相同的效果。 |
• | 参数化属性。VBA 和 Visual Basic 支持接受参数作为只读功能的属性。由于 C# 不支持该种属性,因此必须使用访问器方法设置并检索接受参数的属性值。当使用接受 Variant 参数的方法时,Word 也存在这样的问题。 |
• | 晚期绑定。VBA 可以在运行时确定对象的属性,从而有效地提供代码与对象本身之间的晚期绑定。Word 在 Dialog 类中利用了该行为。Visual Basic 只能使用 Option Strict Off 指令处理晚期绑定。使用 Option Strict On 的 C# 开发人员和 Visual Basic 开发人员不能利用晚期绑定,并且必须使用替代的方法以编程方式与 Word Dialog 类交互。 |
要为 Visual Basic 和 C# 开发人员公开 Office 对象模型功能,Microsoft 创建了一组主 interop 程序集。Visual Studio 2005 Tools for Office 使用 Word 和 Excel 的单独主 interop 程序集,并且每个程序集都有其针对 Visual Basic 和 C# 开发人员的专门行为。本文下面的部分将讨论以上每一问题,说明 Word 和 Excel 主 interop 程序集如何处理每种情况,并提供代码示例以演示 C# 开发人员如何处理这里描述的每一种情况。
Word 对象模型提供的对象希望通过引用传递参数。尽管这对 Visual Basic 开发人员而言不是问题,但作为 C# 开发人员,当您向 Word 方法传递参数时必须格外小心。每个由 Word 提供的方法都希望它的每个方法通过 ref关键字进行传递,并且您只能通过引用传递 lvalues(即,在布局左侧出现的元素)。您不可以用 C# 代码向 Word 方法传递文字值。
作为一个简单的示例,以下过程从现有窗口创建一个新窗口,然后平铺这两个窗口。以下代码片段演示该代码的 Visual Basic 和 C# 版本。
' Visual Basic Friend Sub CreateNewWindowAndTile() ' Create a new window from the active document. Dim wnd As Word.Window = _ Application.ActiveWindow.NewWindow ' Tile the two windows. Application.Windows.Arrange( _ Word.WdArrangeStyle.wdTiled) End Sub // C# public void CreateNewWindowAndTile() { // Create a new window from the active document. Word.Window wnd = Application.ActiveWindow.NewWindow(); // Tile the two windows. Object value = Word.WdArrangeStyle.wdTiled; Application.Windows.Arrange(ref value); }
在该示例中,代码创建了一个 Object 变量,并为其分配了一个值。然后,代码使用 ref关键字向Arrange 方法传递该变量。您必须以相同的方式调用 Word 中的每个方法;每个参数必须使用 ref关键字传递,并且必须传递包含实际值的变量。
注 面向 Excel 的 C# 开发人员不需要采取这些特殊的步骤。 Excel 的主 interop 程序集已经创建了,这样就可以正确地处理按值传递给不同成员的文字值。
在其他支持可选参数的语言中,VBA 中的可选参数必须出现在方法调用列表的结尾,并且在参数标记为可选后,参数的其余部分也必须为可选。Excel 提供的许多方法都接受可选参数;Visual Basic 开发人员可以忽略这些参数并接受它们的默认值。
例如,Workbooks.Add 方法允许您指定可选参数来表示要使用的模版。可以指定模版文件的名称或 XlWBATemplate 常数的成员,来表示您希望新工作簿包含的表单类型;也可以不提供值(创建一个具有空表单的工作簿)。如果选择不提供值(接受默认行为),您可以编写以下代码。
' Visual Basic Dim wb As Excel.Workbook = Application.Workbooks.Add()
但是,由于缺少的参数,C# 中的代码不进行编译。要解决该问题,需要传递可选参数的 System.Type.Missing 字段。如果使用 Visual Studio 2005 Tools for Office 创建一个项目,那么您可以使用名为 missing 的预定义变量,该变量包含 System.Type.Missing 值以保存某些类型。
// C# Excel.Workbook wb = Application.Workbooks.Add(System.Type.Missing); // or Excel.Workbook wb = Application.Workbooks.Add(missing);
当 Visual Basic 开发人员使用反射动态创建对接受可选参数的方法进行的方法调用时,System.Type.Missing 很有用。它表示您希望使用指定参数的默认值。当然,您可以自己阅读 Excel 文档,找到默认值并显式传递该值。
如果 Excel 方法需要多个可选参数,您会发现,用 C# 编写代码比编写相应的 Visual Basic 代码更耗费精力。例如,以下代码片段比较了 Visual Basic 代码与 C# 代码。Workbooks.Open 方法允许您指定几个可选参数,表示您要打开的工作簿的行为。
' Visual Basic Dim wb As Excel.Workbook = _ Application.Workbooks.Open("C:/YourPath/YourWorkbook.xls") // C# Excel.Workbook wb = Application.Workbooks.Open( "C:/YourPath/YourWorkbook.xls", missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
您只可以传递接受引用类型的参数的 System.Type.Missing 值。对于值类型参数,需要确定并传递实际的默认值。例如 Range.Sort 方法,它接受许多枚举值作为参数。作为值类型参数,它们要求您明确指定要传递的值。
' Visual Basic ' rng is a variable of type Excel.Range. rng.Sort(rng, _ orientation:=Excel.XlSortOrientation.xlSortColumns) // C# // rng is a variable of type Excel.Range. rng.Sort(rng, Excel.XlSortOrder.xlAscending, missing, missing, Excel.XlSortOrder.xlAscending, missing, Excel.XlSortOrder.xlAscending, Excel.XlYesNoGuess.xlNo, missing,missing, Excel.XlSortOrientation.xlSortColumns, Excel.XlSortMethod.xlPinYin, Excel.XlSortDataOption.xlSortNormal, Excel.XlSortDataOption.xlSortNormal, Excel.XlSortDataOption.xlSortNormal);
您可能会觉得奇怪,为什么 C# 不支持可选参数。相反,C# 和 Visual Basic 都支持方法重载,这样您可以创建单一过程的多个“版本”,传递不同的参数集。重载方法的主要局限在于:每个单独方法的参数符号必须是不同的;编译器必须能够根据您所调用的参数,确定您调用的是哪个版本的过程。该功能比 VBA 对可选参数的支持更加强大和灵活。
Visual Basic 包含可选参数,因为 Visual Basic 和 VBA 已经在若干版本中包含了此功能。但是,对于您现在编写的代码而言,使用重载比使用可选参数更有益。为了提高成为最佳代码的可能性,C# 设计人员使用了重载,而不是支持可选参数。在一般的编码中,您可能不会注意到 C# 并不具备该功能。只有在针对对象模型(如 Office 所提供的对象模型)编程时,您才会注意到 C# 中缺少可选参数,原因是在该模型中,许多成员会利用可选参数并使用大量可选参数。
在一些情况下,您可能会发现创建内置方法的包装方法很有用。例如,Excel WorksheetFunction 类公开了一大组函数(其初衷是在工作表上使用),它们提供对统计、财务以及其他类型与工作表相关的功能的支持。WorksheetFunction 类的多数方法可以接受 30 个参数,其中有一两个是所需的参数。从 C# 调用这些方法很复杂,如下示例,它调用指定的 Excel Range 对象的 WorksheetFunction.Min 方法。
' Visual Basic MessageBox.Show(Application.WorksheetFunction.Min(rng)) MessageBox.Show(Application.WorksheetFunction.Max(rng)) // C# MessageBox.Show(Application.WorksheetFunction.Min(rng, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing).ToString()); MessageBox.Show(Application.WorksheetFunction.Max(rng, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing).ToString());
对于上述情况,您可以考虑创建一种能调用现有方法的包装方法,从而免于计算和跟踪所有的可选参数。
// C# private delegate double WorksheetFunctionDelegate( object value1, object value2, object value3, object value4, object value5, object value6, object value7, object value8, object value9, object value10, object value11, object value12, object value13, object value14, object value15, object value16, object value17, object value18, object value19, object value20, object value21, object value22, object value23, object value24, object value25, object value26, object value27, object value28, object value29, object value30); private double CallWorksheetFunction( WorksheetFunctionDelegate func, Object value, params object[] values) { // All the values except the first one. object[] overflowParameters = new object[29]; values.CopyTo(overflowParameters, 0); for (int i = values.Length; i < overflowParameters.Length; i++) { overflowParameters[i] = missing; } return func ( value, overflowParameters[0], overflowParameters[1], overflowParameters[2], overflowParameters[3], overflowParameters[4], overflowParameters[5], overflowParameters[6], overflowParameters[7], overflowParameters[8], overflowParameters[9], overflowParameters[10], overflowParameters[11], overflowParameters[12], overflowParameters[13], overflowParameters[14], overflowParameters[15], overflowParameters[16], overflowParameters[17], overflowParameters[18], overflowParameters[19], overflowParameters[20], overflowParameters[21], overflowParameters[22], overflowParameters[23], overflowParameters[24], overflowParameters[25], overflowParameters[26], overflowParameters[27], overflowParameters[28]); }
然后,要调用接受一个所需参数的工作表函数,您可以编写以下代码。
WorksheetFunctionDelegate func = new WorksheetFunctionDelegate( Application.WorksheetFunction.Min); MessageBox.Show( CallWorksheetFunction(func, rng, missing).ToString());
您即可以扩展该功能以支持多个所需参数,也可以使用 C# params关键字。
提示 Visual Studio 2005 Tools for Office 文档包含的示例包括一些常用成员的帮助器方法。在这些示例中,找到标题中带有单词 “helper” 的区域或类。您可以使用这些方法作为自己的方法集的开始,这样就可以更容易地调用 Word 和 Excel 提供的方法。
如果在 Word 中使用可选参数,那么需要您考虑的问题与在 Excel 中使用可选参数时需要考虑的问题一样。您可能会发现自己编写的代码与以下代码片类似,这段代码将在 Visual Basic 中打开的 Word 文档与在 C# 中打开 Word 文档进行比较。
' Visual Basic Application.Documents.Open("C:/Test/MyNewDocument.doc") // C# Object filename = @"C:/Test/MyNewDocument.doc"; Application.Documents.Open(ref filename, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);
通常,从 C# 调用 Word 方法比调用相似的 Excel 方法更复杂,因为您必须按引用传递大多数参数。如果需要频繁地调用这样的方法,您会发现使用由 Visual Studio 2005 Tools for Office 项目模版创建的 missing 变量很有用。
您经常需要引用 Word 中的范围。在 Visual Basic 中,指定不带任何参数的 Range 属性会返回整个范围;如果要使用文档的整个内容,无需指定起始和结束值。当然,对 C# 开发人员而言并非如此,因为在 C# 中,必须经常为所有可选参数传递值。在 C# 中,您可以为所有可选参数传递 System.Type.Missing 以设定默认值,如以下代码片段所示。
' Visual Basic Dim rng As Word.Range = ThisDocument.Range() rng.Select() // C# Word.Range rng = ThisDocument.Range(ref missing, ref missing); rng.Select();
Excel 中的许多属性允许您传递参数,指示您希望与之交互的属性的特定实例。例如,您可以通过将命名范围作为字符串传递来指定一个 Range 对象。您也可以通过传递左上角单元格名称和右下角单元格名称指定一个范围。您必须至少指定一个参数(一个命名范围),也可以指定两个(两个单元格名称)。在每种情况中,属性都返回一个与指定范围相对应的 Excel.Range 对象。
在 Visual Basic 中,您可以编写如下所示的代码,指定并检索对 Range 对象的引用。
' Visual Basic Dim rng1 As Excel.Range = Application.Range("TotalSales") ' or Application.Range("A1", "B2").Font.Bold = True
C# 不支持此类属性引用 — 在 C# 中,只有参数指定了一个索引,属性引用才可以拥有参数。为了突破这一限制,Excel 主 interop 程序集为每个参数化属性提供了访问器 get/set 方法。例如,要使用 C# 检索对 Excel Range 对象的引用,可以重写前面的代码,如以下示例所示。
// C# Excel.Range rng1 = Application.get_Range("TotalSales", missing); // or Application.get_Range("A1", "B2").Font.Bold = true;
请注意,您必须向 get_Range 方法传递两个参数,因为 Excel 中的 Application.Range 属性需要一个参数以及另一个可选参数。
相同的问题也适用于 Range 对象的 Offset 属性;该参数化属性允许您检索指定数目的行和/或列(从左上角开始的一个范围)。以下代码片段演示如何在 Visual Basic 和 C# 中检索属性。
' Visual Basic Private Sub ListRecentFiles() Dim i As Integer Dim rng As Excel.Range = DirectCast( _ Application.Range("RecentFiles"). _ Cells(1, 1), Excel.Range) For i = 1 To Application.RecentFiles.Count rng.Offset(i - 1, 0).Formula = _ Application.RecentFiles(i).Name Next End Sub // C# private void ListRecentFiles() { Excel.Range rng = (Excel.Range)Application. get_Range("RecentFiles", missing).Cells[1, 1]; for (int i = 1; i <= Application.RecentFiles.Count; i++) { rng.get_Offset(i - 1, 0).Formula = Application.RecentFiles[i].Name; } }
提示 Range.Cells 属性看起来像是一个参数化属性,但其实不是。Cells 属性返回一个数组,您可以通过传递行列号的值来检索数组。
如果要使用 Excel 提供的多种文件处理对话框,您需要再次使用 get_FileDialog 访问器方法。因为 Application.FileDialog 属性有一个参数,所以它在 C# 中不直接可用。要突破该限制,可以调用 get_FileDialog,如以下代码片段所示。
' Visual Basic With Application.FileDialog( _ Office.MsoFileDialogType.msoFileDialogFolderPicker) If .Show <> 0 Then Application.Range("FolderPickerResults"). _ Formula = .SelectedItems.Item(1) End If End With // C# dlg = Application.get_FileDialog( Office.MsoFileDialogType.msoFileDialogFolderPicker); if (dlg.Show() != 0) { Application.get_Range("FolderPickerResults", missing). Formula = dlg.SelectedItems.Item(1); }
Excel Range.Value 属性还需要特殊的处理。该属性接受一个参数,但当 C# 设置或检索属性值时不接受参数。在本例中,您必须使用 Value2 属性,这是不需要参数的原始属性的一种变体。例如,以下代码片段显示相同作用的 Visual Basic 和 C# 代码。
' Visual Basic Dim rng As Excel.Range = Application.Range("A1") rng.Value = "Some Value" // C# Excel.Range rng = Application.get_Range("A1", missing); rng.Value2 = "Some Value";
本文显示使用 Range、Offset、Value 和 FileDialog 属性的一些示例;您还可以使用其他许多属性。如果不能直接检索或设置属性值,那么您要查看一下属性是否需要一个参数,如果是,则寻找相应的访问器方法或替换的属性。
尽管 Word 通常不使用参数化属性(像 Excel 一样),但在 Word 中编程时,还有一些情况需要使用 get_ 和 set_ 访问器方法。Word 处理这些方法的情况与 Excel 稍有不同;但在本示例中,访问器方法是隐藏的。当您键入时,不能在可用方法列表中找到它们,也不能在对象浏览器窗口中找到它们。您必须知道它们的确定位置并使用它们。
例如,Word 中的 Style 属性返回并接受 Variant 值,而不是将其转换为 Object 类型以便在 C# 中使用,您必须调用 get_Style 和 set_Style 方法以解决该问题。需要编写以下代码,从而为特定段落设定样式。
' Visual Basic Dim rng As Word.Range = _ ThisDocument.Paragraphs(1).Range rng.Style = "Normal Indent" // C# Word.Range rng = ThisDocument.Paragraphs[1].Range; Object style = "Normal Indent"; rng.set_Style(ref style);
对于 Word 中的其他方法,您必须按引用传递样式名称(或 Style 对象),这需要使用包含所需值的变量。您可以使用相似的代码检索一个范围的 Style 属性,从而调用 get_Style 方法。
Word 中的 Item 方法存在相同的问题。Word 主 interop 程序集公开一个按引用接受 Object 参数的 get_Item 方法,而不是让您向该方法传递一个 Variant 参数。如果要在当前的 Documents 集合内保存特定文档,您可以编写以下代码。
' Visual Basic Application.Documents("MyNewDocument.doc").Save() // C# Object file = "MyNewDocument.doc"; Application.Documents.get_Item(ref file).Save();
规则很简单:对于任何接受 Variant 参数的方法或任何参数化属性而言,需要假定有一个访问器方法(或一对方法)可用。
由于 Word 编程模型已经有一段较长的历史,因此其中某些技术不适用于面向对象的强类型编程。其中之一就是 Dialog 类。该类提供了一组基本的属性和方法,以及一个包含 Word 用户界面中所有可用对话框的数组。您可以显示任何对话框,或者只需使用由对话框公开的不同属性来影响 Word 的行为。例如,您使用 Page Setup 对话框来配置当前文档的页面宽度和高度。
问题在于,Word 对象实际上不包含有关每个指定对话框的信息。对话框有许多属性,对话框模型在您加载每个对话框时“动态”创建这些属性,而不是在类型库(现在为主 interop 程序集)中为 Word 硬编码这些属性。基本上,每个对话框中的每个控件都有一个对应的属性,您可以以编程方式设置或检索每个控件的值。在 VBA 中,这不是问题。尽管您不能使用 Microsoft 智能感知提示来帮助您输入代码,但是您仍可以引用不同的属性并且代码仍可以编译。
在 Visual Basic(启用 Option Strict)或 C# 中并非如此。在强类型语言中,如果要在编写代码时使用标准 Object.Property 语法,那您就别指望编译器会放弃可用的属性(一直到编译时)。例如,Visual Basic 利用 Option Strict Off 可对代码进行编译,但相应的 C# 代码却不能编译。
' Visual Basic with Option Strict Off Dim dlg As Word.Dialog dlg = Application.Dialogs( _ Word.WdWordDialog.wdDialogFilePageSetup) dlg.PageWidth = 3.3 dlg.PageHeight = 6 // C# (This does not compile.) dlg = Application.Dialogs [Word.WdWordDialog.wdDialogFilePageSetup]; dlg.PageWidth = 3.3; dlg.PageHeight = 6;
使用这些属性有两种选择。可以创建一个在顶部包含 Option Strict Off 设置的 Visual Basic 文件,并将代码放在该文件中;也可以采取一种方法执行晚期绑定。C# 和 Visual Basic 开发人员可以使用 System.Reflection 命名空间,这样就允许运行的代码确定指定类型的可用成员,并执行某一类型的晚期绑定。有了成员信息,代码就可以使用 System.Reflection 命名空间来调用属性设置过程,例如,设置一个属性值。
要在 Visual Basic 或 C# 中处理晚期绑定对象,可以针对 System.Reflection 命名空间的功能添加一个简单的包装,以设置对象(只有在运行时才能知道该对象的功能)的属性。
' Visual Basic Private Sub InvokeHelper(ByVal dlg As Word.Dialog, _ ByVal member As String, ByVal dlgValue As Object) Dim dlgType As Type = GetType(Word.Dialog) dlgType.InvokeMember(member, _ BindingFlags.SetProperty or _ BindingFlags.Public or BindingFlags.Instance, _ Nothing, dlg, New Object() {dlgValue}) End Sub // C# private void invokeHelper(Word.Dialog dlg, string member, Object dlgValue) { // Assumes a using statement in the file: // using System.Reflection; Type dlgType = typeof(Word.Dialog); dlgType.InvokeMember(member, BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null, dlg, new object[] {dlgValue.ToString()}); }
要使用 InvokeHelper 方法,可以传递 Dialog 对象、要设置的属性,以及该属性的值。
' Visual Basic Public Sub HiddenPageSetupDialog() Dim dlg As Word.Dialog dlg = Application.Dialogs( _ Word.WdWordDialog.wdDialogFilePageSetup) InvokeHelper(dlg, "PageWidth", 3.3) InvokeHelper(dlg, "PageHeight", 6) dlg.Execute() End Sub // C# public void HiddenPageSetupDialog() { Word.Dialog dlg; dlg = Application.Dialogs[ Word.WdWordDialog.wdDialogFilePageSetup]; invokeHelper(dlg, "PageWidth", 3.3); invokeHelper(dlg, "PageHeight", 6); dlg.Execute(); }
Word 和 Excel 公开了丰富的编程模型,但这些对象模型最初都是为了供 VBA 用户使用而编写的。Visual Basic(即使 Option Strict On)可以处理大多数 Office 对象模型的要求。在 C# 中使用这些对象模型需要格外小心。使用 Visual Studio 2005 Tools for Office 和 C# 编写应用程序时需要记住,您经常需要对不同语言间的差异作出让步,注意可选参数、参数化属性、Variant 参数,以及晚期绑定。在了解了可能遇到的问题类型之后,您会觉得编写与 Office 交互的 C# 代码和编写 Visual Basic 代码的难度相差无几。
Visual Studio 2005 Tools for Office
• | Visual Studio Tools for Office |
• | Microsoft Visual Studio 2005 Tools for Microsoft Office System (VSTO2005) Redistributable Package Beta 2 (x86) |
• | 网络日记:Microsoft Visual Studio 2005 Tools for Microsoft Office System |
• | Visual Studio Tools for Office 新闻组:microsoft.public.vsnet.vstools.office |
Office 开发人员中心
• | Office 开发人员中心 |
• | Office开发人员中心:Visual Studio Tools for Microsoft Office System |
Ken Getz 身兼开发人员、作家以及培训师之职,并且是一位 MCW Technologies, LLC(Microsoft 解决方案提供商)的高级咨询师。他与别人合著有几本针对开发人员的技术书籍,包括畅销的 ASP.NET Developer's Jumpstart、Access Developer's Handbook 系列丛书,以及 VBA Developer's Handbook 系列丛书。Ken 与别人联合制作了 AppDev 的 C#、ASP.NET、Visual Basic .NET 和 ADO.NET 课件。Ken 是 Advisor Publications' VB.NET Technical Journal 的技术编辑,并且是 MSDN Magazine 和 CoDe 杂志的专栏作家。Ken 经常在举办专业领域的活动时发表演讲,包括 Advisor Media's Advisor Live 活动、FTP's VSLive、DevConnection's VS Connection 和 ASP Connection,以及 Microsoft Tech-Ed。