how to create custom function in excel to grab mysql data? - mysql

We need to create a custom formula for users to pull data from our mysql database. After the user is authenticated, they would type in a formula in excel (something like '=retrievemybirthday("Frank Dodge")'. How do we go about doing that? We're not new to programming, just new to programming w/ Excel. Are there any tutorials on this? We've looked but can find anything.
thanks!

1) you need an ODBC driver configured for your MySQL db.
2) figure out the SQL code you need for this function, something like
select birthdate
from YourTable
Where membername=?
You will use this code in your function
3) In your function, you will need the correct Connection String. Check a site like http://www.connectionstrings.com/
4) Here's an example of a function, using ActiveX Data Objects (you need a reference set in Tools > References in the VB Editor)
Function GetNomen(sPN As String) As String
'SkipVought/2006 Mar 7
'--------------------------------------------------
' Access: DWPROD.FRH_MRP.READ
'--------------------------------------------------
':this function returns nomenclature for a given part number
'--------------------------------------------------
'2011-9-26 Converted to Parameter Query
'--------------------------------------------------
Dim sConn As String, sSQL As String, sServer As String
Dim rst As ADODB.Recordset, cnn As ADODB.Connection, cmd As ADODB.Command
Set rst = New ADODB.Recordset
Set cnn = New ADODB.Connection
Set cmd = New ADODB.Command
sServer = "dwprod"
cnn.Open "Driver={Microsoft ODBC for Oracle};" & _
"Server=" & sServer & ";" & _
"Uid=/;" & _
"Pwd="
sSQL = "SELECT PM.Nomen_201 "
sSQL = sSQL & "FROM FRH_MRP.PSK02101 PM "
sSQL = sSQL & "WHERE PM.PARTNO_201 =?"
Debug.Print sSQL
With cmd
.CommandText = sSQL
.CommandType = adCmdText
.Prepared = True
.Parameters.Append .CreateParameter( _
Name:="PARTNO_201", _
Type:=adChar, _
Direction:=adParamInput, _
Size:=16, _
Value:=sPN)
.ActiveConnection = cnn
Set rst = .Execute
End With
rst.MoveFirst
If Err.Number = 0 Then
GetNomen = rst("NOMEN_201")
Else
GetNomen = ""
End If
rst.Close
cnn.Close
Set cmd = Nothing
Set rst = Nothing
Set cnn = Nothing
End Function
You can run this function on the sheet as requested.

Related

copy data form sqlserver database to access database and vice versa

I have built a program by ms access as a front and save DATA IN sql server database. Also I have some local table in my program.
My program is connected to sql server by connection string and i can read, write, delete and update data.Sometimes I need to copy result of a query to my local table into access and sometimes I want to append one of my access table to sql table
I have written a connection and tried to executed it like this:
Function CopyData()
Dim cn as ADODB.Connection
Dim strServer, strDatabase, strUsername, strPassword As String
Dim strConnectionString As String
strServer = "10.25.2.120"
strDatabase = "dbKala"
strUsername = "javid"
strPassword = "1234"
strConnectionString = "Provider=SQLOLEDB;Data Source=" & strServer & ";Initial Catalog=" & strDatabase & ";User ID=" & strUsername & ";Password=" & strPassword & ";"
Set cn = New ADODB.Connection
cn.ConnectionString = strConnectionString
cn.CommandTimeout = 0
cn.Open
cn.Execute "INSERT INTO GetTelServer Select * FROM dbo.telefone"
End Function
but data isn't copied from sql to access and show me a message about invalid object my access table
I need to help me how to copy a query from sql to access table and vice verse
This task would be a lot easier with linked DAO.Tables, but that needs proper ODBC-Driver for SQL-Server.
If Ms-Access and SQL-Servers bitness match (x64) you can try using OPENROWSET on SQL-Server to access Ms-Access tables from there.
E.g
INSERT INTO SqlServerTable (SqlServerField) SELECT AccessField FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'C:\Program Files\Microsoft Office\OFFICE11\SAMPLES\Northwind.mdb';
'admin';'',AccessTable);
If bitness doesn't match, you have to create 2 different connections and use recordsets (or Action-Query for insert)
One rs is to select the data, second is for inserts:
Dim cn As ADODB.Connection, rs As ADODB.Recordset
Dim cn2 As ADODB.Connection, rs2 As ADODB.Recordset
Set cn = New ADODB.Connection
cn.Open "Provider=SQLNCLI11;Server=server;Database=db;Trusted_Connection=yes;"
Set cn2 = New ADODB.Connection
cn2.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Path\To\AccessDb;"
Set rs = cn.Execute("SELECT SqlServerField FROM SQLSERVERTable")
Set rs2 = cn2.Execute("SELECT AccessField FROM AccessTable")
Do Until rs2.Eof
rs.AddNew
rs.Fields("SqlServerField").Value = rs2.Fields("AccessField").Value
rs.Update
rs2.MoveNext
Loop
rs.Close
rs2.Close
cn.Close
cn2.Close
Of course the fields data-types have to be compatible.

Create a linked table in Access from Teradata without DSN?

Connection to Teradata
'Requires reference to ADO and ADOX
Public adoCn As ADODB.Connection
Public adoCat As New ADOX.Catalog
Public adoTbl As New ADOX.Table
Function TD_Make_Linked_Table()
Dim varServer As String
Dim varDatabase As String
Dim varUser As String
Dim varPassword As String
varServer = "Test"
varDatabase = "Test_Test"
varUser = "Test_User"
varPassword = "Test_Password"
Set adoCn = New ADODB.Connection
'I have tried multiple connection strings
adoCn.ConnectionString = "PROVIDER=MSDASQL;DRIVER={Teradata};" & _
"DBCName=" & varServer & ";" & _
"DefaultDatabase=" & varDatabase & ";" & _
"UID=" & varUser & ";" & _
"PWD=" & varPassword & ";"
adoCn.Open
Set adoCat = New ADOX.Catalog
Set adoCat.ActiveConnection = adoCn
Set adoTbl = New ADOX.Table
adoTbl.ParentCatalog = adoCat
adoTbl.Name = "Test"
'I have tried multiple property combinations
'Causes error 3265 Item not found
'adoTbl.Properties("?") = adoCn
'adoTbl.Properties("Jet OLEDB:Link Datasource") = "Test"
'adoTbl.Properties("Jet OLEDB:Link Provider String") =
'adoTbl.Properties("Jet OLEDB:Remote Table Name") = "LinkDatabaseTable"
'adoTbl.Properties("Jet OLEDB:Create Link") = True
'Causes 3251 provider is not capable of performing operation
'adoCat.Tables.Append adoTbl
adoCn.Close
Set adoTbl = Nothing
Set adoCat = Nothing
Set adoCn = Nothing
End Function
I have validated the connection is working. I can query data by opening the connection and executing SQL.
I am unable to create a linked table programmatically in Access using visual basic for applications with the created connection.
Has anyone been able to successfully create a linked dsn-less table from Access to Teradata?
If you have a working ODBC connection string then you should be able to use DoCmd.TransferDatabase to create a linked table. I don't have a Teradata server handy, but this works for me with SQL Server:
Dim connStr As String
connStr = _
"DRIVER=ODBC Driver 11 for SQL Server;" & _
"SERVER=(local)\SQLEXPRESS;" & _
"DATABASE=myDb;" & _
"Trusted_Connection=yes"
DoCmd.TransferDatabase _
TransferType:=acLink, _
DatabaseType:="ODBC Database", _
DatabaseName:="ODBC;" & connStr, _
ObjectType:=acTable, _
Source:="dbo.projects", _
Destination:="dbo_projects"
I eventually found a connection string that works! :)
Function adoTera()
Dim oConn As ADODB.Connection
Dim rs As ADODB.Recordset
Set oConn = New ADODB.Connection
Set rs = New ADODB.Recordset
oConn.ConnectionString = "PROVIDER=MSDASQL;" & _
"DRIVER={Teradata};" & _
"DBCName=yourDBCName;" & _
"DefaultDatabase=yourDBName;" & _
"UID=yourUserName;" & _
"PWD=yourPassword;"
oConn.Open
rs.Open "SELECT * FROM yourTable", oConn
ThisWorkbook.Worksheets("Sheet1").Range("A:A").CopyFromRecordset rs
rs.Close
oConn.Close
Set rs = Nothing
Set con = Nothing
End Function

Instructing ADODB Recordset to use SQL Server current timestamp

I am attempting to write a number of records back to the database from a VB6 application using ADO. The records were read in from the database into an ADODB.Recordset and subsequently updated. I would like to be able to have each record in the set use the current date and time of the database server because I have no confidence that all our machines are time-synchronized. Is there a way to do this without having to query the database for CURRENT_TIMESTAMP (or something similar)? Ideally I'm hoping for some sort of flag that I can set the field value to so that the Recordset works this out on the database server.
See the question in my prototype code below (within the while-loop).
Dim oConn As ADODB.Connection
Dim oRs As ADODB.Recordset
Dim sSQL As String
Dim sColumnName1 As String: sColumnName1 = "UserNID"
Dim sColumnName2 As String: sColumnName2 = "Username"
Dim sColumnName3 As String: sColumnName3 = "LastLoginDTM"
' Open a connection.
Set oConn = New ADODB.Connection
oConn.Open 'my connection string was here
' Make a query over the connection.
sSQL = "SELECT TOP 10 " & sColumnName1 & ", " & sColumnName2 & ", " & sColumnName3 & " " & _
"FROM theTable"
Set oRs = New ADODB.Recordset
oRs.CursorLocation = adUseClient
oRs.Open sSQL, oConn, adOpenStatic, adLockBatchOptimistic, adCmdText
oRs.MoveFirst
While Not oRs.EOF
oRs.Fields(sColumnName3).Value = '-=-=-=-=-What do I put here???-=-=-=-=-
oRs.MoveNext
Wend
' Close the connection.
oConn.Close
Set oConn = Nothing
You could use the TSQL GetDate() Function
Change your Select to:
sSQL = "SELECT TOP 10 " & sColumnName1 & ", " & sColumnName2 & _
", " & sColumnName3 & ", GETDATE() AS ServerTimeStamp " & _
"FROM theTable"
Then, your code could be:
While Not oRs.EOF
oRs.Fields(sColumnName3).Value = oRS.Fields("ServerTimeStamp").Value
oRs.MoveNext
Wend

.Cells VBA reference issue

I have this VBA below that is designed to loop through each WS and insert the top 4 rows of each data set.
This works fine inside of a with, but that only lets me specify one sheet, instead of going through them all. I took the with out and got "Invalid or unqualified reference". After this I added ActiveSheet. to the 'Cells' Method.
Now I'm getting this error below:
"ODBC driver doesn't support the requested properties"
How do I qualify .Cells now? Or is there an alternative? I'm using excel 2010 and mysql.
Public Function InsertData()
Dim rs As ADODB.Recordset
Dim oConn As ADODB.Connection
Dim WS As Worksheet
Dim strsql As String
Set rs = New ADODB.Recordset
Set oConn = New ADODB.Connection
oConn.Open "DRIVER={MySQL ODBC 5.1 Driver};" & _
"SERVER=server.host.com;" & _
"DATABASE=datatime;" & _
"USER=boulders;" & _
"PASSWORD=rocks;" & _
"Option=3"
For Each WS In ActiveWorkbook.Worksheets
For rowcursor = 4 To 8
strsql = "INSERT INTO workflow_metrics (id, code) " & _
"VALUES (" & (ActiveSheet.Cells(rowcursor, 1)) & "," & _
"'" & (ActiveSheet.Cells(rowcursor, 2)) & "')"
rs.Open strsql, oConn, adOpenDynamic, adLockOptimistic
Next
Next WS
End Function
I think you want:
Param1.Value = WS.Cells(rowcursor, 1)
etc.
How do I qualify .Cells now? Or is there an alternative?
This isn't the problem. The problem is you trying to open a recordset (rs.open) using a Data Modification Query (INSERT).
For DML you want to use ADODB.Command.Execute.
Also if you don't have control of the values in the Spreadsheet you're opening yourself up to a SQL Injection Attack. You should use a parameterized query instead.
Dim Cmd As ADODB.Command
Set Cmd = New ADODB.Command
Cmd.ActiveConnection = oConn
Cmd.CommandText = "INSERT INTO workflow_metrics (id, code) VALUES (?,?)"
Set Param1 = Cmd.CreateParameter(, adInteger, adParamInput, 5)
Set Param2 = Cmd.CreateParameter(, adInteger, adParamInput, 5)
For Each WS In ActiveWorkbook.Worksheets
For rowcursor = 4 To 8
Param1.Value = WS.Cells(rowcursor, 1) 'As Doug Glancy this should be WS not ActiveSheet'
Param2.Value = WS.Cells(rowcursor, 2)
cmd1.Execute
Next
Next WS

Error in VBA: Lost Connection to MySQL Server at 'reading authorization packet',system error 2

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