set Access database table field with form check box - ms-access

I am trying to set the value of a number field on a table using the value of a bound checkbox on a form. The value needs to be 40 if checked and 0 if unchecked. I'm new to this and have no idea where to start.
No, the checkbox was added to a form and is bound to a number field in the table. The data is imported from an antiquated system that uses codes that most users would not understand, so if it says 40 in the table I just want the form to show checked, all other values should show unchecked, and I want the user checking/unchecking the checkbox to update the table accordingly.
The checkbox is to indicate whether or not a customer has provided direct debit information. 40 would mean they have, anything other than 40 would mean they haven't.

One way do this is using VBA in Access. The way you access VBA console in Access, is when in your form's design view, right-click the checkbox box control and choose "Build Event" from the menu. Make sure your control's Triple State is set to "Yes" in the property for the checkbox in the form's design view. Also, be certain that the checkbox's Control Source is pointed to the field in the table where you're putting the data.
Please note that prior to doing this, it is helpful to prefix your control's name... something like chkDebitInfo... "chk" stands for check box. You can change the name in the property sheet for the control, by clicking on the Other tab, and simply change the default name, which might say something like Check625. Also, you want to set the table field's data type to an "Integer" so it holds the value.
Once you're in the VBA console, after having chosen Build Event... you're presented with the control's sub procedure. I've done a sample for you:
Private Sub chkDebitInfo_Click()
If chkDebitInfo.Value = True Then
chkDebitInfo.Value = 40 // Sets the checkbox to 40 if checked
ElseIf chkDebitInfo.Value = False Then
chkDebitInfo.Value = 0 // Sets the checkbox to 0 if un-checked
End If
End Sub
I've commented the statements that set the checkbox values if checked or un-checked, so you don't have to add those. Just substitute the control name for your's, or use the default name if you haven't changed it, and you're good. Then when the check box is checked or not checked, you'll see the values populated in the database table.
Alternatively, you can set the checkbox to default value for when the form loads, but you haven't stated it, so I won't go into it. Hope this helps. Let me know if I need to expound further.

Related

Setting properties for combobox in the form.open event Access 2019

I have the following piece of code located in the open event of a form.
If GetUserName = "Bob" Or GetUserName = "Ned" Then
Me.cbo_Position2.LimitToList = False
Me.cbo_Position2.AllowValueListEdits = True
Me.cbo_Position2.ListItemsEditForm = frm_MasterDropDown_lookup
End If
I'm using this code to set who can edit a combo box list. The combo box is bound to a field on the form and the combobox info is in a separate lookup table. What I want to know is whether or not these properties can be set as the form opens.
When I run this code, it executes with no errors but the properties do not change. I also tried doing 'Me.Refresh' at the end but that did not help. My assumption at this time is that they can't be "set on the fly" so to speak. If not, I was wondering if there is something I'm missing to get this to work.
TIA,
Tim
From Access help:
1.If you set the combo box's BoundColumn property to any column other than the first visible column (or if you set BoundColumn to 0), the LimitToList property is automatically set to Yes.
2.When the LimitToList property of a bound (bound control: A control used on a form, report, or data access page to display or modify data from a table, query, or SQL statement. The control's ControlSource property stores the field name to which the control is bound.) combo box is set to No, you can enter a value in the combo box that isn't included in the list. Microsoft Access stores the new value in the form's underlying table (table: A database object that stores data in records (rows) and fields (columns). The data is usually about a particular category of things, such as employees or orders.) or query (query: A question about the data stored in your tables, or a request to perform an action on the data. A query can bring together data from multiple tables to serve as the source of data for a form or report.) (in the field specified in the combo box's ControlSource property), not the table or query set for the combo box by the RowSource property. To have newly entered values appear in the combo box, you must add the new value to the table or query set in the RowSource property by using a macro or Visual Basic event procedure (event procedure: A procedure that is automatically executed in response to an event initiated by the user or program code, or that is triggered by the system.) that runs when the NotInList event occurs.
Example for setting property:
Forms("Order Entry").Controls("States").LimitToList = False

Popup box asking for parameter when using sql query in access forms

I have a form with 3 things for my users to fill in:
a textbox called ProjectName
two ActiveX control objects (Microsoft Time and Date picker Control 6.0) called ProjStartDate and ProjEndDate respectively
After my users have entered either of the above, they can click on a button that will call requery on a list box object in the form which will display the filtered results.
I have set the Row Source Type of the listbox to be "Table/Query" and its Row Source to be the below SQL query:
SELECT p.Title
FROM Project AS p
WHERE
p.Title = [Forms]![Search by project]![ProjectName]
OR (p.StartDate <= [Forms]![Search by project]![ProjStartDate]
AND p.EndDate >= [Forms]![Search by project]![ProjEndDate])
ORDER BY
p.ProjectId DESC;
However, every time I enter the form, it will prompt me with a pop up box asking me for a parameter called Forms!Search by project!ProjectName , Forms!Search by project!ProjStartDate and Forms!Search by project!ProjEndDate . If I enter the parameter for, lets say project name correctly, the list box will display the correct filter results.
Furthermore, even if I enter the correct keyword in the ProjectName textbox and requery, the parameter pop up box will still occur. Do anyone knows how to solve this issue? Thanks a lot in advance!
I first wrote this answer based on the assumption that all the controls were contained in a single form. However, if the list box is on a child form, the parent form's controls (such as [Forms]![Search by project]![ProjectName]) are not yet available when the child form first opens. If that is the case, you could leave the list box row source property empty, and wait until the parent form's Form Load event to assign your SELECT statement to the list box row source. Or leave the list box row source empty until the user clicks the command button.
The rest of this answer was about diagnosing a naming problem. Since you indicated in a comment that the query can work when run at certain times, I don't think naming is involved after all, but will leave it in case it may help someone else.
Open the Immediate window (Ctrl+g) and investigate why the db engine can't find those parameters.
With your "Search by project" form open in Form View, check its .Name property simply to verify Access sees the name you expect. If both you and Access agree on the form's name, you will get this ...
? Forms![Search by project].Name
Search by project
OTOH, if Access thinks the form has a different name, that attempt will trigger an error. If that happens, check the form name as Access sees it. This will give you the names of all open forms:
for each f in Forms : ? f.Name : next
Finally, examine the values of those form controls. Assuming "Search by project" is indeed the correct form name ...
? Forms![Search by project]!ProjectName
? Forms![Search by project]!ProjStartDate
? Forms![Search by project]!ProjEndDate

access 2010 expression builder

I want a text box to contain data which is a calculation based on 2 other control field values - only if it's value is null (ie the current value of the column in the database is null).
So I entered =([control1]*[Control2])/1000 in the expression builder for the default value property - however the result always shows the textbox to be empty (even tho control2 and control2 contain values).
How can I achieve this? Can such an operation only be done in code-behind ie VB??
thanks,
KS
I think you're talking about a control bound to a field in the form's record source. And when the underlying field is Null, you want the control loaded with your calculated value.
If that interpretation is correct, you can do it from the form's On Current event.
If IsNull(Me.txtYourTextBox) Then
Me.txtYourTextBox = (Nz(Me.control1) * Nz(Me.Control2)) / 1000
End If
That will load the computed value into the text box, allow the user to change its value if desired, and store the value to the bound field when the record is saved.
If the bound field is not Null, its value will be displayed in the text box without alteration by the On Current code.
Is that what you want?
To accomplish this using VBA, add a Form_Load Event. (Open the form in Design View and in Form properties click the Event tab and choose Event Procedure for "On Load" and click ...)
This example uses [TextField] to refer to the table data.
Private Sub Form_Load()
TextControl.SetFocus
If IsNull([TextField]) Then
TextControl.Text = ([Control1] * [Control2]) / 1000
End If
End Sub

How to force access to begin a new record

I have a form with a few bound fields and a few 'custom made' checkboxes, which set values per vba. When I now start a new record with 'DoCmd.GoToRecord , , acNewRec', Access clears my form but won't create a fresh ID until a value is entered into one of the bound fields. Since my checkbox-fields are not bound, any changes before a bound field has been edited won't be saved. I tried adding values via sql statements, but access throws an error after I change another field stating that the current recordset has been changed so I doubt that this is the way to go.
My form is based on a query and witch vba I set the checkboxes like [value_x] = true (which works fine when I first enter data into a bound field and thereby a new record is created).
(Another way to avoid this would be to set any bound field during the onload-event to a value and remove the value afterwards. But that's not very clean I guess ..)
After testing a few approaches I found my earlier stated idea to be the easiest approach. This means I set a value of a bound field in the form_load event and work with me.dirty where neccessary.
Of course I have to delete empty recordsets afterwards (if someone only opens and closes the form), but that can be handled very easy.
Another great idea was the one Robert Harvey gave me. He suggested to add a click event to my unbound custom checkboxes and use this to change a hidden bound checkbox field, which also worked great.

Custom row source for combo box in continuous form in Access

I have searched around, and it seems that this is a limitation in MS Access, so I'm wondering what creative solutions other have found to this puzzle.
If you have a continuous form and you want a field to be a combo box of options that are specific to that row, Access fails to deliver; the combo box row source is only queried once at the beginning of the form, and thus show the wrong options for the rest of the form.
The next step we all try, of course, is to use the onCurrent event to requery the combo box, which does in fact limit the options to the given row. However, at this point, Access goes nuts, and requeries all of the combo boxes, for every row, and the result is often that of disappearing and reappearing options in other rows, depending on whether they have chosen an option that is valid for the current record's row source.
The only solution I have found is to just list all options available, all the time. Any creative answers out there?
Edit Also, I should note that the reason for the combo box is to have a query as a lookup table, the real value needs to be hidden and stored, while the human readable version is displayed... multiple columns in the combo box row source. Thus, changing limit to list doesn't help, because id's that are not in the current row source query won't have a matching human readable part.
In this particular case, continuous forms make a lot of sense, so please don't tell me it's the wrong solution. I'm asking for any creative answers.
I also hate Access, but you must play with the cards you are dealt.
Continuous forms are a wonderful thing in Access, until you run into any sort of complexity as is commonly the case, like in this instance.
Here is what I would do when faced with this situation (and I have implemented similar workarounds before):
Place an UNBOUND combobox on the form. Then place a BOUND textBox for the field you want to edit.
Make sure the combobox is hidden behind (NOT invisible, just hidden) behind the textBox.
In the OnCurrent event fill the listBox with the necessary data. Go ahead and "Limit to list" it too.
In the OnEnter or OnClick event of the textBox give the combobox focus. This will bring the combobox to the forefront. When focus leaves the combobox it will hide itself once more.
In the AfterUpdate event of the combobox set the value of the textbox equal to the value of the combobox.
Depending on your situation there may be some other details to work out, but that should more or less accomplish your goal without adding too much complexity.
use continuous forms .. definitely. In fact you can build entire applications with great and intuitive user interface built on continuous forms. Don't listen to Toast!
Your solution of listing all options available is the correct one. In fact there is no other clean solution. But you are wrong when you say that Acccess goes nuts. On a continuous form, you could see each line as an instance of the detail section, where the combobox is a property common to all instances of the detail section. You can update this property for all instances, but cannot set it for one specific instance. This is why Access MUST display the same data in the combobox for all records!
If you need to accept only record-specific values in this combobox, please use the beforeUpdate event to add a control procedure. In case a new value cannot be accepted, you can cancel data update, bringing back the previous value in the field.
You cannot set the limitToList property to 'No' where the linked data (the one that is stored in the control) is hidden. This is logical: how can the machine accept the input of a new line of data when the linked field (not visible) stays empty?
You could also make the value of the combo box into an uneditable text field and then launch a pop-up/modal window to edit that value. However, if I was doing that, I might be inclined to edit the whole record in one of those windows.
I don't think that Access continuous forms should be condemned at all, but I definitely believe that they should be avoided for EDITING DATA. They work great for lists, and give you substantially more formatting capabilities than a mere listbox (and are much easier to work with, too, though they don't allow multi-select, of course).
If you want to use a continuous form for navigation to records for editing, use a subform displaying the detailed data for editing, and use the PK value from the subform for the link field. This can be done with a continuous form where you place a detail subform in the header or footer, linked on the PK of the table behind the continuous form.
Or, if you are using a continuous form to display child data in a parent form, you can link the detail subform with a reference to the PK in the continuous subform, something like:
[MySubForm].[Form]!MyID
That would be the link master property, and MyID would be the link child property.
We also encounter this a lot in our applicatins. What we have found to be a good solution:
Just show all rows in the comboboxes.
Then, as soon as the user enters the compobox in a specific row, adjust the rowsource (with the filter for that row). When the combobox loses the focus, you can re-set the rowsource to display everything.
I have a simpler way to go than Gilligan. It seems like a lot of work but it really isn't. My solution requires having my continuous form as a subform datasheet. On my subform I have two lookup comboboxes, among other fields, called Equipment and Manufacturer. Both simply hold a Long Integer key in the data source. Manufacturer needs to be filtered by what is selected in Equipment. The only time I filter Manufacturer.RowSource is in the Manufacturer_GotFocus event.
Private Sub Manufacturer_GotFocus()
If Nz(Me.Equipment, 0) > 0 Then
Me.Manufacturer.RowSource = GetMfrSQL() '- gets filtered query based on Equipment
Else
Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End If
End Sub
In Manufacturer_LostFocus I reset Manufacturer.RowSource to all Manufacturers as well. You need to do this because when you first click in the subform, GotFocus events fire for all controls, including Manufacturer, even though you are not actually updating any fields.
Private Sub Manufacturer_LostFocus()
Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End Sub
In the Enter event of Manufacturer you have to check if Equipment has been selected, if not set focus to Equipment.
Private Sub Manufacturer_Enter()
If Nz(Me.EquipmentID, 0) = 0 Then
'-- Must select Equipment first, before selecting Manufacturer
Me.Equipment.SetFocus
End If
End Sub
You also need to requery the Manufacturer combobox in Form_Current event (i.e. Me.Manufacturer.Requery), and you should set the Cycle property of this subform to "Current Record".
Seems simple enough, but you're not done yet. You also have to reset Manufacturer.RowSource to all Manufacturers in the SubForm_Exit event in the parent form in case the user goes to the Manufacturer combobox but does not make a selection and clicks somewhere on the parent form. Code sample (in parent form):
Private Sub sFrmEquip_Exit(Cancel As Integer)
Me.sFrmEquip.Controls("Manufacturer").RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End Sub
There is still one piece of this that is not clean. When you click on Manufacturer and have multiple rows in the datasheet grid, Manufacturer field will go blank in other rows (the data underneath the comboboxes is still intact) while you're changing the Manufacturer in the current row. Once you move off this field the text in the other Manufacturer fields will reappear.
This seems to work well.
CBOsfrmTouchpoint8 is a combobox shortened to just the dropdown square.
CBOsfrmTouchpoint14 is a textbox that makes up the rest of the space.
Never say never:
Private Sub CBOsfrmTouchpoint8_Enter()
If Me.CBOsfrmTouchpoint8.Tag = "Yes" Then
CBOsfrmTouchpoint14.SetFocus
Me.CBOsfrmTouchpoint8.Tag = "No"
Exit Sub
End If
Me.CBOsfrmTouchpoint8.Tag = "No"
Me.CBOsfrmTouchpoint8.RowSource = "XXX"
Me.CBOsfrmTouchpoint8.Requery
Me.CBOsfrmTouchpoint8.SetFocus
End Sub
Private Sub CBOsfrmTouchpoint8_GotFocus()
Me.CBOsfrmTouchpoint14.Width = 0
Me.CBOsfrmTouchpoint8.Width = 3420
Me.CBOsfrmTouchpoint8.Left = 8580
Me.CBOsfrmTouchpoint8.Dropdown
End Sub
Private Sub CBOsfrmTouchpoint8_LostFocus()
Me.CBOsfrmTouchpoint8.RowSource = "XXX"
Me.CBOsfrmTouchpoint8.Requery
End Sub
Private Sub CBOsfrmTouchpoint8_Exit(Cancel As Integer)
Me.CBOsfrmTouchpoint14.Width = 3180
Me.CBOsfrmTouchpoint8.Width = 240
Me.CBOsfrmTouchpoint8.Left = 11760
Me.CBOsfrmTouchpoint8.Tag = "Yes"
End Sub
What if you turn off the "Limit To List" option, and do some validation before update to confirm that what the user might have typed in matches something in the list that you presented them?
Better...
Set you combo box Control Source to a column on the query where the values from your combo box will be stored.
For Me I think the best way and easiest way is to create a temporary table that has all your bound fields plus an extra field that is a yeas/no field.
then you will use this table as the data source for the continuous for. You can use onLoad to fill the temporary table with the data you want.
I think it is easy after that to loop for the choices, just a small loop to read the yeas/no field form the temporary table.
I hope this will help
Use OnEnter event to populate the combo box, don't use a fixed rowsource.
I've just done similar. My solution was to use a fixed row source bound to a query. The query's WHERE clauses reference the form's control i.e. Client=Forms!frmMain!ClientTextBox. This alone will fill the combo boxes with the first row's data. The trick then is to set an 'On Enter' event which simply does a re-query on the combo box e.g. ComboBox1.Requery, this will re-query that combo box alone and will only drag in the data related to that record row.
Hope that works for you too!
Disclaimer: I hate Access with a passion.
Don't use continuous forms. They're a red herring for what you want to accomplish. Continuous forms is the same form repeated over and over with different data. It is already a kludge of Access's normal mode of operation as you can't have the same form opened multiple times. The behavior you are seeing is "as designed" in Access. Each of those ComboBox controls is actually the same control. You cannot affect one without affecting the others.
Basically, what you have done here is run into the area where Access is no longer suitable for your project (but cannot ditch because it represents a large amount of work already).
What seems to be the most likely course of action here is to fake it really well. Run a query against the data and then create the form elements programmatically based on the results. This is a fair amount of work as you will be duplicating a good bit of Access's data handling functionality yourself.
Reply to Edit:
But as they are, continuous forms cannot accomplish what you want. That's why I suggested faking out your own continuous forms, because continuous forms have real limitations in what they can do. Don't get so stuck on a particular implementation that you can't let go of it when it ceases to work.