Use powershell to create queries in MS-Access
Asked Answered
M

5

3

I need to automate some data extraction from a Microsoft Access DB. The DB is provided to me by a third party, and so I do not have control over what is in the DB when it is received. I need to use Powershell to automate extraction of data from the DB.

Is there any way to use powershell to create a query in the accessDB? This is, essentially, the essence of the code I am looking for:

$l_dbPath = "C:\Path\To\dataBase.accdb"
$l_accessApp = new-object -com access.application
$l_accessApp.OpenCurrentDatabase($l_dbPath)

$l_query = "SELECT SomeTable.SomeField From SomeTable;"
$l_queryName = "Export_Query"
$l_accessApp.CurrentDB().CreateQueryDef($l_queryName, $l_query)

$l_outputFile = "C:\temp\output.csv"
$e_acExportDelim = 2 #$l_accessApp.Enumerations.AcTextTransferType.acExportDelim #arg.  this does not seem to exist...
$e_HasFieldNamesYes=-1
$l_exportSpec = ""
$l_accessApp.DoCmd.TransferText($e_acExportDelim,$l_exportSpec,$l_queryName,$l_outputFile,$e_HasFieldNamesYes)
$l_accessApp.CloseCurrentDatabase()

However, the line $l_accessApp.CurrentDB.CreateQueryDef($l_queryName, $l_query) fails, because $l_accessApp.CurrentDB() returns null, not the current DB. I can find no way to access CreateQueryDef from Powershell.

I have looked at Programmatically Build Access Query, Create a query dynamically, Use Powershell to create access 2007 Queries?, and other posts, but found nothing that works.

Thanks for any help.

EDIT: It turns out that the code as I had it above does, in fact, work! The issue all along was simply that I did not have a machine on which I had both DAO and Access installed. After testing the separate components (using DAO, and using Access) on different machines, and getting IT support to give me a machine with DAO and Access both actually installed, the above code does in fact work. (With MS Access installed and loaded, but DAO not installed, $l_accessApp.CurrentDB() returns $null. With DAO installed, it returns a DBEngine object, as expected.)

Minos answered 21/6, 2017 at 17:22 Comment(3)
why do you want to create a query inside the database? just connect to it and do your own extraction.. ie: loop through the rows/columns and create the text file..Fenian
There are other reasons I cannot do as you suggest. Suffice it to say that what I really need, what I am looking for, is how to access CreateQueryDef from powershell through $l_accessApp.OpenCurrentDatabase($l_dbPath)Minos
RyanL has provided below the exact answer I was searching for, as well as a few more that may be useful to others with similar issues. Thanks.Minos
G
1

Creating a querydef:

$dbe =new-Object -comobject DAO.DBEngine.120
$path="c:\path\to\db.mdb"
$db = $dbe.opendatabase($path)

$l_query = "select table1.* from table1"
$l_queryName="testquery"
$l_outputFile="z:\test.csv"

$db.CreateQueryDef($l_queryName, $l_query)
$db.closedatabase


$l_outputFile = "z:\test.csv"
$e_acExportDelim = 2 
$e_HasFieldNamesYes=-1
$l_exportSpec = ""

$l_accessApp = new-object -com access.application
$l_accessApp.OpenCurrentDatabase($path)
$l_accessApp.DoCmd.TransferText($e_acExportDelim,$l_exportSpec,$l_queryName,$l_outputFile,$e_HasFieldNamesYes)
            $l_accessApp.CloseCurrentDatabase()

$l_accessApp.CloseCurrentDatabase()
Gretchen answered 23/6, 2017 at 13:16 Comment(2)
My current code now, almost exactly. Thanks. If only I could figure out why neither $l_accessApp.CurrentDB nor $l_accessApp.DBEngine(0) work.Minos
See EDIT to question above: $l_accessApp.CurrentDB() does in fact work, when you get DAO and MS Access both properly installed.Minos
G
1

You may want to give something like this a try. You're extracting information into a CSV without creating a query definition in MS Access.

$OpenStatic = 3
$LockOptimistic = 3

$path = "C:\Path\To\dataBase.accdb"

$connection = New-Object -ComObject ADODB.Connection
$RecordSet = New-Object -ComObject ADODB.Recordset

$connection.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$Path" )

$Query = "SELECT SomeTable.SomeField From SomeTable;"

$RecordSet.Open($Query, $Connection, $OpenStatic, $LockOptimistic)

$RecordSet | Out-File  z:\output.csv
Gretchen answered 21/6, 2017 at 21:55 Comment(0)
G
1

Creating a querydef:

$dbe =new-Object -comobject DAO.DBEngine.120
$path="c:\path\to\db.mdb"
$db = $dbe.opendatabase($path)

$l_query = "select table1.* from table1"
$l_queryName="testquery"
$l_outputFile="z:\test.csv"

$db.CreateQueryDef($l_queryName, $l_query)
$db.closedatabase


$l_outputFile = "z:\test.csv"
$e_acExportDelim = 2 
$e_HasFieldNamesYes=-1
$l_exportSpec = ""

$l_accessApp = new-object -com access.application
$l_accessApp.OpenCurrentDatabase($path)
$l_accessApp.DoCmd.TransferText($e_acExportDelim,$l_exportSpec,$l_queryName,$l_outputFile,$e_HasFieldNamesYes)
            $l_accessApp.CloseCurrentDatabase()

$l_accessApp.CloseCurrentDatabase()
Gretchen answered 23/6, 2017 at 13:16 Comment(2)
My current code now, almost exactly. Thanks. If only I could figure out why neither $l_accessApp.CurrentDB nor $l_accessApp.DBEngine(0) work.Minos
See EDIT to question above: $l_accessApp.CurrentDB() does in fact work, when you get DAO and MS Access both properly installed.Minos
G
0

A different approach. Are you married to the idea of actually creating a query def? My understanding is you're after the results...is this not the case?

#db path
$DBPath = "c:\path\to\db.mdb"

#SQL statement to run
$SQL = "select table1.* from table"

#Output file location
$Output = "z:\test.csv"

#Connection
$Con= New-Object -TypeName System.Data.OleDb.OleDbConnection

#Connection string
$con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= $path"

#create command and fill dataset
$ConCommand= $Con.CreateCommand()
$ConCommand.CommandText = $SQL
$OAdapt = New-Object -TypeName System.Data.OleDb.OleDbDataAdapter $ConCommand
$DS = New-Object -TypeName System.Data.DataSet
$OAdapt.Fill($DS)

#Export
$DS.Tables[0] | export-csv $Output -NoTypeInformation
$Con.Close()
Gretchen answered 23/6, 2017 at 13:3 Comment(1)
This approach worked for me, just need to change $connection to $conConfiteor
I
0

ExportSpecification is what that needs to be played here in order to get some desired output. This specification has to be created from within Microsoft Access using a wizard.

Using exact paths and specification names, later you have to run above script to get the desired output.

Interlinear answered 17/7, 2020 at 7:47 Comment(0)
G
-1

Can you use DAO?

$OpenStatic = 3
$LockOptimistic = 3


$dbe =new-Object -comobject DAO.DBEngine.120
$db = $dbe.opendatabase("C:\Path\To\dataBase.accdb")

$Query = "SELECT SomeTable.SomeField From SomeTable;"

$rs=$db.openrecordset($query)

$rs| Out-File  z:\output.csv
Gretchen answered 22/6, 2017 at 16:59 Comment(2)
$rs| Out-File z:\output.csv does not output the records.Minos
RyanL: if you fix the final line of this answer, it might be more useful to others. Thanks.Minos

© 2022 - 2024 — McMap. All rights reserved.