SQL/ACCESS Function Not Working As Intended - sql

Public Function GetPendingChangeOrders(strJ As String) As Double
strSQL = "SELECT DISTINCT Sum(jcdetail.cost) AS SumOfcost " &
"FROM jcchangeorder INNER JOIN jcdetail ON (jcchangeorder.ordernum = jcdetail.ponum) AND (jcchangeorder.jobnum =jcdetail.jobnum) " &
"GROUP BY jcdetail.jobnum, jcdetail.type, jcchangeorder.type, IIf(DLookUp(""type"",""jcchangeorderstep"",""jobnum = '"" & [jcchangeorder].[jobnum] & ""' and ordernum = '"" & [ordernum] & ""' and Type = 20"")=20,-1,0) " & _
"HAVING (((jcdetail.jobnum)='" & strJ & "') AND ((jcdetail.type)=19) AND ((jcchangeorder.type)<>2) AND ((IIf(DLookUp(""type"",""jcchangeorderstep"",""jobnum = '"" & [jcchangeorder].[jobnum] & ""' and ordernum = '"" & [ordernum] & ""' and Type = 20"")=20,-1,0))=0));"
Set rs = dbs.OpenRecordset(strSQL, dbOpenSnapshot, dbReadOnly, dbReadOnly)
If Not rs.EOF Then
dblResult = Nz(rs.Fields(0), 0)
rs.Close
Set rs = Nothing
GetPendingChangeOrders = dblResult
Else
GetPendingChangeOrders = 0
End If
End Function
So I got tossed into some MS-Access database with VBA/SQL statements all over.
I am literally a beginner, but I have managed to figure some things out, and familiarize myself with our database that we use to print out job reports.
Some of the call functions are setup wrong, and are pulling from the wrong tables, and I basically need some help figuring out which way I should be going to tackle this.
Currently if we run the report, and it calls "GetPendingChangeOrders" it does what it is supposed to do, but when we look at what is under pending.
It shows a result even though it has a status of 21(DENIED) inside of "JCCHANGEORDERSTEP" table. I included images of it.
JCCHANGEORDER has the same as columns as JCCHANGEORDERSTEP(JOBNUM,ORDERNUM,TYPE) but the types in JCCHANGEORDER just has a type of 1 which I assume says hey I'm active.
JCCHANGEORDERSTEP contains 1 initiated (pending), 20 (approved), 21(denied). It filters out the 20's from results on report, but not 21. So I just need some help, and an explanation of why just adding 21 into the mix didn't work.
Thank you for your time.
EDIT-1 ADDED IMGS
IMGUR ACCESS PICTURES

Having looked at your images and studied your existing SQL code, I think the following SQL query may be more suitable and altogether more readable:
select sum(d.cost) as sumofcost
from
(
jcchangeorder o inner join jcdetail d
on o.ordernum = d.ponum and o.jobnum = d.jobnum
) inner join
(
select distinct s.jobnum, s.ordernum
from jcchangeorderstep s
where s.type = 1
) q
on o.jobnum = q.jobnum and o.ordernum = q.ordernum
where
o.jobnum = ?job and d.type = 19 and o.type <> 2
Here, the inclusion of jcdetail records for which the jcchangeorderstep.type = 1 is handled by the inner join between the tables, rather than a separate dlookup for every record.
You could implement this in your function in the following way:
Public Function GetPendingChangeOrders(strJ As String) As Double
Dim strS As String
strS = strS & "select sum(d.cost) "
strS = strS & "from "
strS = strS & " ( "
strS = strS & " jcchangeorder o inner join jcdetail d "
strS = strS & " on o.ordernum = d.ponum and o.jobnum = d.jobnum "
strS = strS & " ) inner join "
strS = strS & " ( "
strS = strS & " select distinct s.jobnum, s.ordernum "
strS = strS & " from jcchangeorderstep s "
strS = strS & " where s.type = 1 "
strS = strS & " ) q "
strS = strS & " on o.jobnum = q.jobnum and o.ordernum = q.ordernum "
strS = strS & "where "
strS = strS & " o.jobnum = ?job and d.type = 19 and o.type <> 2 "
Dim rst As DAO.Recordset
With CurrentDb.CreateQueryDef("", strS)
.Parameters(0) = strJ
Set rst = .OpenRecordset
If Not rst.EOF Then
rst.MoveFirst
GetPendingChangeOrders = Nz(rst.Fields(0), 0)
End If
rst.Close
End With
End Function
EDIT:
Following the subsequent comments, the following seems more aligned with your requirements:
select sum(d.cost)
from
jcchangeorder o inner join jcdetail d
on o.ordernum = d.ponum and o.jobnum = d.jobnum
where
o.jobnum = jobparam and
d.type = 19 and
o.type <> 2 and
not exists
(
select 1 from jcchangeorderstep s
where s.jobnum = o.jobnum and s.ordernum = o.ordernum and s.type <> 1
)
This may be implemented in your VBA function in the following way:
Public Function GetPendingChangeOrders(strJ As String) As Double
Dim strS As String
strS = strS & "select sum(d.cost) "
strS = strS & "from "
strS = strS & " jcchangeorder o inner join jcdetail d "
strS = strS & " on o.ordernum = d.ponum and o.jobnum = d.jobnum "
strS = strS & "where "
strS = strS & " o.jobnum = jobparam and "
strS = strS & " d.type = 19 and "
strS = strS & " o.type <> 2 and "
strS = strS & " not exists "
strS = strS & " ( "
strS = strS & " select 1 from jcchangeorderstep s "
strS = strS & " where s.jobnum = o.jobnum and s.ordernum = o.ordernum and s.type <> 1 "
strS = strS & " ) "
Dim rst As DAO.Recordset
With CurrentDb.CreateQueryDef("", strS)
.Parameters("jobparam") = strJ
Set rst = .OpenRecordset
If Not rst.EOF Then
rst.MoveFirst
GetPendingChangeOrders = Nz(rst.Fields(0), 0)
End If
rst.Close
End With
End Function

This part of the query in your HAVING and GROUP BY clauses is what's giving you problems:
IIf(DLookUp("type",
"jcchangeorderstep",
"jobnum = ' [jcchangeorder].[jobnum] ' and
ordernum = ' [ordernum] ' and
Type = 20")=20,-1,0))=0);
It's convoluted and very difficult to read. But it is saying, "If this job and order appears in JCCHANGEORDERSTEP with a type of 20, exclude it." So, that's what you need to fix.
The whole query should probably be fixed in a variety of ways. But I think this might get you where you need to go.
strSQL = "SELECT DISTINCT Sum(jcdetail.cost) AS SumOfcost " & _
"FROM jcchangeorder " & _
"INNER JOIN jcdetail " & _
"ON (jcchangeorder.ordernum = jcdetail.ponum) " & _
"AND (jcchangeorder.jobnum =jcdetail.jobnum) " & _
"GROUP BY jcdetail.jobnum, " & _
"jcdetail.type, " & _
"jcchangeorder.type, " & _
"DLookUp(""type"",""jcchangeorderstep"",""jobnum = '"" & [jcchangeorder].[jobnum] & ""' and ordernum = '"" & [ordernum] & ""' and Type = 1"") " & _
"HAVING (jcdetail.jobnum='" & strJ & "' AND " & _
"jcdetail.type=19 AND " & _
"jcchangeorder.type <> 2) AND " & _
"DLookUp(""type"",""jcchangeorderstep"",""jobnum = '"" & [jcchangeorder].[jobnum] & ""' and ordernum = '"" & [ordernum] & ""' and Type = 1"")=1;"
What I have done is changed to condition to say "If this job and order appears in JCCHANGEORDERSTEP with a type of 1, include it." Without actually seeing your data and testing the code myself, I can't promise this will work. There may be some typos, so I've explained what I'm trying to do, so you can fix them.
Also, take some time to go through the Stack Overflow tour. This community can be a great help if you work with it.
Try This:
After discussing the desired results with the OP, it appears that this would be a better solution. It gives the sum of all change orders that only have a change order step of PENDING.
strSQL = _
"SELECT SUM(JCD.cost) AS sumofcost " & _
"FROM jcchangeorder JCCO " & _
"INNER JOIN jcdetail JCD " & _
"ON JCCO.ordernum = jcd.ponum " & _
"AND JCCO.jobnum = jcd.jobnum " & _
"INNER JOIN (SELECT JCCOS.ponum, " & _
"JCCOS.jobnum " & _
"FROM jcchangeorderstep JCCOS " & _
"GROUP BY JCCOS.ponum, " & _
"JCCOS.jobnum " & _
"HAVING Count(*) = 1 " & _
"AND First(JCCOS.type) = 1) JCSELECT " & _
"ON JCCO.ordernum = JCSELECT.ponum " & _
"AND JCCO.jobnum = JCSELECT.jobnum " & _
"GROUP BY JCD.jobnum, " & _
"JCD.type, " & _
"JCCO.type "
"HAVING JCD.jobnum='" & strJ & "' AND " & _
"JCD.type=19 AND " & _
"JCCO.type <> 2;"
JCCO, JCCOS, and JCD are SQL aliases. SQL understands them. JCSELECT is an aliased subquery. JCSELECT creates a set of all job/orders that only have a step of PENDING.

Related

Dynamically run strings in a loop

I want to run a string dynamically.
I'm trying to run a VBA loop to build a SQL Union for each record after the first. There could be anywhere from 1 record to 100. I want this to be dynamic so I don't have to limit the number of entries.
Example:
If I have 5 records it creates the SQL query with 4 unions. All the same data etc.
I'm trying to do is this:
When someone opens a form they will enter a list of pack numbers, from that they will select the range of offers under each pack number (All Offers, Promo, or Buyer).
The code then builds a union query for each pack number based on the the offer range they selected.
The output is all the data on those Offers under that pack number.
My full code: (I thought it necessary to get the full picture)
Private Sub ReviewButton_Click()
Dim Owner As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim qdfPassThrough As QueryDef
Dim strSeasonSQL As String
Dim strSeason As String
Dim strType As String
Owner = GetNamespace("MAPI").Session.CurrentUser.AddressEntry
If Me.NewRecord = True Then
Me!Owner.Value = Owner
End If
Set db = CurrentDb
Set rs = CurrentDb.OpenRecordset("RetailEntry")
'Set rs = CurrentDb.OpenRecordset("SELECT * FROM RetailEntry")
strSeason = [Forms]![Retail_Navigation]![NavigationSubform].[Form]![cboSeason]
strType = rs.Fields("Offer").Value '[Forms]![ReviewButton]![RetailEntry].[Form]![Offer].Value
On Error GoTo 1
1:
'Build Initial Query based on first record and make sure there are records
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'All Offers
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If rs.Fields("Offer") = "All Offers" Then
StrSQL = "Set NoCount ON DROP TABLE #catcov; " _
& "SELECT DISTINCT mailyear, offer, description, firstreleasemailed, season_id, offer_type, " _
& "case when description like '%Promo%' then 'Promo' " _
& "Else 'Buyer' end As addtype " _
& "INTO #catcov " _
strSELECT = "FROM supplychain_misc.dbo.catcov; " _
& "SELECT DISTINCT " _
& "a.PackNum " _
& ",a.Description " _
& ",a.CatID " _
& ",DATEPART(QUARTER, FirstReleaseMailed) as Quarter " _
& ",a.RetOne " _
& ",a.Ret2 " _
& ",a.ORIGINALRETAIL " _
& ",a.DiscountReasonCode " _
& ",b.Season_id " _
& ",a.year " _
& ",addtype "
strFROM = "FROM PIC704Current a JOIN #CatCov b ON (a.CatID = b.Offer) and (a.Year = b.MailYear) " _
strWHERE = "WHERE b.Offer_Type In('catalog', 'insert', 'kicker', 'statement insert', 'bangtail', 'onsert', 'outside ad') " _
& " and b.Season_id = '" & strSeason & "' " _
& " and (Case when b.FirstReleaseMailed >= cast(dateadd(day, +21, getdate()) as date) then 1 else 0 end) = 1 "
StrSQL = StrSQL & vbCrLf & strSELECT & vbCrLf & strFROM & vbCrLf & strWHERE
'Promo/Core
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
ElseIf rs.Fields("Offer") = "Promo" Or rs.Fields("Offer") = "Buyer" Then
StrSQL = "Set NoCount ON DROP TABLE #catcov; " _
& "SELECT DISTINCT mailyear, offer, description, firstreleasemailed, season_id, offer_type, " _
& "case when description like '%Promo%' then 'Promo' " _
& "Else 'Buyer' end As addtype " _
& "INTO #catcov " _
strSELECT = "FROM supplychain_misc.dbo.catcov; " _
& "SELECT DISTINCT " _
& "a.PackNum " _
& ",a.Description " _
& ",a.CatID " _
& ",DATEPART(QUARTER, FirstReleaseMailed) as Quarter " _
& ",a.RetOne " _
& ",a.Ret2 " _
& ",a.ORIGINALRETAIL " _
& ",a.DiscountReasonCode " _
& ",b.Season_id " _
& ",a.year " _
& ",addtype "
strFROM = "FROM PIC704Current a JOIN #CatCov b ON (a.CatID = b.Offer) and (a.Year = b.MailYear) " _
strWHERE = "WHERE b.Offer_Type In('catalog', 'insert', 'kicker', 'statement insert', 'bangtail', 'onsert', 'outside ad') " _
& " and b.Season_id = '" & strSeason & "' and b.addtype = '" & strType & "' " _
& " and (Case when b.FirstReleaseMailed >= cast(dateadd(day, +21, getdate()) as date) then 1 else 0 end) = 1 "
StrSQL = StrSQL & vbCrLf & strSELECT & vbCrLf & strFROM & vbCrLf & strWHERE
End If
'Build/Loop Unions for each record after the first
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
rs.MoveNext
strType = rs.Fields("Offer").Value
Do Until rs.EOF = True
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'All Offers
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If rs.Fields("Offer") = "All Offers" Then
StrUnion = "UNION SELECT DISTINCT " _
& "a.PackNum " _
& ",a.Description " _
& ",a.CatID " _
& ",DATEPART(QUARTER, FirstReleaseMailed) as Quarter " _
& ",a.RetOne " _
& ",a.Ret2 " _
& ",a.ORIGINALRETAIL " _
& ",a.DiscountReasonCode " _
& ",b.Season_id " _
& ",a.year " _
& ",addtype "
strFROMnxt = "FROM PIC704Current a JOIN #CatCov b ON (a.CatID = b.Offer) and (a.Year = b.MailYear) " _
strWHEREnxt = "WHERE b.Offer_Type In('catalog', 'insert', 'kicker', 'statement insert', 'bangtail', 'onsert', 'outside ad') " _
& " and b.Season_id = '" & strSeason & "' " _
& " and (Case when b.FirstReleaseMailed >= cast(dateadd(day, +21, getdate()) as date) then 1 else 0 end) = 1 "
StrSQL2 = StrUnion & vbCrLf & strFROMnxt & vbCrLf & strWHEREnxt
'Promo/Buyer
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
ElseIf rs.Fields("Offer") = "Promo" Or rs.Fields("Offer") = "Buyer" Then
StrUnion = "UNION SELECT DISTINCT " _
& "a.PackNum " _
& ",a.Description " _
& ",a.CatID " _
& ",DATEPART(QUARTER, FirstReleaseMailed) as Quarter " _
& ",a.RetOne " _
& ",a.Ret2 " _
& ",a.ORIGINALRETAIL " _
& ",a.DiscountReasonCode " _
& ",b.Season_id " _
& ",a.year " _
& ",addtype "
strFROMnxt = "FROM PIC704Current a JOIN #CatCov b ON (a.CatID = b.Offer) and (a.Year = b.MailYear) " _
strWHEREnxt = "WHERE b.Offer_Type In('catalog', 'insert', 'kicker', 'statement insert', 'bangtail', 'onsert', 'outside ad') " _
& " and b.Season_id = '" & strSeason & "' and b.addtype = '" & strType & "' " _
& " and (Case when b.FirstReleaseMailed >= cast(dateadd(day, +21, getdate()) as date) then 1 else 0 end) = 1 "
StrSQL2 = StrUnion & vbCrLf & strFROMnxt & vbCrLf & strWHEREnxt
End If
'Move to next Record and loop till EOF
rs.MoveNext
Loop
'If there are no Records then error
Else
MsgBox "There are no Pack Numbers Entered."
End If
'END QUERY
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Build Retail Bump File Pass Through Query
db.QueryDefs.Delete "qryMaster"
Set qdfPassThrough = db.CreateQueryDef("qryMaster")
qdfPassThrough.Connect = "ODBC;DSN=SupplyChainMisc;Description=SupplyChainMisc;Trusted_Connection=Yes;DATABASE=SupplyChain_Misc;"
qdfPassThrough.ReturnsRecords = True
qdfPassThrough.sql = StrSQL & vbCrLf & StrSQL2
rs.Close
Set rs = Nothing
DoCmd.OpenForm "SubCanButton"
DoCmd.OpenQuery "MasterQuery"
DoCmd.Close acForm, "ReviewButton"
End Sub
First, you do a "union distinct" when you don't include ALL:
UNION ALL
SELECT DISTINCT ...
Thus, as your selected records seem the same, only one will returned.
Second, including ALL or not, your concept doesn't make much sense. Why union a lot of identical records? Even if they hold different IDs only, they seem to be pulled from the same table, which you could with a single query.
Third, casting a date value to a date value does nothing good, so:
cast(dateadd(day, +21, getdate()) as date)
can be reduced to:
dateadd(day, +21, getdate())

VBA - Get all value in Array as subsequent strings

I have connected VBA & SQL Database in order to pull information.
I have written a script that returns exactly what I want but I would like to make it dynamical (Change years used etc.) and I am here running into problems.
I need to have a special line in my SQL Query which only has 1 thing that changes between the lines (Number of lines need to change and the Case when y.Date_Year = )
I get an Error message in the below code saying that there is a Type mismatch at the " & " sign right above my "period ()" array.
Sub test()
Dim SQLDB As ADODB.Connection
Dim sQuery As String
Dim info()
Dim Start_D As String
Dim End_D As String
Dim Numerator_Used As String
Dim Denominator_Used As String
Dim Number_Years As Integer
Dim period()
Numerator_Used = Range("Numerator")
Denominator_Used = Range("Denominator")
Start_D = Range("Start_Date")
End_D = Range("End_Date")
Range("A11:J100000").Cells.ClearContents
Number_Years = End_D - Start_D
ReDim period(Number_Years + 1)
For i = 0 To Number_Years
period(i + 1) = ",sum(case when y.date_year = " & Start_D + i & " then n." & Numerator_Used & " end) / sum(case when y.date_year = " & Start_D + i & " then s." & Denominator_Used & " end) as '" & Numerator_Used & "/" & Denominator_Used & " " & Start_D + i & "' & _ "
Next i
' Get Margin Expectation Changes
sQuery ="select m.date_month" & _
" m.date_month " & _
period() & _
" from " & Numerator_Used & " as n" & _
" inner join " & Denominator_Used & " as s on s.company_id = n.company_id" & _
" and s.date_month_id = n.date_month_id" & _
" and s.date_year_id = n.date_year_id" & _
" inner join date_year as y on y.date_year_id = n.date_year_id" & _
" inner join date_month as m on m.date_month_id = n.date_month_id" & _
" where y.date_year between " & Start_D & " and " & End_D & " " & _
" and n." & Numerator_Used & " <> 0" & _
" and s." & Denominator_Used & " <> 0" & _
" group by m.date_month;"
Set rs = Common.SQL_Read(SQLDB, sQuery)
ThisWorkbook.Worksheets("Sheet1").Range("A11").CopyFromRecordset rs
Set SQLDB = Common.SQL_Close(SQLDB)
End Sub
As i mentioned in the ocmment to the question, you can not explicity convert period() data into string as it is an array of variant data type (each undefined variable is treated as variant data type). You have to loop through the array data, i.e.:
For i = LBound(period()) To UBound(period())
sQuery = sQuery & period(i) & "...."
Next
'finally:
sQuery = "SELECT ... " & sQuery & " ...."
Change the code as i mentioned above and let me know if it works.

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

Displaying "Similar" or "Related" Vehicles

I have a vehicle database and would like to show "related" vehicles when a user clicks to view a vehicle. For instance, the user views a '2013 Chevy Tahoe' that is listed by dealership 'ABC Dealers'.
I need to create a SQL statement to grab 4 vehicles that are similar to the vehicle they are viewing. Here is the order of importance for now:
1) Dealer Listings (d_id)(Show vehicles also listed by that dealer)
2) Vehicle Category (vc_id)(Vehicle category such as Car, Truck, SUV, etc.)
3) Vehicle Make (vm_id)(Vehicle make such as Ford, Chevy, Lexus, etc.)
I have created a SQL statement, but it does not seem to do what I am looking for it to do. Can anyone offer any suggestions on how to properly build a SQL statement to grab the most relevant records in the order defined above?
strSQL = "SELECT TOP 4 v.v_id, vm.vm_name, v.v_year, v.v_model, v.v_search_price, d.d_name, u.u_name " & _
"FROM tbl_Vehicles v " & _
"LEFT JOIN tbl_VehicleMake vm ON vm.vm_id = v.vm_id " & _
"LEFT JOIN tbl_Dealers d ON d.d_id = v.d_id " & _
"LEFT JOIN tbl_Users u ON u.u_id = v.u_id " & _
"WHERE v.v_processed = 1 AND v.v_active = 1 AND v.v_id <> " & v_id
If Not CheckBlank(d_id) Then
strSQL = strSQL & " OR v.d_id = " & d_id
End If
If Not CheckBlank(vm_id) Then
strSQL = strSQL & " OR v.vm_id = " & vm_id
End If
If Not CheckBlank(vc_id) Then
strSQL = strSQL & " OR v.vc_id = " & vc_id
End If
strSQL = strSQL & " ORDER BY v.d_id, v.vc_id, v.vm_id"
I have a couple of thoughts for you.
Your current query has some ANDs and some ORs. You may need brackets to indicate your preferred order of operations, for example:
strSQL = "SELECT TOP 4 v.v_id, vm.vm_name, v.v_year, v.v_model, v.v_search_price, d.d_name, u.u_name " & _
"FROM tbl_Vehicles v " & _
"LEFT JOIN tbl_VehicleMake vm ON vm.vm_id = v.vm_id " & _
"LEFT JOIN tbl_Dealers d ON d.d_id = v.d_id " & _
"LEFT JOIN tbl_Users u ON u.u_id = v.u_id " & _
"WHERE v.v_processed = 1 AND v.v_active = 1 AND v.v_id <> " & v_id
If Not CheckBlank(d_id) Or Not CheckBlank(vm_id) Or Not CheckBlank(vc_id) Then
strSQL = strSQL & "("
End If
If Not CheckBlank(d_id) Then
strSQL = strSQL & " OR v.d_id = " & d_id
End If
If Not CheckBlank(vm_id) Then
strSQL = strSQL & " OR v.vm_id = " & vm_id
End If
If Not CheckBlank(vc_id) Then
strSQL = strSQL & " OR v.vc_id = " & vc_id
End If
If Not CheckBlank(d_id) Or Not CheckBlank(vm_id) Or Not CheckBlank(vc_id) Then
strSQL = strSQL & ")"
End If
strSQL = strSQL & " ORDER BY v.d_id, v.vc_id, v.vm_id"
But based on what you wrote in your question, you may be better with a query that uses the ORDER BY clause to get the most appropriate records based on the criteria you specified.
strSQL = "SELECT TOP 4 v.v_id, vm.vm_name, v.v_year, v.v_model, v.v_search_price, d.d_name, u.u_name " & _
"FROM tbl_Vehicles v " & _
"LEFT JOIN tbl_VehicleMake vm ON vm.vm_id = v.vm_id " & _
"LEFT JOIN tbl_Dealers d ON d.d_id = v.d_id " & _
"LEFT JOIN tbl_Users u ON u.u_id = v.u_id " & _
"WHERE v.v_processed = 1 AND v.v_active = 1 AND v.v_id <> " & v_id & " ORDER BY"
If Not CheckBlank(d_id) Or Not CheckBlank(vm_id) Or Not CheckBlank(vc_id) Then
If Not CheckBlank(d_id) Then
strSQL = strSQL & " CASE WHEN v.d_id = " & d_id & " THEN 0 ELSE 1 END,"
End If
If Not CheckBlank(vm_id) Then
strSQL = strSQL & " CASE WHEN v.vm_id = " & vm_id & " THEN 0 ELSE 1 END,"
End If
If Not CheckBlank(vc_id) Then
strSQL = strSQL & " CASE WHEN v.vc_id = " & vc_id & " THEN 0 ELSE 1 END,"
End If
strSQL = Left(strSQL, Len(strSQL) - 1)
Else
strSQL = strSQL & "v.d_id, v.vc_id, v.vm_id"
End If
This query will still give you results even if there are no vehicles for that dealer, make or category, so you will always have related vehicles (assuming you have at least 5 records).
It looks like the OR clauses you're using are not going to bring you you want. Assuming I'm understanding the snippet and the unseen db correctly, you need to create a subclause of the OR statements that is "ANDED" in. Try the following, after the initial strSQL assignment:
...
dim strSubClause
strSubClause = ""
If Not CheckBlank(d_id)) Then
strSubClause = "v.d_id = " & d_id
End If
If Not CheckBlank(vm_id) Then
If len(strSubClause) > 0 then
strSubClause = strSubClause & " OR v.vm_id = " & vm_id
Else
strSubClause = "v.vm_id = " & vm_id
End If
End If
If Not CheckBlank(vc_id) Then
If len(strSubClause) > 0 then
strSubClause = strSubClause & " OR v.vc_id = " & vc_id
Else
strSubClause = "v.vc_id = " & vc_id
End if
End If
If len(strSubClause) > 0 then
strSQL = " AND (" & strSubClause & ")"
End If
strSQL = strSQL & " ORDER BY v.d_id, v.vc_id, v.vm_id"
So, assuming all of your checks came back with values, you'd have a where clause that looks like:
...WHERE v.v_processed = 1 AND v.v_active = 1 AND v.v_id <> NNN AND (v.d_id = XXX OR v.vm_id = YYY OR v.vc_id = ZZZ) ORDER BY v.d_id, v.vc_id, v.vm_id
Does that make sense and/or get you closer or all the way to where you're wanting to go?