Store a single value in variable with SQL Select - sql

I have the following vba code. I am using MS Excel 2013. (I have an insert statement in this code as well, but I didn't copy this just to have a better highlight of my problem)
Dim cn As Object
Dim cUserEmail As String
Dim strSqlmail As String
Dim rss As Object
Dim strConnection As String
Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\ActionList.accdb"
strSqlmail = "SELECT [Email-Adress] FROM MyTable WHERE Name='Test'"
Set rss = cn.Execute(strSqlmail)
cUserEmail = rss.Fields(0).Name
At this point it stores the column name (Email-Adress) in my variable. Running the query in Access returns the column with only my desired value in it.
I think I'm as good as finished, but I cannot seem to find how to get the value. When i change to rss.Field(1) it gives an error saying that the item cannot be found.

If you are using the ADO library then the Execute method returns a RecordSet - see the documentation.
So you need to:
Dim rsResult as Recordset
...
Set rsResult = cn.Execute(strSqlmail)
Do While Not rs.EOF
Debug.Print rs!Email-Adress
rs.MoveNext
Loop
rs.Close
So, when you add your WHERE clause to only return one row, then the loop should only iterate once. Whatever is output to the immediate window is what you should assign to cUserEmail.

The following code gave me the requested value:
Dim cn As Object
Dim cUserEmail As String
Dim strSqlmail As String
Dim rss As Object
Dim strConnection As String
Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\ActionList.accdb"
strSqlmail = "SELECT [Email-Adress] FROM MyTable WHERE MyTable.[Name]='Test'"
Set rss = cn.Execute(strSqlmail)
cUserEmail = rss.Fields(0)

Related

VBA populate sql query into ListBox directly into the spreadsheet (no userform)

So I checked some examples and it seems there are a lot of peoples that populate forms from SQLinto excel but in my case, I have a multi selection Excel listBox that is linked with a Sql recordset.
Basically, I managed to send my full SQL recordset into my spreadsheet. It's a table (1500 rows,9 columns) and in my spreadsheet, Above this generated table I have 9 Listboxes, each Listbox should represents all the entries of its linked column.
I want to start simple and populate one column into my excel Listbox so that users can just select whatever entry(ies) they want into the listbox. My problem is that I don't find the right ListBox method to display my entries. Here is my code so far:
Populating the recordset into SQL (That is working for whom who need this):
Sub Get_Datas_From_SQL()
Dim mobjConn As ADODB.Connection
Dim strConn As String
Set mobjConn = New ADODB.Connection
Dim strSQL As String
strConn = "Provider=SQLOLEDB; Data Source=My_server;" _
& "Initial Catalog=My_db;Integrated Security=SSPI;"
mobjConn.Open strConn
Dim rs As ADODB.Recordset
Dim Rn As Range
Set rs = New ADODB.Recordset
Set Rn = My_sheet.Range("A20")
My_sheet.Range(Rn, Rn.Offset(2000, 20)).ClearContents
strSQL = "SELECT * FROM Stocks_table"
With rs
.ActiveConnection = mobjConn
.Open strSQL
Rn.CopyFromRecordset rs
.Close
End With
mobjConn.Close
Set rs = Nothing
End Sub
Now, as a start, I add the code that is supposed to populate one of the nine Listboxes
Sub init_()
Dim mobjConn As ADODB.Connection
Dim strConn As String
Set mobjConn = New ADODB.Connection
Dim strSQL As String
strConn = "Provider=SQLOLEDB; Data Source=My_server;" _
& "Initial Catalog=My_db;Integrated Security=SSPI;"
mobjConn.Open strConn
strSQL = "SELECT DISTINCT Currency FROM Stocks_table "
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
With rs
.ActiveConnection = mobjConn
.Open strSQL
Dim a()
a = rs.GetRows
?
.Close
End With
End Sub
I took some remarks into account from previous questions and I'll get back to potential answers a fast as possible !
Thanks a lot in advance and have a great day
When you use the GetRows-method of a recordset, the data will be put into a 2-dimensional array. What's a little bit counter-intuitive is that the first index is the index into fields and the second is the index into the rows of the recordset.
You can assign a 2-dimensional array to the List-property of a listbox - but the first index needs to be the row and the second the field number (if you deal with a multi-column listbox). So all you need to do is to transpose the array before assigning it:
a = rs.GetRows
shtEquity.ListBoxCcy.List = Application.WorksheetFunction.Transpose(a)
For those who want to know, here is the answer:
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
With rs
.ActiveConnection = mobjConn
.Open strSQL
Dim a
a = rs.GetRows
For Each Row In a
shtEquity.ListBoxCcy.AddItem Row
Next
.Close
End With
a = Rs.GetRows
Worksheets(1).Shapes(1).ControlFormat.List = a 'control ListBox
Worksheets(1).OLEObjects(1).Object.List = WorksheetFunction.Transpose(a) 'Oleobject listbox
if your Listbox is MSForms.ListBox then refer below.
Dim Ws As Worksheet
Dim oleObjt As MSForms.ListBox
Set Ws = Worksheets(1)
Set oleObjt = Ws.OLEObjects("ListBox1").Object 'Ws.OLEObjects(1).Object
oleObjt.Clear
oleObjt.List = WorksheetFunction.Transpose(a)
Control & Oleobject image

How to return multiple values from table based on specific item that I entered?

I tried to use Tooling_No_AfterUpdate() for both Sub and Function but it prompt me 'Ambiguous name detected' as I know that I can't use the same identifier. Then, I changed the identifier and set it to public function but it doesn't work and prompt me 'User-defined type not defined'.
I'm creating a form for user to enter the tooling number to know the storage location where it can be more than one location. I tried to use ADODB.Recordset to get data from my asset table. So here's what I tried:
Private Function Tooling_No_Enter() As ADODB.Recordset
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
Set Tooling_No_Enter = CurrentProject.Connection.Execute("select FirstName, LastName from Employees")
End Function
Private Sub Tooling_No_AfterUpdate()
Dim strStorage_Location_1 As String
Dim strStorage_Location_2 As String
Dim strStorage_Location_3 As String
Dim strStorage_Location_4 As String
Dim strStorage_Location_5 As String
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
Set rst = Tooling_No_Enter()
Do While Not rst.EOF
strStorage_Location_1 = rst!Storage_Loacation_1
strStorage_Location_2 = rst!Storage_Loacation_2
strStorage_Location_3 = rst!Storage_Loacation_3
strStorage_Location_4 = rst!Storage_Loacation_4
strStorage_Location_5 = rst!Storage_Loacation_5
Debug.Print strStorage_Location_1 + vbCrLf + strStorage_Location_2 + vbCrLf + strStorage_Location_3 + vbCrLf + strStorage_Location_4 + vbCrLf + strStorage_Location_5
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
End Sub
After that, users able to choose the location while the chosen location will be recorded into asset table and transaction table and these are the parts i can't figure it out.
You are using the wrong method to open ADODB recordset. For one thing, Execute is used for action SQL (DELETE, UPDATE, INSERT).
One way to use a recordset object in multiple procedures is to declare recordset variable in module header. Example shows declaring and setting and opening connection and recordset objects which are then referred to in another procedure not shown.
Option Compare Database
Option Explicit
Public strOldLabNum
Dim cn As ADODB.Connection
Dim rsOldSample As ADODB.Recordset
___________________________________________________
Private Sub cbxOldLabNum_AfterUpdate()
Set cn = CurrentProject.Connection
Set rsOldSample = New ADODB.Recordset
strOldLabNum = Me.tbxOldYear & "A-" & Me.cbxOldLabNum
'select old sample info from table zSample
rsOldSample.Open "SELECT * FROM zSample WHERE LabNum='" & strOldLabNum & "';", _
cn, adOpenStatic, adLockPessimistic
End Sub

Is there a limit to the query length being passed to ADODB?

I am currently testing a framework that stores a SQL query in a cell on an excel workbook and then passes the cell value to a variable. This variable then gets executed through rs.Open query, cn where:
Dim rs As ADODB.Recordset
Dim cn As ADODB.Connection
and I have tried these for "query" :
Dim query as String
Dim query as Variant
or even playing with fixed length queries:
Dim query as String * 9999
In playing with the output of the query string, it cuts off somewhere around 8000. Google is coming up short for me, so I am coming here for answers. Is there a specific limit to what a variable can pass to recordset.Open()?
NB: The connection string I am using for this particular query is :
ConnectionString = "User ID=User;Password=PW;Data Source=DB;Provider=OraOLEDB.Oracle"
But if you know whether there is a system specific limit for Oracle, NetezzaSQL, or MS SQL Server (SQLOLEDB.1) please let me know. I will need to specify the limitations of each in order to define which new queries will need to be converted into stored procedures.
Here is the essentials of the code:
Sub RunQueryTable()
Dim cn As ADODB.Connection
Dim RS As ADODB.Recordset
Dim iCols As Integer
Dim DB As String, User As String, PW As String
Dim SQLTable As Worksheet
Dim ConnectionString as String
Dim query As String 'Or Dim query As Variant 'Or Dim query As String * 9999
Dim i As Long
etc, etc.
Set SQLTable = Sheet32
Set cn = New ADODB.Connection
Set RS = New ADODB.Recordset
DB = _____
User = ______
PW = ____
ConnectionString = "User ID=" & User & _
";Password=" & PW & _
";Data Source=" & DB & _
";Provider=OraOLEDB.Oracle"
query = SQLTable.Cells(i, 3).Text
cn.Open (ConnectionString)
RS.CursorType = adOpenForwardOnly
RS.Open (query), cn
For iCols = 0 To RS.Fields.count - 1
Worksheets("Output").Cells(1, iCols + 1).Value = RS.Fields(iCols).Name
Next
Worksheets("Output").Cells(2, "A").CopyFromRecordset RS
RS.Close
cn.Close
End Sub
The specific error I am getting from VBA is : "ORA-00923: FROM keyword not found where expected" because the query is getting cut off.
Here's your problem:
query = SQLTable.Cells(i, 3).Text
Consider:
Range("A1").Value=string(12000,"*")
? len(range("a1").value) '>> 12000
? len(range("a1").text) '>> 8221

Error while storing records from Access field in array

Situation :
I have this code which stores all the records from the field Shipment ID in an array called arrayShipmentID.
Dim conn As New ADODB.Connection
Dim connStr As String
Dim rs As ADODB.Recordset
Dim ShipmentIDSQL As String
Dim arrayShipmentID() As Variant
connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & "P:\PathToTheAccessDatabase\" & "NewVersion.accdb" & ";"
conn.ConnectionString = connStr
conn.Open
' Store Shipment IDs
Set rs = New ADODB.Recordset
ShipmentIDSQL = "SELECT [Shipment ID] FROM 12Dec"
rs.Open ShipmentIDSQL, conn, adOpenStatic, adLockReadOnly, adCmdText
If Not rs.EOF Then
arrayShipmentID = rs.GetRows
End If
Dim i As Integer
For i = 0 To UBound(arrayShipmentID, 2)
Debug.Print arrayShipmentID(0, i)
Next i
Set rs = Nothing
In order to make sure it works I Debug.Print each element of the array.
Issue :
This code WORKS most of the time, but for some reason, sometimes I get as a value 'subscript out of range' (instead of 181 in my case) for MsgBox UBound(arrayShipmentID, 2) and of course in that case Debug.Print doesn't display anything in the Immediate Window.
Any ideas where could this come from ?
With DAO recordsets you often have to find the recordcount to retrieve all records. That might be the case for ADO as well:
RecordCount = ' Obtain true count of records.
arrayShipmentID = rs.GetRows(RecordCount)
Also, I normally declare the variable as a simple Variant:
Dim arrayShipmentID As Variant

Why would my recordset be empty after running a Select?

I am trying to get this code to work, but It keeps returning -1 for the RecordCount. The select statement does find values, I went to the database and ran it there. But I am unable to get any values in my program.
Dim quotedPubs As ADODB.Connection
Set quotedPubs = New ADODB.Connection
quotedPubs.Open "PROVIDER=SQLOLEDB; DATA SOURCE=*****;INITIAL CATALOG=*****; User ID=****; Password=****"
Dim hoursPubs As ADODB.Connection
Set hoursPubs = New ADODB.Connection
hoursPubs.Open "PROVIDER=SQLOLEDB; DATA SOURCE=*****;INITIAL CATALOG=*****; User ID=****; Password=****"
Dim lsPubs As ADODB.Recordset
Set lsPubs = New ADODB.Recordset
With lsPubs
.ActiveConnection = quotedPubs
.Open "SELECT ProjectNumber FROM hours h"
' WHERE h.lead = " & sEmpNum & ""
If (lsPubs.RecordCount > 0) Then
arr = lsPubs.GetRows(lsPubs.RecordCount)
.Close
You are openning cursor, but not moving through it, so the result of .RecordCount will allways be -1. Check this.
You correctly pulled the records into the Recordset, but lspubs.RecordCount won't work since the Recordset's cursor is still at the first record. Try replacing
(lsPubs.RecordCount > 0)
with
(not(lsPubs.EOF))