I have an access 2007 front-end app. On a particular form, there are 2 radio buttons in a radio button group. I am trying to detect when the radio button group is changed and capture the old and new values, but my OldValue and Value properties are = in the save event, even if I have changed it. The OldValue is equal to the New radio button value, not what it was originally.
I tried coding this in the form's Save subroutine. The intent was to compares the RB value with the original dataset value to force setting the old value, but it doesn't like the 'SET' statements
If fraResistOption.Value = 1 And (IsNull([Dl_Resisted]) Or UCase([Dl_Resisted]) = "N") Then
Set fraResistOption.OldValue = 1
[Dl_Resisted] = "N"
Else
If fraResistOption.Value = 1 And (Not IsNull([Dl_Resisted]) Or UCase([Dl_Resisted]) = "Y") Then
Set fraResistOption.OldValue = 2
[Dl_Resisted] = "N"
Else
If fraResistOption.Value = 2 And (IsNull([Dl_Resisted]) Or UCase([Dl_Resisted]) = "N") Then
Set fraResistOption.OldValue = 1
[Dl_Resisted] = "Y"
Else
If fraResistOption.Value = 1 And (Not IsNull([Dl_Resisted]) Or UCase([Dl_Resisted]) = "Y") Then
Set fraResistOption.OldValue = 2
[Dl_Resisted] = "Y"
End If
End If
End If
End If
Could someone suggest a way to do this? Please and thank you.
The .OldValue property of the Option Group (sometimes referred to as "Frame") does work. I have a table named [optValues]:
[ID] - AutoNumber
[optValue] - Numeric (Long Integer)
It contains one record:
ID optValue
1 3
My form's Record Source is the [optValues] table. The form has an Option Group named "Frame0" whose Control Source is the [optValue] field. It contains three Option buttons
label: "foo", value: 1
label: "bar", value: 2
label: "baz", value: 3
The After Update event handler for Frame0 is:
Private Sub Frame0_AfterUpdate()
MsgBox "Old value: " & Me.Frame0.OldValue & ", New value: " & Me.Frame0.Value
End Sub
When I open the form, "baz" is selected (because [optValue] is 3 in the table):
When I click on "foo" I immediately see the (correct) old and new values:
The only way I can think of to detect and capture changes to Option-Group values is to handle the Form_Current event (save the Option Group value), then also handle the Option-Group After event. Although you can change the Option-Group.Value, OldValue is likely a protected (read-only) property. Hope something like the following helps:
Dim OldValue As Byte
Dim CurrentValue As Byte
Private Sub Form_Current()
OldValue = Frame0.Value
End Sub
Private Sub Frame0_AfterUpdate()
CurrentValue = Frame0.Value
Debug.Print "AFTER: OldValue=" & OldValue & "' CurrentValue=" & CurrentValue
End Sub
I don't know why but .oldvalue doesn't work for me.
If you are in the same boat as me, you can use the BeforeUpdate event of the optionGroup and set a static variable.
Then read the static variable in afterUpdate event and reset it for the next change.
Related
I was wondering if it were possible to have a field shown or active if another previous field is selected.
For example, if I have a Status field and then choose Inactive then I would like another field to show for Inactive Date
Thanks
Let say, you have checkbox for status and textbox to capture date on your form. AfterUpdate event gets triggered when control value changes and you can enable/disable other controls here.
Private Sub chkStatus_AfterUpdate()
If Me.chkStatus Then
Me.txtDate.Enabled = True
Else
Me.txtDate.Enabled = False
End If
End Sub
To enable/disable textbox on dropdown change using VBA
Private Sub cmbStatus_Change()
If Nz(Me.cmbStatus, "") = "Active" Then
Me.txtDate.Enabled = True
ElseIf Nz(Me.cmbStatus, "") = "InActive" Then
Me.txtDate.Enabled = False
End If
End Sub
Using Macro builder - without VBA
How would i add a check("chk3") that will be ticked when ("Customer order Number") field has been inputted. when an order number is entered, then the check box will tick..
i also would like to know if it is possible that When the value field ("Value") is under £10,000 then the check box ("chk2") will tick. if it is over £10,000 then it will not tick
You may use AfterUpdate events for such validations.
Nz function checks for null value and converts them to empty string & 0 respectively
For Customer Order Number:
Private Sub txtCustomerOrderNo_AfterUpdate()
If Nz(Me.txtCustomerOrderNo, "") <> "" Then
Me.chk3 = True
Else
Me.chk3 = False
End If
End Sub
For Project value is less than 10K:
Private Sub txtProjEstimate_AfterUpdate(Cancel As Integer)
If Nz(Me.txtProjEstimate, 0) < 10000 Then
Me.chk2 = True
Else
Me.chk2 = False
End If
End Sub
Depends on your version of Access. In older versions, it was the AfterUpdate event. In newer ones, I think it's OnExit.
In whichever event of Customer Order Number, just set its value to True.
Private Sub CustomerOrderNumber_Exit(Cancel As Integer)
Me.chk3 = true
End Sub
It sort of depends what you're trying to do with the chk3 validation. If you're looking for a specific structure. For instance, a 10 digit number, then you would want a validation along those lines within the IF Statement. Something like:
(Using AfterUpdate)
If Me.[Customer order Number] LIKE "##########" Then
Me.chk3 = True
End If
Similiarly with the validation on the ck2 > £10,000 (assuming this is an appropriately designated currency field):
If Me.[Value] <= 10000 Then
Me.chk2 = True
End If
when double clicking on a value i need to open a form. the value gets passed to the opened form. I want the form to directly filter on that value instead of pushing on a button first. i tried filtering on change and on load but it doesn't work. when loading it doesn't know the value because it gets added after it opened the form.
this is the code for passing the value:
DoCmd.OpenForm "SubmenuRubrieken", acNormal
Forms!SubmenuRubrieken.Tv_rubrieknaam.Value = Me.Tekst14.Value
this is the code for filtering on that value in Tv_rubrieknaam:
Dim filter As String
filter = ""
If Not IsNull(Tv_rubrieknaam) Then filter = filter & " AND rubrieknaam = '" & Tv_rubrieknaam.Value & "'"
Me.filter = Right(filter, Len(filter) - 5)
Me.FilterOn = True
for some reason it doesn't trigger the filter on changing the value of Tv_rubrieknaam. how do i need to solve this?
I guess, the Form_Load() event is finished before you set the value (OpenForm is performed before value is set), so you would have to do the filtering in the OnChange() event of the Textfield or similar.
Better: pass the Me.Text14.Value with the DoCmd.OpenForm command either as a prepared whereCondition OR as OpenArgs with filtering option in the On_Load event.
A basic example:
I have a Form1 with a TextBox called Text0 on it. Text0 has a value of 2.
I have a Form2 with a Table called Table1 as Recordsource. Table1 has a column called Field1 containing numbers between 1 and 3
All I need to do is add the following code into the module of the Form1 and the moment I click on Text0 Form2 will be openend filtered down to rows with Field1 = 2
Private Sub Text0_Click()
DoCmd.OpenForm "Form2", acFormDS, , "Field1 = " & Nz(Me!Text0, 0)
End Sub
I have a MS Access 2007 application which has several forms where I've used the same list box design. I have two list boxes, one of which gets values from a table with a query like:
SELECT id, value FROM table
And the second which is initially empty. In between these two list boxes are add and remove buttons, which are disabled by default. Clicking a value in the first list box enables the add button, and clicking a value in the second list box enables the remove button. Clicking the add button adds the selected item to the second list, and clicking the remove button removes an item for the second list.
The code I have for the add button is as follows ("ALLLIST" refers to the list with the query values, "SELECTEDLIST" is the one that's initially empty) :
Dim selectedId, selectedValue, safeValue As String
Dim existing As Boolean
Dim index As Integer
existing = False
selectedId = Me.ALLLIST.Value
index = Me.ALLLIST.ListIndex
selectedValue = Me.ALLLIST.Column(1,index)
'Loop through the list of selected values and see if this one has already been added to the list
For i = 0 To (Me.SELECTEDLIST.ListCount)
If (Me.SELECTEDLIST.Column(0, i) = selectedId) Then
existing = True
End If
Next i
'Only add the value if it's not already on the list
If (existing) Then
MsgBox "This list can't contain duplicate values", vbOKOnly + vbInformation, "Error"
Else
safeValue = Replace(selectedValue & "", "'", "''")
Me.SELECTEDLIST.AddItem (selectedId & ";'" & safeValue & "'")
Me.SELECTEDLIST.Value = Null
Me.REMOVEBUTTON.Enabled = False
End If
And the code for the remove button is:
Dim numItems, index As Integer
index = Me.SELECTEDLIST.ListIndex
'Remove the selected item and move to the top of the list
Me.SELECTEDLIST.RemoveItem (index)
Me.SELECTEDLIST.Selected(0) = True
numItems = Me.SELECTEDLIST.ListCount
'Cosmetic feature, select the row above the one we're removing
If (index > 0) Then
Me.SELECTEDLIST.Selected(index - 1) = True
Else
Me.SELECTEDLIST.Selected(0) = True
End If
'If the list is empty now, disable the remove button
If (numItems = 0) Then
Me.ALLLIST.SetFocus
Me.REMOVEBUTTON.Enabled = False
Me.SELECTEDLIST.Selected(-1) = True
End If
What I would like to do is, rather than copy and paste this code all over the place, have this template stored somewhere and then in my form code write something like:
hookUpLists(allListName, selectedListName, addButtonName, removeButtonName)
How can I do this? Can I write a module to do this some how? I'm also open to any improvements I can make on the above code.
Thanks
Thanks for the hint on using class modules, HK1, I'd never used them before.
To solve the original question, I created a new class module "MultiSelectListBox", which has the following code:
Option Compare Database
Private WithEvents allList As ListBox
Private WithEvents selectedList As ListBox
Private WithEvents addBtn As CommandButton
Private WithEvents removeBtn As CommandButton
Private numColumns As Integer
Public Sub hookUpLists(numberOfColumns As Integer, allValuesList As ListBox, selectedValuesList As ListBox, addButton As CommandButton, _
removeButton As CommandButton)
'Grab all the controls passed in
Set allList = allValuesList
Set selectedList = selectedValuesList
Set addBtn = addButton
Set removeBtn = removeButton
numColumns = numberOfColumns
'Tell Access we want to handle the click events for the controls here
allList.OnClick = "[Event Procedure]"
selectedList.OnClick = "[Event Procedure]"
addBtn.OnClick = "[Event Procedure]"
removeBtn.OnClick = "[Event Procedure]"
End Sub
Private Sub allList_Click()
addBtn.Enabled = True
End Sub
Private Sub selectedList_Click()
removeBtn.Enabled = True
End Sub
Private Sub addBtn_Click()
Dim selectedId As String
Dim existing As Boolean
Dim index As Integer
existing = False
selectedId = allList.Value
index = allList.ListIndex
'Loop through the list of selected values and see if this one has already been added to the list
For i = 0 To (selectedList.ListCount)
If (selectedList.Column(0, i) = selectedId) Then
existing = True
End If
Next i
'Only add the value if it's not already on the list
If (existing) Then
MsgBox "This list can't contain duplicate values", vbOKOnly + vbInformation, "Error"
Exit Sub
End If
Dim item As String
item = selectedId & ";"
'Loop over all of the columns and add them to the second list box
For i = 1 To numColumns - 1
item = item & "'" & Replace(allList.Column(i, index) & "", "'", "''") & "'"
'Don't add a trailing semicolon
If (i <> numColumns - 1) Then
item = item & ";"
End If
Next i
selectedList.AddItem (item)
selectedList.Value = Null
removeBtn.Enabled = False
'Select the next row
If (index <> allList.ListCount - 1) Then
allList.Selected(index + 1) = True
allList.Value = allList.Column(0, index + 1)
End If
End Sub
Private Sub removeBtn_Click()
Dim numItems, index As Integer
index = selectedList.ListIndex
'Remove the selected item and move to the top of the list
selectedList.RemoveItem (index)
selectedList.Selected(0) = True
numItems = selectedList.ListCount
'Cosmetic feature, select the row above the one we're removing
If (index > 0) Then
selectedList.Selected(index - 1) = True
Else
selectedList.Selected(0) = True
End If
'If the list is empty now, disable the remove button
If (numItems = 0) Then
allList.SetFocus
removeBtn.Enabled = False
selectedList.Selected(-1) = True
End If
End Sub
Most of the above is identical to what I was already using, one important thing to note for anyone stumbling across this is the use of "WithEvents" when declaring the variables. This tells Access to look in the class module for event handlers. Finally, from my form I can do the following:
Private contactList As MultiSelectListBox
Private Sub Form_Open(Cancel As Integer)
Set contactList = New MultiSelectListBox
contactList.hookUpLists 3, Me.allContactsList, Me.selectedContactsList, Me.addContactBtn, Me.removeContactBtn
End Sub
I am trying to revert back to the original value if, at the MsgBox prompt, the user chooses "No". However, this is not happening. Can you please have a look to see where I am going wrong?
Private Sub txtNov2_AfterUpdate()
Dim x As Integer
Dim NewValue As Integer
Dim OrigValue As Integer
NewValue = Me.txtNov2.Value
OrigValue = [Forms]![DataEntry]![txtNov2].OldValue 'Me.txtNov2.OldValue
If NewValue <> OrigValue Then
x = MsgBox("Value Has Changed Do you Want to Update?", vbQuestion + vbYesNo, "Value Change")
If x = vbYes Then
MsgBox ("Please Press Update Button")
btnUpdateData2.SetFocus
Else
txtNov2.SetFocus
'Me.Undo
txtNov2.Value = OrigValue
'Cancel = True
End If
End If
End Sub
It appears to me that your code is working, as far as it goes. I open the form...
...and change the value from 123 to 124...
...then when I hit the [Tab] key so the control loses the focus I get the MsgBox...
...and if I choose "No" then the value reverts to 123
The only difference between that state and the initial state (when I first opened the form) is that the form is still "dirty", as indicated by the "pencil" icon in the record selector on the left side of the form. If you want to completely undo all changes to the form then try replacing...
Else
txtNov2.SetFocus
'Me.Undo
txtNov2.Value = OrigValue
'Cancel = True
End If
...with...
Else
DoCmd.RunCommand acCmdUndo
End If