Reputation: 303
Is there a way in VBA that allows one to check if a record exists in a database before adding a record?
I tried to capture a select query in a variable:
sSQL = "select count(*) from OptionRestriction where Feature_ID_1 = 1021 AND OptionValue_1 = 3 AND value = 0 AND Feature_ID_2 = 403 AND OptionValue_2 = 5 and visible = 1"
I used the variable in an if statement to check whether the count is not 1. If the statement is true the record should be added:
If sSQL <> "1" Then
conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue As OptionValue_1, 0, OV.FeatureID As Feature_ID_2, OV.OptionValue AS OptionValue_2, 1 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
End If
However this won't work in VBA. Any ideas how I can make this work?
Based on the comments of Vityata, I made the following changes:
I added a function:
Public Function RestrictionCount() As Long
RestrictionCount = DCount("Feature_ID_1", "OptionRestriction", "Feature_ID_1 = 1023 AND OptionValue_1 AND value = 0 AND Feature_ID_2 = 403 AND optionValue_2 = 5 AND visible = 1")
End Function
And used the function in the code where my if resides:
Private Sub CommandButton1_Click()
Dim conn As New ADODB.Connection
conn.Open "<string to connect to DB. Not displayed here due to confidentiality reasons>"
If RestrictionCount() <> 1 Then
conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue As OptionValue_1, 0, OV.FeatureID As Feature_ID_2, OV.OptionValue AS OptionValue_2, 1 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
End If
End Sub
Now I am getting a compile error stating that a sub or function is not defined, while the DCount resides in another function. Is there a way to solve this? Sorry for my questions (I am new to VBA).
The check can now be performed thanks to the last comment of Vityata. The code is now as follows, including the loop I am using to add my data to the database:
rs.ActiveConnection = conn
rs.Open "select * from OptionRestriction where Feature_ID_1 = 1021 AND OptionValue_1 = 3 AND value = 0 AND Feature_ID_2 = 403 AND OptionValue_2 = 5 and visible = 1"
i = 2
Do Until IsEmpty(Cells(i, 1))
s_OptionValue_1_s = ActiveSheet.Cells(i, 1)
value_s = ActiveSheet.Cells(i, 2)
s_OptionValue_2_s = ActiveSheet.Cells(i, 3)
If value_s <> "" Then
If rs.RecordCount <> 1 Then
conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue As OptionValue_1, 0, OV.FeatureID As Feature_ID_2, OV.OptionValue AS OptionValue_2, 1 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
End If
conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue As OptionValue_1, '" & Replace(value_s, "'", "''") & "', OV.FeatureID As Feature_ID_2, OV.OptionValue AS OptionValue_2, 0 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
Else
conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue As OptionValue_1, 1, OV.FeatureID As Feature_ID_2, OV.OptionValue AS OptionValue_2, 0 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
conn.Execute "INSERT INTO OptionRestriction (Feature_ID_1, OptionValue_1, value, Feature_ID_2, OptionValue_2, visible) SELECT TOP(1) CF.FeatureID As Feature_ID_1, CF.OptionValue As OptionValue_1, 0, OV.FeatureID As Feature_ID_2, OV.OptionValue AS OptionValue_2, 1 From Value as CF Cross Join Value as OV INNER JOIN Feature f on CF.FeatureID = f.ID INNER JOIN Feature f_2 on OV.FeatureID = f_2.ID Where CF.Name = '" & Replace(s_OptionValue_1_s, "'", "''") & "' AND OV.Name = '" & Replace(s_OptionValue_2_s, "'", "''") & "'"
End If
i = i + 1
Loop
The result in the database is now:
Yet, the row that is selected should not be there. So it needs to add 1021 - 3 - 0 - 403 - 5 - 1 only once. What do I need to change in my loop to achieve this?
The excel file from which the data is inserted into the database looks like this:
Upvotes: 2
Views: 10598
Reputation: 43575
If you work in MS Excel, this is a sample of what you can use:
Public Sub CheckDataInSQLServer()
Dim cnLogs As Object
Dim rsData As Object
On Error GoTo CheckDataInSQLServer_Error
Set cnLogs = CreateObject("ADODB.Connection")
Set rsData = CreateObject("ADODB.Recordset")
cnLogs.Open ConnectionString 'this is a string function
rsData.ActiveConnection = cnLogs
rsData.Open "SELECT * FROM A WHERE B = C;"
If rsData.EOF Then
debug.print "no values"
Else
debug.print "has values"
End If
End Sub
In VBA the function that you need is called DCount
, if you work with MS Access:
You can use the DCount function to determine the number of records that are in a specified set of records (a domain). Use the DCount function in Visual Basic, a macro, a query expression, or a calculated control. For example, you could use the DCount function in a module to return the number of records in an Orders table that correspond to orders placed on a particular date. MSDN
See more how to use DCount - DCount with 2 criteria
This is a sample how to build DCount
in a function and to use it:
Public Function OrdersCount(ByVal strCountry As String, ByVal dteShipDate As Date) As Long
OrdersCount = DCount("[ShippedDate]", "Orders", _
"[ShipCountry] = '" & strCountry & _
"' AND [ShippedDate] > #" & dteShipDate & "#")
End Function
If OrdersCount("Bulgaria", Now()) = 0 then
'Execute the SQL query.
End if
Upvotes: 1