Invalid use of Null VBA Excel - mysql

Please find the below table and code. I am facing Invalid use of Null Error
Table 1
Table 2
VBA code:-
Sub sql()
sql_string = "Select [Sheet1$].[Sr], [Sheet2$].[Name], [Sheet2$].[Value] From [Sheet1$]" & _
" Inner Join [Sheet2$] On CInt([Sheet1$].[Sr]) = CInt(Mid([Sheet2$].[Name],InStr(1,[Sheet2$].[Name],""#"")+1))"
sq = SQL_query(sql_string)
end sub
Function SQL_query(ByRef sql_string As Variant)
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
strFile = ThisWorkbook.FullName
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile _
& ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
strSQL = sql_string
rs.Open strSQL, cn
Sheet5.Range("A21").CopyFromRecordset rs ''HERE I AM FACING ERROR
End Function
Please guide me.. on my below error.
In table2 column Sr after # there are some number's which is similar to table1 column Sr number's.I want to do inner join as per that particular number.
required output.

Start by writing Option Explicit on top of the module. Why does my code run without 'Option Explicit' but fail with it?
Then change the Sub sql() to something like this:
Function sql_string() as string
sql_string = "Select [Sheet1$].[Sr], [Sheet2$].[Name], [Sheet2$].[Value] From [Sheet1$]" & _
" Inner Join [Sheet2$] On CInt([Sheet1$].[Sr]) = CInt(Mid([Sheet2$].[Name],InStr(1,[Sheet2$].[Name],""#"")+1))"
end sub
In the immediate window, write ?sql_string and see what you get.
Find a way to test what you get

Related

Performing SQL queries taking inputs from Excel Table in VBA Macro

I would like to take inputs from a table in Excel to perform SQL query and output it to a location in the Excel sheet.
Macro:
Sub SQL(Dim strSQL as String)
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
strFile = ThisWorkbook.FullName
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile _
& ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
rs.Open strSQL, cn
Debug.Print rs.GetString
End Sub
SQL Query:
SELECT
e.`isin`,
b.*
FROM
`risk_reference`.`basket_debt` AS b
JOIN `risk_reference`.`etp` AS e
ON IF(
e.`parentid_override` > 0,
e.`parentid_override`,
e.`parentid`
) = b.`parentid`
AND e.`isin` = ?
AND e.`date_out` IS NULL
WHERE b.`processing_date` IN
(SELECT
MAX(processing_date)
FROM
`risk_reference`.`basket_debt`)
GROUP BY e.`isin`, b.`pk_id`
The ? in the SQL query is where I need a list of items to go in based on a table in Excel.
Should i do SQL query item by item or can i do it in one shot? If so, how do i do it? If I do line by line, how do I get to output one location in the excel?
Need some advise.
Assuming your variant of sql supports it, use IN and loop through cells to buiold the list
strsql = "SELECT e.`isin`, b.* FROM `risk_reference`.`basket_debt` AS b JOIN "
strsql = strsql & "`risk_reference`.`etp` AS e ON IF( e.`parentid_override` > 0, "
strsql = strsql & "e.`parentid_override`, e.`parentid`) = b.`parentid`"
strsql = strsql & "AND e.`isin` IN ("
dim c as range
for each c in range("your range here")
strsql = strsql & "'" & c.text & "',"
next c
strsql = strsql & ") "
strsql = strsql & "AND e.`date_out` IS NULL WHERE b.`processing_date` IN "
strsql = strsql & "(SELECT MAX(processing_date) FROM `risk_reference`.`basket_debt`) "
strsql = strsql & "GROUP BY e.`isin`, b.`pk_id`"

Why can I run a Query via the query editor but running through vba fails?

I am trying to retrieve records from a table in access using VBA. So far I have this simple function:
Private Function GNCN() As String
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim cm As ADODB.Command
Dim strSQL As String
Dim intYD As Integer
Set cn = CurrentProject.Connection
'cn.CursorLocation = adUseClient
rs.CursorLocation = adUseClient
rs.LockType = adLockReadOnly
intYD = 16
strSQL = "SELECT DCN FROM tblDCD WHERE (DCN like '" & intYD & "*')"
Set rs = cn.Execute(strSQL)
Debug.Print rs.RecordCount
Set rs = Nothing
Set cm = Nothing
Set cn = Nothing
End Function
When I run this, I don't get any records returned.
However if I take the SQL query:
SELECT DCN FROM tblDCD WHERE (DCN like '16*')
and run this within Access' query builder, I get around 912 records returned, so I know I am able to retrieve the records and that the query itself appears to be correct.
The table is simple data which consists of string values such as (in the DCN column):
"13000"
"17001"
"16003"
Around 38000 in total so I shaln't print them all here...
Does anyone know why this will work via the query builder but not via VBA?
Thanks
Appear to be mixing DAO and ADODB. Consider:
Private Function GNCN() As String
Dim rs As DAO.Recordset
Dim strSQL As String
Dim intYD As Integer
intYD = 13
strSQL = "SELECT DCN FROM Rates WHERE DCN like '" & intYD & "*';"
Set rs = CurrentDb.OpenRecordset(strSQL)
rs.MoveLast
Debug.Print rs.RecordCount
Set rs = Nothing
End Function

How to loop in Visual Basic 6, my FOR loop is not working

Hello everyone!
I,m trying to use FOR loop in my vb6 project. In the subject there are two recordsets. First recordset find the record in MS Access database table and get some values then second recordset use these values to update in another table.
When I compile there is no error, but in the table no value update. Moreover this loop work only one time I mean it is not looping. What is wrong? Please Help!
Thanks
Sub UpdatePreQty()
Dim rsTmp As New ADODB.Recordset
Dim rsStock As New ADODB.Recordset
Dim tmpICODE As String
Dim tmpBCODE As String
Dim tmpQty As String
For I = 1 To Val(txtTmpItemCount.Text)
Dim strsql As String '-----Write this line only once on a form
strsql = "SELECT * FROM [bill_details] WHERE [bill_sno] =" & sno
If rsTmp.State = adStateOpen Then rsTmp.Close
rsTmp.Open strsql, cn, adOpenStatic, adLockOptimistic
tmpICODE = rsTmp("prod_sno")
tmpBCODE = rsTmp("Batch")
tmpQty = rsTmp("qty")
If rsStock.State = adStateOpen Then rsStock.Close
rsStock.Open "SELECT * FROM Batch where BCODE='" & tmpBCODE & "' and ICODE ='" & tmpICODE & "' and [ccode]='" & Ccode & "'", cn, adOpenDynamic, adLockOptimistic
rsStock("OUT") = (Val(rsStock("OUT")) - tmpQty)
rsStock("CBAL") = Val(rsStock("OBAL")) + Val(rsStock("IN")) - Val(rsStock("OUT")) '
rsStock.Update
Next
MsgBox "Previous stock update"
If rsStock.State = adStateOpen Then rsStock.Close
If rsTmp.State = adStateOpen Then rsTmp.Close
End Sub
Solved with change FOR LOOP to DO WHILE
Do While Not rsTmp.EOF
Loop
Thanks to all

Excel VBA MySQL "SELECT * FROM table" not full informaton

I have a really weird issue with my Excel VBA code selecting values from a MySQL database. I structured a simple database with following columns:
ID
Name
Surname
City
And lets assume having following entrys:
01; Pan; Peter; NYC
02; P; Peter; NYC
But now the issue, if I select * from my table it shows me only following output:
01; P; Pan; NYC
02; P; Pan; NYC
That means the I only see the minimal lenght of an entry .... what is going on there? I have really casual VBA code in different modules for that task:
Public variables:
Public cn As ADODB.Connection
Public rs As ADODB.Recordset
Public strSql As String
Connection module:
Public Function connectDB()
Dim strServer_Name As String
Dim strDB_Name As String
Dim strUser_ID As String
Dim strPassword As String
With Sheet2
strServer_Name = .Range("B2").Value
strDB_Name = .Range("B3").Value
strUser_ID = .Range("B4").Value
strPassword = .Range("B5").Value
End With
Set cn = New ADODB.Connection
cn.Open "DRIVER={MySQL ODBC 5.3 Unicode Driver}" & _
";SERVER=" & strServer_Name & _
";DATABASE=" & strDB_Name & _
";UID=" & strUser_ID & _
";PWD=" & strPassword & ""
End Function
Sub module:
Sub request()
strSql = "SELECT * FROM test"
Call connectDB
Set rs = New ADODB.Recordset
rs.Open strSql, cn, adOpenDynamic
With Sheet1.Range("A1")
.ClearContents
.CopyFromRecordset rs
End With
Call disconnectDB
End Sub
Is this a VBA issue or are there any bugs in my MySQL?
Okay guys I've found a solution in this post: sql-query-doesnt-return-full-results-for-only-one-field
Solved it the same way the other guy did. In my code it looks like this:
Sub request()
Dim iCols As Integer
Dim iRows As Integer
strSql = "SELECT * FROM test"
Call connectDB
Set rs = New ADODB.Recordset
rs.Open strSql, cn, adOpenDynamic
iRows = 10
While Not rs.EOF
For iCols = 0 To rs.Fields.Count - 1
Tabelle1.Cells(iRows, iCols + 1).Value = rs.Fields(iCols).Value
Next
rs.MoveNext
iRows = iRows + 1
Wend
Call disconnectDB
End Sub
But thanks to everyone who tried to help me!

"LIKE" operator works in MS Access, but not ADO

I'm trying to filter records using "Like" with asterisks, it works when using Access 2010 returning many records. I'm stumped why it returns nothing when used with ADO. The code includes multiple tables and columns so to troubleshoot I made a simple query. Here's the code:
strsql = "SELECT tproducts.Prod_Name FROM tproducts " _
& " WHERE tproducts.Prod_Name Like " & Chr(34) & "SO*" & Chr(34)
Set cn = New ADODB.Connection
cn = connString
cn.Open
Set rs = New ADODB.Recordset
rs.Open strsql, cn, adOpenStatic, adLockOptimistic
' test here
iRecCount = rs.RecordCount
rs.MoveFirst
Recordcount returns -1.
When "Like" is replaced by "equals" it returns correct record so I'm sure it's able to connect to the database, for example:
strsql = "SELECT tproducts.Prod_Name FROM tproducts " _
& " WHERE tproducts.Prod_Name = " & Chr(34) & "SONY Vaio SVD13213CXB" & Chr(34)
Is there a special way to use the Like operator in ADO?
What other ways can I filter to give results same as using "Like"? For example, to find all "SVD" products?
In MS Access, the wildcard is nearly always *, outside of MS Access it is nearly always %, so
str = "SELECT tproducts.Prod_Name FROM tproducts) " _
& " WHERE tproducts.Prod_Name Like ""SO%"""
However, I strongly recommend that you move to parameters to avoid a number of serious problems.
DAO is by far the better choice for ACE / Jet ( rough example Loop table rows in Access, with or without use of Private Const )
You cannot count on RecordCount. It often returns -1 even if rows were returned. It will only return actual count if you are using a client side cursor.
Instead, use rs.EOF to check for end of recordset. Try something like the following:
Set cn = New ADODB.Connection
cn = connString
cn.Open
Set rs = New ADODB.Recordset
rs.Open strsql, cn, adOpenStatic, adLockOptimistic
' very innefficient way to find the record count, but gives you the idea. If you just care about record count use "COUNT(*)" in your query
do while not rs.eof
iRecCount = iRecCount + 1
rs.MoveNext
loop
dim strSQL as string
dim RC as variant
dim rs as adodb.recordset
set rs = new adodb.recordset
strSQL = "Select * from sometable"
rs.open strSQL,currentproject.connection,
adopenDynamic, adlockOptimistic
RC = rs.recordcount
rs.close
set rs = nothing
is a problem but..
dim strSQL as string
dim RC as variant
dim rs as adodb.recordset
set rs = new adodb.recordset
strSQL = "Select * from sometable"
rs.Open strSQL, CurrentProject.Connection,
adOpenKeyset, adLockReadOnly
RC = rs.recordcount
rs.close
set rs = nothing
will return the correct record count.