I have a connection through VBA to a MySQL database but I can't determine the proper syntax to return the values from a SHOW TABLES query.
Dim rs As Object
Dim ws As Worksheet
Dim sqlstr As String
Set rs = CreateObject("ADODB.Recordset")
Set ws = ThisWorkbook.Worksheets(1)
sqlstr = "SHOW TABLES"
Call connectDatabase
rs.Open sqlstr, DBCONT
For i = 0 To (rs.RecordCount - 1)
ws.Cells(i+1, 1).value = rs(i)
rs.movenext
Next i
rs.Close
Set rs = Nothing
Call closeDatabase
The error statement reads as:
Run-time error '3265' - Item cannot be found in the collection
corresponding to the requested name or ordinal.
This exact same code works perfectly when I am trying to view the results from a "SHOW COLUMNS FROM tableName" query and also from a "SELECT columnName1 FROM tableName" query. I assume the error is that the Table names are not supposed to return as a Recordset???
As requested, this is how I connect to my database:
Public DBCONT As Object
Public Function connectDatabase()
Set DBCONT = CreateObject("ADODB.Connection")
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim Port As String
Dim sConn As String
Server_Name = "localhost"
Database_Name = "databaseName"
User_ID = "userID"
Password = "password"
Port = "3306"
sConn = "Driver={MySQL ODBC 5.1 Driver};Server=" & _
Server_Name & ";Database=" & Database_Name & _
";UID=" & User_ID & ";PWD=" & Password & ";Option=3;"
DBCONT.Open sConn
DBCONT.cursorlocation = 3
End Function
This is how I close my database:
Public Function closeDatabase()
On Error Resume Next
DBCONT.Close
Set DBCONT = Nothing
On Error GoTo 0
End Function
Answered by barrowc in the comments:
In general, you could replace the whole For..Next loop with ws.Cells(1, 1).CopyFromRecordset rs Not sure if it would help with this specific error though – barrowc Apr 8 at 23:54
Related
I'm doing something like this for the first time and it seems incredibly hard to find any useful information at all.
What I want to do:
Pass a select-query to a MySQL database and show the result in a table.
I've got that far by now: I have a button on a form and when clicked the following happens
Option Compare Database
Sub RunPassThrough(strSQL As String)
Dim ConnectionString As String
Dim Server As String
Dim User As String
Dim Pwd As String
Dim DatabaseName As String
Dim Cn As ADODB.Connection
Dim Rs As ADODB.Recordset
' Server Hostname (or IP)
Server = "192.168.178.10"
User = "user"
Pwd = "mypass"
DatabaseName = "myDB"
ConnectionString = "Provider=MSDASQL;Driver={MYSQL ODBC 5.1 DRIVER};" & _
"Server=" & Server & ";Database=" & DatabaseName
Set Cn = New ADODB.Connection
Cn.CursorLocation = adUseClient
Cn.Mode = adModeShareDenyNone
Cn.Open ConnectionString, User, Pwd
Set Rs = New ADODB.Recordset
Rs.Open strSQL, Cn, adOpenDynamic, adLockReadOnly
'Set Rs = Cn.Execute("select * from SurveyResults limit 10;")
End Sub
Private Sub Befehl0_Click()
Dim SQL As String
SQL = "select * from SurveyResults limit 10;"
RunPassThrough (SQL)
End Sub
I know that Rs.Open strSQL, Cn, adOpenDynamic, adLockReadOnly returns an ADO recordset and I could do things with it using VBA, but all I want is to show that recorod set to the user in table.
something like OpenRecordset("Rs", as a table that the user can see)
can someone please point me into the right direction I'm going crazy...
I figured it out. My problem was simply that the ReturnsRecords Property is set to false by default.
it works now, so I'm posting a answer if anyone ever needs it.
Sub RunPassThrough(strSQL As String)
Dim Server As String
Dim User As String
Dim Pwd As String
Dim DatabaseName As String
Dim qdfPassThrough As DAO.QueryDef, MyDB As Database
Dim strConnect As String
' Server Hostname (or IP)
Server = "192.168.178.10"
User = "user"
Pwd = "mypass"
DatabaseName = "database"
For Each qdf In CurrentDb.QueryDefs
If qdf.Name = "PassQuery" Then
CurrentDb.QueryDefs.Delete "PassQuery"
Exit For
End If
Next
strConnect = "ODBC;DRIVER={MYSQL ODBC 5.1 DRIVER};SERVER=" & Server & ";DATABASE=" & DatabaseName & ";Uid=" & User & ";Pwd=" & Pwd & ";"
Set MyDB = CurrentDb()
Set qdfPassThrough = MyDB.CreateQueryDef("PassQuery")
qdfPassThrough.Connect = strConnect
qdfPassThrough.SQL = strSQL
qdfPassThrough.Close
Application.RefreshDatabaseWindow
MyDB.QueryDefs("PassQuery").ReturnsRecords = True
DoCmd.OpenQuery "PassQuery", acViewNormal, acReadOnly
DoCmd.Maximize
End Sub
I have gone through a few tutorials already and my connection keeps failing, I have tried a lot of different ways of connecting.
I have a connection to mySQL through the mySQL workbench. I am using the IP address and the Port number and then my credentials to login. This works well and I am able to do the queries I need.
I am now trying to access this database through Excel, preferably through VBA. I tried to create a new connection but nothing I do seems to work. I am not sure what to put into my strConn string.
I am currently using:
Options Explicit
Private Sub CommandButton2_Click()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strConn As String
Set cn = New ADODB.Connection
strConn = "DRIVER={MySQL ODBC 5.3.7 Driver};" & _
"SERVER=XXX.XXX.X.X;" & _
"PORT=3306" & _
"DATABASE=cahier_de_lab;" & _
"UID=xxx;" & _
"PWD=xxx;" & _
"Option=3"
cn.Open strConn
' Find out if the attempt to connect worked.
If cn.State = adStateOpen Then
MsgBox "Welcome to Pubs!"
Else
MsgBox "Sorry. No Pubs today."
End If
' Close the connection.
cn.Close
End Sub
Thanks for your help!
Export from Excel to SQL Server.
Sub InsertInto()
'Declare some variables
Dim cnn As adodb.Connection
Dim cmd As adodb.Command
Dim strSQL As String
'Create a new Connection object
Set cnn = New adodb.Connection
'Set the connection string
cnn.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=Northwind;Data Source=Excel-PC\SQLEXPRESS"
'cnn.ConnectionString = "DRIVER=SQL Server;SERVER=Excel-PC\SQLEXPRESS;DATABASE=Northwind;Trusted_Connection=Yes"
'Create a new Command object
Set cmd = New adodb.Command
'Open the Connection to the database
cnn.Open
'Associate the command with the connection
cmd.ActiveConnection = cnn
'Tell the Command we are giving it a bit of SQL to run, not a stored procedure
cmd.CommandType = adCmdText
'Create the SQL
strSQL = "UPDATE TBL SET JOIN_DT = '2013-01-22' WHERE EMPID = 2"
'Pass the SQL to the Command object
cmd.CommandText = strSQL
'Execute the bit of SQL to update the database
cmd.Execute
'Close the connection again
cnn.Close
'Remove the objects
Set cmd = Nothing
Set cnn = Nothing
End Sub
OR . . . .
Import from SQL Server into Excel . . . . .
Sub Create_Connectionstring()
Dim objDL As MSDASC.DataLinks
Dim cnt As ADODB.Connection
Dim stConnect As String 'Instantiate the objects.
Set objDL = New MSDASC.DataLinks
Set cnt = New ADODB.Connection
On Error GoTo Error_Handling 'Show the Data-link wizard
stConnect = objDL.PromptNew 'Test the connection.
cnt.Open stConnect 'Print the string to the VBE Immediate Window.
Debug.Print stConnect 'Release the objects from memory.
exitHere:
cnt.Close
Set cnt = Nothing
Set objDL = Nothing
Exit Sub
Error_Handling: 'If the user cancel the operation.
If Err.Number = 91 Then
Resume exitHere
End If
End Sub
I have a MySQL DB on Localhost, which I wish to access from VBA.
I have set up the ODBC connection to MySQL, and I am able to query results.
Presently, the MySQL table has 2 rows of data which should be returned. But the "Items" in "Recordset.Fields" is retaining only the last row.
My code is as follows
Public Sub Query_()
Dim connection As connection
Set connection = OpenConnection()
' Create a record-set that holds all the tasks
Dim records As ADODB.Recordset
Set records = New ADODB.Recordset
Call records.Open("SELECT pk_Client, PAN_Client FROM client", connection)
Dim result() As String
For Each Item In records.Fields
MsgBox (Item.OriginalValue)
Next
connection.Close
End Sub
Here is the OpenConnection UDF:
Private Function OpenConnection() As ADODB.connection
'Read type and location of the database, user login and password
Dim source As String, location As String, user As String, password As String
source = "taskman"
location = "localhost"
user = "root"
password = ""
'Build the connection string depending on the source
Dim connectionString As String
connectionString = "Driver={MySQL ODBC 5.3 Unicode Driver};Server=" & location & ";Database=taskman;UID=" & user & ";PWD=" & password
'Create and open a new connection to the selected source
Set OpenConnection = New ADODB.connection
Call OpenConnection.Open(connectionString)
End Function
Please help me in figuring out why the entire query result is not being retained.
Thanks
-Chinmay Kamat
This is how you'd typically code this sort of operation:
Public Sub Query_()
Dim conn As ADODB.Connection
Dim records As ADODB.Recordset, fld As ADODB.Field
Set conn = OpenConnection()
Set records = New ADODB.Recordset
records.Open "SELECT pk_Client, PAN_Client FROM client", conn
'check you got any records
If Not records.EOF Then
'loop over records
Do While Not records.EOF
Debug.Print "-------------------------"
For Each fld In records.Fields
Debug.Print fld.Name, fld.OriginalValue
Next
records.movenext 'next record
Loop
End If
records.Close
conn.Close
End Sub
Dim oConn As ADODB.Connection
Private Sub ConnectDB()
Set oConn = New ADODB.Connection
Dim str As String
str = "DRIVER={MySQL ODBC 5.2.2 Driver};" & _
"SERVER=sql100.xtreemhost.com;" & _
"PORT=3306" & _
"DATABASE=xth_9595110_MyNotes;" & _
"UID=xth_9595110;" & _
"PWD=myPassword;" & _
"Option=3"
''' error '''
oConn.Open str
End Sub
Private Sub InsertData()
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
ConnectDB
sql = "SELECT * FROM ComputingNotesTable"
rs.Open sql, oConn, adOpenDynamic, adLockOptimistic
Do Until rs.EOF
Range("A1").Select
ActiveCell = rs.Fields("Headings")
rs.MoveNext
Loop
rs.Close
oConn.Close
Set oConn = Nothing
Set rs = Nothing
End Sub
Doing the similar things in PHP, I could successfully log in to the MySQL server.
I have installed the ODBC connector.
But in the above VBA codes, I failed.
An error turns up. (see the codes where the error exists)
$connect = mysql_connect("sql100.xtreemhost.com","xth_9595110","myPassword") or die(mysql_error());
mysql_select_db("myTable",$connect);
This piece of vba worked for me:
Sub connect()
Dim Password As String
Dim SQLStr As String
'OMIT Dim Cn statement
Dim Server_Name As String
Dim User_ID As String
Dim Database_Name As String
'OMIT Dim rs statement
Set rs = CreateObject("ADODB.Recordset") 'EBGen-Daily
Server_Name = Range("b2").Value
Database_name = Range("b3").Value ' Name of database
User_ID = Range("b4").Value 'id user or username
Password = Range("b5").Value 'Password
SQLStr = "SELECT * FROM ComputingNotesTable"
Set Cn = CreateObject("ADODB.Connection") 'NEW STATEMENT
Cn.Open "Driver={MySQL ODBC 5.2.2 Driver};Server=" & _
Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
rs.Open SQLStr, Cn, adOpenStatic
Dim myArray()
myArray = rs.GetRows()
kolumner = UBound(myArray, 1)
rader = UBound(myArray, 2)
For K = 0 To kolumner ' Using For loop data are displayed
Range("a5").Offset(0, K).Value = rs.Fields(K).Name
For R = 0 To rader
Range("A5").Offset(R + 1, K).Value = myArray(K, R)
Next
Next
rs.Close
Set rs = Nothing
Cn.Close
Set Cn = Nothing
End Sub
Ranjit's code caused the same error message as reported by Tin, but worked after updating Cn.open with the ODBC driver I'm running. Check the Drivers tab in the ODBC Data Source Administrator. Mine said "MySQL ODBC 5.3 Unicode Driver" so I updated accordingly.
Just a side note for anyone that stumbles onto this same inquiry... My Operating System is 64 bit - so of course I downloaded the 64 bit MySQL driver... however, my Office applications are 32 bit... Once I downloaded the 32 bit version, the error went away and I could move forward.
Updating this topic with a more recent answer, solution that worked for me with version 8.0 of MySQL Connector/ODBC (downloaded at https://downloads.mysql.com/archives/c-odbc/):
Public oConn As ADODB.Connection
Sub MySqlInit()
If oConn Is Nothing Then
Dim str As String
str = "Driver={MySQL ODBC 8.0 Unicode Driver};SERVER=xxxxx;DATABASE=xxxxx;PORT=3306;UID=xxxxx;PWD=xxxxx;"
Set oConn = New ADODB.Connection
oConn.Open str
End If
End Sub
The most important thing on this matter is to check the proper name and version of the installed driver at:
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers\
Enable Microsoft ActiveX Data Objects 2.8 Library
Dim oConn As ADODB.Connection
Private Sub ConnectDB()
Set oConn = New ADODB.Connection
oConn.Open "DRIVER={MySQL ODBC 5.1 Driver};" & _
"SERVER=localhost;" & _
"DATABASE=yourdatabase;" & _
"USER=yourdbusername;" & _
"PASSWORD=yourdbpassword;" & _
"Option=3"
End Sub
There rest is here: http://www.heritage-tech.net/908/inserting-data-into-mysql-from-excel-using-vba/
Just to update this further
instead of looping through every row and column which takes forever.
try using
`Sub connect()
Dim Password As String
Dim SQLStr As String
'OMIT Dim Cn statement
Dim Server_Name As String
Dim User_ID As String
Dim Database_Name As String
'OMIT Dim rs statement
Set rs = CreateObject("ADODB.Recordset") 'EBGen-Daily
Server_Name = "Server_Name "
Database_Name = "Database_Name" ' Name of database
User_ID = "User_ID" 'id user or username
Password = "Password" 'Password
SQLStr = "SELECT * FROM item"
Set Cn = CreateObject("ADODB.Connection") 'NEW STATEMENT
Cn.Open "Driver={MySQL ODBC 8.0 ANSI Driver};Server=" & _
Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
rs.Open SQLStr, Cn, adOpenStatic
Range("A2").CopyFromRecordset rs
rs.Close
Set rs = Nothing
Cn.Close
Set Cn = Nothing
End Sub
this is multiple minutes faster
This is the error which I get after my macro executes for about 10 mins. The macro is basically performing the task to update the MySQL database every five seconds.
What could be wrong?
My macro is as below:
Public RunWhen As Double
Public Const cRunIntervalSeconds = 10 ' five seconds
Public Const cRunWhat = "UpdateMarketData" ' the name of the procedure to run
Sub UpdateMarketData()
Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim SQLStr As String
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rad = 0
TextStrang = TextStrang & "'"
field2 = "cid"
field1 = "bid"
table1 = "MMbanner"
For rowCursor = 3 To 4
SQLStr = "UPDATE tbl_MarketData SET Mid = '" & Cells(rowCursor, 2) & "',Bid = '" & Cells(rowCursor, 5) & "',Offer = '" & Cells(rowCursor, 6) & "',DateEntered = '" & Format(DateTime.Now(), "yyyy-MM-dd hh:mm:ss") & "' WHERE IndexCode = '" & Cells(rowCursor, 1) & "'"
Debug.Print SQLStr
Set Cn = New ADODB.Connection
Cn.Open "DRIVER={MySQL ODBC 3.51 Driver};SERVER=<Servername>; PORT=Portno; DATABASE=Databasename; USER=Username; PASSWORD=Password; OPTION=0;"
Cn.Execute SQLStr
rad = rad + 1
Next
Set rs = Nothing
Cn.Close
Set Cn = Nothing
Call StartTimer
End Sub
Sub StartTimer()
RunWhen = Now + TimeSerial(0, 0, cRunIntervalSeconds)
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, _
Schedule:=True
End Sub
Sub StopTimer()
On Error Resume Next
Application.OnTime EarliestTime:=RunWhen, Procedure:=cRunWhat, _
Schedule:=False
End Sub
Your for loop creates two separate connections via Set Cn = New ADODB.Connection etc but Cn.Close is only called once after the for loop. Therefore, the first connection created isn't explicitly closed and may still be considered active by the server. Eventually you'll run out of available connections and things will grind to a halt.
Not sure if this is the cause of your problem but it's definitely worth fixing. I would create and open the connection prior to the for loop but keep the Cn.Execute part within the body of the loop