I have been struggling with this code. I can get the desired result if Iam only passing one parameter, however as soon as I try and pass two I get value error.
for example the parameters I need to pass is for period 202110 AccountCode 412 both are type long.
I set my Rs to execute as such:
Set rs = conn.Execute("SELECT SUM(ActualAmountOrgCurrency) AS AmountOrg FROM Vba_ProfitandLoss WHERE FinPeriod = AND AccountCodeShort = " & Period & Account)
This returns a value error in excel but if I choose only one parameter it returns fine.
full code is here;
Public Function AmountOrgCurrency(Period As Long, Account As Long)
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strConnString As String
strConnString = "Provider=SQLOLEDB;Data Source=sql2016ch01;" _
& "Initial Catalog=ODS;Integrated Security=SSPI;"
Set conn = New ADODB.Connection
conn.Open strConnString
Set rs = conn.Execute("SELECT SUM(ActualAmountOrgCurrency) AS AmountOrg FROM Vba_ProfitandLoss WHERE FinPeriod = AND AccountCodeShort = " & Period & Account)
If Not IsNumeric(rs.Fields("AmountOrg").Value) Then
AmountOrgCurrency = 0
Else
AmountOrgCurrency = rs.Fields("AmountOrg").Value
rs.Close
End If
End Function
Set rs = conn.Execute("SELECT SUM(ActualAmountOrgCurrency) AS AmountOrg " & _
" FROM Vba_ProfitandLoss WHERE FinPeriod = " & Period & _
" AND AccountCodeShort = " & Account)
You need to build a string which is valid SQL - while debugging it's useful to Debug.Print the final SQL to check it for correctness.
Related
I would like to search the access database with the user initials in the UserInitials column but I get the error no value given for one or more required parameters
However, if I search the database with the ID in the ID column it works perfectly fine.
Is it possible to do this? I have checked the spelling which is fine and there are no empty fields in the database itself. I have also changed and set the Primary key from ID to UserInitials but this doesn't seem to make any difference.
Many thanks.
Public Function searchDatabase()
If UserForm1.TextBox4.Value = "" Then
MsgBox "field empty"
Else
Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
con.connectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data
Source=C:\Users\MyPC\Desktop\DatabaseOne.accdb;"
'Open Db connection
con.Open
Set rs.ActiveConnection = con
rs.Open "Select * from TableUser where UserInitials= " & UserForm1.TextBox4.Text & ""
StartRow = 3
Do Until rs.EOF
'User Initials
UserForm1.TextBox1.Text = rs.Fields(1).Value
'User Full Name
UserForm1.TextBox2.Text = rs.Fields(2).Value
'User Email
UserForm1.TextBox3.Text = rs.Fields(3).Value
rs.MoveNext
StartRow = StartRow + 1
Loop
Set rs = Nothing
con.Close
Set con = Nothing
End If
End Function
You need to embed UserForm1.TextBox4.Text in quotation marks otherwise the SQL statement will not be interpreted correctly
Try
rs.open "Select * from TableUser where UserInitials= '" & UserForm1.TextBox4.Text & "'"
Further reading Quotation marks in string expressions
I have around 80 queries which I execute on a daily basis for monitoring purpose. All of them being SELECT queries, we capture the mostly the counts. This is turning out to be a boring task that's just running the query and manually capturing the output in an excel file.
For example, these are my queries with their sample respective outputs:
Query#1: SELECT count(*) from table WHERE certain_condition = 'True'
OUTPUT: 985
Query#2: SELECT count(*) from another_table WHERE yet_another_condition = 'True'
OUTPUT: 365
…
Query#80: SELECT count(*) from another_table WHERE yet_another_condition = 'True'
OUTPUT: 578
My requirement is this:
Capture the output of these 80 queries and paste them in an excel file in a certain order.
In Excel, I'll already have a heading (condition) in a cell. So I want the output of each query to be mapped to a specific cell corresponding to the heading (condition).
Is there any way of automating this boring task, or am I stuck for eternity as a bot?
PS: I am using Toad for Oracle v 12.9.0.71 database
Like Tim was saying ADO is your best bet here. Lucky for you I just had to do this myself so hopefully this should work for you.
Sub SQLQuery(sqlServer As String, strDatabase As String, strQuery As String, _
exportLocation As Variant, strUserId As String, strPassword As String)
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Set conn = Nothing
Set rs = Nothing
'create the Connection and Recordset objects
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
'open the connection
conn.Open _
"Provider=SQLOLEDB;" & _
"Data Source=" & sqlServer & ";" & _
"Initial Catalog=" & strDatabase & ";" & _
"User ID=" & strUserId & ";" & _
"Password=" & strPassword & ";" & _
"Trusted_Connection=" & "True" & ";"
'execute
Set rs = conn.Execute(strQuery)
'check if data exists
If Not rs.EOF Then
'if so, copy to location
exportLocation.CopyFromRecordset rs
'close the recordset
rs.Close
End If
'clean up
conn.Close
Set conn = Nothing
Set rs = Nothing
End Sub
An example of using this subroutine:
Call SQLQuery( _
oSERVER, _
oDB, _
"SELECT count(*) from table WHERE certain_condition = 'True'", _
ThisWorkbook.Sheets("Sheet1").Cells(1, 1), _
oUSER, _
oPW)
Just for reference you will likely have to enable Microsoft ActiveX Data Objects 2.8 Library in your References for this to work.
Just to give you background of my work, i have to fetch data from MS Sql on daily basis and for that every time have to go to other server to run the query. Once the query is executed, have to paste into my common drive, which takes a lot time. ~55 mins to paste 5,00,000 row & 30 fields to common or to move file. In total 2 hours for execution & movement from one location to other.
To reduce this i would need your help to use the SQL queries through excel with the below things:
If possible,
Point1: Query will be stored in the text file in the common location
Point2: Query Parameter to be populate to get
Or
Point2:Range to be defined for parameter
If not possible above,
Query will be pasted into the code and parameter to be populated based on the above mentioned suggestion.
Connection type is windows authentication, it will work based on logged in users windows name.
This code will allow you to provide variables that you use within your SQL statement and put those into cells on a spreadsheet (In this case Cred2) and return the results on a separate sheet (Sheet2).
The first portion of the code establishes a connection with the SQL server.
The column Headers will be started in Row 2 and then the data will begin populating starting on row 3. I have used this to pull well over 100,000 records at a time and this works very quickly.
Private Sub CommandButton1_Click()
Dim cn As Object
Dim rs As Object
Dim strCon As String
Dim strSQL As String
strCon = "DRIVER=SQL Server;SERVER=ServerName;DATABASE=DBName;Trusted_Connection=True"
Set cn = CreateObject("ADODB.Connection")
cn.Open strCon
' if not a trusted connection you could replace top line of strCon with
strCon = "DRIVER=SQL Server; Server=myServerAddress;Database=myDataBase;User Id=myUsername; Password=myPassword"
' set up where you are getting your variables to include in the SQL statement
stat = Sheets("Cred2").Range("c7").Value
barg = Sheets("Cred2").Range("c10").Value
worksite = Sheets("Cred2").Range("c11").Value
' Construct SQL statement
strSQL = "select * " _
& " FROM tableName A , table2 B " _
& "WHERE A.[field1] = B.[field1] " _
& " and field1 like '" & stat & "'" _
& "and field2 like '" & barg & "'" _
& "and field3 like '" & worksite & "'" _
& " order by Field? "
' Build Record Set
Set rs = CreateObject("ADODB.RECORDSET")
rs.ActiveConnection = cn
rs.Open strSQL
' Display Data
For intColIndex = 0 To rs.Fields.Count - 1
Sheet2.Range("A2").Offset(0, intColIndex).Value = rs.Fields(intColIndex).name
Next
Sheet2.Range("A3").CopyFromRecordset rs
' Close Database
rs.Close
cn.Close
Set cn = Nothing
end sub
I would like to connect to my Access tables using VBA. I want to be able to type in a purchase order number, and reference that value in a query to the Access table. I want to print the results of that query to my Excel worksheet. This is what I have so far.. any ideas?
Sub CommandButton1_Click()
Dim myValue As Variant
myValue = InputBox("Enter Purchase Order Number:")
Range("A1").Value = myValue
Call ADO_Conn(myValue)
End Sub
Sub ADO_Conn(myValue)
Dim conn As New Connection
Dim rstAnswer As New ADODB.Recordset
Dim connected As Boolean
Dim RootPath, DBPath As String
Dim tempString As String
connected = False
RootPath = "Z:\BSD Internship Program\FY14 Intern Files\John Jameson\Vouchers"
DBPath = RootPath & "Acquisition Support Datamart Build 9.11-03.accdb"
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source= Z:\BSD Internship Program\FY14 Intern Files\John Jameson\Vouchers\Acquisition Support Datamart 9.1103.accdb;"
connected = True
rstAnswer.Open "SELECT VW_PUB_PURCHASE_ORDER.PO_NO FROM VW_PUB_PURCHASE_ORDER " & _
"WHERE VW_PUB_PURCHASE_ORDER.PO_NO = ' " & myValue & " ';", conn, adOpenKeyset, adLockOptimistic
Do Until rstAnswer.EOF
tempString = CStr(rstAnswer!VW_PUB_PURCHASE_ORDER)
Application.ActiveWorkbook.Worksheets("Sheet1").Range("A5").Value = tempString
rstAnswer.MoveNext
Loop
rstAnswer.Close
conn.Close
connected = False
End Sub
A couple of things about your initial query:
rstAnswer.Open "SELECT VW_PUB_PURCHASE_ORDER.PO_NO FROM VW_PUB_PURCHASE_ORDER " & _
"WHERE VW_PUB_PURCHASE_ORDER.PO_NO = ' " & myValue & " ';", conn, adOpenKeyset, adLockOptimistic
You are searching only for PO_NO in this query, so that is the only value that will return. If you want more than just that data (as I assume you might), then you want this:
rstAnswer.Open "SELECT * FROM VW_PUB_PURCHASE_ORDER " & _
"WHERE VW_PUB_PURCHASE_ORDER.PO_NO = ' " & myValue & " ';", conn, adOpenKeyset, adLockOptimistic
... where the asterisk means "all".
In addition, this bit concerns me:
' " & myValue & " '
You are adding leading and trailing blanks to your search term. This may or may not be what you want, but I assume that you do not want this. You probably want:
'" & myValue & "'
And if your PO_NO is a numeric value, you need to omit the apostrophes:
" & myValue & "
Lastly, I don't think you want to loop at all. The SELECT query will return all the results without requiring you to iterate rows. Maybe you should try getting rid of your "do" loop and using this instead:
Worksheets("Sheet1").Range("A5").CopyFromRecordset rstAnswer
Your query values will then be dropped into a dynamic range starting at the designated sheet & cell.
I didn't test the code so I might not have caught everything, but those jumped out at me.
Hope that helps!
Nate
I am writing an sql statement for an access database that will return a unique value regardless of the inputs. I am using this code however I am getting a type mismatch on the execute statement.
strSQL = "SELECT FilePath " _
& "FROM ToolFiles " _
& "WHERE Project_Num = '" & theSelectedProj & "'" _
& "AND Tool_Name = '" & theSelectedProjName & "'"
filePath = cn.Execute(strSQL)
Is there a way to return a string from an sql statement?
Thanks
The quick answer is No. The ADO Execute() method returns a recordset object which you will need to read into your string variable. Something like this should do it:
Dim rs As ADODB.Recordset
....
Set rs = cn.Execute(strSQL)
If Not (rs Is Nothing) Then
With rs
If Not (.BOF) And Not (.EOF) Then
strFilePath = Format$(.Fields(1).Value)
End If
End With
End If