I have a form with a text box named fchName and subform of queryWorkerSub from a query named queryWorker which is "SELECT query". It needs a parameter.
I'd like to execute the query without prompt dialog box and with updating the sub form but I can't find way to do that. (I want queryWorker to be executed without prompt updating sub form)
Private Sub fchName_Exit(Cancel As Integer)
Dim qdf As DAO.QueryDef
Dim prmChName As DAO.Parameter
Dim dbs As Database, rst As Recordset
Set dbs = CurrentDb
Set qdf = dbs.QueryDefs("queryWorker")
qdf.Execute 'causes runtime error of 3065. Because of SELECT query
Set rst = qdf.OpenRecordset(dbOpenDynaset, dbSeeChanges) 'does not update subform of queryWorkerSub
Me.queryWorkerSub.Form.Requery' updates the sub form but shows prompt.
rst.Close
Set rst = NothingEnd
Set dbs = Nothing
End Sub
Related
I have DAO recordset that is generated with pass-through query to postgresql stored function. I use it to fill out combobox in my form. What I need is additional item in combobox with "AllItems" description. But the recordset is read-only (that's normal in this case). So I cannot just add new row to it. Can I do any kind of in memory recordset clone, copy or anything like that to make addition possible? I don't want to update recordsource. And I don't want to hardcode this option in to the pgsql function as well.
Public Sub fillCboAssortmentType()
Dim rs As DAO.Recordset
If (lngViewContext = acMyItems) Then
Set rs = getAssortmentTypesByDAO(TempVars!loggedUser)
Else (lngViewContext = acAllItems) Then
Set rs = getAssortmentTypesByDAO
End If
' It wont work, because the rs is RO
With rs
.AddNew
!type_id = 0
!type_name = "***AllItems***"
End With
' It wont work neither, because cboTypeFilter rowsource is Table/Query
Set Me.cboTypeFilter.Recordset = rs
Me.cboTypeFilter.AddItem "0;***AllItems***"
End Sub
Any suggestions?
TY All.
I think you are asking for a "In Memory" Recordset. Let's assume you have a table which looks like this
Then the following code will read the values from the table and copy it to a in memory recordset and add a new value but only in memory
Option Compare Database
Option Explicit
Sub inMemory()
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
With rs.Fields
.Append "val", adVarChar, 64
End With
Dim sourceRs As DAO.Recordset
Dim db As DAO.Database
Set db = CurrentDb
Set sourceRs = db.OpenRecordset("SELECT * FROM tbl")
Dim i As Long
rs.Open
Do Until sourceRs.EOF
rs.AddNew
rs.Fields(0).Value = sourceRs.Fields(0).Value
rs.Update
sourceRs.MoveNext
Loop
rs.AddNew
rs.Fields(0).Value = "Cancel"
rs.Update
' let's print the list just for testing
rs.MoveFirst
Do Until rs.EOF
Debug.Print rs.Fields(0).Value
rs.MoveNext
Loop
End Sub
This question already has answers here:
Vba Access error 91
(2 answers)
Closed 5 years ago.
I'm working with a couple tables, CTOL and CTOL_Asbuilt in Access. I'm trying to run a query to join these two tables together using VBA code. I ran the query in Access and it works. I'm using DAO for the database library to retrieve data from the local Access database (code is in the same database project as the database), and I'm new to VBA Access scripting.
SELECT CTOL.ID, CTOL.BOM_PART_NAME, CTOL.CII, CTOL.[PART FIND NO], CTOL.CSN,
CTOL.AFS, CTOL.EQP_POS_CD, CTOL.LCN, CTOL.POS_CT, CTOL.SERIAL_NO,
CTOL.PART_NO_LLP, [CTOL_Asbuilt].[PART-SN], [CTOL_Asbuilt].[PART-ATA-NO],
[CTOL_PW-E750207_Asbuilt].[PW-PART-NO]
FROM CTOL LEFT JOIN [CTOL_Asbuilt] ON CTOL.[PART FIND NO] = [CTOL_Asbuilt].[PART-ATA-NO];
This is the code below:
Option Compare Database
Option Explicit
'Const adOpenStatic = 3
'Const adLockOptimistic = 3
Function queryDatabase()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rsQuery As DAO.Recordset
Dim part_find_no() As String
Dim eqp_pos() As Integer
'Dim strSQL As String
Dim i As Integer
Dim j As Integer
'Set objConnection = CurrentDb.OpenRecordset("CTOL")
Set db = CurrentDb
Set rsQuery = db.OpenRecordset("SicrProcess", dbOpenDynaset)
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
End Function
I'm getting the following error when I run this code with a macro that calls the function:
Run time error '91':
Object variable or With block variable not set
I'm trying to use the code with the query to loop through two fields and increment the value of the EQP_POS_CD field when the PART FIND NO entry matches the last (else, it just moves to the next record until it reaches the end of the result set). I want to test-run this query to make sure that the code retrieves the result that is output by running the query manually in Access.
Can you help me in fixing this error so I can run my code to retrieve the data? Thanks!
rs.Close
You cannot close something that is not open. Perhaps you meant it to be rsQuery.Close?
Open a recordset and loop through records.
Sub queryDatabase()
On Error GoTo ErrProc
Dim db As DAO.Database
Set db = CurrentDb
Dim qdf As DAO.QueryDef
Set qdf = db.QueryDefs("SicrProcess") 'set your query name here
Dim rs As DAO.Recordset
Set rs = qdf.OpenRecordset(dbOpenDynaset)
Dim part_find_no() As String
Dim eqp_pos() As Integer, i As Integer
If rs.EOF Then GoTo Leave
rs.MoveLast
rs.MoveFirst
For i = 1 To rs.RecordCount
'...
'Do work here
'...
rs.MoveNext
Next i
Leave:
On Error Resume Next
rs.Close
Set rs = Nothing
qdf.Close
Set qdf = Nothing
Set db = Nothing
On Error GoTo 0
Exit Sub
ErrProc:
MsgBox Err.Description, vbCritical
Resume Leave
End Sub
I am trying to write a MS Access report based on a query that I can programically put the a date range in using VBA. I set up the query with Between [StartDate] and [EndDate] as the criteria. Then I have the following code on a form:
Private Sub AutoReport1_Click()
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Set qdf = CurrentDb.QueryDefs("MixByRangeA")
qdf.Parameters("StartDate").Value = #10/2/2014#
qdf.Parameters("EndDate").Value = #11/2/2014#
Set rst = qdf.OpenRecordset()
End Sub
Nothing seems to happen. Should the query open and show on the screen? I have tried a few code variations of the above based on my internet searches but nothing works.
Nothing is happening because you're not doing anything with qdf and rst after you set them. I'm not entirely sure what you're trying to accomplish, but:
1. If you want to open a Report whose RecordSource is the results of the Query (with parameters dynamically set), try placing the following in the Report's code module:
Private Sub Report_Open(Cancel As Integer)
Dim db As DAO.Database: Set db = CurrentDb
Dim qdf As DAO.QueryDef
Dim sql As String
Set qdf = db.QueryDefs("MixByRangeA")
sql = qdf.sql
sql = Replace(sql, "[StartDate]", "#10/2/2014#")
sql = Replace(sql, "[EndDate]", "#11/2/2014#")
Me.RecordSource = sql
On Error Resume Next
qdf.Close: Set qdf = Nothing
db.Close: Set db = Nothing
End Sub
And in the Form, use this to open the Report:
Private Sub AutoReport1_Click()
DoCmd.OpenReport "Report1", acViewReport
End Sub
2. If instead you just want to open the Query (with parameters dynamically set), try the following:
Public Sub AutoReport1_Click()
Dim db As DAO.Database: Set db = CurrentDb
Dim qdf As DAO.QueryDef
Dim sql As String
Set qdf = db.QueryDefs("MixByRangeA")
sql = qdf.sql
sql = Replace(sql, "[StartDate]", "#10/2/2014#")
sql = Replace(sql, "[EndDate]", "#11/2/2014#")
qdf.sql = sql
DoCmd.OpenQuery (qdf.Name)
On Error Resume Next
qdf.Close: Set qdf = Nothing
db.Close: Set db = Nothing
End Sub
I don't think it can be done the way simple way you want.
This seems a shame because you've followed what could be considered 'best practise' by using a stored procedure with parameters parameters, rather than constructing dynamic SQL.
The truth is, even if it is good practise generally, you are guilty of going against the natural flow of how the Access Team want you use its software! Looks like you are compelled to dynamically construct a WHERE clause to squirt into the provided method :(
The easy method is to remove the parameters from the query and apply a filter to the report:
Dim StartDate As Date
Dim EndDate As Date
StartDate = #10/2/2014#
EndDate = #11/2/2014#
DoCmd.OpenReport "YourReport", , , "[YourDateField] Between #" & Format(StartDate, "yyyy\/mm\/dd") & "# And #" & Format(EndDate, "yyyy\/mm\/dd") & "#"
Im using the code below to loop through the recordset of a subform in datasheet view and update a field, so that I avoid doing a SQL update as I want to also manually update when needed and this way avoids the "The data has been changed by another user..." message.
My question is, if I have 10 records in the recordset but the cursor is on the 5th record down on the form, then only the records from that point on get changed, eg 5 to 10.
Should this not update all the records? I can't figure out why it's not.
thanks
Dim tmprs As DAO.Recordset
Dim fld As DAO.Field
Dim bkmrk As Variant
Set tmprs = Forms!frmtanks!Child67.Form.Recordset
bkmrk = Me.Bookmark
tmprs.MoveFirst
While Not tmprs.EOF
For Each fld In tmprs.Fields
If fld.name = "freeDays" Then
freeDays = fd
End If
Next
tmprs.MoveNext
Wend
Me.Bookmark = bkmrk
You should use the form's RecordsetClone to do your updates. This will not alter the active record of your form when you use the MoveNext/MovePrevious type functions, start from first record of the recordset, and not require you to move back to your record with a bookmark.
Dim tmprs As DAO.Recordset
Dim fld As DAO.Field
Dim bkmrk As Variant
Set tmprs = Forms!frmtanks!Child67.Form.RecordsetClone
On Error GoTo Cant_Update
While Not tmprs.EOF
tmprs("freeDays") = fd
tmprs.Update
tmprs.MoveNext
Wend
I have found how to loop through recordsets with the following link:
Code to loop through all records in MS Access
However, I want to know if it is possible if I can remove a record from the recordset if it doesn't meet criteria that I specify in the loop.
EDIT
I am now getting an error with the following code:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("fieldHistory", dbOpenTable)
where fieldHistory is the name of the query recordset I want to open. Why am I getting this error? The last line of code there is the source of the error and Access simply states "Invalid operation"
Yes, you can use the DAO recordset's Delete method to delete the current record. This example will delete rows where the fname value is "xxx".
Public Sub DeleteRecordsetRow()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("tblDiscardMe", dbOpenTable)
Do While Not rs.EOF
If rs!fname = "xxx" Then
rs.Delete
'* the next line would trigger *'
'* error 3167: "Record is deleted." *'
''Debug.Print rs!fname
End If
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Notice that immediately after rs.Delete (i.e. before MoveNext), the deleted row is still "current", but you can't access its values. You can uncomment the Debug.Print line to examine this further.
Edit:
Since your record source is a query rather than a table, try this to narrow down the reason you're getting an error with OpenRecordset.
Public Sub foo20110527a()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("fieldHistory")
If Not (rs.BOF And rs.EOF) Then
rs.MoveLast
MsgBox "RecordCount: " & rs.RecordCount
Else
MsgBox "No records"
End If
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Since you used English (rather than English-like technical terms), your intent isn't very clear. You ask if you can "...remove a record...", which can mean either that you want to Delete it (in which case you already have a good answer form HansUp), or that you want to filter it out so that you don't see it, while leaving it in the underlying database.
If your intent is the latter (filtering), you have two choices:
Use a SQL statement with a WHERE clause in the original OpenRecordset call.
Use the Recordset's .Filter property before you enter the loop.
Access comes with adequate (if not stellar) Help on either topic.