2015-01-21 129 views
0

我试图让一个web脚本,并使其接受一个字符串数组作为参数的函数。目前我通过从同一个脚本中创建两个函数来解决这个问题。然后我使用My-Function1 -arr $1 -arr2 $2,然后使用My-Function2 -arr $1 -arr2 $2来解决阵列问题。Powershell函数,接受多维数组作为参数

必须有一个更简洁的方法来传递这种类型的数据只有一个功能,但在我的搜索我没有看到任何东西。我还看到了使用Tables刷新方法运行新查询的问题,但是使用我有限的脚本经验,我不确定如何将其与我的脚本一起使用。

两个函数的原因是:1)第一个查询运行并将结果插入到新的Excel工作簿和工作表中。 2)接下来调用第二个函数来运行相同的T-SQL查询,但这次是从#1打开工作簿,然后插入一个新的命名工作表。

原始脚本http://www.maxtblog.com/2014/06/powershell-extracting-sql-server-data-into-excel/

$docs = "D:\Scripts\Reboots2.xlsx" 
If (Test-Path $docs){Remove-Item "D:\Scripts\Reboots2.xlsx"} Else {Continue} 
Function First-Query { 
param([string[]]$arr,$arr2) 
### SQL query results sent to Excel 
$SQLServer = 'SERVERNAME' 
$Database = 'DATABASENAME' 
## - Connect to SQL Server using non-SMO class 'System.Data': 
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection; 
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $Database; Integrated Security = True"; 
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand; 
$SqlCmd.CommandText = $arr; 
$SqlCmd.Connection = $SqlConnection; 
## - Extract and build the SQL data object '$DataSetTable': 
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter; 
$SqlAdapter.SelectCommand = $SqlCmd; 
$DataSet = New-Object System.Data.DataSet; 
$SqlAdapter.Fill($DataSet); 
$SqlConnection.Close() 
$DataSetTable = $DataSet.Tables["Table"]; 
## - Create an Excel Application instance: 
$xlsObj = New-Object -ComObject Excel.Application; 
## - Create new Workbook and Sheet (Visible = 1/0 not visible) 
$xlsObj.Visible = 0; 
$xlsWb = $xlsobj.Workbooks.Add(1); 
$xlsSh = $xlsWb.Worksheets.item(1); 
$xlsSh.Name = $($arr2) 
## - Build the Excel column heading: 
[Array] $getColumnNames = $DataSetTable.Columns | Select ColumnName; 
## - Build column header: 
[Int] $RowHeader = 1; 
foreach ($ColH in $getColumnNames) 
{ 
$xlsSh.Cells.item(1, $RowHeader).font.bold = $true; 
$xlsSh.Cells.item(1, $RowHeader) = $ColH.ColumnName; 
$RowHeader++; 
}; 
## - Adding the data start in row 2 column 1: 
[Int] $rowData = 2; 
[Int] $colData = 1; 
foreach ($rec in $DataSetTable.Rows) 
{ 
foreach ($Coln in $getColumnNames) 
{ 
## - Next line convert cell to be text only: 
$xlsSh.Cells.NumberFormat = "@"; 
## - Populating columns: 
$xlsSh.Cells.Item($rowData, $colData) = $rec.$($Coln.ColumnName).ToString(); 
$ColData++; 
}; 
$rowData++; $ColData = 1; 
}; 
## - Adjusting columns in the Excel sheet: 
$xlsRng = $xlsSH.usedRange; 
$xlsRng.EntireColumn.AutoFit() | Out-Null 
## ---------- Saving file and Terminating Excel Application ---------- ## 
$xlsFile = "D:\Scripts\Reboots.xlsx" 
$xlsObj.ActiveWorkbook.SaveAs($xlsFile) | Out-Null 
$xlsObj.Quit() 
## - End of Script - ## 
While([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsObj)){Remove-Variable xlsObj} 
start-sleep 1 
}#End Function 
Function Rest-Query { 
param([string[]]$arr,$arr2) 
### SQL query results sent to Excel 
$SQLServer = 'SERVERNAME' 
$Database = 'DATABASENAME' 
## - Connect to SQL Server using non-SMO class 'System.Data': 
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection; 
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $Database; Integrated Security = True"; 
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand; 
$SqlCmd.CommandText = $arr; 
$SqlCmd.Connection = $SqlConnection; 
## - Extract and build the SQL data object '$DataSetTable': 
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter; 
$SqlAdapter.SelectCommand = $SqlCmd; 
$DataSet = New-Object System.Data.DataSet; 
$SqlAdapter.Fill($DataSet); 
$SqlConnection.Close() 
$DataSetTable = $DataSet.Tables["Table"]; 
## - Create an Excel Application instance: 
$xlsObj = New-Object -ComObject Excel.Application; 
## - Create new Workbook and Sheet (Visible = 1/0 not visible) 
$xlsObj.Visible = 0; 
$xlsWb = $xlsObj.Workbooks.Open("D:\Scripts\Reboots.xlsx") 
$xlsSh = $xlsWb.Worksheets.Add([System.Reflection.Missing]::Value, $xlsWb.Worksheets.Item($xlsWb.Worksheets.Count)) 
$xlsSh.Name = $($arr2) 
$xlsObj.DisplayAlerts = $false 
## - Build the Excel column heading: 
[Array] $getColumnNames = $DataSetTable.Columns | Select ColumnName; 
## - Build column header: 
[Int] $RowHeader = 1; 
foreach ($ColH in $getColumnNames) 
{ 
$xlsSh.Cells.item(1, $RowHeader).font.bold = $true; 
$xlsSh.Cells.item(1, $RowHeader) = $ColH.ColumnName; 
$RowHeader++; 
}; 
## - Adding the data start in row 2 column 1: 
[Int] $rowData = 2; 
[Int] $colData = 1; 
foreach ($rec in $DataSetTable.Rows) 
{ 
foreach ($Coln in $getColumnNames) 
{ 
## - Next line convert cell to be text only: 
$xlsSh.Cells.NumberFormat = "@"; 
## - Populating columns: 
$xlsSh.Cells.Item($rowData, $colData) = $rec.$($Coln.ColumnName).ToString(); 
$ColData++; 
}; 
$rowData++; $ColData = 1; 
}; 
## - Adjusting columns in the Excel sheet: 
$xlsRng = $xlsSH.usedRange; 
$xlsRng.EntireColumn.AutoFit() | Out-Null 
## ---------- Saving file and Terminating Excel Application ---------- ## 
$xlsFile = "D:\Scripts\Reboots.xlsx" 
$xlsObj.ActiveWorkbook.SaveAs($xlsFile) | Out-Null 
$xlsObj.Quit() 
$xlsObj.DisplayAlerts = $true 
While([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsObj)){Remove-Variable xlsObj} 
[gc]::collect() 
[gc]::WaitForPendingFinalizers() 
start-sleep 1 
}#End Function2 
$a = @' 
SELECT DISTINCT 
'@ 
$b = @' 
SELECT DISTINCT 
'@ 
$c = @' 
SELECT DISTINCT 
'@ 
$d = @' 
SELECT DISTINCT 
'@ 
$e = @' 
SELECT DISTINCT 
'@ 
$f = @' 
SELECT DISTINCT 
'@ 
$g = @' 
SELECT DISTINCT 
'@ 
First-Query -arr $a -arr2 Monday 
Rest-Query -arr $b -arr2 Tuesday 
Rest-Query -arr $c -arr2 Wednesday 
Rest-Query -arr $d -arr2 Thursday 
Rest-Query -arr $e -arr2 Friday 
Rest-Query -arr $f -arr2 Saturday 
Rest-Query -arr $g -arr2 Sunday 
+0

另一个有趣的结果是剩下的僵尸Excel过程。但是,打开resulant电子表格然后关闭它,Excel过程将退出。 – user4317867 2015-01-21 06:45:13

回答

1

你的确可以写一个函数为你想要做什么,但你需要重新安排你的代码,并添加一些结构给它。

我试图给下面的例子一些你需要适应你的脚本的结构。

基本上,从我能够从您发布的代码中了解的情况来看,您每周都在运行特定的SQL查询并希望将结果保存在Excel中。

在下面的示例中,我使用for循环来确保每个数组中使用的索引相同。 评论中是您需要从代码中添加的命令。

Function First-Query { 
    param([string[]]$arr,[string[]]$arr2) 

    #initialize Excel 
    # do your Excel commands like opening the file, adding the workbook 

    #Now perform the query by using the appropriate element in each array (1 query/day) 
    for ($i = 0; $i -lt $arr.Count; $i++) 
    { 
     $day = $arr2[$i] 
     $query = $arr[$i] 


     # then add the worksheet 
     $xlsSh.Name = $day 

     # run the query 
     $SqlCmd.CommandText = $query; 

     # Save the results in the Excel columns 
    } 

    # Save and Quit 
}#End Function 
$arr = @() 
$arr += "SELECT DISTINCT" 
$arr += "ANOTHER QUERY SELECT DISTINCT" 
# additional queries added with $arr += 

$weekdays = @("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday") 
First-Query -arr $arr -arr2 $weekdays 
+0

看起来不错,我会努力工作并报告。谢谢! – user4317867 2015-01-21 23:11:52

+0

得到它的工作,不得不添加几件事情。首先,'$ xlsSh = $ xlsWb.Worksheets.Add([System.Reflection.Missing] :: Value,$ xlsWb.Worksheets.Item($ xlsWb.Worksheets.Count))'在最后添加新工作表。下一个'$ del = $ xlsWb.Sheets |其中{$ _。Name -eq'Sheet1'}'删除Sheet1,最后'$ activate = $ xlsWb.Sheets |其中{$ _。Name -eq'Monday'}'设置星期一(第一张)为活动状态。 – user4317867 2015-01-22 00:12:57

+0

仅供参考,将其作为单个函数'TotalMinutes:1.74'运行,并作为双重函数'TotalMinutes:2.09'另请注意,我的'Test-Path'子句不正确。如果有人发现有帮助,它需要是'If(Test-Path $ docs){Remove-Item $ docs}'。 – user4317867 2015-01-22 00:24:55

相关问题