使用Set-Variable在循环中设置子值(例如$ Myvar.item.value)的问题

时间:2014-01-26 12:57:06

标签: powershell powershell-v2.0 powershell-v3.0

我正在编写一个脚本,该脚本在几十个工作表中输出大约600个变量,并且它只占用大约500行代码,只是为了将列标题添加到每个工作表中。为了减少大量的整体代码,我试图将创建列标题的操作放到函数中,但由于某种原因,set-variable不会设置该值。当我尝试在项目中设置子值时,它只会给我一个错误。

返回以下错误

Function PopulateWorkSheet($Worksheet,$Values) {
    ForEach ($Value in $Values) {
        $ColumnCount++
        Set-Variable -Name $($Worksheet).Cells.Items(1,$ColumnCount) -value $Value
    }
    Remove-Variable -Name ColumnCount
}

错误

You cannot call a method on a null-valued expression.
At line:4 char:30
+         Set-Variable -Name $($Worksheet).Cells.Items(1,$ColumnCount) -value $Val ...
+                              ~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

但这不会返回错误。

Function PopulateWorkSheet($Worksheet,$Values) {
    ForEach ($Value in $Values) {
        $ColumnCount++
        Set-Variable -Name $($Worksheet) -value $Value
    }
    Remove-Variable -Name ColumnCount
}

我的完整代码

Function PopulateWorkSheet($Worksheet,$Values) {
    ForEach ($Value in $Values) {
        $ColumnCount++
        Set-Variable -Name $($Worksheet).Cells.Items(1,$ColumnCount) -value $Value
    }
    Remove-Variable -Name ColumnCount
}

clear
#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()

#=======================================================
# 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.
#=======================================================
$Excel_Worksheet_SystemSummary = $Excel.Worksheets.Item(1)
$Excel_Worksheet_SystemSummary.Name = "System Summary"

#=======================================================
# = System Summary = Create Table Headers
#=======================================================

PopulateWorkSheet -Worksheet Excel_Worksheet_SystemSummary -value @("Computer Name","Serial Number","Operating System","Service Pack","OS Architecture","Part of Domain","Domain Role","System Uptime","IP Address","OS HD Smarts Check","# of Mice","# of Keyboards","# of Hard Drives","# of CD/DVD Drives","# of Network Adapters")

3 个答案:

答案 0 :(得分:1)

为什么你认为你需要使用Set-VariableSet-Variable用于设置Powershell变量,如果您事先不知道名称,或者您想要执行特殊操作,例如将它们设置为只读。在这种情况下,您根本不想设置Powershell变量,您希望在工作表中设置单元格的值。

所以忘记Set-Variable。还要忘记Remove-Variable:从函数返回无论如何都会删除所有局部变量,你不必自己动手。

$Worksheet,如果我正确阅读您的代码,则只是对工作表的引用。那你为什么写$($Worksheet)?实际上并没有做任何只写$Worksheet本身就不会做的事情。

现在考虑$Worksheet.Cells.Items(1,$ColumnCount)。前两个元素不会在循环内部发生变化,因此将它们从循环中提升出来。现在你应该有:

Function PopulateWorkSheet($Worksheet,$Values) {
    $cells = $Worksheet.Cells
    $ColumnCount = 0
    ForEach ($Value in $Values) {
        $ColumnCount++
        $cells.Item(1,$ColumnCount) = $Value
    }
}

这也有效:

Function PopulateWorkSheet($Worksheet,$Values) {
    $Worksheet.Range(
        $Worksheet.Cells.Item(1,1),
        $Worksheet.Cells.Item(1,$Values.Count)).value() = $Values
}

并将一次性分配完整列表。

答案 1 :(得分:0)

而不是

Set-Variable -Name $($Worksheet).Cells.Items(1,$ColumnCount) -value $Value

尝试

$var=Get-Variable -Name $($Worksheet)
$var.Cells.Items(1,$ColumnCount)=$Value

注意......我没有试过这个,但是没有理由不这样做。

答案 2 :(得分:0)

所以我试图过度思考它。我不需要尝试在函数中加载变量,但是将值传递给“Worksheet”变量,因为$ Excel_Worksheet_SystemSummary只是一个指向单元格内容的链接,它实际上并不包含任何真实信息。

Function PopulateWorkSheet($Worksheet,$Values) {
    ForEach ($Value in $Values) {
        $ColumnCount++
        $worksheet.Cells.Item(1,$ColumnCount)=$Value
    }
    Remove-Variable -Name ColumnCount
}