2015-01-21 2 views
0

웹 스크립트를 가져 와서 문자열 배열을 인수로 받아들이려고합니다. 현재 나는 같은 스크립트에서 두 가지 기능을 만들어이 문제를 해결합니다. 그런 다음 My-Function1 -arr $1 -arr2 $2을 사용하고 My-Function2 -arr $1 -arr2 $2을 사용하면 배열 문제를 해결할 수 있습니다.다차원 배열을 매개 변수로 받아들이는 Powershell 함수

이 유형의 데이터를 한 가지 기능에만 전달하는 방법은 훨씬 더 깨끗해야하지만 내 검색에서는 아무 것도 볼 수 없습니다. 또한 테이블 새로 고침 메서드를 사용하여 새 쿼리를 실행하는 방법에 대한 질문을 보았습니다. 그러나 제한된 스크립팅 환경에서 스크립트를 사용하는 방법을 알지 못했습니다.

두 가지 기능의 이유는 다음과 같습니다. 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

또 다른 흥미로운 결과는 좀비 엑셀 프로세스입니다. 그러나, resulant 스프레드 시트를 연 다음 닫으면 Excel 프로세스가 종료됩니다. – user4317867

답변

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

+0

작동 했으므로 몇 가지 사항을 추가해야했습니다. 먼저 새로운 워크 시트를 추가하려면'$ xlsSh = $ xlsWb.Worksheets.Add ([System.Reflection.Missing] :: Value, $ xlsWb.Worksheets.Item ($ xlsWb.Worksheets.Count))' 다음'$ del = $ xlsWb.Sheets | where {$ _. Name -eq 'Sheet1'}'Sheet1을 삭제하고, 마지막으로'$ activate = $ xlsWb.Sheets | 여기서 {$ _. Name -eq 'Monday'}'는 월요일 (1 번째 시트)을 활성으로 설정합니다. – user4317867

+0

이 함수를 'TotalMinutes : 1.74'라는 단일 함수와 'TotalMinutes : 2.09'이중 함수로 실행하는 FYI 참고로'Test-Path' 절이 올바르지 않습니다. 누군가가 도움이된다면'If (Test-Path $ docs) {Remove-Item $ docs} '여야합니다. – user4317867

관련 문제