1

我的目标: 创建一个新选项卡并在函数中命名。

我的问题: 当我在函数内部创建新选项卡时,我无法命名该选项卡。

注意: 当我在函数之外创建选项卡时,它会正确命名。

我的代码:

Function Function_CreateWorksheets($Worksheets) {
    ForEach ($Worksheet in $Worksheets) {
        $Excel_Count_Worksheet++
        If ($Excel_Count_Worksheet -gt 3) {$Script:Excel.Worksheets.Add() |Out-Null}
        $Script:Excel.Worksheets.Item($Excel_Count_Worksheet).Name = $Worksheet
    }
}

#Load-Module -Module grouppolicy -Reload
Get-Variable Excel_* |Remove-Variable -Force

#Create Excel Com Object
$Excel = New-Object -com Excel.Application

# Make the Excel Application Visible to the end user
$Excel.visible = $True

# Create a WorkBook inside the Excel application
# that we can start manipulating.
$Excel_Workbook = $Excel.Workbooks.Add()
$Action_CreateWorksheet = 

#=======================================================
# Now that we have a workbook we need to create some
# additional worksheets (Tabs) beyond that initial 3
# that are created when the workbook is opened.
#=======================================================
#$Temp_MakeWorkSheet = $Excel.Worksheets.Add()

#=======================================================
# Once all the sheets are created each of the worksheets
# need to be assigned to a variable so they can be
# manipulated.
#=======================================================
Function_CreateWorksheets -Worksheets "System Summary","Test1","Test2","Test3","Test4"
4

2 回答 2

4

问题是您假设新工作表作为最后一个工作表添加,但默认情况下Add方法在开头添加新工作表。您拥有的脚本最多可用于三个工作表,但之后它会在开头添加具有默认名称的新工作表并不断重命名最后一个工作表。您需要在最后添加工作表。

改变

$Script:Excel.Worksheets.Add()

$Script:Excel.Worksheets.Add([System.Reflection.Missing]::Value, $Script:Excel.Worksheets.Item($Script:Excel.Worksheets.Count))

这是如何工作的:

  • Add方法接受四个参数:Before 、After、Number 和 Type。
  • $Excel.Worksheets.Item($Excel.Worksheets.Count))获取表示最后一个工作表的对象。您希望将其作为After参数提供,以便在最后一个工作表之后添加新工作表。
  • [System.Reflection.Missing]::Value是缺少的Before参数的占位符(不能为空)

附录

作为事后的想法......虽然它适用于这个特定的脚本,但我发现依赖三个工作表的默认初始配置有点不确定,根据该假设更改函数行为(重命名三个工作表,然后开始添加更多) , 并依靠计数器变量来确定要重命名的工作表,而不是重命名刚刚添加的活动工作表。由于该函数继承了一个预先存在的工作簿而不是创建一个新工作簿,因此我认为编写一个函数会“更干净”,该函数将为您提供一个具有指定名称的空白工作表的工作簿,而不管初始配置如何。

也许这只是我个人的哲学倾向,以更普遍适用(阅读:可重用)而不是临时的方式编写函数,但我更喜欢尽可能少的假设的函数。这是我的做法:

function Function_CreateWorksheets {
  [CmdletBinding()]
  param (
    [string[]] $WorkSheets,
    [object] $Excel
  )
  for ($i = 1; $i -le $Excel.Worksheets.Count; $i++) {
    $Excel.Worksheets.Item($i).Name = "DeleteMe$i"
  }
  foreach ($Worksheet in $Worksheets) {
      $Excel.Worksheets.Add([System.Reflection.Missing]::Value,$Excel.Worksheets.Item($Excel.Worksheets.Count)) | Out-Null
      $Excel.ActiveSheet.Name = $Worksheet
  }
  $Excel.DisplayAlerts = $false
  while ($Excel.Worksheets.Count -gt $Worksheets.Count) {
    $Excel.Worksheets.Item(1).Delete()
  }
  $Excel.DisplayAlerts = $true
}
  • 最后的while循环删除所有预先存在的工作表。所有新工作表都在最后添加,因此循环从头开始删除工作表,直到工作簿中的工作表数量 ( $Excel.Worksheets.Count ) 与新工作表的数量 ( $Worksheets.Count ) 匹配。这需要放在最后,因为工作簿必须至少有一个工作表,因此如果您在创建任何新工作表之前尝试删除所有工作表,则会出现错误。
  • 最初的 for循环重命名所有预先存在的工作表,以便在任何新名称与已在使用的名称匹配时函数不会中断。无论如何,你都会摆脱它们,所以你不在乎它们的名字是什么。
  • 通过将 Application 对象作为参数传递给函数,您可以避免需要继续确定它的范围。您可以像这样调用该函数:

    Function_CreateWorksheets -Worksheets "System Summary","Test1","Test2","Test3","Test4" -Excel $Excel
    

(当然,只要保持正确的顺序,您可以省略参数名称-Worksheets-Excel 。)

于 2014-01-27T17:04:26.807 回答
0

感谢您的帖子,我能够得到我需要的结果。我做了一些细微的改动以使该功能可重用。

Function Function_CreateWorksheets {
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$true,ValueFromPipeline=$true)][object] $Excel,
        [string[]] $WorkSheets
    )
    ForEach ($Worksheet in $Worksheets) {
        $Script:Excel_Count_Worksheet++
        If ($Excel_Count_Worksheet -gt $Excel.Worksheets.Count) {$Excel.Worksheets.Add([System.Reflection.Missing]::Value, $Excel.Worksheets.Item($Script:Excel.Worksheets.Count)) |Out-Null}
        $Excel.Worksheets.Item($Excel_Count_Worksheet).Name = $Worksheet
    }
    While ($Excel.Worksheets.Count -gt $Script:Excel_Count_Worksheet) {
        $Excel.Worksheets.Item($Excel.Worksheets.Count).Delete()
    }
}
于 2014-01-28T08:24:50.657 回答