Seems like I've been hitting quite a number of pitfalls after starting out on Microsoft Access. Anyway, the latest one is this: my macro will auto-populate a field in my (datasheet) form whenever the record is dirty, which means that for this field everything is totally behind-the-scenes. Sounds good!
I faced a problem when trying to copy-paste over several columns from Excel though. Access didn't seem to recognise that I was "dirty-ing" more than one row, and consequently help me to auto-populate the fields of all these rows. Instead, it threw me the error message You must enter a value in the "xx.xx" field. followed by a disappointing Do you want to suppress further error messages telling you why records can't be pasted?. It seems Form_Dirty() isn't sufficient for my purposes...
Is there any solution or workaround for this? Let me know your comments and ideas, I'll be more than glad to listen :)
The Dirty event only fires once for the form:
The Dirty event occurs when the contents of a form or the text portion
of a combo box changes. It also occurs when you move from one page to
another page in a tab control.
You can programmatically set the DefaultValue for each form. It needs to be set specifically to a string, though, so requires additional quotes:
Private Sub Form_Open(Cancel As Integer)
Me.txtFirstName.DefaultValue = """Dave"""
End Sub
Related
I have some fields like textbox's and combobox's that show related data when a datagridview line is clicked. Thus every clicked row should present the same values and from related table into that textbox's and combobox's but some does not appear. This happens with the data related (from other table) and even with from the datagridview.
As some field data are right and other not I think that perhaps this is a memory issue. Is there any way to clear and refill those fields? I have try the code below but with no success.
EDITED:
It seems that every 3 clicks cleans the combobox. But if I clicked a 4th and return to click the one before it reappears. I am puzzled!
EDITED 2:
It seems this is a known issue by Microsoft and have no solution.
As posted here: Winforms combobox loses autocomplete value on lostfocus
Even the "3 steps test" relate... unfortunately the link to Microsoft is no longer active. So I have to continue my investigation...
...
Private Sub Month_work_ListDataGridView_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles Month_work_ListDataGridView.CellClick
Me.AndrosAdapter.Fill(Me.ActivworkxDataSet.Andros)
Me.Month_work_ListTableAdapter.Fill(Me.ActivworkxDataSet.Month_work_List)
(... other code tasks ...)
End Sub
Bug confirmed.
A supposed Hotfix was here: https://support.microsoft.com/en-us/help/2868238/a-combo-box-control-selects-an-unexpected-value-in-windows-7-sp-1-or-windows-server-2008-r2
but is no logger available: https://support.microsoft.com/en-us/help/4343220/this-hotfix-is-no-longer-available
Instead Microsoft suggests to upgrade to Windows 10.
I solve it with a workaround:
Me.CBoxObra.DropDownStyle = ComboBoxStyle.DropDownList
Where before was:
Me.CBoxObra.DropDownStyle = ComboBoxStyle.DropDown
And the problem no longer appears.
I've got a form frm_New_Datasheet to enter datasheets from volunteers into a database I'm making. For the volunteer id text box txt_Vol_ID I've got two buttons to either search for an existing volunteer or add a new one, each opening a respective form. I want the Vol_ID from frm_Volunteers to get passed back to frm_New_Datasheet once I add a new volunteer.
To do this, I added the following code to my volunteer form:
Private Sub Form_AfterInsert()
If Not IsNull(Me.vol_Vol_ID) Then
Dim volVal As Double
volVal = Me.vol_Vol_ID
Forms!frm_New_Datasheet!txt_Vol_ID.Value = volVal
End If
End Sub
And it worked perfectly. Then I tried creating my 'Search for Volunteers' form, added the same code to it, but now I get the following error on both:
Run-time error -2146500594 (800f000e):
Method 'Item' of object 'Forms' failed
The debugger is highlighting the line where I set the .Value = volVal so I've looked for other ways to call that text box but no luck yet. I've tried
Forms([frm_New_Datasheet]).[txt_Vol_ID] = volVal`
but that gives me a different error:
Run-time error '2465':
Microsoft Access can't find the field '|1' referred to in your expression
I'm pretty lost on this because I think I'm calling the other form's text box properly, and when I search for the first run-time error the best advice I've found is "Sometimes VBA is buggy and try restarting" which hasn't helped. So far this is the best idea I've had to pass the value from one form to another. If there's another place I can drop this code or another way to skin this cat I'm all ears.
Thanks!
Looks like you should check form/control names more carefully and make sure that the form frm_New_Datasheet is open.
Here is the correct variant for referring using Forms collection by form name:
Forms("frm_New_Datasheet").txt_Vol_ID = volVal
I'm not sure if this actually counts as an answer but after HansUp helped me through with some trouble shooting in the comments above I just copied the form that wasn't being found (still not sure why), pasted it with a new name, and deleted the original form. After that everything is working well.
I'm building a relatively simple datasheet-style form for selecting a record (which will be used to populate another form)
The form pulls from a query with multiple columns. Since it's counter-intuitive to have a highlighted field and data entry cursor when all the user wants to do is select a record, I added the following code to each field on the form:
Private Sub Model_Enter()
RunCommand acCmdSelectRecord
End Sub
This works fine for the "Model" field, but for every other field it gives me the following error:
Run-time error 3125
" is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.
There's literally nothing else going on in this form, so I have no idea what the issue is, or why the code works for Model and breaks for everything else. Anyone else run into this issue?
I suggest you use the On Current event, rather than write code for each control. It is also possible to use conditional formatting and a little code to highlight a record.
I would like to know if there is a way to set the parameters in an Access 2007 query using VBA. I am new to using VBA in Access, and I have been tasked with adding a little piece of functionality to an existing app.
The issue I am having is that the same report can be called in two different places in the application. The first being on a command button on a data entry form, the other from a switchboard button. The report itself is based on a parameter query that has requires the user to enter a Supplier ID.
The user would like to not have to enter the Supplier ID on the data entry form (since the form displays the Supplier ID already), but from the switchboard, they would like to be prompted to enter a Supplier ID.
Where I am stuck is how to call the report's query (in the report's open event) and pass the SupplierID from the form as the parameter. I have been trying for a while, and I can't get anything to work correctly. Here is my code so far, but I am obviously stumped.
Private Sub Report_Open(Cancel As Integer)
Dim intSupplierCode As Integer
'Check to see if the data entry form is open
If CurrentProject.AllForms("frmExample").IsLoaded = True Then
'Retrieve the SupplierID from the data entry form
intSupplierCode = Forms![frmExample]![SupplierID]
'Call the parameter query passing the SupplierID????
DoCmd.OpenQuery "qryParams"
Else
'Execute the parameter query as normal
DoCmd.OpenQuery "qryParams"?????
End If
End Sub
I've tried Me.SupplierID = intSupplierCode, and although it compiles, it bombs when I run it. And here is my SQL code for the parameter query:
PARAMETERS [Enter Supplier] Long;
SELECT Suppliers.SupplierID, Suppliers.CompanyName, Suppliers.ContactName, Suppliers.ContactTitle
FROM Suppliers
WHERE (((Suppliers.SupplierID)=[Enter Supplier]));
I know there are ways around this problem (and probably an easy way as well) but like I said, my lack of experience using Access and VBA makes things difficult. If any of you could help, that would be great!
The suggestion being made here is to 100% REMOVE the parameter from the query. This not only solves your problem, but then means you can use the query for code, other forms and not have your whole design fall apart because one stupid form is not open (hence the VERY reason for your question).
So, remove the parameters from the query. This also means that your report will now not need some form that already opened. And again, if some silly form is not opened, why should your report fail to work?
So, remove the parameter. Now, in your form that opens the report, it can pass the filter, and more in point use what is a called a "where" clause. This "where" clause is designed in MS-access to solve the problem of having to know ahead of time what kind of parameters and filters you need. It occurs at runtime, and thus MANY DIFFERENT forms can call and open that report.
Now in the form that calls and opens the form, you go:
Docmd.OpenReport "rptSuppliers",acViewPreview, , _
"SupplierCode = " & me.SupplierCode
So, in the above, the parameter is created on the fly. The great advantage is tomorrow you can have another form open the same report and perhaps filter by region.
In the case of NO where clause being passed and a user simply opening the form, then no filters will be used and no prompts will occur and all records will show. This is probably your best approach.
However if for some strange reason you still deem it REALLY necessary to have some report prompt when one silly form just happens to not be opened, then place the following code in the forms on-open event.
If CurrentProject.AllForms("form1").IsLoaded = False Then
Me.Filter = "SupplierID = " & InputBox("Enter Supplier ID")
Me.FilterOn = True
End
However, I would really make efforts to avoid hard coding some silly form name in the reports open event. Not only does this mean your hard coding dependencies of some silly form that is now attached to a report, but if you later on copy that report, or even copy the original form (or even rename any of these objects), then you have to go into the application and hunt about and now find the places you as a developer introduced dependences. This approach can substantially increase the maintenance costs of an application and thus should be advoied.
So, the suggestion here is to dump the parameter query. Simply provide a form or some prompt system to launch the reports. Those forms should prompt the user for the information you wish to filter. Or as in your case the bound form and it current record provides that information. The beauty of this system is now there is no depdancy from the report.
Any form, or even any code down the road is free to pass a pramaeter, and it will not be limited to SupplierID, but can be any type of filter or parameter you wish.
Keep in mind that perhaps the user might not want that form to be open and perhaps they don't want the prompt. With your design and question the user will be forced to enter a parameter value even when launching the report without any forms open and not desiring to be prompted to allow them to view all reocrds in that report.
As I outlined in a recent post, I tend never to hardwire any parameters or form control references into the recordsources of reports or forms. Instead, I set them at runtime. The simplest way is by passing the WhereCondition property in the DoCmd.OpenForm/DoCmd.OpenReport:
DoCmd.OpenReport "MyReport", , , "[SupplierID]=" & Me!SupplierID
That assumes you're running it from a form that has the relevant SupplierID already present in its recordsource (i.e., you're on a record with that SupplierID).
More complicated is to use the OnOpen event of the report to set the reports's recordsource. That's what I outlined in the cited post above. But that example hardwires the choice to a selection form, whereas you might want to instead offer different sets of choices depending on context. There are two ways to handle that:
if A2003 and later, pass an OpenArg (the last parameter of the DoCmd.OpenReport) to tell the OnOpen event what to do to collect the information on what to filter to.
use an outside structure like a standalone class module to store criteria that the OnOpen event will read and act upon accordingly.
I suspect that the WhereCondition in the DoCmd.OpenReport is your easiest solution, but if you want details on the other two, just ask.
As in the title I cam across a strange phenomenon. I have a form which contains two subforms. On both subforms I have a button which triggers requery of the relevant subform. If after loading the form, I immediately click on this button (requery the form) I get error "3021: No current record" when I try to save the value of the primary key of the current record in the OnCurrent event to a variable. Strangely enough in the debugger the relevant values are like this:
Form.CurrentRecord=1
Form.RecordSet.Absoluteposition=-1
Form.RecordSet.RecordCount=14
Form.RecordSet.EOF=False
Form.RecordSet.BOF=False
Also note, that when the form is loaded, in the load event it still works correctly and the there I can save the primary key value which is the primary key contained in the first record.
Somewhere between Form_Load and me clicking that requery button the status of the form is getting out of synch. I just recently switched from Access 2003 to 2007 and as far as I can remember this error did not happen before (although I might just not click this button right afer load).
For now I have a workaround, but I'd really like to understand how this can happen.
If this is ADO, check which OLE DB provider is being used e.g. (guessing)
Debug.Print Form.RecordSet.ActiveConnection.Provider
If by chance it is the 3.51 version, see:
INFO: AbsolutePosition Property with JET Databases in ADO
...if you are using the ACE provider, perhaps it's a regression bug?!
You have to place the record pointer on a particular record in the form's Recordset via a MoveFirst or whatever. And the return value appears to be zero-based instead of 1-based.
I can't reproduce the error you're getting returning -1. Are you setting the form's recordset to an ADO recordset? If so, that might explain it -- DAO recordsets never return -1 for any of these values, but I believe that before a .MoveLast an ADO RecordCount returns -1. Perhaps AbsolutePosition does the same in ADO.
What are you trying to accomplish? I don't see any utility in using the form's Recordset object when it's so much easier to assign a recordsource and navigate the RecordsetClone (which is much more closely bound to the form's edit/display buffer than the form's Recordset, particularly when the Recordset has been assigned with an ADO recordset).
I have the exact same problem when I try to go to "Design View". I don't need to click quickly, I can wait an hour and then do that and bang! there is this error.
Note that I only get the error if the sub-form is still empty (i.e. really does not include any records which is the case when I first open the window.) So I always thought that was normal.
The AbsolutePosition is set to -1 when the cursor is not currently pointing to a specific position. Also, this value is zero based (as mentioned by someone else: first row is AbsolutePosition 0). However, this position may be -1 even if you have focus on a specific row in the sub-form. This means it is useless.
What you want to use if you need to know the current cursor position is CurrentRecord. This is a number that starts at 1. I would imagine that if the list is empty, the CurrentRecord may be set to 0 or -1 representing the fact that no row is available.
I used all of these in a function used to calculate a complex total of different columns, here is the page http://linux.m2osw.com/msaccess-sum-focus-recordset-problem