VBA error in excel - vba

I have the following code:
Sub Stats1()
Workbooks("2006_2007_2008.xls").Sheets("Sheet1").Select
Worksheets("Sheet1").Activate
Dim my_cell As String
my_cell = InputBox("Which cell?")
Dim objConn As ADODB.Connection
Dim rsData As ADODB.Recordset
Dim strSQL As String
Dim mycell As String
szconnect = "Provider=SQLOLEDB;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=*****;Data Source=*****"
'Create the Connection and Recordset objects.
Set objConn = New ADODB.Connection
Set rsData = New ADODB.Recordset
On Error GoTo errHandler
'Open the Connection and execute the stored procedure
objConn.Open szconnect
strSQL = "SELECT *fom mytable"
objConn.CommandTimeout = 0
Set rsData = objConn.Execute(strSQL)
For iCols = 0 To rsData.Fields.Count - 1
ActiveSheet.Range(my_cell).Select
ActiveSheet.Cells(ActiveCell.Row, ActiveCell.Column + iCols).Value = rsData.Fields (iCols).Name
ActiveSheet.Cells.Font.Name = "Arial"
ActiveSheet.Cells.Font.Size = 8
Next
ActiveSheet.Range(ActiveSheet.Cells(ActiveCell.Row, ActiveCell.Column), ActiveSheet.Cells(ActiveCell.Row, ActiveCell.Column + rsData.Fields.Count)).Font.Bold = True
If Not rsData.EOF Then
'Dump the contents of the recordset onto the worksheet
On Error GoTo errHandler
ActiveSheet.Cells(ActiveCell.Row, ActiveCell.Column).CopyFromRecordset rsData
If Not rsData.EOF Then
MsgBox "Data set too large for a worksheet!"
End If
rsData.Close
End If
Unload frmSQLQueryADO
Exit Sub
errHandler:
MsgBox Err.Description, vbCritical, "Error No: " & Err.Number
'Unload frmSQLQueryADO
End Sub
i get the "424 Object required error"...dont know what the issue is...!
i think i have added all the correct references

One obvious problem:
strSQL = "SELECT *fom mytable"
should be
strSQL = "SELECT * from mytable"
EDIT: I tested the code above in a mock-up, and while it ought to be considerably tidied, it does work. Therefore, I suggest the error is in this line:
Unload frmSQLQueryADO
Try commenting the line and seeing if it works.

rsData is the Record Set returned from the query, not the connection.
Try objConn.Close instead

Related

Using VBA to query a VIEW from SQL Server

I am trying to create a VBA script that will pull the results from a View (SELECT * FROM view_name) from the RecordSet.Source property, but when attempted, my CloseConnection error handler keeps getting caught. I can get results from a table using a simple query like SELECT * FROM tbl_name with no issues.
Below is the code I am using. Note: my Const variable has the Provider and Database information removed.
I guess it really comes down to is it even possible to get results from a View like I would from a table?
Option Explicit
Const ConStrMSSQL As String = _
"Provider=provider_name;Database=database_name;Trusted_Connection=yes;"
Sub test()
Dim formConnect As ADODB.connection
Dim formData As ADODB.recordSet
Dim formField As ADODB.Field
Set formConnect = New ADODB.connection
Set formData = New ADODB.recordSet
formConnect.ConnectionString = ConStrMSSQL
formConnect.Open
On Error GoTo CloseConnection
With formData
.ActiveConnection = formConnect
.Source = "SELECT * FROM v_data_extract_658"
.LockType = adLockReadOnly
.CursorType = adOpenForwardOnly
.Open
End With
On Error GoTo CloseRecordset
Sheets("test").Range("A1").Select
For Each formField In formData.Fields
ActiveCell.Value = formField.Name
ActiveCell.Offset(0, 1).Select
Next formField
Sheets("test").Range("A2").CopyFromRecordset formData
On Error GoTo 0
CloseRecordset:
formData.Close
CloseConnection:
formConnect.Close
End Sub
This is the error message:
run-time error 2147467259 (80004005): unknown token received from SQL Server
I think the big issue here is that you haven't defined a Command Object.
I somewhat put this together "freehand" and for certain, didn't test it but it should get you to where you need to go.
Sub test()
On Error GoTo ErrorHandle:
Dim formConnect As ADODB.Connection
Set formConnect = New ADODB.Connection
formConnect.ConnectionString = ConStrMSSQL
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
formConnect.Open
With cmd
.ActiveConnection = formConnect
.CommandType = adCmdText
.CommandText = "SELECT * FROM v_data_extract_658"
.CommandTimeout = 30
End With
Dim formData As ADODB.Recordset
Set formData = New ADODB.Recordset
formData.Open cmd, , adOpenStatic, adLockReadOnly
Sheets("test").Range("A1").Select
Dim formField As ADODB.Field
For Each formField In formData.Fields
ActiveCell.value = formField.Name
ActiveCell.Offset(0, 1).Select
Next formField
Range("A2").CopyFromRecordset formData
On Error GoTo 0
Cleanup:
If Not formData Is Nothing Then
If formData.State <> adStateClosed Then formData.Close
Set formData = Nothing
End If
If Not formConnect Is Nothing Then
If formConnect.State <> adStateClosed Then formConnect.Close
Set formConnect = Nothing
End If
Set cmd = Nothing
Exit Sub
ErrorHandle:
MsgBox Err.Description
'Do whatever else is needed to respond to errors.
Resume Cleanup
End Sub
Using Excel & VBA to fetch dta from SLQ Server is quite easy (not always, but these days).
Sub ADOExcelSQLServer()
' Carl SQL Server Connection
'
' FOR THIS CODE TO WORK
' In VBE you need to go Tools References and check Microsoft Active X Data Objects 2.x library
'
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
Server_Name = "EXCEL-PC\SQLEXPRESS" ' Enter your server name here
Database_Name = "NORTHWND" ' Enter your database name here
User_ID = "" ' enter your user ID here
Password = "" ' Enter your password here
SQLStr = "SELECT * FROM [Customers]" ' Enter your SQL here
Set Cn = New ADODB.Connection
Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & _
";Uid=" & User_ID & ";Pwd=" & Password & ";"
rs.Open SQLStr, Cn, adOpenStatic
' Dump to spreadsheet
For iCols = 0 To rs.Fields.Count - 1
Worksheets("Sheet1").Cells(1, iCols + 1).Value = rs.Fields(iCols).Name
Next
With Worksheets("sheet1").Range("a2:z500") ' Enter your sheet name and range here
'.ClearContents
.CopyFromRecordset rs
End With
' Tidy up
rs.Close
Set rs = Nothing
Cn.Close
Set Cn = Nothing
End Sub
As an aside, you can try this as well (please change to suit your specific setup/configuration)...
Sub Working2()
Dim con As Connection
Dim rst As Recordset
Dim strConn As String
Set con = New Connection
strConn = "EXCEL-PC\SQLEXPRESS;Database=Northwind;Trusted_Connection=True"
con.Open strConn
'Put a country name in Cell E1
Set rst = con.Execute("Exec dbo.MyOrders '" & ActiveSheet.Range("E1").Text & "'" & ActiveSheet.Range("E2").Text & "'")
'The total count of records is returned to Cell A5
ActiveSheet.Range("A5").CopyFromRecordset rst
rst.Close
con.Close
End Sub
Please see the link below for more details.
https://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm#Excel%20Data%20Export%20to%20SQL%20Server%20Test%20Code

Using ADODB to print recordset to an Excel sheet

I'm trying to use an ADODB connection to create a record set from a query, then copy the contents of that record set into a range of cells
Below is the outline of my code, but I keep getting errors
Run-time error '-2147467259 (80004005)' Unspecified error
(I've replaced my specific references with all caps dummy references)
Sub Subroutine()
'establish ADODB connection to retrieve data from TABLE
Dim objConnection As New ADODB.connection
Dim objRecordset As New ADODB.Recordset
With objConnection
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source = MYDATASOURCE" & _
"Extended Properties = Excel 8.0;HDR = Yes;"
.Open
End With
'use query to record data to Excel range
Set objRecordset = objConnection.OpenRecordset("Select * From TABLE Where FieldNm = NAME")
With objRecordset
.Open
.MoveFirst
Do Until .EOF
Worksheets("WORKSHEET").Cells(14, 1) = objRecordset.Fields.Item("FieldNm")
.MoveNext
Loop
End With
End Sub
The debug goes to the .Open in my With objConnection block. Before that I was having problems with the .MoveNext method.
Assuming your SQL is correctly specifying worksheet range, consider adjusting some items in and outside of With...End With block.
OpenRecordset is a DAO method. Use Recordset.Open for ADO
Remove the second .Open call
Remove the recordset name inside With
Loop through worksheet down the rows instead of reassign same cell
Use error handling for more informative error message to capture runtime exceptions
VBA
Sub Subroutine()
On Error Goto ErrHandle
'...same as above...
objRecordset.Open "Select * From TABLE Where FieldNm = NAME", objConnection
With objRecordset
.MoveLast
.MoveFirst
i = 0
Do Until .EOF
Worksheets("WORKSHEET").Cells(14 + i, 1) = .Fields("FieldNm")
i = i + 1
.MoveNext
Loop
.Close
End With
objConnection.Close
ExitHandle:
Set objRecordset = Nothing
Set objConnection = Nothing
Exit Sub
ErrHandle:
Msgbox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Resume ExitHandle
End Sub

This key is already associated with an element of this collection error

Dim colResults As New Collection
Dim intI As Integer
Dim objConn As ADODB.Connection
Dim objCmd As ADODB.Command
Dim objRs As ADODB.Recordset
Dim strErrText As String
Dim oField As ADODB.Field
Dim sVal
On Error GoTo RaiseError
Set objConn = New ADODB.Connection
objConn.open DBConnString
Set objCmd = New ADODB.Command
Set objCmd.ActiveConnection = objConn
objCmd.CommandType = adCmdStoredProc
objCmd.CommandText = "spSearchHistory_Read"
objCmd.Parameters(1) = CLng(sUserID)
Set objRs = objCmd.Execute
intI = 1
For Each oField In objRs.fields
If IsNull(oField.Value) Then
'fix null vals so the front end doesnt trip up trying to access them
sVal = ""
Else
If oField.Type = adDBTimeStamp Then
sVal = Format(oField.Value, "dd/mm/yyyy hh:mm")
Else
sVal = oField.Value
End If
End If
colResults.Add sVal, oField.Name
Next
objConn.Close
Set SearchHistory = colResults
Set objRs = Nothing
Set objCmd = Nothing
Set objConn = Nothing
GoTo END_OF_FUNC
RaiseError:
strErrText = "CutomerSearch.SearchHistory" & vbTab & " - " & vbTab & Err.Number & " - " & Err.Description
WriteToLogFile strErrText
WriteToEventLog strErrText
END_OF_FUNC:
a collection will accept only elements with no duplicated keys
it must be that your code at some point tries to add to colResults a new "value" but with a "key" you already gave to a previously added element
to find out what's happening you can adopt this snippet:
On Error Resume Next '<~~ temporarily suspend your error handling mode to detect duplicates
colResults.Add sVal, oField.Name '<~~ this will result in error 457 if trying to add a new item with a key you assigned to an element already in collection
If Err <> 0 Then
'possible code to handle duplicates
'On Error GoTo RaiseError '<~~ resume your error handling mode
'... code
End If
On Error GoTo RaiseError '<~~ resume your error handling mode
from your code I could guess it's happening because you're adding elements to the collection even if IsNull(oField.Value), thus making it possible to add elements with the same Null key
should that be the case you may want to keep colResults.Add sVal, oField.Name statements inside the Else-End If block, like follows
If IsNull(oField.Value) Then
'fix null vals so the front end doesnt trip up trying to access them
sVal = ""
Else
If oField.Type = adDBTimeStamp Then
sVal = Format(oField.Value, "dd/mm/yyyy hh:mm")
Else
sVal = oField.Value
End If
colResults.Add sVal, oField.Name '<~~ add elements only if oField.Value is not Null
End If

SQL query to extract employee details from access table

I am new to Excel VBA. I have a user form in which I am trying to populate names of those employees who are AMO. I have a database called Ofc. Under which I have a table EmployeeDetails. Primary key is PeoplesoftId.
Here is the structure and the contents of the Employee table:
PeoplesoftId Nameofemployee RacifId Employeeid Designation
43243309 Maddala V43309 99651823 AMO
43243310 Abhishek A43301 99651824 AMO
43243311 Atanu A43311 99651825 MO
43243312 Rajiv R43312 99651826 CSE
This is the code I've written so far:
Dim cnn As ADODB.Connection 'dim the ADO collection class
Dim rs As ADODB.Recordset 'dim the ADO recordset class
Dim dbPath As String
Dim SQL As String
Dim i As Integer
Dim var
'add error handling
On Error GoTo errHandler:
'Disable screen flickering.
Application.ScreenUpdating = False
dbPath = "E:\office_hsbc\ofc.accdb"
var = "AMO"
Set cnn = New ADODB.Connection ' Initialise the collection class variable
cnn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
cnn.Open
SQL = "SELECT Nameofemployee FROM EmployeeDetails where Designation= '" & var & "'"
Set rs = New ADODB.Recordset 'assign memory to the recordset
rs.Open SQL, cnn
If rs.EOF And rs.BOF Then
rs.Close
cnn.Close
'clear memory
Set rs = Nothing
Set cnn = Nothing
'Enable the screen.
Application.ScreenUpdating = True
MsgBox "There are no records in the recordset!", vbCritical, "No Records"
Exit Sub
End If
For i = 0 To rs.Fields.Count - 1
comboamo.AddItem rs.Fields(i).Value, i
Next
rs.Close
cnn.Close
Set rs = Nothing
Set cnn = Nothing
MsgBox "Congratulation the data has been successfully Imported", vbInformation, "Import successful"
'error handler
On Error GoTo 0
Exit Sub
errHandler:
'clear memory
Set rs = Nothing
Set cnn = Nothing
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure Import_Data"
You need to move through each record in the recordset. Currently you are trying to read all of the fields from a single record but your query only returns one field. Try this instead:
MsgBox "There are no records in the recordset!", vbCritical, "No Records"
Exit Sub
End If
i = 0
Do Until rs.EOF
comboamo.AddItem rs.Fields("Nameofemployee").Value, i
rs.MoveNext
i = i + 1
Loop
rs.Close

Issues connecting to MSSQL through VBA

I'm having some trouble connecting to an MSSQL Server through VBA Below is my code that is having trouble
Set con = New ADODB.Connection
Set rs = New ADODB.Recordset
con.Provider = "sqloledb"
sConnectionString = "Server=SQLServer;Database=DBName;UID=sa;Pwd=NiceTry"
con.Open sConnectionString
'Dim sh As Worksheet
Dim tempSheet As String
tempSheet = "IgnoreMe"
'See if there is already an "IgnoreMe" Sheet, create it if not.
Dim wsSheet As Worksheet
On Error Resume Next
Set wsSheet = Sheets("IgnoreMe")
On Error GoTo 0
If Not wsSheet Is Nothing Then
'Sheet exists, don't recreate it.
Else
Sheets.Add.Name = tempSheet
End If
Set sh = Worksheets("IgnoreMe")
' Clean up the sheet's contents
sh.UsedRange.Clear
' Now get the table's data
rs.Open "SELECT JobHeaderID, Job, ProofApproved, SleeveLabel, MasterLabel" & _
" FROM JobHeader " & _
" WHERE Job IN ('665511', '671259', '671259-1')", con
End Sub
This is just the part to download the information. I have other code to read through the recordset. On the rs.Open line I always get an Automation Error I can't figure out what problem it's hitting. Any ideas on what it's hitting?
I'm trying to follow http://webcheatsheet.com/ASP/database_connection_to_MSSQL.php the piece without DSN
Found a very straightforward example here
Here is my working code sanitized
Sub IterateColE()
' Clean up the destination sheet's contents
Sheets("IgnoreMe").UsedRange.Clear
'We're going to iterate through column E until we hit a blank/empty cell.
For Each currCell In Worksheets("Main").Range("E:E").Cells()
'Oh! and we dont want to get the header row
If currCell.Row 1 Then
If (currCell.Text "") And (currCell.Text vbNullString) Then
'Get values for job in currCell and place in the matching row on IgnoreMe
getValues currCell.Value, currCell.Row
Else
'Well, seems we've hit a blank cell, stop processing
Exit For
End If
End If
Next
End Sub
'Gets the needed values for the job and places them in "IgnoreMe" sheet on specified row. They can then be referenced like "=IgnoreMe!C3"
Sub getValues(job As String, destinationRow As Integer)
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sConnString As String
' Create the connection string.
sConnString = "Provider=SQLOLEDB;Data Source=SQLServer;" & _
"Initial Catalog=InitialTableName;" & _
"UID=DBUsername;Pwd=Nicetry;"
' Create the Connection and Recordset objects.
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Open the connection and execute.
conn.Open sConnString
Set rs = conn.Execute("SELECT JobHeaderID, Job, DataProofApproved, SleevePackLabel, MasterLabel" & _
" FROM JobHeader " & _
" WHERE Job='" & job & "'")
' Check we have data.
If Not rs.EOF Then
' Transfer result.
Sheets("IgnoreMe").Range("A" & destinationRow).CopyFromRecordset rs
' Close the recordset
rs.Close
Else
MsgBox "Error: No records returned.", vbCritical
End If
' Clean up
If CBool(conn.State And adStateOpen) Then conn.Close
Set conn = Nothing
Set rs = Nothing
End Sub
'Close out your connection when you close the workbook. Locked database tables are annoying
Private Sub Workbook_Deactivate()
If Not (con Is Nothing) Then
con.Close
Set con = Nothing
End If
End Sub