INNER JOIN VBA Access - sql

I'm trying to do a dynamic SQL statement in which the command will add the field "Drawn" in a certain area of the depending on the value of j. This is because there are several instances where the field "Rev" in table "Revision" appears. I created this statement in the query design but only to update a specific field in the table, not dependent on my counter j. I'm getting 'JOIN expression not supported'. Can anyone help me with this issue?
Select Case selection(n)
Case "A"
j = 1
Case "B"
j = 2
Case "0"
j = 3
Case "1"
j = 4
Case "2"
j = 5
End Select
With rs
While Not .EOF
DoCmd.RunSQL "SELECT Area.Drawn " & _
"FROM (Revision INNER JOIN RevDesc ON Revision.Rev" & j & " = RevDesc.Rev) " & _
"INNER JOIN Area ON Revision.LineNumber = ArealineNmuber ;"
.MoveNext
wend
end with

Probably you looking for method like OpenRecordset...
Lopping Recordset use result fields to generate simple Update with you can run by RunSQL method.
EDIT:
example update:
UPDATE [Revision]
SET [Drawn] = (SELECT [Drawn] FROM [Area] WHERE [Area].[LineNumber] = [Revision].[LineNumber] )
WHERE Exists(SELECT 1 FROM [RevDesc]
WHERE [RevDesc].[Rev] = [Revision].[Rev]);

Related

select in select sql query

I want to create a sql query. The column name that I want, it's in another table. I wrote this query.
SELECT (SELECT FieldName From TableGENQuest WHERE ID = 1)
FROM TableGEN
WHERE strSO = 'RV12648-01';
I want to get the data from the strGEN1 columns using the FieldName column of the TableGENQuest table.That is data I want No significant transportation damage observed.
tl;dr: Your request is not possible using MS Access SQL alone.
You will need to use VBA to open a recordset containing the content of the table TableGENQuest and construct an appropriate SQL statement whilst iterating over the records held by such recordset.
For example:
Sub GenerateQuery()
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Dim sql As String
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("SELECT FieldName FROM TableGENQuest WHERE ID = 1")
With rst
If Not .EOF Then
.MoveFirst
Do Until .EOF
sql = sql & "[" & !FieldName & "], "
.MoveNext
Loop
sql = "select " & Left(sql, Len(sql) - 2) & " from TableGEN WHERE strSO = 'RV12648-01';"
End If
.Close
End With
If sql <> vbNullString Then dbs.CreateQueryDef "OutputQuery", sql
Set rst = Nothing
Set dbs = Nothing
End Sub
The above will generate a query defined in the current database with a SQL statement selecting the fields whose fieldnames are sourced using the SQL:
SELECT FieldName FROM TableGENQuest WHERE ID = 1
The difficulty and convoluted nature of this method indicates that your database is poorly designed: the field names themselves should instead appear as rows within another table.
SELECT b.FieldName FROM TableGEN a
LEFT OUTER JOIN TableGENQuest b
ON a.ID=b.ID
WHERE a.strSO = 'RV12648-01'
AND b.ID=1
OR
SELECT a.strSO,b.FieldName,b.ID
FROM TableGEN a
LEFT OUTER JOIN
(
SELECT FieldName,ID From TableGENQuest WHERE ID = 1
)
b
ON a.ID = b.ID
WHERE strSO = 'RV12648-01'
Try This Query...or can change Join Type...
Try this:
SELECT TableGENQuest.FieldName
FROM TableGEN, TableGENQuest
WHERE TableGENQuest.ID=1 AND WHERE strSO = 'RV12648-01';

MS Access VBA Add Decimals to Output

I have data which have 2 decimal places (See Figure) and am using the function to subtract the two values but I'm getting a rounded number as my output. I've tried to add float to the following expression "(L.M123_Corr_Integrator-R.M123_Corr_Integrator)" but it's throwing out an error. I'm not familiar with sql/vba code so any useful information would help.
sql = "UPDATE (SELECT R.DateLog , ( L.M123_Corr_Integrator - R.M123_Corr_Integrator) AS Gross " & _
"FROM tbl_M123_DataSet AS L INNER JOIN tbl_M123_DataSet AS R " & _
"ON L.DateLog = DATEADD('d', 1, R.DateLog)) as T " & _
"INNER JOIN tbl_M123_DataSet ON tbl_M123_DataSet.DateLog = T.DateLog " & _
"Set Gross_kWh = Gross"
dbs.Execute sql, dbFailOnError
MsgBox dbs.RecordsAffected & " rows affected on column GrossKW"
That query unobfuscated looks like this:
UPDATE
(
SELECT
R.DateLog,
L.M123_Corr_Integrator - R.M123_Corr_Integrator AS Gross
FROM
tbl_M123_DataSet AS L
INNER JOIN tbl_M123_DataSet AS R
ON L.DateLog = DATEADD('d', 1, R.DateLog)
) AS T
INNER JOIN tbl_M123_DataSet
ON tbl_M123_DataSet.DateLog = T.DateLog
SET Gross_kWh = Gross
It looks to me that you have the table field Gross_kWh set to integer. In the table design view, highlight the row Gross_kWh and set its number type to 'Double'.
Also be aware that Access will sometimes round numbers for display, but the decimal accurate number is stored in the table correctly.

Update query in Access with variable that can be empty but constraint the prevents update

ok, so I have an Update query, whithin VBA:
dim StatusID as Long
SQLString = "UPDATE tblRegister SET tblRegister.Status = " & StatusID & " WHERE tblRegister.ID = 'reg01'
there is also a table statuses, which contains statusID 1 through 5 with their descriptions.
User can select a status in a combobox. Now, if the user has not selected a status yet (which is ok) the value of StatusID will be 0. The update query will not accept that 0 for there is a relationship between statuses and register.
I cannot set the Long type to -1 or NULL...
Anybody have an idea? (the query is much longer than above, so a simple if Status = 0 then.. will not do.
How about using IIF?
SQLString = "UPDATE tblRegister" & _
" SET tblRegister.Status = " & IIF(StatusID=0,"NULL", StatusID) & _
" WHERE tblRegister.ID = 'reg01'

Access - create a sub total in a query

I have a query over a few tables and get a result in the form of:
SomeId Input
1 2
1 5
2 3
2 1
1 2
I'd like to be able to sum by Id as a third field, so I would get
SomeId Input subTotal
1 2 2
1 5 7
2 3 3
2 1 4
1 2 9
Is it possible?
Thanks
Here's a couple other ideas. Both have their drawbacks though. Both of them involve using a regular query.
First idea: Calling a VBA function to keep track of totals.
The drawback is that you have to order your table by SomeID.
Also the running total only resets itself when the function gets a different SomeID even if it's a different query. This means that the value of SomeID on the first record must be different than the last record of the last previous query.
SELECT SomeTable.SomeId, SomeTable.SomeInput, MyRunningTotal([SomeID],[SomeInput]) AS SubTotal
FROM SomeTable
ORDER BY SomeTable.SomeId;
Function MyRunningTotal(SomeID As Long, SomeInput As Long) As Long
Static LastSomeID As Long
Static RunningTotal As Long
If SomeID <> LastSomeID Then
RunningTotal = 0
LastSomeID = SomeID
End If
RunningTotal = RunningTotal + SomeInput
MyRunningTotal = RunningTotal
End Function
Second Idea: Using DSum. This is basically a query within a query.
The drawback is that for large recordsets it can be very slow. This is because it has to run a separate query for every record.
Also, you have to add an Auto-increment field (in the sample code below it's ID).
SELECT SomeTable.ID, SomeTable.SomeId, SomeTable.SomeInput,
DSum("SomeInput","SomeTable","[SomeID]=" & [SomeID] & " and [ID]<=" & [ID]) AS SubTotal
FROM SomeTable;
Yes, it's certainly possible, but with the problem as stated it cannot be accomplished by using just Access SQL queries. The two issues are:
The source data has no sequential key value (so a self-join with a <= condition cannot be used)
The source data is not sorted by SomeId (suggesting that the order may have some other significance), which would further complicate a set-based approach.
Fortunately, the VBA required to do this is not too involved:
Sub CreateSubtotals()
Dim cdb As DAO.Database, rst As DAO.Recordset
Dim dct As Object '' Dictionary
Set dct = CreateObject("Scripting.Dictionary") '' New Dictionary
Set cdb = CurrentDb
'' 'dct' will hold the running totals for each 'SomeId'
Set rst = cdb.OpenRecordset( _
"SELECT DISTINCT SomeId " & _
"FROM qryYourOriginalQuery", _
dbOpenSnapshot)
Do While Not rst.EOF
dct.Add rst!SomeId.Value, 0
rst.MoveNext
Loop
rst.Close
'' create new table to hold results
cdb.Execute _
"SELECT SomeId, Input, 0 AS subTotal " & _
"INTO tblYourDataWithSubtotals " & _
"FROM qryYourOriginalQuery", _
dbFailOnError
'' fill in the 'subTotal' column
Set rst = cdb.OpenRecordset("tblYourDataWithSubtotals", dbOpenTable)
Do While Not rst.EOF
dct(rst!SomeId.Value) = dct(rst!SomeId.Value) + rst!Input.Value
rst.Edit
rst!subTotal.Value = dct(rst!SomeId.Value)
rst.Update
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
Set dct = Nothing
Set cdb = Nothing
End Sub

N Top Record Selection Based on Own SQL Statement in MS-Access

I'm re-writing a small ms-access application to take examinations on.
What they want is for the tests to grab a set of random questions based on how large the exam's size is.
If each exam was a set number of questions, I could just stick the number in the TOP statement and be done with it, but there are a variable number of questions for each exam, so I want to replace the constant number next to the TOP with a field from the query.
What I basically want is like this:
SELECT TOP tblExam.[ExamSize] *
FROM tblExamQuestions INNER JOIN tblExam
ON tblExamQuestions.ExamID = tblExam.ExamID
WHERE tblExam.ExamID = 10
ORDER BY Rnd(tblExamQuestions.ExamQuestionID);
I'm supplying the new ExamID to this query for each exam session when I open the report, so this will probably get in the way.
DoCmd.OpenForm strExamName, , , "tblExam.ExamID = " & strExamID
I think you would have to build the query dynamically.
sSQL="SELECT TOP " & DlookUp("ExamSize","tblExam","ExamID = 10") _
& " FROM tblExamQuestions INNER JOIN tblExam " _
& "ON tblExamQuestions.ExamID = tblExam.ExamID " _
& "WHERE tblExam.ExamID = 10 " _
& "ORDER BY Rnd(tblExamQuestions.ExamQuestionID)"
'' Permanently change an existing query
CurrentDB.QueryDefs("MyReportQuery").SQL=sSQL