Is there a way I can use VBA to search a SQL table and return a Yes/No result if a cell in excel contains the same data found in a SQL table??
I have customer records in an Excel sheet where I need to compare the record id (A1) I need to compare cell by cell to the 'Client' table if there is a match, if so... I need some sort of output from sql if the value exists or not.
Example:
If Cell.A1 is = SQLTableA
then 'yes'
else
'no'
I feel like I am close, but cant get the right output from sql.
enter code here
Option Explicit
Dim cell As Range
Dim CustRow As Range
Const SQLConStr As String = "Driver={SQL Server} ;Server=<svrname>;Database=CustData; UID=user; PWD=<pass>"
Sub connectTODB()
Dim CustDataConn As ADODB.Connection
Dim CustDataCMD As ADODB.Command
Dim rs As ADODB.Recordset
Set CustDataConn = New ADODB.Connection
Set CustDataCMD = New ADODB.Command
Set rs = New ADODB.Recordset
CustDataConn.ConnectionString = SQLConStr
CustDataConn.Open
CustDataCMD.ActiveConnection = CustDataConn
Dim CustValue As String
CustValue = "ACP"
Dim strSQL As String
strSQL = "SELECT * FROM [CustData].[dbo].[CustomerData] WHERE (CustomerData.Client='" & CustValue & "')"
With rs
.ActiveConnection = CustDataConn
'open strsql
'.Open "IF EXISTS(SELECT * FROM [CustData].[dbo].[CustomerData] WHERE CustomerData.Client = 'ACA') Print 'Yes' Else Print 'No'" '(notworking)
'.Open "IF EXISTS(SELECT Client FROM CustData.dbo.CustomerData WHERE CustomerData.Client = 'hdh') Print 'Yes' Else Print 'No'" '(notworking)
.Open "IF EXISTS(SELECT Client FROM CustData.dbo.CustomerData WHERE CustomerData.Client = 'hdh')"
Workbooks("<file>.xlsm").Worksheets("CustOutput").Range("A2").CopyFromRecordset rs
.Close
End With
CustDataConn.Close
Set rs = Nothing
Set CustDataConn = Nothing
End Sub
You can use the ADODB.Recordset.Filter property to return just the matching records. If there are no matching records then ADODB.Recordset.BOF will return true.
With rs
.ActiveConnection = CustDataConn
.Open strSQL
.Filter = "CustomerData.Client = 'ACA'"
Debug.Print IIf(.BOF, "No", "Yes")
.Filter = "CustomerData.Client = 'hdh'"
Debug.Print IIf(.BOF, "No", "Yes")
'Clear Filter
.Filter = ""
Workbooks("<file>.xlsm").Worksheets("CustOutput").Range("A2").CopyFromRecordset rs
.Close
End With
can someone check my understanding here...
This will open the connection and send the string, then filter my value, after the filter the .BOF will return as false, I change the answer to a "yes/no" result and output that to a cell....
I have not used the BOF (EOF) values before and the description from Microsoft is even harder to understand... but..
If BOF = True (then the value does not exist > change to "No")
If BOF = False (then the value does exist > change to "Yes")
so..
enter code here
With rs
.ActiveConnection = CustDataConn
.Open strSQL
.Filter = "Client = 'ABC'"
Workbooks("file.xlsm").Worksheets("CustOutput").Range("A2") = IIf(.BOF, "No", "Yes")
.Close
End With
Related
I'm trying to use the seek method within a VBA code nested loop. The goal is to use a query to search a table for ID values that match what was identified in the first loop. I'm returning 'Method or data member not found' The error is occurring on the line 'Set StrSQL2.Index = "ID"'. Since "ID" is the only column in that table created by the query I tried commenting it out, but it only shifts the error down to the next line 'StrSQL2.Seek "=", !external_nmad_id
Public Sub EditFinalOutput2()
'set variables
Dim i As Long
Dim qs As DAO.Recordset
Dim ss As DAO.Recordset
Dim StrSQL2 As DAO.QueryDef
Dim IRSfileFormatKey As String
Dim external_nmad_id As String
Dim nmad_address_1 As String
Dim nmad_address_2 As String
Dim nmad_address_3 As String
Dim mytestwrite As String
'open reference set
Set db = CurrentDb
Set qs = db.OpenRecordset("SunstarAccountsInWebir_SarahTest")
'Set ss = db.OpenRecordset("1042s_FinalOutput_7")
'Set StrSQL1 = db.OpenRecordset("SELECT RIGHT(IRSfileFormatKey, 10) As ID
FROM 1042s_FinalOutput_7;")
With qs.Fields
intCount = qs.RecordCount - 1
For i = 0 To intCount
If (IsNull(!nmad_address_1) Or (!nmad_address_1 = !nmad_city) Or (!nmad_address_1 = !Webir_Country) And IsNull(!nmad_address_2) Or (!nmad_address_2 = !nmad_city) Or (!nmad_address_2 = !Webir_Country) And IsNull(!nmad_address_3) Or (!nmad_address_3 = !nmad_city) Or (!nmad_address_3 = !Webir_Country)) Then
DoCmd.RunSQL "INSERT INTO Addresses_ToBeReviewed SELECT SunstarAccountsInWebir_SarahTest.* FROM SunstarAccountsInWebir_SarahTest WHERE (((SunstarAccountsInWebir_SarahTest.external_nmad_id)='" & qs!external_nmad_id & "'));"
Else:
Set StrSQL2 = CurrentDb.CreateQueryDef("", "SELECT RIGHT(IRSfileFormatKey, 10) As ID FROM 1042s_FinalOutput_7;")
Set ss = db.OpenRecordset("1042s_FinalOutput_7")
Set StrSQL2.Index = "ID"
StrSQL2.Seek "=", !external_nmad_id
If ss.NoMatch Then
DoCmd.RunSQL "INSERT INTO Addresses_NotUsed SELECT SunstarAccountsInWebir_SarahTest.* FROM SunstarAccountsInWebir_SarahTest WHERE (((SunstarAccountsInWebir_SarahTest.external_nmad_id)='" & qs!external_nmad_id & "'));"
Else: Set ss = db.OpenRecordset("1042s_FinalOutput_7")
ss.Edit
ss.Fields("box13c_Address") = qs.Fields("nmad_address_1") & qs.Fields("nmad_address_2") & qs.Fields("nmad_address_3")
ss.Update
End If
End If
qs.MoveNext
Next i
End With
'close reference set
qs.Close
Set qs = Nothing
ss.Close
Set ss = Nothing
End Sub
Consider a stripped down version of your code which still recreates the problem you're trying to solve.
Dim StrSQL2 As DAO.QueryDef
Set StrSQL2 = CurrentDb.CreateQueryDef("", "SELECT RIGHT(IRSfileFormatKey, 10) As ID FROM 1042s_FinalOutput_7;")
Set StrSQL2.Index = "ID"
When you attempt to run that code, Access will complain "Object doesn't support this property or method". The reason that happens is because StrSQL2 is a DAO.QueryDef and a QueryDef does not have an Index property. See QueryDef Members (DAO)
So then you disable that problem line and try this ...
StrSQL2.Seek "=", 27 'I substituted an arbitrary number for !external_nmad_id just to keep this simple '
But Access responds with the same complaint again, which is because a QueryDef does not have a Seek method.
Both Index and Seek are object members of a DAO.Recordset, so use them with a Recordset instead of a QueryDef
And if you go that route, designate the name of your controlling index like this ...
YourRecorsetVariable.Index = "ID"
Don't use Set there and make sure that "ID" is the name of the index ... which is not necessarily the name of the column which is indexed.
I am trying to delete duplicate records in MS ACCESS.
I have created a query that is sorted on field name.
I have VBA code that runs through the query, and then when finds a match it deletes the record - however it is not picking up the match.
My code looks as follows:
Dim db As DAO.Database
Dim recIn As DAO.Recordset
Dim strFieldName1 As Variant
Dim strFieldDescr2 As Variant
Dim strDomainCat3 As Variant
Dim strBusinessTerm4 As Variant
Dim strtableName5 As Variant
Dim lngRecordsDeleted As Variant
lngRecordsDeleted = 0
Set db = CurrentDb()
Set recIn = db.OpenRecordset("qryMyRecords")
If recIn.EOF Then
MsgBox ("No Input Records")
recIn.Close
Set recIn = Nothing
Set db = Nothing
Exit Sub
End If
Do
If recIn!FieldName = strFieldName1 And _
recIn!FieldDescr = strFieldDescr2 And _
recIn!DomainCatID = strDomainCat3 And _
recIn!BusinessTermID = strBusinessTerm4 And _
recIn!TableID = strtableName5 Then
recIn.Delete
lngRecordsDeleted = lngRecordsDeleted + 1
Else
strFieldName1 = recIn!FieldName
strFieldDescr2 = recIn!FieldDescr
strDomainCat3 = recIn!DomainCatID
strBusinessTerm4 = recIn!BusinessTermID
strtableName5 = recIn!TableID
End If
recIn.MoveNext
Loop Until recIn.EOF
recIn.Close
Set recIn = Nothing
Set db = Nothing
MsgBox ("You Deleted " & lngRecordsDeleted & " Records")
End Sub
My StrFieldname1, through to to StrTablename5 does populate (after the else statement)
However when I do the compare a second time
If recIn!FieldName = strFieldName1 And _
recIn!FieldDescr = strFieldDescr2 And _
recIn!DomainCatID = strDomainCat3 And _
recIn!BusinessTermID = strBusinessTerm4 And _
recIn!TableID = strtableName5 Then
recIn.Delete
lngRecordsDeleted = lngRecordsDeleted + 1
Even though the values are the same, it moves to the else statement, and never does the record delete.
Now I suspect that this could be because I declared my variables as VARIANT type, but if I use any other type, the code falls over every time it reaches a NULL value in the query, and there are cases where any of the fields from the query can and will be null.
Any suggestions would be greatly appreciated
To expand on what Justin said, use the Nz function in your main If statement, like so:
If Nz(recIn!FieldName, "") = strFieldName1 And _
...
Else
strFieldName1 = Nz(recIn!FieldName, "")
...
I am using the below code to track changes on a form and it works fine.
However, I am trying to use it on my main form to record just the date/time that someone clicks a button However I get the following error:
You entered an expression that has no value
The debug takes me to this:
rs!PriorInfo = Screen.ActiveControl.OldValue
My code
Function TrackChanges()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
Dim strCtl As String
Dim strReason As String
' strReason = InputBox("Reason For Changes")
strCtl = Screen.ActiveControl.Name
strSQL = "SELECT Audit.* FROM Audit;"
Set db = CurrentDb()
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
If rs.RecordCount > 0 Then rs.MoveLast
With rs
.AddNew
rs!FormName = Screen.ActiveForm
rs!ControlName = strCtl
rs!DateChanged = Date
rs!TimeChanged = Time()
rs!PriorInfo = Screen.ActiveControl.OldValue
rs!NewInfo = Screen.ActiveControl.Value
rs!CurrentUser = fOSUserName
' rs!Reason = strReason
.Update
End With
Set db = Nothing
Set rs = Nothing
End Function
I assume I need to tell it to accept null values but unsure how?
Nz(Screen.ActiveControl.OldValue) will return an empty string instead of a null value.
Nz(Screen.ActiveControl.OldValue,"<Null>") if PriorInfo is text and you want to record it was null.
Nz(Screen.ActiveControl.OldValue,-1) if PriorInfo is numeric and -1 is a safe "null" number.
I am using VB6 in my system. I want to pass the selected row value of a datagrid to the textbox and edit the record. But I'm getting this error every time I run the code. "Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record." Here's my codes in update button. Please help. Thanks in advance! :D
Private Sub cmdEdit_Click()
Dim conn As New Connection
Dim myRS As New Recordset
Dim sql As Integer
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;DataSource=C:\Users\FSCNDCIT\Desktop\GSTD\GSTDdb.mdb"
myRS.CursorLocation = adUseClient
myRS.Open "SELECT * FROM Table1 WHERE ID = '" & DataGrid1.Text & "'", conn, adOpenDynamic, adLockBatchOptimistic
frmGoSee.txtID.Text = myRS!ID 'This line was highlighted.
frmGoSee.txtGSTD.Text = myRS!GSTDCode
frmGoSee.txtGSTDCode.Text = myRS!WorkGroup
frmGoSee.txtTL.Text = myRS!TL
frmGoSee.txtDeptHead.Text = myRS!DeptHead
frmGoSee.txtParticipants.Text = myRS!Participants
frmGoSee.txtCoach.Text = myRS!Coach
frmGoSee.txtProblem_Des.Text = myRS!Problem_Des
frmGoSee.txtMI.Text = myRS!MI
frmGoSee.txtInter_Correction.Text = myRS!Inter_Correction
frmGoSee.txtICWho.Text = myRS!ICWho
frmGoSee.txtICWhen.Text = myRS!ICWhen
frmGoSee.txtICStatus.Text = myRS!ICStatus
frmGoSee.lblpicture.Caption = myRS!Picture
frmGoSee.Image1.Picture = LoadPicture(lblpicture)
myRS.Update
Set myRS = Nothing
conn.Close
End Sub
The error is telling you that the query did not bring back any records. Your code just assumes there will be a record. You should check for an empty recordset before trying to assign values.
Private Sub cmdEdit_Click()
Dim conn As New Connection
Dim myRS As New Recordset
Dim sql As Integer
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;DataSource=C:\Users\FSCNDCIT\Desktop\GSTD\GSTDdb.mdb"
myRS.CursorLocation = adUseClient
myRS.Open "SELECT * FROM Table1 WHERE ID = '" & DataGrid1.Text & "'", conn, adOpenDynamic, adLockBatchOptimistic
If myRS.EOF = False Then
frmGoSee.txtID.Text = myRS!ID 'This line was highlighted.
frmGoSee.txtGSTD.Text = myRS!GSTDCode
frmGoSee.txtGSTDCode.Text = myRS!WorkGroup
frmGoSee.txtTL.Text = myRS!TL
frmGoSee.txtDeptHead.Text = myRS!DeptHead
frmGoSee.txtParticipants.Text = myRS!Participants
frmGoSee.txtCoach.Text = myRS!Coach
frmGoSee.txtProblem_Des.Text = myRS!Problem_Des
frmGoSee.txtMI.Text = myRS!MI
frmGoSee.txtInter_Correction.Text = myRS!Inter_Correction
frmGoSee.txtICWho.Text = myRS!ICWho
frmGoSee.txtICWhen.Text = myRS!ICWhen
frmGoSee.txtICStatus.Text = myRS!ICStatus
frmGoSee.lblpicture.Caption = myRS!Picture
frmGoSee.Image1.Picture = LoadPicture(lblpicture)
'Commented because nothing in the record has changed
'There is nothing to update
'myRS.Update
End If
'checking the state of your objects here before closing would be good practice
If Not myRS Is Nothing Then
If myRS.State = adStateOpen Then
myRS.Close
End If
Set myRS = Nothing
End If
If Not conn Is Nothing Then
If conn.State = adStateOpen Then
conn.Close
End If
Set conn = Nothing
End If
End Sub
this code is to populate textboxes in form where sql query is fatching data from table RR_info on the behalf of hr_id. it compare hr_id of rr_info with the bounded value of listbox.
Private Sub Form_Load()
Dim SQL As String
Dim db As Database
Dim rs As DAO.Recordset
SQL = "select * from RR_info where hr_id = " & Forms![hhrrr]![List38] & ";"
Set db = CurrentDb
Set rs = db.OpenRecordset(SQL)
'DoCmd.RunSQL SQL 'at this point it gives me error 2342
Me.RR_ID.value = rs!RR_ID
Me.HR_ID.value = rs!HR_ID
Me.Room_No.value = rs![Room No]
Me.No_of_Beds.value = rs!No_of_Beds
Me.Room_Category.value = rs!Room_Category
Set rs = Nothing
Set db = Nothing
End Sub
You dont need string "DoCmd.RunSQL SQL".
And it is better to use .Value insted of .Text