Show ADO recordset in subform - ms-access

I have inspected a lot of websites and books, and I still cannot solve my problem.
I want to show a Recordset in a form's subform as a table. The Recordset results from a query (query is valid, and the recordset is generated properly - checked with Debug.Print). I know that I have to use the following line in VBA code: Set Me.subform.Form.Recordset = rs but it only works when the Sourceobject is manually set in the Properties window (e.g., a table). When it is set, I noticed that the subform property .Form. Otherwise, there is information that refers to an object which is closed or does not exist. So I was looking for a dynamically creating this property, but I didn't find anything working.
Moreover, I want to apply some changes to this Recordset before show it, but first of all, I want to show it raw.

Related

Access VBA: Changing record source of subform

I have a form with a subform, and I want the subform record source that populates the subform to change depending on the inputs on some combo boxes in the main form.
Using VBA, I have built a function that generates the SQL statement I want to populate the subform with. I know this works because I have tested it with the msgbox and it gives me the SQL statement I want. The sql statement uses an aggregate function so the resulting table has a different structure than the table it is querying from.
The code I use to change the subform record source is:
me![subformname subform].form.recordsource=myfunction()
This has worked for me in the past, but does not work here, I simply get "#Name?" in the subform on my form.
When I open the subform separately I get "#Name?" but when I open the Recourd Source and run the query from the record source I get a value so I am confused.
Any ideas?
Try setting up two subforms - one for each format that you need - and when you swap the underlying recordsets also swap or hide/unhide the relevant subform. Then you can set the controlsource for the relevant controls to the fields that are actually available in the current recordset.
I got it to work by changing the structure of the subform I was changing so that the structure stayed the same when I altered the recordsource. The lesson is, you can change the recordsource in VBA, but you can't change the structure of the subform.
My problem occurred because I used an alias in my subform record source SELECT query. When I replaced the alias table names with the actual database table names in my VBA code, the .recordsource = strSQL01 statement worked and the data appeared in my subform.

VBA Access subform gets unbound after editing data in one row and then clicking another row

For a client I have to use MS Access 2007 as a lightweight front-end to SQL Server 2008.
One of the requirements, security-wise, is that I need to fetch my recordset data via stored procedures. I'm doing this via SQLOLEDB, based on tutorials provided here: http://accessexperts.com/blog/2011/07/29/sql-server-stored-procedure-guide-for-microsoft-access-part-1/
I have a mainform with some general data, on which I also set the form recordset (Me.recordset) in the code-behind. At the bottom of the form, there is a subform, with a table of rows of data. This is also an ADO recordset being set in the code. In order to make those subform records editable, I made a extra recordset in which I cloned the data in, then I bound it to the subform's recordset (Me.recordset -> but in context subform). I added a save button after each row in the subform, and via an event I'm doing the writes manually via another stored procedure.
This all works, but I get some very weird behavior when I edit some data in the first row (for example), and then click on a field in another row (for example the second row). Now suddenly all my fields change to '#Name?'; basically my subform gets unbound.
Now I'm not sure how to debug this, let stand fix it. Any help on this error is greatly appreciated.
I forget to put tempRs.ActiveConnection = Nothing
It is working as intended now :)

Passing recordset between froms, reports

I have a form which will generate a report for mailing.
The form opens a recordset with all the fields needed. I'm wandering how can i pass this recordset to the report, so that i don't need to open the same recordset once again.
Similarly, sometimes i also want to pass recordset between forms (no main/sub form relation), how can i do this?
Another little question, when i open a form in datasheet view, it's always very big. How can i limit its size when opening?
Thanks!
EDIT:
To be clearer, say i have "FORM", when the user hit a button on it, "Report" will be open. I want "Report" to use the recordset that is already created(opened) in "FORM".
Also on "FORM", there is a textbox, filled by users, i want also to show it on the "Report".
EDIT2:
I tired but cannot passe the recordset, nor populating a field in my report from a textbox on my form, very annoying ..
You should be able to accomplish this by simply passing the correct SQL statement to your report. This can be done using the Opening Arguments.
Assuming that you really do want the identical set of records on your report as you see on your form, what you need to do depends on how you have opened your form, or how you are filtering your form. You could indeed use an identical DAO Recordset object and set your reports Recordset object to a copy or clone of the Form's Recordset object. However, this might not be necessary to get the results your look for.
Solution #1
If your form uses a query or SQL statement you can use this solution.
Code on your form:
DoCmd.OpenReport "rptReportName", acViewPreview, , , acWindowNormal, Me.RecordSource
Code on your report:
Private Sub Report_Open(Cancel As Integer)
Me.RecordSource = Nz(Me.OpenArgs, "")
End Sub
Solution #2
Use this solution if your form is using the form's filter property to filter down to the correct set of records. I'm assuming you then want to pass that filter condition on to the report. You'll need to configure the report so that it uses the same RecordSource as your Form (or it must at least contain the table/fields that will be included in your filter statement). The problem is that passing the recordsource of your report to your form doesn't pass any filter that you might have set on the form.
DoCmd.OpenReport "rptReportName", acViewPreview, , Nz(Me.Filter, ""), acWindowNormal
As a final note, it is not possible to set a Report's recordset property. You can assign a Recordsource as I've already shown (a recordsource is a tablename, a queryname, or an SQL statement) but you cannot use the Recordset property unless the database is an Access Data Project, which I don't recommend using at all.
Edit1
It wasn't clear from the original post what problem the OP was trying to solve. I incorrectly assumed he was having trouble getting the same records to show on his report as what he has on his form. It appears that rather the OP is concerned about making two trips to the server to retrieve records.
Because you cannot set the Recordset value on an Access report, your best option might be to create a local Access table and simply use it as a temp table. I don't know what size your recordset typically is. If it's quite large (5000+ records) this solution may not be a good idea. One problem I can think of is that it will cause your front-end database application file to bloat over time unless you have the file setup to run Compact and Repair on close.
I think the worry about two trips to the server is unwarranted.
If you were using a Jet/ACE back end, Jet would cache the data locally, and there wouldn't be a re-retrieval unless the data had changed (in which case I think you'd probably want the up-to-date data, no?).
With a server database, the server itself is likely to cache the results, particularly if the SQL statement used is identical in both cases.
This looks to me like a case of premature optimization.
Well If I have understand from your question you need to manipulate the data in a table by knowing/unknowing the record set number.
If that is then you need to reform the mentality of how to access data in a table, because to promote the record set number in your list is not the quite right way, usually we promote the data and the record numbers are hidden.
So when you read your table try to pass your fields into variables for later use or pass them directly to your list view.
The way of accessing the table to get each data it comes from another process which always varied.
But even when you want to keep the record numbers for later use try to declare a name as public variable as ArrayList() then when you read from table you may use the 'Variable'.add(RecordNumber) .
So when you need to access a particular number take the reading line number from your list view by calling VariableName(ListViewLineNumber)
Please inform me if this solution comes closely to you issue solution.

Datasheet with dynamic recordsource shows no records in Access 2007, but works in Access 2003

I have an Access 2003 database which uses a main form with a datasheet in a subform. The main form allows the user to select from a menu which updates the recordsource of the subform. The subform also updates the number and type of fields available for editing based on the number and types of fields in the form's recordsource. It's basically a dynamic datasheet generator. This works just fine in Access 2003 and has been for years. If I open the same database in Access 2007 (full or runtime), most of the menu selections work. However, if I choose any menu option that references one particular table, the subform shows column headers, but does not show any rows of data or display any errors. It's as if the query is returning zero rows. Why would there be a difference in Access 2007? Did they add new reserved words?
Things I've tried:
Updated every field in the table to ensure there are no null values (no change)
Renamed every field and the table name just in case there are new reserved words (no change)
Compacted and repaired the front end and back end (no change)
Tried including and excluding fields one by one to see if anything changed (no change)
Put the form's recordsource in a new query. (it returned the expected number of rows)
Checked to make sure the form is not set to data entry mode. (It's not)
Checked to ensure that no filters were being applied in code. (none were)
Checked to make sure the query is updateable in Access 2007. (It is)
Selectively deleted chunks of data from the source table. (no change)
I'm stumped.
I was able to finally resolve the issue. As I noted above, my datasheet is a subform. The parent form sets the options that determine how the subform will be built. While the datasheet is being built, the subform's sourceobject is replaced with a blank form to hide the prior datasheet and present a smooth transition to the new datasheet. It works beautifully in Access 2000/2003.
When the blank form is replaced with the new datasheet in Access 2007, I found that Access is automatically assigning the primary key of the subform data to the LinkMasterFields and LinkChildFields properties of the unbound parent form. Those properties had previously been blank, and I never set them in code. Perhaps this is as an attempt by Access 2007 to be helpful rather than a bug, but the behavior difference is not noted in any tech reference I can find, including the built-in help file. Since the parent form is unbound, it has the effect of filtering out all of my subform records. If I explicitly set LinkMasterFields="" and LinkMChildFields="" during the form substitution step, everything works as it did before. Hooray!
Again, the solution is that when setting the sourceobject of a subform, be sure to explicitly set the linkmastfields and linkchildfields properties to prevent Access from doing it for you. I hope this saves someone the hours of frustration I experienced.

Do sfSubForm.fForm.RecordSource and Forms(fForm).RecordSource refer to the same object and property?

this has me pretty confused and I can't find the answer anywhere else so thought I'd post here to see if anyone can help!
I have a form in an Access 2007 database with a subform (sfSubform) embedded in it. The subform control's SourceObject is set to be another form (fForm). fForm's RecordSource starts out as a table.
At one point I want to change the data displayed in the subform to the result of a SQL statement, so I use
sfSubform.Form.RecordSource = strSQL.
This works fine. However, if I ouput the name of the RecordSource for fForm after making this change, it still gives the name of the table that I orginially set.
Does sfSubform.Form.RecordSource not change the source of fForm? Is it a copy of fForm that is embedded in the control?
Hope all that makes sense.
The sub-form and the form each have their own record source (or are unbound). That's the whole point, actually -- the ability to present two different data sets. Typically the two forms have related record sources and this relationship is declared using Master/Child Link, but that also is optional according to the need.
So no, changing one won't cause the other to be changed.