Table updating - but report is empty. Reopening report shows correct data - vba

Should be an easy one for the experienced?
I collect data from multiple other tables and do calculations in VBA with which I add rows with DoCmd.RunSQL to a printout table. (Before this, I delete previous printout rows.)
After this I do a db.Close + Set db=Nothing, then display a dialog whether to preview or print. Upon selecting Preview, the report is shown, but it's empty. (As in, all the labels are there, there are 0 rows of data, and all the other data fields are blank.)
The report associates printout rows with the current user, so it's valid to "just open" the report, and then it shows the correct data.
If I keep the table open while running, I can see the DELETE FROM taking effect ('##Deleted##' or something similar), but I can't see INSERT INTOs taking effect until I re-open the table.
I use no connection, I use Dim db as dao.Database + Set db=CurrentDB; data is written to a local (non-linked) table; there's nothing special in the query (sort of, SELECT field1,field2... FROM mytbl WHERE user=currentuser) the report is based on; there's no code module for the report.
What's going on here, and how do I fix it?

Boy, am I feeling stupid now. I copied the DoCmd.OpenReport line from an identical report that used another table as data. The problem is, when I changed it to have an OpenArg, I had too few commas and it unnoticably ended up being a "filter". Code hinting is there for a reason... oh well :)

Related

MS Access 2016 Woes - Lockups in MultiUser (Inserting Dummy Entries to Add New Item)

I found an interesting conundrum with a database I administer. To create a new Stock Item, it adds a dummy entry and then opens this new entry in the usual Form for editing. See the code below.
The code works perfectly fine until you have the database open on more than one PC.
If the user on the 1st PC adds a new item, the 2nd PC freaks out over the dummy entry. This causes 10-20 second delay on everything they do on the 2nd PC.
I'm trying to think of a simple / elegant way to achieve this without using a dummy entry (because it doesn't actually have a StockCode until the user enters one, I think on the 2nd PC the program chokes on the dummy entry with no StockCode)
I really have no idea at this point.
Case vbKeyF1 ' F1 Key to Add New Record
stokmastSQL = "INSERT INTO tblSTOKMAST (STOCKCODE, PER, SELL1, SELL2, SELL3, GST) VALUES ('', '', 0.00, 0.00, 0.00, 'N');"
DoCmd.SetWarnings False ' Turn off SQL warnings for Action Queries
DoCmd.RunSQL stokmastSQL
DoCmd.SetWarnings True ' Re-enable SQL warnings for Action Queries
[Forms]![frmSTOKMASTLIST]![lst_STOKMASTLIST].Requery ' Requery ListBox after change
SQL = "SELECT STOCKCODE, DESCR, PER, SELL1 FROM tblSTOKMAST ORDER BY STOCKCODE" ' Re-initialize Record Source of ListBox
[Forms]![frmSTOKMASTLIST]![lst_STOKMASTLIST].RowSource = SQL
[Forms]![frmSTOKMASTLIST]!lst_STOKMASTLIST.SetFocus ' Set Focus to ListBox and select first record
[Forms]![frmSTOKMASTLIST]!lst_STOKMASTLIST.Selected(0) = True
DoCmd.OpenForm "frmSTOKMASTEDIT", , , "[STOCKCODE] = '" & [Forms]![frmSTOKMASTLIST]![lst_STOKMASTLIST].Column(0) & "'" ' Open new record in frmSTOKMASTEDIT
KeyCode = 0
End Select
Well, there is a MASSIVE HUGE LARGE difference here between a long delay, and that of something not working.
What you described so far is something that is SLOW, not that it does not work.
About once a week on SO, this issue comes up, and has come up for about the last 20 years in a row!!!
You don't want to try and write a boatload of code to fix this issue, since virtually EVERYTHING you do will have to be fixed, and in 99% of cases, writing code will NOT fix this issue!!!
In other words, this is NOT due to the dummy entry, but something wrong.
You don't mention/note if the database is split - but lets leave that issue for a bit.
The first test/thing to try?
Do this:
launch the applcation. Now, open ANY table (and you not noted if you using linked tables here - a MASSIVE issue we need to know here).
Now, from the nav pane, open ANY table. Now minimize the table (assuming the application is in windowed mode. But, regardless, JUST OPEN any table.
At this point, now launch the form that creates the new record. is it slow?
The above is what we call a persistent connection. By opening a table (any table), then this forces access to keep the database open. And in multi-user mode, this "opining" process can be VERY slow (like 20 seconds).
So, first and foremost, try the above. So, you can open ANY table (and if using linked tables, then ANY linked table). Now, just leave that table open, and now again try your form. The delay (even with 2 users) should not be gone.
if you don't address this delay, then that dealy will start to appear everywhere, and will appear even without writing code.
And conversly, then writing code will not fix this issue.
If you determine the above fixes this issue? Then on application startup, you can in VBA code create what we call a persistent connection. Another way is to open a form (any form) bound to a existing table.
As noted, if the above does not fix this issue, then we have to look at how that new record is added, and perhaps it uses something like dmax() or some such to get the "max ID value". In that case? Then adding a index to that column will/can fix this issue.
So, try the above first (since you can do this without any code). Just open any table, and THEN launch/use the form(s) in question, and see if the long delay goes away.

Microsoft Access Table Shows Up Blank, But Query Correctly Pulls Data From Table

I am having an issue with my Microsoft Access database. One of my tables looks completely blank, but it has 11632 records listed in the bottom. Take a look at this screenshot. Though the table shows up blank, when I run the query it pulls the correct data from this table, so I know the data is there, it is just not appearing for some reason. I have tried on Access 2013 and 2016 on a different computer, and both have the same effect. I have also tried compacting and repairing, and also exporting the table but the file it exports to also appears blank, aside from the field names. Any ideas on what I could try?
Thanks!
Turn your import into a 2 step process (or more...). Write it raw into a scratch pad table. Then fire an append query, that has the appropriate criteria to result in only valid records going into the final table.
This isn't unusual at all given that some outside data sources may not have the controls to prevent bad records. Sometimes one must "wash" the data with several different query criteria/steps in order to filter out the bad guys.

Access 2013 query only pulls the first record

i'm hopeing someone will be able to solve this. I have a combo box which shows the records that are available to view. Upon selecting a record, my query updates without any problem. I tried to use this query within a subform however, for some reason, only the first record in the data set is shown upon selection. When I select anyting else from the available options, the subform doesn't change. However, when i re-select the first record, it shows.
The weird thing is, that when I change the drop down box to say the 2nd record & run the query itself, the desired record shows within the query designer.
To explain further: the combo box is called searchByAcc_cb. This is set so that it retrieves the account name & various other fields from the same table. Below that, there is a subform which is set to requery once another account from the drop down box is selected. When I select the 1st account, the record shows. However, upon selecting the 2nd account, 3rd, etc, nothing shows. I can then re-select the 1st record & i see the account information - so i know it's not a problem with the form updating.
The other strange thing is that upon selecting another account within the drop down box & then running the query from the query designer, the account information is retrieved for the 2nd / 3rd 4th record within the datasheet view. So, i know it isn't a problem with the query.
Any ideas on how to resolve? I've tried deleting the subform & re-inserting it (ensuring that the names match).
For anyone else struggeling with the same problem, I managed to resolve it: You need to delete any reference to the child / master fields within the subforms properties.

access report from dynamic crosstab query and vba to "manually" generate reports

I have come across the problem of generating complex access reports (by complex I mean with data processing, variable number of fields, among others).
Let me explain in deeper detail some of the things I need to implement:
Some fields should not show according to some values in a query
If a certain record does not exist, a nice colored (very noticeable) message should appear instead of the values that would be there (Suppose, for example, that a record with 03/04/2009 in the date field exists, a record with 03/06/2009 in the date field also exists but no record with 03/05/2009 exists. Before showing the data related to the last record, I should print something like "Didn't show up on 03/05/2009")
A bar chart that takes as data not the values in the records, but instead something else that is calculated over a set of records (like an average of all grades for a certain date). The number of series in this chart also varies according to values in the records, this chart would not be in the detail section, but instead in the page heading or some kind of group heading.
It should also be mentioned that the query is a TRANSFORM query (more precisely, an INNER JOIN of many TRANSFORM queries), and thus the number of columns returned by the query varies. While in the past I've been unable to bind this query as the recordsource for the report, somehow Access stopped complaining for now (can someone please clarify this? Is this normal, should I not worry about it and use it as a recordsource or should I avoid it?)
There are two options to achieve what I want (that I can see for now):
Create a report with no record source and lots of unbound fields, and through several events (Report_Open, Section_Format, etc.) and with the help of DAO, manually set the values of these fields. Changing the Data Series of the chart is also possible through VBA.
Set the record source to the query, and create some crazy and confusing VBA code to deal with the data and implement everything I need.
It seems to me that option 2 is going to be a huge headache and waste of time, and I recognize option 1 is pretty much like writing to an Excel file (since all the data is obtained with DAO), which would be much easier since I have much more control over almost everything there (but for many other reasons, we want everything in an access report)
While I'm biased and intend to go with option 1, I have found several problems with this option, for example:
I can't find a way to create new pages in the report with VBA, and thus I'm limited only to the first page.
Lack of some kind of free, online, decent and complete documentation on VBA and Access Reports
Also, if option 2 is more viable, I'm certainly willing to go with it, but I would also need some advice, and perhaps some tips to solving the problems I mentioned in this question.
So, the questions are:
Where can I find some decent and complete documentation on Access Reports and VBA?
How can I create pages in an access report, and choose which page I want to write to?
With the problem I have in my hands, will I reach any bottlenecks I should know about? Should I already be thinking of alternatives to Access Reports (writing to a spreadsheet, for example?)
Sounds like you want to dynamically create the report and avoid all the dummy text boxes.
In regard to:
I can't find a way to create new pages
in the report with VBA, and thus I'm
limited only to the first page.
Your solution #1 seems to assume an unbound report.
I think what I'd do is have the form the crosstab as the rowsource, so you'd have records to generate the pages, and then define your report's controls with no ControlSource (except for the controls that are bound to fields that are always present in the CrossTab). Then you could assign the ControlSources at runtime based on the particular columns. Here's the SQL for a crosstab grabbed from an app I'm working on now:
TRANSFORM First(impNoMatch.PersonID) AS FirstOfPersonID
SELECT impNoMatch.LastName, impNoMatch.FirstBame
FROM impNoMatch
GROUP BY impNoMatch.LastName, impNoMatch.FirstName
PIVOT impNoMatch.Status;
Now, you know that the fields in the SELECT clause will always be present, so if you opened a recordset on the SQL string you are using and count the number of fields in the recordset's Fields collection (you can't use the report's Recordset unless it's an ADO recordset, i.e., not bound to the Recordsource):
Dim strSQL As String
Dim rsFields As DAO.Recordset
Dim lngFieldCount As Long
strSQL = Me.Recordsource
Set rsFields = CurrentDB.OpenRecordset(strSQL)
lngFieldCount = rsFields.Fields.Count
From that, since you know the number of fields in the SELECT statement (i.e., the row headings), you can calculate the number of dynamic controls you want to assign, and you can use this recordset's fields collection to assign the ControlSources and unhide the controls.
You'd start out with all your controls that will display the dynamic fields set so their Visible property is FALSE. You'd also use a naming convention for those controls. In the code below, I've used txtNN, where NN is the numeric index in the Fields collection formatted as 2 digits. Here's the code (which adds lines to what's listed above, and is run in the OnOpen event):
Dim strSQL As String
Dim rsFields As DAO.Recordset
Dim lngFieldCount As Long
Dim l As Long
Dim strControlName As String
strSQL = Me.RecordSource
Set rsFields = CurrentDb.OpenRecordset(strSQL)
lngFieldCount = rsFields.Fields.Count
For l = 2 To lngFieldCount - 1
strControlName = "txt" & Format(l, "00")
Me(strControlName).ControlSource = rsFields.Fields(l).Name
Me(strControlName).Visible = True
Next l
rsFields.Close
Set rsFields = Nothing
Now, if you want to get fancy, you can reformat the controls, changing widths and horizontal/vertical position. If you do that, you have to do it in a different event, and it's a bit tricky to choose that. The only good place to put it is in a report group's header's OnFormat event. If you don't have any grouping, you can add one that doesn't do anything. In the case of my crosstab, a two-level sort on Lastname and Firstname and a header on the Firstname group with nothing in it is a good place to use the OnFormat event to change the appearance/layout of the controls on your report.
As to your question about how to learn how to do this, I recommend picking up an intermediate/advance Access programming book. The Access Developers Handbook is the gold standard on this, and includes tons of examples of programmatic control of reports.

MS Acess 2003 - VBA for Update SQL query?

hey guys, could someone show me the simple update query through vb? I need to add new fields to the table (just 3) and add a couple text boxes on a form so that users can add some additional data relative to the record (which is already what this form is based on).
So the first form I have is a form that populates a list, when the user double clicks on a selection from that list, it opens a new form, so that the ID of the the table that is tied to this form that I need to add the these text boxes on (all the combo boxes and text boxes relative to one record are tied to the active form at this point, however there are all unbound. On a button click there is already vb that saves the information to the table). I did not create this however, it was built by someone who is not there anymore, and apparently is better than I at this stuff. My problem is that there is soooo much vb that checks for records, and various sql statements based on case, that I cannot decipher it to its simplest form.
So I was looking for a simple example of an update sql statement in vb so I can try to break this apart.
I need it to update the record based on the ID: sql WHERE RecordID = me.RecordID
I actually thought I knew how to do this based on examples, however every time I try, then try to run on button click, I get a run-time error of SYNTAX error, and the debug just highlights the db.execute(sql) part. So I tried to get the resulting immediate window of the sql statement, and it looks fine to me:
UPDATE tblMain
SET [Name] = "John Doe",
[DATE] = #9/30/2009#,
[TYPE] = "TypeA",
WHERE RecordID = 958;
Can I update a table without accounting for every field in the table (because this one has about 15 plus the new 3, so I am ignoring about 14 fields here, but I do not want to alter those anyway???
So as always, I appreciate the help yall!! Thanks!
EDIT:
Sorry I always forget this....I was actaully trying it DAO....
Dim db as DAO.Database
Dim sql as String
set db = CurrentDb
etc
You were thaaat close! You have a simple extra comma after your last column. Get rid of it and it works fine.
UPDATE tblMain SET
[Name] = "John Doe",
[DATE] = #9/30/2009#,
[TYPE] = "TypeA"
WHERE RecordID = 958;
Yes, you can absolutely update only a few columns rather than all of them. That is a best practice, BTW.
Finally, It's considered bad practice to name your columns after reserved words like "Name" and "Date", but I know you inherited this.
You were wise to include Debug.Print sql in your code. bpayne already pointed out the extra comma in your SQL statement.
I want to point out another trouble shooting technique you may find useful to debug SQL statement problems.
Copy the statement from the Immediate Window, and paste it into the SQL View of a new query. Modify the query in the query designer until you can get it working, then revise your VBA code to generate a matching SQL statement.
In this case you might not have noticed the extra comma. However, you could create another new query and build the UPDATE statement from scratch in the query designer. After getting that one working, you could compare its SQL View to the failing query.