How to merge two database tables when only some fields are common? - sql

In MS Access I have two tables (A and B), and the task is to insert B into A. However, there are some special conditions:
All fields are of type text.
A and B have a some common fields.
The same key field is guaranteed to exist in both, and its values to be always different.
A has some fields that B does not have. The inserted records should have those fields blank.
B has some fields that A does not have. These fields must be created in A, and the existing records in A should have them blank.
There are many cases like this one, so the query should not explicitly include the field names, since it would be tedious to personalize the query for each case. However, the key field is always named the same.
Creating a new table C instead of directly replacing A is acceptable.
Example:
Table A:
key a b c
--- ------- ------- -------
k0 hello dear world
k1 bye cruel world
Table B:
key a d e
--- ------- ------- -------
k2 welcome john doe
k3 turulu ann harp
Table C (the new A):
key a b c d e
--- ------- ------- ------- ------- -------
k0 hello dear world
k1 bye cruel world
k2 welcome john doe
k3 turulu ann harp

Create an Access Module and use the following code. Replace the values in the test sub with your table and destination names
Option Compare Database
Option Explicit
Function SplatTablesSql(pT1 As String, pT2 As String, pDest As String)
Dim lDb As Database
Dim lTd1 As TableDef, lTd2 As TableDef
Dim lField As Field, lF2 As Field
Dim lS1 As String, lS2 As String, lSep As String
SplatTablesSql = "Select "
lS1 = "Select "
lS2 = "Select "
Set lDb = CurrentDb
Set lTd1 = lDb.TableDefs(pT1)
Set lTd2 = lDb.TableDefs(pT2)
For Each lField In lTd1.Fields
SplatTablesSql = SplatTablesSql & lSep & "x.[" & lField.Name & "]"
lS1 = lS1 & lSep & "a.[" & lField.Name & "]"
Set lF2 = Nothing
On Error Resume Next
Set lF2 = lTd2.Fields(lField.Name)
On Error GoTo 0
If lF2 Is Nothing Then
lS2 = lS2 & lSep & "Null"
Else
lS2 = lS2 & lSep & "b.[" & lField.Name & "]"
End If
lSep = ", "
Next
For Each lField In lTd2.Fields
Set lF2 = Nothing
On Error Resume Next
Set lF2 = lTd1.Fields(lField.Name)
On Error GoTo 0
If lF2 Is Nothing Then
SplatTablesSql = SplatTablesSql & lSep & "x.[" & lField.Name & "]"
lS1 = lS1 & lSep & "Null as [" & lField.Name & "]"
lS2 = lS2 & lSep & "b.[" & lField.Name & "]"
End If
lSep = ", "
Next
SplatTablesSql = SplatTablesSql & " Into [" & pDest & "] From ( " & lS1 & " From [" & pT1 & "] a Union All " & lS2 & " From [" & pT2 & "] b ) x"
End Function
Sub Test()
CurrentDb.Execute SplatTablesSql("a", "b", "c")
End Sub

The easiest way I can think to solve this is to use VBA to create the query definition.
I will assume that there's a column named key which is common to both tables.
I found here that you can use collections to make a dictionary-like structure. I'll use that to build the field list.
So, here we go:
public function contains(col as Collection, key as variant) as boolean
dim obj as variant
on error goto err
contains = True
obj = col(key)
exit function
err:
contains = false
end function
public sub create_this_query(tbl1 as String, tbl2 as String, keyField as String)
' tbl1 and tbl2 are the names of the tables you'll use
dim db as DAO.database, rs1 as DAO.recordset, rs2 as DAO.recordset
dim columns as Collection
dim strSQL as String
dim i as integer
dim obj as variant, colName as String
set db = currentdb()
set tbl1 = db.openrecordset(tbl1, dbopendynaset, dbreadonly)
set tbl2 = db.openrecordset(tbl2, dbopendynaset, dbreadonly)
set columns = new Collection
' Let's create the field list (ommiting the keyField)
for i = 1 to tbl1.fields.count
if not contains(columns, tbl1.fields(i).Name) _
and tbl1.fields(i).Name <> keyField then
columns.add tbl1.fields(i).Name, tbl1.fields(i).Name
end if
next i
for i = 1 to tbl2.fields.count
if not contains(columns, tbl2.fields(i).Name) _
and tbl2.fields(i).Name <> keyField then
columns.add tbl1.fields(i).Name, 1 ' The value is just a placeholder
end if
next i
' Now let's build the SQL instruction
strSQL = "select [a].[" & keyField & "]"
for colName in columns
strSQL = strSQL & ", [" & colName & "]"
next obj
strSQL = strSQL & " " & _
"from " & _
" (" & _
" select [" & keyField & "] from [" & tbl1 & "] " & _
" union " & _
" select [" & keyField & "] from [" & tbl2 & "] " & _
" ) as a " & _
"left join [" & tbl1 & "] as t1 " & _
" on a.[" & keyField & "] = t1.[" & keyField & "] " & _
"left join [" & tbl2 & "] as t2 " & _
" on a.[" & keyField & "] = t2.[" & keyField & "] "
' Finally, let's create the query object
db.createQueryDef("myNewQuery", strSQL)
end sub
Hope this helps

Related

find missing number buckets

I was wondering if there's a better way
I need to find missing number buckets. There's a set of number buckets in which the weights are distributed. I want to make sure that if the user misses a number somewhere, his attention is drawn to it and hes told that he's missing some buckets, otherwise his data for these will not show.
I already found each missing number but it shows a line for each and the user is only interested in the entire bucket.
so, I need the thing on the left to become the thing on the right. The FROM and TO is what I have to work with.
I have a feeling there's some beautiful VBA solution for this, something with arrays :)
Besides all this ugliness that I wrote, to get the original missing weight, I had to create a table with all weights from 0 to 1000. there has to be a better way
Sub sbMissingBuckets()
Dim vrQDF As Object
Dim vrSQL As String
Dim vrQueryName As String
Dim vrCountsMissingBuckets As Long
sbWOff
DoCmd.RunSQL "DELETE FROM MissingServicesShippingWeightBuckets"
Dim vrRs1 As DAO.Recordset
Dim vrServicesShippingWeightCollectionID As Long
Set vrRs1 = CurrentDb.OpenRecordset("SELECT ServicesShippingWeightBuckets.ServicesShippingWeightCollectionID FROM ServicesShippingWeightBuckets GROUP BY ServicesShippingWeightBuckets.ServicesShippingWeightCollectionID " & _
", ServicesShippingWeightBuckets.IsMultiweight HAVING (((ServicesShippingWeightBuckets.IsMultiweight)=False));")
Do Until vrRs1.EOF
vrServicesShippingWeightCollectionID = vrRs1("ServicesShippingWeightCollectionID")
vrSQL = "SELECT ServicesShippingWeightBuckets.ServicesShippingWeightCollectionID, AllWeights.Weight FROM ServicesShippingWeightBuckets " & _
", AllWeights GROUP BY ServicesShippingWeightBuckets.ServicesShippingWeightCollectionID, AllWeights.Weight, IIf([WeightFromInequalitySymbolID]=1,IIf([WeightToInequalitySymbolID]=3,[Weight]>[WeightFrom] " & _
"AND [Weight]<[WeightTo]) & IIf([WeightToInequalitySymbolID]=4,[Weight]>[WeightFrom] AND [Weight]<=[WeightTo]) & IIf(IsNull([WeightToInequalitySymbolID]),[Weight]>[WeightFrom] " & _
"AND [Weight]<=999999999)) & IIf([WeightFromInequalitySymbolID]=2,IIf([WeightToInequalitySymbolID]=3,[Weight]>=[WeightFrom] AND [Weight]<[WeightTo]) & IIf([WeightToInequalitySymbolID]=4,[Weight]>=[WeightFrom] " & _
"AND [Weight]<=[WeightTo]) & IIf(IsNull([WeightToInequalitySymbolID]),[Weight]>=[WeightFrom] AND [Weight]<=999999999)), ServicesShippingWeightBuckets.IsMultiweight " & _
"HAVING (((ServicesShippingWeightBuckets.ServicesShippingWeightCollectionID)=" & vrServicesShippingWeightCollectionID & ") AND ((IIf([WeightFromInequalitySymbolID]=1,IIf([WeightToInequalitySymbolID]=3,[Weight]>[WeightFrom] " & _
"AND [Weight]<[WeightTo]) & IIf([WeightToInequalitySymbolID]=4,[Weight]>[WeightFrom] AND [Weight]<=[WeightTo]) & IIf(IsNull([WeightToInequalitySymbolID]),[Weight]>[WeightFrom] " & _
"AND [Weight]<=999999999)) & IIf([WeightFromInequalitySymbolID]=2,IIf([WeightToInequalitySymbolID]=3,[Weight]>=[WeightFrom] AND [Weight]<[WeightTo]) & IIf([WeightToInequalitySymbolID]=4,[Weight]>=[WeightFrom] " & _
"AND [Weight]<=[WeightTo]) & IIf(IsNull([WeightToInequalitySymbolID]),[Weight]>=[WeightFrom] AND [Weight]<=999999999)))=-1) " & _
"AND ((ServicesShippingWeightBuckets.IsMultiweight)=False)) ORDER BY AllWeights.Weight;"
vrQueryName = "qMissingBucketsBase"
fnDeleteObjectIfExists "Query", vrQueryName
Set vrQDF = CurrentDb.CreateQueryDef(vrQueryName, vrSQL)
'count qMissingBuckets
vrCountsMissingBuckets = dCount("cTo", "qMissingBuckets")
'if 0 do nothing
If vrCountsMissingBuckets > 0 Then
'loop thoruhg and onl add records to the table if the diff is more than 1
DoCmd.OpenQuery "qMissingBuckets2"
DoCmd.OpenQuery "qMissingBuckets3"
Dim vrRs2 As DAO.Recordset
Dim vrFrom As Long
Dim vrTo As Long
Dim vrDiff As Long
Dim vrPlaceholder As Boolean
Dim vrFromPlaceholder As Variant
Set vrRs2 = CurrentDb.OpenRecordset("mtT")
Do Until vrRs2.EOF
vrFrom = vrRs2("cFrom")
vrTo = vrRs2("cTo")
vrDiff = vrRs2("cDiff")
If vrDiff > 1 Then
If vrPlaceholder = False Then
If vrDiff < 99999 Then
DoCmd.RunSQL "INSERT INTO MissingServicesShippingWeightBuckets (ServicesShippingWeightCollectionID, ServicesShippingWeightBucket, WeightFromInequalitySymbolID, WeightFrom, WeightToInequalitySymbolID, WeightTo) SELECT " & vrServicesShippingWeightCollectionID & _
", '>=" & vrFrom & " and <" & vrTo & "', 2 as WeightFromInequalitySymbolID, " & vrFrom & " as WeightFrom, 3 as WeightToInequalitySymbolID, " & vrTo & " as WeightTo"
End If
Else
DoCmd.RunSQL "INSERT INTO MissingServicesShippingWeightBuckets (ServicesShippingWeightCollectionID, ServicesShippingWeightBucket, WeightFromInequalitySymbolID, WeightFrom, WeightToInequalitySymbolID, WeightTo) SELECT " & vrServicesShippingWeightCollectionID & _
", '>=" & vrFromPlaceholder & " and <" & vrTo & "', 2 as WeightFromInequalitySymbolID, " & vrFromPlaceholder & " as WeightFrom, 3 as WeightToInequalitySymbolID, " & vrTo & " as WeightTo"
vrPlaceholder = False
vrFromPlaceholder = Null
End If
ElseIf vrDiff = 1 Then
If vrPlaceholder = False Then
vrFromPlaceholder = vrFrom
vrPlaceholder = True
End If
End If
vrRs2.MoveNext
Loop
vrRs2.Close
Set vrRs2 = Nothing
End If
vrRs1.MoveNext
Loop
vrRs1.Close
Set vrRs1 = Nothing
sbWOn
End Sub

a temp table for updating the values, getting error message saying 'temp table0' already exists, how to navigate this?

I am using a VBA query in Access database for creating a temp table for updating the values, however I am getting error message saying 'temp table0' already exists, how to navigate this?
I am getting error message in 'CurrentProject.Connection.Execute strSql'
rs2.Close 'Close the recordset
Set rs2 = Nothing 'Clean up
'Create temporary tables
Dim tableFlag As String
tableFlag = "Treaty"
For x = 1 To 2
If (rs1![Prems/Claims] = "Premium") Then
If (tableFlag = "Treaty") Then
strSql = "SELECT [Premiums " & tableFlag & "].ID, [Premiums " & tableFlag & "].[Pricing Segment]"
For i = 0 To columnsCount - 1 ' loop through all boolean atributes
strSql = strSql & ", [Premiums " & tableFlag & "].[" & boolAtrName(i) & "]"
Next
strSql = strSql & " INTO [tempTable " & tablesCount & "] FROM [Premiums " & tableFlag & "] WHERE [GDS Version] = " & rs1!ID & ";"
'Execute temporary table string
CurrentProject.Connection.Execute strSql
'Add column percentage to table
CurrentDb.Execute "ALTER TABLE [tempTable " & tablesCount & "] ADD COLUMN Percentage double, Identifier Text"
'Update values in column percentage
Set rs2 = CurrentDb.OpenRecordset("SELECT * FROM [tempTable " & tablesCount & "];")

Update SQL in Access VBA -- Updating Table Values From Another Table

I'm fairly new to Access VBA and SQL coding. So far, I've been able to find most of the answers to issues I've had by using the internet. I'm currently trying to write some code in MS Access (2013) VBA that updates the data in one table from another table in the same database when a particular form closes.
I've worked out several errors so far, but I'm stuck on a syntax error in the "UPDATE" for SQLReplace. There could be other errors that I don't know about yet, but I'm not sure. Any help/Guidance would be greatly appreciated!
Thanks!
Private Sub Form_Close()
Dim SQLMove As String
Dim SQLReplace As String
Dim CountyCaseType As String
Dim CaseNumber As String
Dim County As String
Dim FirstName As String
Dim MiddleName As String
Dim LastName As String
Dim Facility As String
Dim VOL As String
Dim Diagnosis As String
Dim AppearanceWaived As String
Dim Dismissed As String
Dim HearingResults As String
Dim Disposition As String
Dim DOB As String
Dim Minor As String
Dim Sex As String
Dim ClerkName As String
Dim Judge As String
Dim CourtDate As String
CountyCaseType = "Tables!tblTemp.CountyCaseType.Value"
CaseNumber = "Tables!tblTemp.CaseNumber.Value"
County = "Tables!tblTemp.County.Value"
FirstName = "Tables!tblTemp.FirstName.Value"
MiddleName = "Tables!tblTemp.MiddleName.Value"
LastName = "Tables!tblTemp.LastName.Value"
Facility = "Tables!tblTemp.Facility.Value"
VOL = "Tables!tblTemp.VOL.Value"
Diagnosis = "Tables!tblTemp.Diagnosis.Value"
AppearanceWaived = "Tables!tblTemp.AppearanceWaived.Value"
Dismissed = "Tables!tblTemp.Dismissed.Value"
HearingResults = "Tables!tblTemp.HearingResults.Value"
Disposition = "Tables!tblTemp.Disposition.Value"
DOB = "Tables!tblTemp.DOB.Value"
Minor = "Tables!tblTemp.Minor.Value"
Sex = "Tables!tblTemp.Sex.Value"
ClerkName = "Tables!tblTemp.Clerk.Value"
Judge = "Tables!tblTemp.Judge.Value"
CourtDate = "Tables!tblTemp.CourtDate.Value"
SQLMove = "INSERT INTO tblCalendar SELECT * FROM tblTemp"
SQLReplace = "UPDATE tblCalendar " & _
"SET tblCalendar.CountyCaseType.Value = CountyCaseType, " & _
" tblCalendar.CaseNumber.Value = CaseNumber, " & _
" tblCalendar.County.Value = County, " & _
" tblCalendar.FirstName.Value = FirstName, " & _
" tblCalendar.MiddleName.Value = MiddleName, " & _
" tblCalendar.LastName.Value = LastName, " & _
" tblCalendar.Facility.Value = Facility, " & _
" tblCalendar.VOL.Value = VOL, " & _
" tblCalendar.Diagnosis.Value = Diagnosis, " & _
" tblCalendar.AppearanceWaived.Value = AppearanceWaived, " & _
" tblCalendar.Dismissed.Value = Dismissed, " & _
" tblCalendar.HearingResults.Value = HearingResults, " & _
" tblCalendar.Disposition.Value = Disposition, " & _
" tblCalendar.DOB.Value = DOB, " & _
" tblCalendar.Minor.Value = Minor, " & _
" tblCalendar.Sex.Value = Sex, " & _
" tblCalendar.ClerkName.Value = Clerk, " & _
" tblCalendar.Judge.Value = Judge, " & _
"FROM tblTemp " & _
"Where 'CourtDate = tblCalendar.CourtDate.Value'"
DoCmd.SetWarnings False
DoCmd.RunSQL (SQLMove)
DoCmd.RunSQL (SQLReplace)
DoCmd.SetWarnings True
End Sub
There are several potential errors in your code:
You do not need to add .Value to the end of an attribute to get its actual value.
As you are working directly in Access, you to not need the Tables! part either. That is the syntax used when dealing with recordsets. For example, write tblTemp.CountyCaseType instead of Tables!tblTemp.CountyCaseType.Value
The values of your variables are not in the SQL string. You have to concatenate them to the SQLReplace String using [&]. For example, write
SQLReplace = "UPDATE tblCalendar " & _
"SET tblCalendar.CountyCaseType = " & CountyCaseType & ", " & _
" tblCalendar.CaseNumber = " & CaseNumber & ", " & _
....
As #AlanHadsell pointed out, remove the single quotes from the WHERE clause.
Where 'CourtDate = tblCalendar.CourtDate.Value'
should be
WHERE CourtDate = tblCalendar.CourtDate
But as I said in 3) CourTDate is a String variable, so it needs to be concatenated. Your final WHERE clause should be:
"WHERE " & CourtDate & " = tblCalendar.CourtDate"
You don't need the FROM tblTemp clause in the SQLReplace String.
EDIT: As #Parfait pointed out, tblTemp does not exist in scope of the SQLReplace statement. You should do an INNER JOIN to fix that:
UPDATE tblCalendar INNER JOIN tblTemp ON tblCalendar.CourtDate = tblTemp.CourtDate SET ...
After fixing everything, your final code should look like:
Private Sub Form_Close()
Dim SQLMove As String
Dim SQLReplace As String
Dim CountyCaseType As String
Dim CaseNumber As String
Dim County As String
Dim FirstName As String
Dim MiddleName As String
Dim LastName As String
Dim Facility As String
Dim VOL As String
Dim Diagnosis As String
Dim AppearanceWaived As String
Dim Dismissed As String
Dim HearingResults As String
Dim Disposition As String
Dim DOB As String
Dim Minor As String
Dim Sex As String
Dim ClerkName As String
Dim Judge As String
Dim CourtDate As String
CountyCaseType = "tblTemp.CountyCaseType"
CaseNumber = "tblTemp.CaseNumber"
County = "tblTemp.County"
FirstName = "tblTemp.FirstName"
MiddleName = "tblTemp.MiddleName"
LastName = "tblTemp.LastName"
Facility = "tblTemp.Facility"
VOL = "tblTemp.VOL"
Diagnosis = "tblTemp.Diagnosis"
AppearanceWaived = "tblTemp.AppearanceWaived"
Dismissed = "tblTemp.Dismissed"
HearingResults = "tblTemp.HearingResults"
Disposition = "tblTemp.Disposition"
DOB = "tblTemp.DOB"
Minor = "tblTemp.Minor"
Sex = "tblTemp.Sex"
ClerkName = "tblTemp.Clerk"
Judge = "tblTemp.Judge"
CourtDate = "tblTemp.CourtDate"
SQLMove = "INSERT INTO tblCalendar SELECT * FROM tblTemp"
SQLReplace = "UPDATE tblCalendar " & _
"INNER JOIN tblTemp ON tblCalendar.CourtDate = tblTemp.CourtDate " & _
"SET tblCalendar.CountyCaseType = " & CountyCaseType & ", " & _
" tblCalendar.CaseNumber = " & CaseNumber & ", " & _
" tblCalendar.County = " & County & ", " & _
" tblCalendar.FirstName = " & FirstName & ", " & _
" tblCalendar.MiddleName = " & MiddleName & ", " & _
" tblCalendar.LastName = " & LastName & ", " & _
" tblCalendar.Facility = " & Facility & ", " & _
" tblCalendar.VOL = " & VOL & ", " & _
" tblCalendar.Diagnosis = " & Diagnosis & ", " & _
" tblCalendar.AppearanceWaived = " & AppearanceWaived & ", " & _
" tblCalendar.Dismissed = " & Dismissed & ", " & _
" tblCalendar.HearingResults = " & HearingResults & ", " & _
" tblCalendar.Disposition = " & Disposition & ", " & _
" tblCalendar.DOB = " & DOB & ", " & _
" tblCalendar.Minor = " & Minor & ", " & _
" tblCalendar.Sex = " & Sex & ", " & _
" tblCalendar.ClerkName = " & Clerk & ", " & _
" tblCalendar.Judge = " & Judge
DoCmd.SetWarnings False
DoCmd.RunSQL (SQLMove)
DoCmd.RunSQL (SQLReplace)
DoCmd.SetWarnings True
End Sub
To finish, instead of declaring a String variable for each attributes in tableTemp that you want to copy, and then assigning some values to them, you can simply omit the declarations and put the attributes dicrectly in the SQL. That will geatly reduce the length of your code as follow:
Private Sub Form_Close()
Dim SQLMove As String
Dim SQLReplace As String
SQLMove = "INSERT INTO tblCalendar SELECT * FROM tblTemp"
SQLReplace = "UPDATE tblCalendar " & _
"INNER JOIN tblTemp ON tblCalendar.CourtDate = tblTemp.CourtDate " & _
"SET tblCalendar.CountyCaseType = tblTemp.CountyCaseType, " & _
" tblCalendar.CaseNumber = tblTemp.CaseNumber, " & _
" tblCalendar.County = tblTemp.County, " & _
" tblCalendar.FirstName = tblTemp.FirstName, " & _
" tblCalendar.MiddleName = tblTemp.MiddleName, " & _
" tblCalendar.LastName = tblTemp.LastName, " & _
" tblCalendar.Facility = tblTemp.Facility, " & _
" tblCalendar.VOL = tblTemp.VOL, " & _
" tblCalendar.Diagnosis = tblTemp.Diagnosis, " & _
" tblCalendar.AppearanceWaived = tblTemp.AppearanceWaived, " & _
" tblCalendar.Dismissed = tblTemp.Dismissed, " & _
" tblCalendar.HearingResults = tblTemp.HearingResults, " & _
" tblCalendar.Disposition = tblTemp.Disposition, " & _
" tblCalendar.DOB = tblTemp.DOB, " & _
" tblCalendar.Minor = tblTemp.Minor, " & _
" tblCalendar.Sex = tblTemp.Sex, " & _
" tblCalendar.ClerkName = tblTemp.ClerkName, " & _
" tblCalendar.Judge = tblTemp.Judge"
DoCmd.SetWarnings False
DoCmd.RunSQL (SQLMove)
DoCmd.RunSQL (SQLReplace)
DoCmd.SetWarnings True
End Sub
Remove the single quotes from "Where 'CourtDate = tblCalendar.CourtDate.Value'"

access 2013 increasing quantity in a table field

Good day. I'm a little stumped about what is happening in my code. I have a userform which collects txtQntyRecd and cboSupplySource. I calculate the lookupValue. And it works just fine. It successfully places the txtQntyRecd in the correct tblWarehouseLocations.WQuantity location. The code is:
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = '" & Me.txtQntyRecd & "'" & _
"WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
CurrentDb.Execute updateQnty, dbFailOnError
What I want to do is add the next quantity to the same location. I get weird results if I change the SET statement to the following:
SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + '" & Me.txtQntyRecd & "'"
If I put 200 in the first statement, I get 200 in my WQuantity field. When I change to the second statement and I try to add 1 to the 200 I get a result of 211. If I add 1 again, the result is 223. Add 1 again, the result is 236.
Could someone explain what is happening and why the results aren't 201, 202 and 203? In the future I will need to subtract quantities from WQuantity as well.
Thanks
You're adding quotes around an integer and appending it as a string. Change it to:
".....
SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + " & val(Me!txtQntyRecd) & "....
...."
I've changed the . to a ! as I think it's still a nice distinction between objects properties and controls, and used the val function as it converts the string number value to the integer value.
This is your query in full:
' When I use values from controls, I like to store them in vars
Dim quantityReceived As integer
quantityReceived = val(Me!txtQntyRecd)
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = tblWarehouseLocations.WQuantity + " & quantityReceived & _
" WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
I solved the problem. I created a SELECT query to get the present amount in WQuantity. Now quantityReceived = Me!txtQntyRecd + the present amount. With SET tblWarehouseLocations.WQuantity = " & quantityReceived it works fine. However, if just seems so cumbersome.
' lookupValue gives the index into the tblWarehouseLocations where WQuantity resides
Dim lookupValue As Integer
lookupValue = DLookup("[WLocation_ID]", "[tblWarehouseLocations]", "[Location_Name] = '" & Me.cboWLocation & "'")
'Define SQL Query
strSQL = "select tblWarehouseLocations.WQuantity FROM tblWarehouseLocations WHERE (((tblWarehouseLocations.WLocation_ID)= " & lookupValue & "))"
Set rs = db.OpenRecordset(strSQL)
If IsNull(rs!WQuantity) Then
dbvalue = 0
Else
dbvalue = rs!WQuantity
End If
Dim quantityReceived As Integer
quantityReceived = Val(Me!txtQntyRecd) + dbvalue
updateQnty = "UPDATE tblSupplySources INNER JOIN ((tblWarehouseLocations " & _
"INNER JOIN tblSupplySource_WarehouseLocation ON tblWarehouseLocations.WLocation_ID = tblSupplySource_WarehouseLocation.SWLocation_ID)) " & _
"ON tblSupplySources.SupplySourceID = tblSupplySource_WarehouseLocation.Supply_Source_ID " & _
"SET tblWarehouseLocations.WQuantity = " & quantityReceived & _
" WHERE (((tblSupplySource_WarehouseLocation.Supply_Source_ID)= " & Me.cboSupplySource & ") " & _
" AND ((tblWarehouseLocations.WLocation_ID)=" & lookupValue & "))"
CurrentDb.Execute updateQnty, dbFailOnError

data type mismatch error with OpenRecordSet

Using Access 2007. I'm trying to write a VBA function that will construct a query from the table name, fields, and values that I pass as parameters. I keep getting a "Run-time error '3464': Data type mismatch in criteria expression."
Here's the code:
Function getPrimaryFromForeign(db As Database, table As String, field As String, _
value As Long, _
field2 As String, value2 As Long) As Long
Dim sStr As String
Dim istr As String
Dim rs As Recordset
sStr = "select * from " & table & " where " _
& field & "='" & value & "' and " & field2 & "='" & value2 & "'"
istr = "insert into " & table & "(" & _
field & "," & field2 & ") values ('" & value & "','" & value2 & "')"
Set rs = db.OpenRecordset(sStr)
If rs.RecordCount < 1 Then
db.Execute (istr), dbFailOnError
Set rs = db.OpenRecordset(sStr)
End If
getPrimaryFromForeign = rs("id")
End Function
The error occurs at the line:
Set rs = db.OpenRecordset(sStr)
I think it has something to do with the variable types of Value and Value2. But I've checked them using typename(), and they're both Long when OpenRecordSet() is called. The query is on a table where both of those fields are of type Number. So why is there a type mismatch?
This can occur if you have both DAO and an ADO in you reference library.
In this case declaration order in both your Dim statements and in the references window matters.
1) "You must reference and use both DAO and ADO Recordset objects, dimension the objects explicitly as follows:
Dim adoRS As ADODB.Recordset
Dim daoRS As DAO.Recordset"
2) "Make sure that the reference for the DAO object library has a higher priority in the References dialog box, or clear the reference to Microsoft ActiveX Data Objects."
see Here:
https://support.microsoft.com/en-us/help/181542/you-receive-a-type-mismatch-error-when-you-run-the-openrecordset-metho
I haven't used Access in a long time, but I think that the problem is because you're enclosing Value and Value2 in single quotes in your SQL statement, and not enclosing the fields in the WHERE clause in brackets.
Try it like this:
sStr = "select * from " & table & " where [" _
& field & "] = " & value & " and [" & field2 & "] = " & value2
istr = "insert into " & table & "([" & _
field & "], [" & field2 & "]) values (" & value & "," & value2 & ")"