Excel 脚本编写

来源:互联网 发布:一淘和淘宝客同时返利 编辑:程序博客网 时间:2024/05/21 14:05
本页内容
使用 Excel:快速回顾 使用 Excel:快速回顾 将数据添加到电子表格中 将数据添加到电子表格中 Excel 中的格式设置 Excel 中的格式设置 使用范围 使用范围 数据排序 数据排序 哦,真的是这样:从 Active Directory 中提取数据 哦,真的是这样:从 Active Directory 中提取数据 就这些吗? 就这些吗?

我猜测当您自称为 Microsoft Scripting Guy 并撰写名为脚本编写门诊 (Scripting Clinic) 的专栏时,人们认为您的生活被脚本包围就不足为奇了。而实际上,在工作之外我并没花太多的时间研究脚本编写。譬如,我从来不阅读关于脚本编写的书;相反,我喜欢读 Brian Greene 所著的The Fabric of the Cosmos 这类的书,这是一本很吸引人的书,讲述的是量子力学、弦论和其他一些我一点都不懂的东西。

:唯一的例外是这本书讨论薛定鄂猫 (Schr?dinger's cat) 的部分。薛定鄂 (Edwin Schr?dinger) 是一个物理学家,他提出了下述思想实验:将猫放在一个完全封闭的盒子里,其中释放的放射性气体有 50% 的几率杀死猫。薛定鄂的命题是,如果您实际上没有向盒中看一看,那么这只猫既不是死的也不是活的,而是处于某种不确定的状态。我理解这种理论,因为我敢肯定,当我们还是小孩时,我们都曾拥有 过薛定鄂猫。只不过对于我们的猫,即使您真地 看一看它,您也不知道它是死是活,或许它根本就不是薛定鄂猫。

顺便说一句,如果您想知道那只猫现在正做什么,嗯,这是很难讲的。

现在我读到 Greene 讨论“时间之箭 (time's arrow)”这一部分。显然,许多物理学家不明白为什么时间的流逝是那么的悄无声息,而其倒退却是如此之难;甚至爱因斯坦也觉得过去、现在和将来并没有什么不同。(从我已经经历过的来看,他的观点可能是正确的。)

您大概想到了,当您读到时间之箭时,您可能会不由自主地思考一些问题。您会考虑宇宙的性质,您也会考虑时间旅行所涉及的道德和伦理问题,您还会想,“在上个月的专栏中,我们告诉人们如何使用脚本从 Microsoft Excel 电子表格中提取数据,并使用这些数据在 Microsoft Active Directory 中创建用户帐号。如果时光可以倒流,我就想知道这一过程是否也可以逆转。我想知道脚本是否可以从 Active Directory 中提取数据并用这些数据填充Excel电子表格。”

如您所料,我周围的每个人都说我是疯子(在我提到这个观念之前 就已经这样了)。因此我决定回到 1905 年,去问一问爱因斯坦,他是否认为您可以使用脚本将数据写入 Excel。毕竟,我不想在这个专栏里欺骗我自己。遗憾的是,爱因斯坦走在我的前面,我们彼此错过了。(我在他的应答机上留了言,但是那时电话应答机还没有发明,我不能确定什么时候能得到答复。)因此我决定,“究竟是怎么回事儿啊?让我试一试,看看到底会发生什么。如果这条路终究行不通,我就及时撤回来,并在专栏张贴到 MSDN 之前将其删除掉。”所以,如果您不能立刻读到这个专栏,就知道这是为什么了。

使用 Excel:快速回顾

上个月,我们学习了如何编写脚本来从 Excel 电子表格提取数据。(如果您想不起上个月的专栏,您可以及时地返回去,也可以单击此处。)在该专栏中,我们指出了仅仅使用下面两行代码就能够创建 Excel 实例:

Set objExcel = CreateObject("Excel.Application")objExcel.Workbooks.Add

当然,这是薛定谔电子表格的一个例子:在您看见之前,您不能确定它是否真的是 电子表格。这是因为,在默认情况下,您任何时候创建的 Excel 实例都运行在不可见的窗口之中。要实际地看一看 Excel 实例,您需要将 Visible 属性设置为 TRUE,如下所示:

Set objExcel = CreateObject("Excel.Application")objExcel.Workbooks.AddobjExcel.Visible = True

这三行代码在屏幕上显示一个空白的电子表格。这本身是非常令人兴奋的,但如果该电子表格实际上包含一些数据就更令人兴奋了。根据量子力学,电子表格的原子自发重排以显示有意义的数据还是有可能的。不过,我们还是不要等待这种可能性了,让我们看一看依靠自己的力量是否能够将有意义的数据添加到电子表格中。

返回页首返回页首

将数据添加到电子表格中

当电子表格关闭时,您可以很容易地将数据添加到电子表格中,而不用重排所有的原子:首先您简单地引用一个单元格,然后相应地设置值。例如,假设我们想要将单词 Schr?dinger 输入第一行第一列。试一试下面的脚本,看看会发生什么:

Set objExcel = CreateObject("Excel.Application")objExcel.Visible = TrueobjExcel.Workbooks.AddobjExcel.Cells(1, 1).Value = "Schr?dinger"

当您运行这个脚本时,您会看到类似于这样的输出:


1. 将数据写入 Excel 电子表格

哈哈,很酷吧!如果您想要添加其他的数据,我们只需要多引用几个单元格并且设置合适的值就可以了。例如,下面的脚本将四个著名物理学家的名字添加到我们的电子表格中:

Set objExcel = CreateObject("Excel.Application")objExcel.Visible = TrueobjExcel.Workbooks.AddobjExcel.Cells(1, 1).Value = "Schr?dinger"objExcel.Cells(1, 2).Value = "Bohr"objExcel.Cells(1, 3).Value = "Heisenberg"objExcel.Cells(1, 4).Value = "Einstein"

当您运行这个脚本时,您会看到类似于这样的输出:


2. 将数据写入 Excel 电子表格中的多个单元格

现在,真的非常酷……!嗯,不错,您真行!但这还不 够,是吗?可以将数据添加到电子表格是一件了不起的事哦,不过,让我们考虑一下这个问题。我们为什么愿意在 Excel 中显示数据而不愿意在命令窗口中显示数据或将其保存到文本文件中呢(编写系统管理脚本最常使用后两种方法)?我们之所以愿意这么做,最可能的原因并不是选择这两种方法会让您花大量的精力去安排数据的格式。至少我们可以说将数据输出到命令窗口或保存到文本文件会缺少某种美感。这就是我们愿意使用 Excel 的原因;Excel 使您能够创建格式漂亮、易于阅读的输出。但是在这里我们还无法保证有格式漂亮的输出;毕竟,您可能连 Schr?dinger 或 Heisenberg 这样的名字都读不到。因此,在进一步讨论之前,让我们来一个量子跃迁,谈一谈 Excel 中的格式设置。

返回页首返回页首

Excel 中的格式设置

如果您曾经使用过 Excel,您就知道在 Excel 中设置格式是多么的容易:您只需选择一两个单元格,然后就可以应用某种格式了(更改字体大小、更改单元格的背景颜色、将文本设置为黑体等等,想做什么都可以)。在程序化地使用 Excel 时,您也可以做同样的事情。例如,仅仅通过使用一些设置格式的命令,您就可以设置活动单元格(您正在输入的单元格)的格式。下面的脚本将单词 Schr?dinger 输入第一行第一列的单元格中,然后:

将文本设为黑体(通过将 Bold 属性设置为 TRUE)。

将字体大小设为 24(通过将 Size 属性设置为 24)。

将字体颜色设为红色(通过将 ColorIndex 属性设置为 3)。

Set objExcel = CreateObject("Excel.Application")objExcel.Visible = TrueobjExcel.Workbooks.AddobjExcel.Cells(1, 1).Value = "Schr?dinger"objExcel.Cells(1, 1).Font.Bold = TRUEobjExcel.Cells(1, 1).Font.Size = 24objExcel.Cells(1, 1).Font.ColorIndex = 3

当您运行这个脚本时,您会看到如下所示的输出:


3. 将带格式的数据写入 Excel 电子表格

屏住呼吸,怎么样?

最好的是除了 ColorIndex 属性略显复杂之外(等一会儿我们将讨论它),这段代码是非常简单的。如果想要将文本设为斜体该怎么办?可以使用下面这行代码:

objExcel.Cells(1, 1).Font.Italic = TRUE

如果想要使用 Times New Roman 字体该怎么办?可以使用下面这行代码:

objExcel.Cells(1, 1).Font.Name = "Times New Roman"

:遗憾的是,我们没有时间全面介绍您在处理时会使用的许多格式设置选项。不过,您将此处找到一些非常好的关于 Excel 对象模型的信息。

好的,但 ColorIndex 属性又怎么样呢?虽然在 Excel 中有两种不同的方法更改颜色,但 ColorIndex 可能是最简单的(它还可以告诉您一些关于其他方法的内容)。在 Excel 中,有 56 种内置的颜色(索引号 1–56)可供您使用;您必须做的事情就是将 ColorIndex 属性的值设置为期望的索引号。唯一的问题就是:您如何知道索引号 3 是红色,而索引号 4 是您真正感兴趣的绿色阴影呢?

这个问题提得好。我粗略地搜索了一下 MSDN,却没有找到这些索引号的文档。但是没关系,下面这个简单的小脚本会向您显示所有的 56 个索引号都代表什么颜色:

Set objExcel = CreateObject("Excel.Application")objExcel.Visible = TrueobjExcel.Workbooks.AddFor i = 1 to 56    objExcel.Cells(i, 1).Value = i    objExcel.Cells(i, 1).Interior.ColorIndex = iNext

当您运行这个脚本时,您会看到如下所示的输出:


4. Excel ColorIndex 值

您可以看出,如果您想要将字体颜色设置为清绿色,则只需将 ColorIndex 设置为 8 就行了。

顺便提一句,如果您仔细地看过了前面的脚本,您现在就会知道如何设置单元格的背景颜色:只需使用 Interior.ColorIndex 属性就行了。例如,要将单元格的颜色设置为红色,可以使用下面的代码:

objExcel.Cells(1, 1).Interior.ColorIndex = 3

在我看来,您到现在还不知道这回事确实 是个奇迹。

在继续讨论之前,先来为我们的格式设置脚本做另外一件事。您可能会想得起来,我们的测试脚本向我们显示以下所示的输出:


5. 将带格式的数据写入 Excel 电子表格

问题在哪里?嗯,首先单词 Schr?dinger 并没有全部显示在第一列中。那好,如果我们在第一行第二列中输入一些内容会怎么样呢?我们会看到类似于这样的输出:


6. Excel 电子表格中大小设置不正确的列

没有正确地得到我们所希望的输出类型。显然,我们需要做的是将第一列加宽一点。但怎么做呢?

返回页首返回页首

使用范围

非常高兴您问这个问题,因为现在是讨论范围的时候了。到此为止,我们还只是设置了活动单元的格式,为其更改字体大小、单元格颜色等等。然而,有时您需要使用多个单元格。或许您想要更改特定行中所有单元格的字体大小。或许您想要对您收集的所有数据进行排序。或许,和下面的例子一样,您想要重新设置整个列的大小。如果这样,您就需要使用范围,一组 指定的单元格。

虽然有几种不同的方法指示范围中包含的单元格,但是它们有一点是共同的:它们都需要您创建 Range 对象的实例,然后 指定哪些单元格是该范围的一部分。例如,下面是一些创建范围的常用方法。

要创建包含单个单元格的范围:

Set objRange2 = objExcel.Range("A1")

要创建包含整个列的范围:

Set objRange = objExcel.ActiveCell.EntireColumn

正如您所期望的,有相似的命令来创建包含整个行的范围:

Set objRange = objExcel.ActiveCell.EntireRow

如果您想要选择的行或列不同于带有活动单元格的行或列怎么办?没问题。使用所需的行或列中的一个单元格来创建范围,然后使用 Activate 方法来使其成为活动单元格。此时,设置代表整个行或列的范围。例如,下面这段代码使单元格 E5 成为活动单元格,然后通过选择整个行来创建包含第 5 行中的所有单元格的范围:

Set objRange = objExcel.Range("E5")objRange.ActivateSet objRange = objExcel.ActiveCell.EntireRow

要创建包含一组单元格的范围:

Set objRange = objExcel.Range("A1:C10")

注意,您在这里做的是指定起点 (A1) 和终点 (C10)。Excel 会自动选择这两个点之间的所有单元,并把它们放在范围之中。

要创建包含所有数据的范围:

Set objCell = objExcel.Range("A1").SpecialCells(11)

在这个例子中,11 是表示包含数据的电子表格中最后的单元格的参数。这个命令所创建的范围从单元格 A1 开始一直延伸到所有包含数据的单元格。

为了进行演示,让我们再看一下前面的脚本,看看我们是否能够使它变得更漂亮一点。在这个经过修改的脚本中,我们将把物理学家的名字放在单列(而不是单行)中,并且我们将给该列加上粗体标签 (Name)。然后,仅仅是为了使它变得更美观一些,我们将:

更改带标签的单元格 (1,1) 的背景颜色和字体颜色。

创建包含我们正在使用的五个单元格的范围 (A1:A5) 并更改字体大小。

创建包含带有四个物理学家名字的单元 (A2:A5) 的范围并更改背景颜色。

选择列 A 并使用 Autofit() 方法来重新设置列的大小,以便所有的文本都适合。

脚本如下:

Set objExcel = CreateObject("Excel.Application")objExcel.Visible = TrueobjExcel.Workbooks.AddobjExcel.Cells(1, 1).Value = "Name"objExcel.Cells(1, 1).Font.Bold = TRUEobjExcel.Cells(1, 1).Interior.ColorIndex = 30objExcel.Cells(1, 1).Font.ColorIndex = 2objExcel.Cells(2, 1).Value = "Schr?dinger"objExcel.Cells(3, 1).Value = "Heisenberg"objExcel.Cells(4, 1).Value = "Bohr"objExcel.Cells(5, 1).Value = "Einstein"Set objRange = objExcel.Range("A1","A5")objRange.Font.Size = 14Set objRange = objExcel.Range("A2","A5")objRange.Interior.ColorIndex = 36Set objRange = objExcel.ActiveCell.EntireColumnobjRange.AutoFit()

下面是最终的输出结果:


7. Excel 电子表格中美观的格式

现在,您知道米开朗基罗完成圣母玛利亚雕像时的心情了吧。

返回页首返回页首

数据排序

当然,我们对米开朗基罗怀着应有的尊敬,虽然圣母玛利亚雕像非常出色,但是您不能对其进行排序。然而,您可以 对 Excel 中的输出进行排序。将下面这两行代码放在脚本的末尾(我们等会儿就要解释这两行代码的含义),然后再次运行脚本:

Set objRange2 = objExcel.Range("A1")objRange.Sort objRange2,,,,,,,1

您应该看到如下所示的输出:


8. Excel 电子表格中经过排序的数据

您必须按范围对 Excel 中的数据进行排序。因而,您需要创建一个范围,它包含您想要按其进行排序的列的第一个单元格。因为我们想要按列 A 进行排序,所以我们创建的范围包含单个单元格:A1。下面这行代码的作用就在于此:

Set objRange2 = objExcel.Range("A1")

这种 Sort 方法看起来很疯狂(这么多逗号!),但这是因为我们仅仅按单列进行排序。当您在 Excel 中对一些内容进行排序时,您必须依次指定所有的排序参数;如果您不使用参数,则将其保留为空。下表对这些参数进行了总结。

参数位置 说明

1

按第一列进行排序。必须将其指定为范围。

2

第一列的排序次序。将其设置为 1 表示升序(默认),将其设置为 2 表示降序。

3

按第二列进行排序。必须将其指定为范围。

4

不用于脚本。将其保留为空。

5

第二列的排序次序。

6

按第三列进行排序。必须将其指定为范围。

7

第三列的排序次序。

8

指示将要进行排序的数据是否有标题行。将其设置为 1,指示该数据有标题行;将其设置为 0,指示该数据没有标题行;而 0 可以让 Excel 确认数据是否有标题行。

下面是在我们的样本脚本中解释排序参数 objRange2,,,,,,,1 的方式:

参数 说明

objRange2

按第一列进行排序。在我们的例子中,这是包含单元格 A1 的范围。

,

第一列的排序次序。我们不使用这个参数,所以将其保留为空。

,

按第二列进行排序。我们不使用这个参数,所以将其保留为空。

,

不用于脚本。将其保留为空。

,

第二列的排序次序。我们不使用这个参数,所以将其保留为空。

,

按第三列进行排序。我们不使用这个参数,所以将其保留为空。

,

第三列的排序次序。

1

指示将要进行排序的数据有标题行。

在稍后的代码中,我们将对两个不同的列进行排序,您将看到一个空想家如何进行排序的例子。

返回页首返回页首

哦,真的是这样:从 Active Directory 中提取数据

如果您的记忆力比较好(或者您可以访问时间机器),您就可能会想起,在这个专栏的开头我答应教您如何从 Active Directory 中提取数据并将其直接放到电子表格中。我们确实是绕了一个圈子才回到这儿,不过,我们马上就要进入正题了。

我们将要做的事情是编写一个脚本来搜索 Active Directory 并提取每个用户帐号的信息;然后,我们使用这些信息来建立公司电话目录。注意,当我向您显示用于搜索 Active Directory 的代码时,我们将不会采用任何方式来讨论这些代码;毕竟,这是一个关于 Excel 而不是 Active Directory 的专栏。(如果您想要获得更多关于使用脚本来搜索 Active Directory 的信息,您可能需要查看我们关于这个主题最新的网络广播。

首先我们来看一看这段代码,然后我们将对相关的部分做一些介绍:

Const ADS_SCOPE_SUBTREE = 2Set objExcel = CreateObject("Excel.Application")objExcel.Visible = TrueobjExcel.Workbooks.AddobjExcel.Cells(1, 1).Value = "Last name"objExcel.Cells(1, 2).Value = "First name"objExcel.Cells(1, 3).Value = "Department"objExcel.Cells(1, 4).Value = "Phone number"Set objConnection = CreateObject("ADODB.Connection")Set objCommand =   CreateObject("ADODB.Command")objConnection.Provider = "ADsDSOObject"objConnection.Open "Active Directory Provider"Set objCommand.ActiveConnection = objConnectionobjCommand.Properties("Page Size") = 100objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE objCommand.CommandText = _    "SELECT givenName, SN, department, telephoneNumber FROM " _        & "'LDAP://dc=fabrikam,dc=microsoft,dc=com' WHERE " _            & "objectCategory='user'"  Set objRecordSet = objCommand.ExecuteobjRecordSet.MoveFirstx = 2Do Until objRecordSet.EOF    objExcel.Cells(x, 1).Value = _        objRecordSet.Fields("SN").Value    objExcel.Cells(x, 2).Value = _        objRecordSet.Fields("givenName").Value    objExcel.Cells(x, 3).Value = _        objRecordSet.Fields("department").Value    objExcel.Cells(x, 4).Value = _        objRecordSet.Fields("telephoneNumber").Value    x = x + 1    objRecordSet.MoveNextLoopSet objRange = objExcel.Range("A1")objRange.ActivateSet objRange = objExcel.ActiveCell.EntireColumnobjRange.Autofit()Set objRange = objExcel.Range("B1")objRange.ActivateSet objRange = objExcel.ActiveCell.EntireColumnobjRange.Autofit()Set objRange = objExcel.Range("C1")objRange.ActivateSet objRange = objExcel.ActiveCell.EntireColumnobjRange.Autofit()Set objRange = objExcel.Range("D1")objRange.ActivateSet objRange = objExcel.ActiveCell.EntireColumnobjRange.Autofit()Set objRange = objExcel.Range("A1").SpecialCells(11)Set objRange2 = objExcel.Range("C1")Set objRange3 = objExcel.Range("A1")objRange.Sort objRange2,,objRange3,,,,,1

确实,这段代码看起来 有点复杂。但实际上,它非常简单。例如,看到了用斜体字显示的代码行了吗?嗯,现在,我们完全可以忽略它们。它们用于:

创建可见的 Excel 实例(您已经知道如何去做了)。

标记四个用于输出的列 (Last name、First name、Department、Phone number)。您也已经知道如何去做了。

搜索 fabrikam.com 域并检索所有用户帐号的 SN(姓或名)、givenName(名)、departmenttelephoneNumber 属性。如果您不 知道如何去做,可以查看网络广播。

事实上,只有开始编写这些用黑体字显示的代码行之后,脚本编写才开始变得有趣:

x = 2Do Until objRecordSet.EOF    objExcel.Cells(x, 1).Value = _        objRecordSet.Fields("SN").Value    objExcel.Cells(x, 2).Value = _        objRecordSet.Fields("givenName").Value    objExcel.Cells(x, 3).Value = _        objRecordSet.Fields("department").Value    objExcel.Cells(x, 4).Value = _        objRecordSet.Fields("telephoneNumber").Value    x = x + 1    objRecordSet.MoveNextLoop

这是我们从 Active Directory 中实际提取数据并将其显示在 Excel 中的地方。为此,我们首先将变量 x 的值设置为 2。该变量指示电子表格中的当前行。我们为什么从第二行开始而不从第一行开始呢?其原因很简单,我们把列标题放在了第一行。因此,我们从第二行开始显示数据。

接下来,我们创建一个循环来循环显示返回记录集中的所有记录。循环中的第一个命令是:

    objExcel.Cells(x, 1).Value = _        objRecordSet.Fields("SN").Value

这段代码选择第 2 行(用 x 表示)第 1 列,并且将该值设置为 objRecordSet.Fields("SN")。这是记录集中第一个用户的 SN(姓)。然后,脚本转到第 2 行第 2 列,并且将该单元格的值设置为用户的 givenName(名)。在为 departmenttelephoneNumber 执行了相同的操作之后,脚本将 x 增加 1(从而使 x = 3)。然后,它循环处理记录集中的下一个记录,并将数据显示在第 3 行中。这样继续下去,直到所有的用户数据都添加到电子表格中为止。

换句话说,就是 您从 Active Directory 中提取数据并将其显示在 Excel 中。您首先检索数据,然后简单地将指定单元格的值设置为从 Active Directory 中提取的值。通过使用简单的 Do Loop 循环并将行号每次增 1,您可以显示记录集中的每一项的信息。就是这么简单!

脚本的剩余部分纯粹就是点缀了。例如,这段代码将活动范围设置为单元格 A1,选择整个列,然后使用 Autofit 方法来重新设置该列的大小,这样所有的数据就都可以显示在屏幕上。该脚本然后对列 B、C 和 D 重复这个过程。

Set objRange = objExcel.Range("A1")objRange.ActivateSet objRange = objExcel.ActiveCell.EntireColumnobjRange.Autofit()

代码的最后四行对所有的返回数据进行排序,首先按部门名称进行排序,然后按姓进行排序。脚本首先创建包含所有数据的范围,然后为单元格 C1(按第一列进行排序)和单元格 A1(按第二列进行排序)创建单独的范围。此时,脚本调用 Sort 方法,将单独的范围对象作为参数传入。(相信我:这听起来虽然有点复杂,但是它真的非常简单!)

如果您在填充了电子表格之后想要自动保存它,该怎么做呢?如果与这个例子的情况一样,就只要在脚本的末尾加上下面这段代码就行了;这三行代码将电子表格保存为 C:/Scripts/Phone_Directory.xls 并终止 Excel 实例:

Set objWorkbook = objExcel.ActiveWorkbookobjWorkbook.SaveAs("C:/Scripts/Phone_Directory.xls")objExcel.Quit

如果不想终止 Excel 实例,只要不加上最后一行就可以了。

记住,您并不限于显示 Excel 中的 Active Directory 信息。例如,下面是一个非常简单的 WMI 脚本,它检索运行在计算机上的所有服务的状态和名称,然后将这些 信息显示在 Excel 中。

Set objExcel = CreateObject("Excel.Application")objExcel.Visible = TrueobjExcel.Workbooks.Addx = 1strComputer = "."Set objWMIService = GetObject _    ("winmgmts://" & strComputer & "/root/cimv2")Set colServices = objWMIService.ExecQuery _    ("Select * From Win32_Service")For Each objService in colServices    objExcel.Cells(x, 1) = objService.Name    objExcel.Cells(x, 2) = objService.State    x = x + 1Next

虽然相当简单,但是它为您提供了一些创建脚本的基础。

返回页首返回页首

就这些吗?

不管您信不信,您可以在系统管理脚本中使用的所有奇妙的方法,我们都还没有接触到。例如,我们还没有讨论使用 Excel 来创建图表或图形的可能性。这是我们将来要做的事情吗?嗨!我看起来像什么,一个时间旅行者?(事实上,我们将 讨论如何创建图表或图形。唯一的问题是,我们将在这个系列中进行讨论,还是在一些并行的系列中进行讨论。)

如果您碰巧读到这个系列并且对本月的专栏有什么问题或建议的话,请通过电子邮件将它们发送至 scripter@microsoft.com。下个月见(这取决于时间之箭指向何方,上个月见)。

脚本编写门诊

Greg Stemp 是国家公认的脚本编写权威之一,并且被大家广泛誉为世界级……哈哈!嗯,他们 的履历表中怎么都当过足球教练?真的吗?他被解雇 了?哦,很好!Greg Stemp 工作在……哦,现在继续,难道我还没有说出来吗?好吧!Greg Stemp 现在在微软工作,他拥有System Administration Scripting Guide 首席作家的终身头衔。