I am attempting to update one column of a table based on data present in other records of the same table. All records either have the same date in the "CurrentDate" field or are null. I want to change those with null values to be the same as the rest of the fields.
Here is my code, but I am getting a syntax error:
Public Sub RiskVisual()
Dim db As DAO.Database
Set db = CurrentDb
---
DoCmd.RunSQL "UPDATE Hold3 SET CurrentDate = (SELECT CurrentDate FROM Hold3 LIMIT 1) WHERE CurrentDate IS NULL;"
End Sub
Thanks in advance for your help.
In MS Access the "TOP 1" works better than "LIMIT 1". You will also want to specify when seeking for the top 1 that the top 1 that is not null. Try something like this:
UPDATE Hold3 SET Hold3.CurrentDate = (SELECT TOP 1 Hold3.CurrentDate FROM Hold3 WHERE (((Hold3.CurrentDate) Is Not Null))) WHERE (((Hold3.CurrentDate) Is Null));
Related
In MS Access using VBA trying to subtract a calculated value (time between dates) from a total amount of time in another table.
The query holding the total amount of time is QryScsBatchHandler the field I want to subtract the value from is FreezerLifeUsed and the match condtion is BatchID
The query holding the value I want to subtract is QrySCSMaterialFreezerLog or the form is Frm_MaterialFreezerLog.. the value is AccumilatedTime and the Match condition is Batch ID
Private Sub BkInFrzr_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strSQL As String
Set db = CurrentDb()
strSQL = "SELECT FreezerLifeUsed FROM QryScsBatchHandler WHERE [BatchID] = BatchID"
Set rst = db.OpenRecordset(strSQL, dbOpenDynaset)
With rst
.MoveFirst
.Edit
FreezerLifeUsed = -AccumilatedTime
.Update
End With
End Sub
I can’t seem to get this simple subtraction to work… any suggestions on what’s not right?
Any help will be greatly appreciated..
At least 3 issues with code.
concatenate reference to form field/control for dynamic criteria in SQL:
strSQL = "SELECT FreezerLifeUsed FROM QryScsBatchHandler WHERE [BatchID] = " & Me.BatchID
The VBA needs to use dot or bang when referencing controls or fields and qualifying with prefix is advised:
!FreezerLifeUsed
Me.AccumilatedTime
Nothing is subtracted from anything, so consider:
!FreezerLifeUsed = !FreezerLifeUsed - Me.AccumilatedTime
However, if query is expected to return only one record, don't bother with loop. Also, instead of opening a recordset, an UPDATE action would work.
I have a MS Access database and inside it I import tables from an external source every month. What I want to do is get the earliest date in the database since it is out of order. I am creating forms and so far this is what I have:
'Get start and end date
Dim DBGeo As DAO.Database
Dim rstStartDate As DAO.Recordset
Set DBGeo = CurrentDb
varStartDate = "SELECT [time] FROM [" & cboTableName & "] ORDER BY [time] ASC LIMIT 1;"
MsgBox (varStartDate)
Set rstStartDate = DBGeo.OpenRecordset(varStartDate, dbOpenSnapshot)
The field name is called time and I know that is a keyword but I dont want to change it or else I have to change it in all the tables. CboTableName has the name of the table I am using.
Im not great at this stuff so I am sure it is something simple. Thank you
SELECT TOP 1 Table1.Time
FROM Table1
ORDER BY Table1.Time;
There are three mdb files in folders on a network drive that may hold the required record(s). How do I determine which db holds the record(s), ideally without data transfer/linking/etc.? Then a single SQL or DAO select can get the data from the correct db. Note: I'm trying to use Access as a front end to SQL using existing Access data spread all around the network drives.
My current solution of configuring 3 DAO objects and checking for no results, in succession until found, seems to load the remote tables to the local recordset and takes too long.
Is there a way to use IF EXISTS in this scenario?
This code throws "Invalid SQL statement; expected DELETE,INSERT,PROCEDURE,SELECT,OR UPDATE" error but is generally what I'd like to do :
Dim strSQL As String
Dim strSku As String
Dim intDbToSearch As Integer
strSku = DLookup("SKUNo", "tblCurrentItem") 'Note: this returns valid SKU#
strSQL = "IF EXISTS(SELECT xxTable.SKUNo "
strSQL = strSQL & "FROM [S:\Our Inventory\Cust Sleeves.mdb].[xxTable] "
strSQL = strSQL & "Where xxTable.SKUNo = " & "'" & strSku & "') Then intDbToSearch = 1"
DoCmd.RunSQL strSQL
This is one of three IF Exists that would run if SKUNo not found in db 1 or 2.
Ultimately intDbToSearch should point to db 1,2,or 3 if SKUNo found or 0 if not.
Thanks
In the end, I pushed usage rules for the 3 databases upstream and can now predetermine which database to search. Thanks again for your input.
Will the sought for SKU always occur in only 1 of the tables?
If you don't want to set table links or use VBA recordsets, only other approach I can see is a query object with a dynamic parameter that references a form control for the SKU input. No idea if this will be faster and will need a query for each remote table.
SELECT SKUNo FROM xxTable IN "S:\Our Inventory\Cust Sleeves.mdb" WHERE SKUNo = Forms!formname!cbxSKU
Then just do DCount on the query.
Dim intDbToSearch As Integer
If DCount("*", "xxQuery") > 0 Then
intDbToSearch = 1
End If
Could UNION the SELECT statements so would have only 1 query object to work with.
SELECT "x1" AS Source, SKUNo FROM xxTable IN "S:\Our Inventory 1\Cust Sleeves.mdb" WHERE SKUNo = Forms!formname!cbxSKU
UNION SELECT "x2", SKUNo FROM xxTable IN "S:\Our Inventory 2\Cust Sleeves.mdb" WHERE SKUNo = Forms!formname!cbxSKU
UNION SELECT "x3", SKUNo FROM xxTable IN "S:\Our Inventory 3\Cust Sleeves.mdb" WHERE SKUNo = Forms!formname!cbxSKU;
How about a simple Function to check if exists by passing the table name and value?
Something like this:
Public Function ExistInTable(Byval TableName As String, ByVal Value As String) As Boolean
ExistInTable = (DCount("*", TableName, "[SKUNo]='" & Value & "'" > 0)
End Function
To call it:
Sub Test()
If ExistInTable("T1", "Whatever") Then 'Exists in T1
If ExistInTable("T2", "Whatever") Then 'Exists in T2
'....
End Sub
How should I write the name of the recordset correctly? I have a type mismatch error on & rsg & at "sq3=..." line. Thanks in advance.
Dim rsG As DAO.Recordset
Dim sq2, sq3 As String
sq2 = "SELECT * from GeneralTable "
sq2 = sq2 & "where gsede='LION' and (gExclu is null) and (gAda is null) "
sq2 = sq2 & "order by gnomb,gnif;"
Set rsG = CurrentDb.OpenRecordset(sq2)
sq3 = "UPDATE " & rsG & " SET gsede ='AA' WHERE gsede='LION'"
DoCmd.RunSQL (sq3)
You are mixing up totally different ways to update data - UPDATE SQL and VBA recordset.
If you want to update a recordset row by row, you do something like
Do While Not rsG.EOF
If rsG!foo = "bar" Then
rsG.Edit
rsG!gsede = "AA"
rsG.Update
End If
rsG.MoveNext
Loop
Do the update using a single query:
update generaltable
set gsede = 'AA'
where gsede ='LION' and (gExclu is null) and (gAda is null);
If you do the update off of rsG, then you'll likely do a separate update for each row, and that is inefficient.
You can't mix and match SQL and recordset objects. You can either build a full update statement that includes the logic of the first select (as other answer suggests), or you can open a dynamic recordset and loop through the records programmatically to make the updates.
That being said, looping through large recordsets programmatically to make updates is usually better handled by a bulk SQL statement, unless it is essential to consider each row individually inside the code - which in your basic example would not be the case.
MS has a good article on the DAO.Recordset object. There is a dynamic-type Recordset example about halfway down.
I am working on a simple read write database with design form.
I used this query for counting all rows
SELECT COUNT (*) FROM tblData
Now I can't get to count the rows when I am adding a filter. I tried various queries, some instructions here, but I can't decode it and make it vba. I need to find all pending status of 338559
Dim db As Database
Dim rs As DAO.Recordset
Dim query As String
Dim i As Integer
query = "SELECT COUNT Status = 'Pending' FROM tblData WHERE UID = 338559"
Set db = CurrentDb
Set rs = db.OpenRecordset(query)
For i = 0 To recordCountOfTheItem
'code to display it to listbox
Next i
Thank you for some assistance coders :)
You can use that request :
SELECT COUNT(*)
FROM tblData
WHERE UID = 338559
AND Status = 'Pending';
You can achieve this by CASE statement, if the condition is satisfies set as 1 and if not satisfies set as NULL. This will work for MySQL
When Count it won't consider the null values, so you will get valid count for your filter
SELECT COUNT(CASE WHEN Status = 'Pending' THEN 1 ELSE NULL END)
FROM tblData WHERE UID = 338559
For VBA Access 2007
SELECT COUNT(IIF(Status = 'Pending', 1, NULL))
FROM tblData WHERE UID = 338559
You don't have to count, just loop:
query = "SELECT COUNT Status = 'Pending' FROM tblData WHERE UID = 338559"
Set db = CurrentDb
Set rs = db.OpenRecordset(query)
If rs.RecordCount > 0 Then
While rs.EOF = False
'code to display it to listbox
rs.MoveNext
Wend
End If
rs.Close
Set rs = Nothing
Set db = Nothing
For the record: To fill a listbox with data from a query, you need neither Count() nor VBA at all.
Just set the listbox RowSource to the query, e.g.
SELECT <whichever fields you want to display> FROM tblData
WHERE UID = '338559' AND Status = 'Pending';