How to connect VBA to postgreSQL and run query - sql

I am trying to run a query from an Microsoft excel application and have not been able to connect successfully.
I have PostgreSQL 9.3 on my local machine, and am running 64 bit windows 7. I have a sample database name dvdrental which is a demo database.
I simply need to connect to the database, run a query, and view the output in my worksheet(or immediate window, either one resolves the connection issue).
Here is what I have so far which is not working.
Option Explicit
Public objConnection As ADODB.Connection
Public strConnection As String
Public Sub TestPostgresConnection()
Dim strConnection As String
strConnection = "Driver={PostgreSQL Unicode};Server=localhost;Port=5432; Database=dvdrental;UID=sa;PWD=wrox;"
Set objConnection = New ADODB.Connection
Set objRecordSet = New ADODB.Recordset
objConnection.Open strConnection
With objRecordSet
.ActiveConnection = objConnection
.Open "SELECT * FROM actor"
End With
Do While Not objRecordSet.EOF
Debug.Print objRecordSet.Fields(0).Value
objRecordSet.MoveNext
Loop
objRecordSet.Close
objConnection.Close
Set objRecordSet = Nothing
Set objConnection = Nothing
End Sub
Here is a list of my references;
Visual Basic For Applications
Microsoft Excel 14.0 Object Library
OLE Automation
Microsoft Office 14.0 Object Library
Microsoft Forms 2.0 Object Library
Microsoft Access 14.0 Object Library
Microsoft ADO Ext. 6.0 for DOL and Security
Microsoft ActiveX Data Objects 2.8 Library
Microsoft Windows Common Confrols 6.0 (SP6)
When I execute this test method TestPostgresConnection, I get "[Miscrosoft][ODBC Driver Manager] Data source name not found and no default driver specified"
My setup of postgres has been standard and I have simply followed the directions on their website for creating a local RDBMS for testing.
Can anyone tell me why I am not able to connect and run a query?
None of the solutions have worked so far. Thanks.

My answer is a general answer. Giving back to the community. So be nice. I had a similar question and I used the following to set it up.
Note: I suggest using DSN instead of the driver then you can use a named connection that has the password already, rather than having the password in your code.
These instructions were a huge help generally:
http://www.dashbay.com/2011/03/working-with-postgres-on-windows-via-odbc/
The download link in the link above didn't work for me. I found the ODBC downloads here:
https://www.postgresql.org/ftp/odbc/versions/msi/
I think I downloaded this one:
psqlodbc_09_05_0400-x86.zip
I used Konstantin's answer to get %WINDIR%\SysWOW64\odbcad32.exe from this link:
PostgresSQL ODBC Drivers on Windows 7 not showing up
I also downloaded MS Power Query here which I found helpful:
https://www.microsoft.com/en-us/download/details.aspx?id=39379
I am happy to edit my answer if I should add clarification.
Below is the sub for the query and below that is a sub that demonstrates how you use it.
Sub CcQueryPg(sSql As String, Optional sOdbcName As String = "ConnectionNameHere")
'Declare a Connection object
Dim cnDB As New ADODB.Connection
'Declare a Recordset Object
Dim rsRecords As New ADODB.Recordset
'Open the ODBC Connection using this statement
cnDB.Open sOdbcName
rsRecords.Open sSql, cnDB
'Close everything and set the references to nothing
rsRecords.Close
Set rsRecords = Nothing
cnDB.Close
Set cnDB = Nothing
End Sub
Sub SendQuery()
Call CcQueryPg("COPY sometablenamehere FROM '/mnt/somepathhere/somefilename.csv' DELIMITER ',' CSV HEADER;")
End Sub
The above file reference is to a file on a Linux machine. Your path format may differ.

Related

Connect Oracle SQL to VBA

I am able to connect Python to my Oracle SQL DB on a Windows computer, but strangely enough I cannot seem to get it working from VBA.
For reference, this is the Python Code to connect:
cx_Oracle.connect(f'{self.user}/{self.pwd}#//{self.host}:{self.port}/{self.service_name}')
I have tried replicating this similar structure in my VBA code, but I get an error message. Here is the code I've been using:
Sub CallDB_Return_Flexible(stSQL As String, rstStart As Range)
Dim sqlConn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim rtn As Boolean
Dim cmd As New ADODB.Command
Dim cs As String
'On Error Resume Next
Set sqlConn = New ADODB.Connection
cs = "Provider=OraOLEDB.Oracle;User ID=myuserID;Password=myPsswd;Data Source=host:port/service_name;"
sqlConn.ConnectionString = cs
sqlConn.CommandTimeout = 10000
sqlConn.Open
I get the following error messages:
1) The system cannot find message text for message text 0x80040e0c in the message file for OraOLEDB.
2) Sometimes, dependent on the iteration of the connection I use (IE a TNS connection), I get a TNS listener error message.
I currently have the ActiveX 6.1 Data Objects Library enabled. Furthermore, I am on a 64-bit machine with a 64-bit Oracle client installed. I have a 64-bit Office. I am quite certain I have a 64-bit ADO as well - my ODAC (if this is the same) is the same as the 64 bit version online. I have an ODP.NET of 2.12 and another with 4.121 in the registry. I just have an ODP.NET.Managed of 4.12.
This doesn't make much sense to me, how in one language I can connect with no issues, but in another I cannot!
I backtested using an earlier ActiveX Data Library - this solved it.
Thank you!!!!!

Can't connect to Access DB, neither with OleDB, DAO, etc

I want to read and write data from a CATIA macro to and from an Access DataBase. I've got Windows 10 and Office 2013 on it (64bit Windows).
Unfortunately I can't connect to that Access DataBase from VBA. (From VB.NET works fine)
I tried it all:
Various connection strings (JET.4.0, ACE.12.0) etc with ADODB
-> Error that Provider cant be found
Connection via DAO
-> Various other errors
Any idea why I cant connect?
I referenced all DLLs possible to reference, etc.
Only idea I have that theres a problem with Access 2013 32bit and the 64 bit Windows?
I tried from Excel with the following code (source), it works like a charm.
Sub test()
Dim cnn As ADODB.Connection 'Requieres reference to the Microsoft
Dim rs As ADODB.Recordset 'ActiveX Data Objects Library
Set cnn = CreateObject("adodb.Connection")
cnn.Open "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\Users\someFolder\myDb.accdb;"
Set rs = cnn.Execute("SELECT * FROM versions")
While Not rs.EOF
Debug.Print rs(1), rs(2), rs(3)
rs.MoveNext
Wend
rs.Close
End Sub
if that doesn't work, the client PC may lack a piece of software ?

Office365 VBA's Recordsetclone prompts for a data source

I maintain an Access DB that I built a few years ago when Office 2010 (32bit) was the standard. We've recently upgraded to Office 365 (also 32bit). This db is very dependent on using Me.Recordsetclone to do stuff. For example:
Private Sub Form_Unload(Cancel As Integer)
Dim rst As ADODB.Recordset
Set rst = Me.RecordsetClone
'Do stuff
End Sub
Now that Office has been upgraded, when the code calls Me.RecordSetClone, the 'Select Data Source' Dialog box shows up. When I try out the same code on an RDP we having running 2010, it works normally. Based on that and what little I can find on the net, I think it's a library switching/version issue.
The only work-around I can think of is to have the users run both versions side-by-side and switch back and forth. But that would be a maintenance headache. Can anyone suggest a better alternative?
I've never seen ADO used for this, only DAO:
Private Sub Form_Unload(Cancel As Integer)
Dim rst As DAO.Recordset
Set rst = Me.RecordsetClone
'Do stuff
End Sub
I have had the same issue and seem to have rectified by changing my recordset clone reference from
Me.*Subform*.Form.RecordsetClone
to the following
Set Rst = Forms!*Mainform*.Form!*Subform*.Form.Recordset.Clone
I hope this helps.

Teradata ODBC 15.0 "ODBC Driver does not support the requested properties"

I'm using ADODB in Excel 2007 VBA to connect to a Teradata 14.0 server using the Teradata ODBC 15.0 driver. Everything works as expected, except for when I submit very large queries through ADODB.Recordset.Open.
Sporadically, when I attempt recordset.open with a query that is 5000+ characters it throws ODBC Driver does not support the requested properties Error -2147217887.
The error appears after what seems like a set amount of time (30 seconds or so) when I don't get a loaded recordset object back.
The code is straightforward:
Sub getData()
Dim strSQL As String
Dim scRS As ADODB.Recordset
Dim adoConn As ADODB.Connection
strSQL = "Very Large SQL"
'open the connection
Set adoConn = New ADODB.Connection
On Error GoTo adoExit
adoConn.Open "SessionMode=Teradata;Driver=Teradata;DBCName=<SERVERIP>;Database=<DATABASE>;CharSet=UTF16;Uid=<USERID>;Pwd=<PASSWORD>"
'get the data
Set scRS = New ADODB.Recordset
scRS.Open strSQL, adoConn, adOpenKeyset, adLockOptimistic
...
End Sub
Edited to add: I've tried variations of nearly anything that sounded like it might affect packet sizes/timeouts/character sets (which I thought might affect total bytes)/etc in the connection string using http://www.info.teradata.com/htmlpubs/DB_TTU_13_10/index.html#page/Connectivity/B035_2509_071A/2509ch03.05.06.html as a guide. And still I get sporadic timeouts.
Had the same problem while trying to run a composite query.
Try to add: ;QueryTimeout=0 at the end of your connection string (the one that follows adoConn.Open)

Are Access 2010 databases not accessible with Excel if password protected using default encryption (High Security)?

I am currently supporting an Excel 2010 spreadsheet and Access 2010 database that were written by business users. One of the requirements of the Access database is that it be encrypted. It was encrypted with the default encryption settings "Use default encryption(Higher security)" which can be set in Options -> Client Settings.
Now that the database is password protected and encrypted, I am unable to connect to the database through Excel. My testing revolves around importing data into Excel, but what I really need to do is create a row in a log table. I am trying both to import directly to the sheet using the "Data" tab and "From Access" selection and through VBA code. Using the Excel interface, the password dialog box comes up and will never accept the correct password. Using VBA and ADO, the Open statement throws a "not a valid password" error. Both methods work fine if I encrypt the database using the "Use legacy encryption" setting.
I thought it also may be my setup, I'm using Windows 7 32-bit and Office 2010. I have also tried with Windows 8.1 64-bit using Office 2013 with the same results. It works with legacy encryption, but not with default encryption. I didn't try anything earlier. The default higher security encryption was introduced with Office 2010 and Windows 7.
My research has led me to this Technet thread and this Stackoverflow question, both suggesting that Excel cannot interact with Access using the default encryption method. I haven't found a whole lot more discussing this exact issue.
My question to you is does password protecting an Access 2010 database using the default settings really prevent Excel 2010 from importing data (when using the password)? Something about that doesn't sound right to me since sharing data between the two applications is a pretty basic function. I also think that if it were an issue, Google would have turned up more information about it. My guess at this point is that Excel and Access are using the Next Generation encryption engine by default, but that the ADO library has not been updated to use it.
I've attached the connection code for review. For testing I am doing a simple Now() command and emitting the results. The connection fails on the open with a "not a valid password" error even when using the correct password. Works with legacy encryption, not with default encryption.
Sub ADOCNGConnect()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim ds As String
'setting up connection
Set cn = New ADODB.Connection
With cn
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source='FILEPATH'" & _
";Jet OLEDB:Database Password=password"
.Open
End With
'setup recordset object
Set rs = New ADODB.Recordset
'retrieve new number
rs.Open "SELECT Now() AS qryTest", cn, adOpenKeyset
MsgBox rs!qryTest
rs.MoveLast
'close ADO object vars
rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing
End Sub
According to ConnectionStrings.com, the ACE provider doesn't work with the new stronger Access 2010 db encryption:
"Note! Reports say that a database encrypted using Access 2010 - 2013 default encryption scheme does not work with this connection string. In Access; try options and choose 2007 encryption method instead. That should make it work. We do not know of any other solution."
However, that doesn't tell the whole story. Your code worked as an Access VBA procedure and successfully connected to another ACCDB which had the stronger Access 2010 encryption. But I could not find any way to make similar code work as an Excel VBA procedure.
Eventually I abandoned that effort. Since your goal seems to be to make an ADO recordset containing Access data available to Excel, I decided to automate Access and use its CurrentProject.Connection.Execute method to load the recordset.
This may seem kind of clunky, but it works ...
Const cstrPath As String = "C:\Users\hans\Documents\a2010_DbPass_foo.accdb"
Const cstrPwd As String = "foo"
Dim objAccess As Object ' Access.Application
Dim rs As Object ' ADODB.Recordset
Dim strSelect As String
Set objAccess = CreateObject("Access.Application")
objAccess.Visible = True
objAccess.OpenCurrentDatabase cstrPath, , cstrPwd
'strSelect = "SELECT Now() AS qryTest"
strSelect = "SELECT some_text AS qryTest FROM tblFoo"
Set rs = objAccess.CurrentProject.Connection.Execute(strSelect)
MsgBox rs!qryTest
rs.Close
Set rs = Nothing
objAccess.Quit
Set objAccess = Nothing
Note when I used "SELECT Now() AS qryTest" for strSelect, Access crashed at .Quit I don't understand why that happened. But the code worked trouble-free in Excel 2010 as written.