Access vba adOpenStatic - vba

I was looking at the documentation for adOpenStatic which says:
Uses a static cursor. A static copy of a set of records that you can
use to find data or generate reports. Additions, changes, or deletions
by other users are not visible.
I am trying to understand what this means. Is this saying that when we open an adOpenStatic recordset and try to perform some operation like reading, editing etc, changes made by other users from the time we open this recordset to the time we close the recordset is not visisble. So if any other user changes the same record while we are trying to change it will it use the what ever was the last change?

Related

Using filtered records from a form in a query

I have a large table. I am making a form that displays the table, and allows the user to use Access' standard filters on many different fields to choose only some of the data. Then, after the user has used the filters to choose only some of the data, I want to be able to include only the resulting recordset (and not the entire original table) in various queries.
I'm not sure if there's a way I can directly reference the form's underlying recordset in a query.
The obvious thing would be to use vba to iterate through the recordset, and either fill a temporary table with it that would be used in the queries, or directly do what I want with the data without using sql. But I believe iterating through a recordset is considerably slower than a query. Is there some way that I can reference a form's recordset directly from within a query, or dump the entire contents of the recordset into a temporary table?
Using Form.RecordsetClone will copy the subform's recordset and include any filters applied through the Access' built-in filters.
Note: the Form. is standard and does not refer to your form. So your reference would need to be Me!SubformName!Form.RecordsetClone if triggered from the main form. MSDN
After you create a clone, it seems you can use sql to drop the recordset into a temp table. But as #Andre mentioned, adding the PK only would be ideal to reduce load in large recordsets. The SQL string creation I found is simply:
sql = "INSERT INTO TEMPTable VALUES" & rs.Fields("YourPKFieldNameFromSUBFORM")
Assuming sql and rs have been declared as a string and your cloned recordset respectively, and TEMPTable has already been created with one column for your PK. Source: #5 and MSDN However, you will still need to loop through each record of the clone, as the sql statement only outputs a single row at a time.
As a supplement to Christopher D.'s answer, here is the final code I ended up using:
CurrentDb.Execute "DELETE FROM FilteredJobs"
Dim rs As Recordset
Set rs = Search_subform.Form.RecordsetClone
rs.MoveFirst
While Not rs.EOF
CurrentDb.Execute "INSERT INTO FilteredJobs VALUES (" & rs.Fields("JobID") & ")"
rs.MoveNext
Wend

Edit Current Object's SQL in MS Access through VBA

I am using MS Access 2013 trying to edit the SQL of the current query that is being displayed on the screen. I can get the name of the current query using qName = Application.CurrentObjectName however the current query is not saved, nor do I want it to be saved.
I know that using something like below, I can get the SQL of a saved query and modify that query.
Dim qd As QueryDef
Set qd = CurrentDb.QueryDefs(qName)
qd.SQL = "Select Customers.ID From Customers"
However, the query that I want to modify is not saved, but rather just being worked on. What I want to do is access the SQL which is visible in SQL view, read that into a variable, and modify it. I am not sure how to proceed and would appreciate some help. (What I have tried is summarized above.)
(In case you are curious. The queries I am working on may be new or may be being modified from saved queries; saving could overwrite something which I am not yet finished with/is not working, thus causing more issues.)
If your unsaved new query is open in Datasheet View, you can retrieve its SQL like this:
MsgBox Application.Screen.ActiveDatasheet.RecordSource
However if you want to modify that SQL within its current query window, I can't help you.

VBA Access Need to obtain autonumber before saving new record

I've got a database with a SQLServer back end which was migrated from Access and an Access front end. After the migration one problem I keep running into is that autonumbers are not generated until after the record is saved (kind of obvious but Access didn't seem to care). I have a form that opens to create a new record in a table, but elements of that form require the value of the autonumber (Identity) field of that new record to calculate things. I want to somehow obtain this number right as the form loads instead of having to save it and reopen it just to obtain this number. What's the best way to go about this? Thanks in advance.
Access databases return + generate the autonumber when the record is dirty. In the case of SQL server + Access you cannot use nor does the form display the autonumber UNTIL record save time.
The simple solution is to thus force a save in the forms data, and then any following/existing code you have will continue to work.
So your code can look like this:
If Me.NewRecord = True Then
Me.Dirty = False
End If
The above will work as long as SOME editing has occurred. Note that if NO editing has occurred the above will NOT generate the autonumber ID (however even in non SQL server databases, when no editing has occurred then autonumber is not available anyway).
The above works for a bound form. If you have reocrdset code, then you change typial code like this:
Set rstRecords = CurrentDb.OpenRecordset("tblmain")
rstRecords.AddNew
In above your VBA code can/could grab autonumber. However the above code for sql sever will have to force a save.
In fact code that will work for both ACE or SQL server is thus:
will become:
Dim rstRecords As DAO.Recordset
Dim lngNext As Long
Set rstRecords = CurrentDb.OpenRecordset("tblmain", dbOpenDynaset, dbSeeChanges))
rstRecords.AddNew
' code here does whatever
rstRecords.Update
rstRecords.Bookmark = rstRecords.LastModified
lngNext = rstRecords!ID
rstRecords.Close
So the simple “issue” is you need to write out the record to force SQL server to generate the auotnumber. Once you done this record save, then your forms and most VBA code should run “as is”. You do not need to "resort" to additional code such as select ##identity UNLESS you using SQL insertcommands as opposed to say above forms or recordset code.
What you are referring to is the AutoNumber column in Access which is an Identity field in SQL.
The only way to accomplish this functionality in SQL is to insert the record when your form is opening and then use the ##Identity in SQL to retrieve the most recent value.
When your Access application was combined together with the database, Access was essentially doing this for you. You can check the following link for more details.
http://bytes.com/topic/sql-server/answers/143378-identity-sql-vs-autonumber-access
If its on a bound form, give a save button which will save record to database of Master table.It will have nothing except the identity field's value. Then enable or show subform which needs ID from this master table/form.
Looks ##identity code may not be possible for you since its bound form. To convince users why they need to save before adding any data to form, I name the button "show details" or "Add data to details" , this saves the record using docmd on the form, and makes visible the details section.
DoCmd.RunCommand acCmdSaveRecord
'OR a different code snippet, Just update Dirty status of form
If Me.Dirty = True then
Me.Dirty = False
End If
'You may write code to show/visible detail section/subform

query criteria based on form field

So I have a query where I select a field and set the criteria so that it only selects records based on the current value of a particular field in my form. The criteria looks like this.
[Forms]![FORMAL_CERT_REVIEW_CHECK_FORM]![REVIEW_CHECK_ID]
Pretty simple stuff. But I am running into the issue where when I run the query I get the prompt that says I need to enter a value. I know that this usually happens when you set the criteria to something that may not exist or you spelt it incorrectly, but I have checked all of this and it seems like everything looks fine.
I was curious if there is something I could be missing, like a property on the field or something that I have not thought of.
When you directly open a query which includes a reference to a form control, Access is able to retrieve the query's parameter value from that control on the open form.
However, if you attempt to use the same query as the source for a recordset, Access does not resolve the query parameter from the open form.
For example, this is my query, qryREVIEW_CHECK_ID.
SELECT f.id, f.datetime_field, f.some_text
FROM tblFoo AS f
WHERE f.id=[Forms]![FORMAL_CERT_REVIEW_CHECK_FORM]![REVIEW_CHECK_ID];
With FORMAL_CERT_REVIEW_CHECK_FORM open, everything works fine when I open the form directly ... like this for example ...
DoCmd.OpenQuery "qryREVIEW_CHECK_ID"
However, using that query as the source for a recordset triggers error 3061, "Too few parameters. Expected 1."
Dim db As DAO.database
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("qryREVIEW_CHECK_ID")
The workaround is to open the recordset from the QueryDef object. And include Eval() so that Access will resolve the parameter using the parameter's name.
Dim qdf As DAO.QueryDef
Set qdf = db.QueryDefs("qryREVIEW_CHECK_ID")
qdf.Parameters(0) = Eval(qdf.Parameters(0).Name)
Set rs = qdf.OpenRecordset
Your description doesn't specify whether your form is a simple form or a sub-form. I came across the same issue and realized that I was only entering the sub-form's name in the criteria.
Assuming that you have FORMAL_CERT_REVIEW_CHECK_FORM sub-form under PARENT_FORM, your criteria should read
[Forms]![PARENT_FORM]![FORMAL_CERT_REVIEW_CHECK_FORM]![REVIEW_CHECK_ID]
I hope this helps you or others. Used in Access 2016.
I have experienced this on several occasions after making a design change to the form. There is no fault with what you have done - it is an access corruption. The solution is to copy the database to another file name, delete your forma and query, compact and repair, and then import the form and query again. This normally solves the problem. It appears importing it resets the internal references allowing the form to work as it should.
Doesn't seem like this was ever solved, and I just came up with the same issue. I solved it by deleting the form and recreating it. Like you I had, [Forms]![MyForm]![ID] and out of no where it started asking for user input for the criteria on my listbox query. Making a new form and copying over the fields seems to have fixed it.

How can we do Multiple Operations using Single RecordSet?

I have some task regarding do operations on database using ADODB in Vb.NET. Can any help me regarding using the same record set multiple times?
I have tried on this topic just by closing the recordset after performing First operation and doing second operation e.t.c.
Example:
Dim rs As New ADODB.Recordset()
OpenConnection()
rs.Open("table1")
//Some Operations
//Now using same recordSet for Second Operation
rs.Close()
rs.Open("table2")
In ADO.NET we have "MultipleActiveResultSets=True" in ConnectionString for SqlDataReader.Do we have any property like this in ADODB?
The more similar thing that exists in ADODB is sending multiple queries in your Sql String then proccessing them one by one using rs.NextRecordset (rs is the Recordset), here is an example: ADO NextRecordset Method Demonstration
But, personally, i prefer doing it as you're doing it now, using just one recordset for each query. Take into account that using multiple recordsets inside one, like in the previous example may require some additional commands in some dbs to ensure no additional unwanted recordsets are created from messages coming from the backend, for example for Sql Server it's a good idea using:
Set NoCount On and Set ANSI_Warnings OFF