2017-08-18 7 views
0

powershellを使用して、SQLサーバーから新しいExcelファイルにデータを抽出します。小さなデータセットの場合、私のコードは機能しますが、テーブルによっては100,000以上の行があり、これには年月がかかります。 SQlサーバでユーティリティを使用しない理由は、mutilpleテーブルを抽出したいからです。 大きなテーブルをエクスポートするためにスクリプトを最適化する方法はありますか?またはこれを行う別の方法がありますか?私は以下のスクリプトPowershellを使用してExcelにデータを抽出する

## ---------- Working with SQL Server ---------- ## 

## - Get SQL Server Table data: 
$SQLServer = 'server'; 
$Database = 'database'; 
$SqlQuery = @' Select top 10 * from database.dbo.table '@; 

## - 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 = $SqlQuery; 
$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); 
$DataSetTable = $DataSet.Tables["Table"]; 


## ---------- Working with Excel ---------- ## 

## - 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(); 
$xlsSh = $xlsWb.Worksheets.item(1); 

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

## ---------- Saving file and Terminating Excel Application ---------- ## 

## - Saving Excel file - if the file exist do delete then save 
$xlsFile = ` 
"C:\path\file.xls"; 

if (Test-Path $xlsFile) 
{ 
Remove-Item $xlsFile 
$xlsObj.ActiveWorkbook.SaveAs($xlsFile); 
} 
else 
{ 
$xlsObj.ActiveWorkbook.SaveAs($xlsFile); 
}; 

## Quit Excel and Terminate Excel Application process: 
$xlsObj.Quit(); (Get-Process Excel*) | foreach ($_) { $_.kill() }; 

## - End of Script - ## 
+0

メモリ内の範囲を構築してすぐにExcelオブジェクトに配置しようとすると、セルによってセルを書き込むのが非常に遅くなります。私のコメントはアドバイスです。他のものを調整する必要があるかもしれませんが、確かにセルごとに書きません。ここで便利なリンクですが、コードは.netにありますが、powershell [Write array to excel](https://stackoverflow.com/questions/536636/write-array-to-excel-range)に調整することができます –

+0

この部分を置き換えるには? '## - ポピュレート列: $ xlsSh.Cells.Item($ rowData、$ colData)=' ' $ rec。$($ Coln.ColumnName).ToString(); $ ColData ++; }; $ rowData ++; $ ColData = 1; }; ' – MBurger

答えて

0

を使用してい

あり、この多くを容易にするために、いくつかの簡単な魔法だし、それはコピー/貼り付けます。あなたのデータテーブルをタブ区切りCSVに変換し、それをクリップボードにコピーしてExcelに貼り付けることができます。私はあなたのSQL部分を無視します。あなたはそれを手にしているようです。

## ---------- Working with Excel ---------- ## 

## - 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(); 
$xlsSh = $xlsWb.Worksheets.item(1); 

## - Copy entire table to the clipboard as tab delimited CSV 
$DataSetTable | ConvertTo-Csv -NoType -Del "`t" | Clip 

## - Paste table to Excel 
$xlsObj.ActiveCell.PasteSpecial() | Out-Null 

## - Set columns to auto-fit width 
$xlsObj.ActiveSheet.UsedRange.Columns|%{$_.AutoFit()|Out-Null} 
関連する問題