views:

63

answers:

3

I see in the Excel documentation the QueryTables collection and ODBCConnection object, but not how to use them in powershell.

I want to create a new workbook with a single worksheet, connect to a System DSN (doesn't need login/passowrd), and run "SELECT * FROM someTable" and have the results go into the worksheet. Excel is 2007; powershell is 2.0; the odbc connection is a system DSN.

Thanks

A: 

For the Excel part, you can use the new-object cmdlet with the -COM parameter to instantiate an Excel worksheet:

$xl = New-Object -Com Excel.Application
$xl.Visible = $true
$wb = $xl.Workbooks.Add()
$ws = $wb.Worksheets.Item(1)
$ws.Cells.Item(1,1) = 1

Then for the data base access I would use a .NET DB access layer (PowerShell can access .NET rather easily). See this two part article(part one, part two) for details.

Keith Hill
Thanks for the pointer; the Sheldon article looks helpful.For this project, I am hoping there is a way that is even easier, with no ADO or datatables. I'm hoping I can find a way to use Excel objects in Powershell that mimics interactive use of excel - specify a data source, specify the cell that is the left-upper corner of the destination for the data, and run the query. All I need is "select * from sometable" dropped in at cell A1 in Sheet 1, and the workbook saved with a name. But that link you gave, I'm glad to have.
TortTupper
It worked to copy data into excel using the ado method and writing into Cells.Item(x,y), but it's too slow to go a cell at a time. So I think I wind up with a different question -can I write a DataTable from an odbc dataset into Excel all in one shot? And does that turn out to be faster as I'd expect? I think my other choices are to write a VBA macro that sets the value in the spreadsheet, or get the data to some intermediate form - csv or xml - that excel can read, but I'm hold onto hope I can do it all in a few lines of powershell.
TortTupper
Look into using an Excel Range object which will let you insert into multiple cells (assuming the value is a 2D array) in a single statement.
Keith Hill
Not sure I follow - are you suggesting there should be a way to assign a powershell array directly to a Range object, or that I should fill the range a cell at a time and that might be faster than writing into cells?
TortTupper
A: 

I would keep going the way that Keith was going.
Record a Macro in Excel and insert a Data Connection in the worksheet to draw down your table. The code in the recorded Macro will point to the objects and methods that you need to insert the table into your worksheet, directly from Powershell, using the approach above.

JoeK
This is promising but I haven't hit paydirt yet. First thing I want is a listobject. Worksheet.listobjects.add() can take a DataSourceType, there's an enumeration of those, the one I believe I want is [Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcExternal. I think I have to add the connection string at the same time that I specify xlSrcExternal, and can't find the syntax. If I use XlListObjectSourceType xlSrcRange, the Listobject.Add() call succeeds; if I use xlSrcExternal it fails (with a message "The parameter is incorrect")
TortTupper
A: 

For me, it turned out to be as simple as (with $ws as a worksheet)

$qt = $ws.QueryTables.Add("ODBC;DSN=favoriteDSN", ws.Range("A1"), "SELECT * FROM faveTable")
$qt.Refresh()
$wb.SaveAs("H:\favoriteNewFile.xlsx")
TortTupper