Unable to filter datasheet form after inserting value in ms access - ms-access

I am using a datahseet subform in my main form for the realtime view of entries added in the table via the main form. This subform filters data on load event and checks with users windows username and compares it with data, it should only show data of respective owner. That means it willl filter the name field and shows only the entries made by the respective user(to unable users to edit each other's entries). It works well with the below code which I used in this datasheet form's vba :
Option Compare Database
Option Explicit
Dim GetUserName As String
Dim GetEmpID As String
Dim RecCount As String
Public Sub GetValues()
Dim obj1 As Object
Set obj1 = CreateObject("WScript.Network")
GetUserName = DLookup("[BAFUser]", "BAF_User", "[BRID] = '" & obj1.UserName & "'")
RecCount = DCount("[ID]", "Mau_con", "[AdvisorName] = '" & GetUserName & "'")
Set obj1 = Nothing
End Sub
Private Sub Form_AfterInsert()
Call Form_Load
End Sub
Private Sub Form_Load()
Call GetValues
If RecCount > 0 Then
Dim strOpen As String
strOpen = "[AdvisorName] = '" & GetUserName & "'"
Me.Filter = strOpen
Me.FilterOn = True
Me.Recordset.MoveLast
End If
End Sub
It filters the data on load but problems arises when a new user comes and login, then it will skip the if loop and will work normally, I tried to requery the form after making first entry by the new user & I also tried to call form_load in after insert event but both did not work.
But it filters the data once we close it and reopen it.
What is the best way to overcome this ?
Please ask if any other information needed.
Thanks in Advance.

Related

not able to update access table field using VBA

I have a userform in access which submits the data to a table, there are two fields in table which I want to get populated automatically whenever user makes a new entry in form. I am using the below vba code with that form :
Option Compare Database
Public Function GetUserName() As String
Dim obj1 As Object
Set obj1 = CreateObject("WScript.Network")
GetUserName = DLookup("[BAFUser]", "BAF_User", "[BRID] = '" & obj1.UserName & "'")
Set obj1 = Nothing
End Function
Private Sub Form_BeforeInsert(Cancel As Integer)
Owner2 = CreateObject("WScript.Network").UserName
AdvisorName = GetUserName
End Sub
Private Sub Form_Load()
Me.DataForm.Form.Recordset.MoveLast
End Sub
Private Sub SaveBtn_Click()
RunCommand acCmdSaveRecord
Me.Requery
Me.DataForm.Form.Recordset.MoveLast
End Sub
I am able to get the value in "owner" field but not in "AdvisorName" field.
What can be the possible reason behind this ?
is there any mistake in my code or is there any better method of doing this ?
The below code should commit both values to your table using a querydef. This is my preferred approach but there are other ways to do it as well. The qdf represents a sql string that can accept parameters from code. We are inserting the values of our variables directly into the sql string.
I copied the code from the save button to re-establish the form state after entry. This should bring the last record back up, but it will depend on the cursortype of the recordset whether the saved record is represented or not (it might go backwards).
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim qdf As QueryDef
Dim Owner2 As String
Dim AdvisorName As String
Owner2 = CreateObject("WScript.Network").UserName
AdvisorName = GetUserName
Set qdf = CurrentDb.CreateQueryDef("", "INSERT INTO Mau_con (Owner, AdvisorName) VALUES ('" & Owner2 & "', '" & AdvisorName & "')")
qdf.Execute
Me.Requery
Me.DataForm.Form.Recordset.MoveLast
Set qdf = Nothing
End Sub

MS Access: Subform Datasheet - Variable RecordSources

I have a subform datasheet whose RecordSource can be variable. My database constructs an SQL query based on user selections (a different collection of columns with each query). The resulting query is intended to be the RecordSource for a datasheet on a subform. (Read-only view for user)
Problem:
The various queries produce the desired results when run on their own
Setting a resulting query as the datasheet's RecordSource does not produce any result (no columns/rows)
I suspect I need to insert the query's attributes into the subform in order to see any results (much like "Add Existing Fields" in the menu strip).
Question:
Any pointers to get me off square one?
Thank you!
Remove the datasheet form from your subform object and leave the source object property empty.
Create a new query (sql doesn't matter) and name it qryTemp (or whatever you like).
Then whenever you want to set the source for the subform, use this
CurrentDb.QueryDefs("qryTemp").SQL = "<your new sql here>"
<yoursubformobject>.SourceObject = "Query.qryTemp".
Here is an example I use to populate a sub-form:
Private Sub cmdFind_DisplayName_Click()
Dim dbs As Database, rstPatient As Recordset
Dim txtDisplayName, strQuote As String
strQuote = Chr$(34)
On Error GoTo ErrorHandler
Me.OrderBy = "DISPLAYNAME"
Me.OrderByOn = True
Set dbs = CurrentDb
Set rstPatient = Me.RecordsetClone
txtDisplayName = Trim(InputBox("Please Enter Patient Name ", "Patient Find By Name"))
txtDisplayName = UCase(txtDisplayName) & "*"
If IsNull(txtDisplayName) Then
MsgBox ("No Patient Name Entered - Please Enter a Valid Patient Name")
Else
rstPatient.FindFirst "[DISPLAYNAME] Like " & strQuote & txtDisplayName & strQuote
If Not (rstPatient.NoMatch) Then
Me.Bookmark = rstPatient.Bookmark
Me.Refresh
Else
MsgBox ("Patient Not Found - Please Enter a New Patient Name")
End If
End If
GoTo Exit_cmdFind_Click
ErrorHandler:
MsgBox LTrim(RTrim(Me.NAME)) + "." + "Patient Find By Display Name - " + "Error: " + AccessError(Err.Number)
Exit_cmdFind_Click:
rstPatient.Close
Set dbs = Nothing
Set rstPatient = Nothing
End Sub

Warning for Dynamic Combobox list

I have a combobox that builds it's list upon first usage. I know that the way I want "NotInList" to behave isn't conventional - I don't want to waste adding the item to a table separate from the needed entry, but I'd like to still warn about an item that hasn't been used yet, so that the user has to think twice before accepting the entry.
Once the user adds the item, it will automatically appear in the list next time because the data source for the combo box is as follows:
SELECT tbl_SP.PROGRAM
FROM tbl_SP
GROUP BY tbl_SP.PROGRAM
HAVING (((tbl_SP.PROGRAM) Is Not Null And (tbl_SP.PROGRAM)<>""));
I tried this:
Private Sub cmbPROGRAM_NotInList(NewData As String, Response As Integer)
If MsgBox("'" & Chr(34) & NewData & Chr(34) & " hasn't been used yet. Add to list? ", vbQuestion + vbYesNo, "Add - " & NewData & "?") = vbYes Then
Response = acDataErrAdded
End If
End Sub
but of course, Access wants the item to actually exist before it will release the error. And...if I set LimitToList to "No" then the user doesn't get a warning.
How can I achieve this behavior?
Ok, I tried this which works fine if the user selects YES, but becomes more complicated when the user selects "NO"
Public Function ReturnsRecords(strSQL As String) As Boolean
Dim d As DAO.Database
Dim arr(1 To 3) As DAO.Recordset
'Dim rs As DAO.Recordset
'assume 3 items in array above
Set d = CurrentDb
Set arr(1) = d.OpenRecordset(strSQL)
' MsgBox "Record Count is " & arr(1).RecordCount
If arr(1).RecordCount > 0 Then
ReturnsRecords = True
Else
ReturnsRecords = False
End If
Set d = Nothing
End Function
Private Sub cmbPROGRAM_BeforeUpdate(Cancel As Integer)
Dim strSQL As String
strSQL = "Select * from LU_PROGRAM where PROGRAM ='" & Me.cmbPROGRAM & "'"
If ReturnsRecords(strSQL) = False Then
If MsgBox("'" & Chr(34) & Me.cmbPROGRAM & Chr(34) & " hasn't been used yet. Add to list? ", vbQuestion + vbYesNo, "Add - " & Me.cmbPROGRAM & "?") = vbNo Then
Cancel = True
' how do I reset this? Me.cmbPROGRAM.Text = Null
End If
End If
End Sub
How do I clear the combobox if the user selects NO? If I select me.undo, that will undo all of the entries, but I just want to clear the combobox.
Incidentally, the form is totally unbound and doesn't accept an entry until the user selects "Save"
First, I'm not quite sure what you wish to achieve ...
Then, educate the users to press Escape to cancel. This is mandatory wisdom when operating an Access application.
For your code to work, you can't change the content of a control in the BeforeUpdate event. So try the AfterUpdate event with either:
Me!cmbPROGRAM.Text = ""
or:
Me!cmbPROGRAM.Value = Null

Microsoft Access Sub Form Write Conflict Troubles

I have a form which contains a subform which displays editable fields linked to one my tables. For a project I'm currently working on, one of the requirements is that I have to track when the last change was made to a record and who did so.
So what I've done is for each editable textbox or combobox within the form and subform I've made it so they have events on their BeforeUpdate and AfterUpdate events.
For example my BeforeUpdate for a textbox:
Private Sub textbox_BeforeUpdate(Cancel As Integer)
If Not isValidUser Then
Cancel = True
Me.textbox.Undo
End If
End Sub
and my AfterUpdate is:
Private Sub textbox_AfterUpdate()
updateRecord Me.textbox.Value, UserNameWindows
End Sub
and updateRecord is:
Public Sub updateRecord(bucNumber As String, updater As String)
Dim Dbs As Object
Dim rst As Object
Dim fldEnumerator As Object
Dim fldColumns As Object
sqlStatement = "SELECT fName " & _
"FROM t_Staff " & _
"WHERE uName='" & updater & "';"
'Getting fullname of user via username
Set rst = CurrentDb.OpenRecordset(sqlStatement)
'Setting fullname to updater variable
updater = rst(0)
'Clean Up
Set rst = Nothing
'Opening Bucket Contents
Set Dbs = CurrentDb
Set rst = Dbs.OpenRecordset("Bucket Contents")
Set fldColumns = rst.Fields
'Scan the records from beginning to each
While Not rst.EOF
'Check the current column
For Each fldEnumerator In rst.Fields
'If the column is named Bucket No
If fldEnumerator.Name = "Bucket No" Then
'If the Bucket No of the current record is the same as bucketNumber
If fldEnumerator.Value = bucNumber Then
'Then change the updated fields by updater and todays date
rst.Edit
rst("Last Updated By").Value = updater
rst("Last Updated On").Value = Date
rst.Update
End If
End If
Next
'Move to the next record and continue the same approach
rst.MoveNext
Wend
'Clean Up
Set rst = Nothing
Set Dbs = Nothing
End Sub
Okay now is the weird thing, this works totally fine when I make a modification to a control within the Main form, however as soon as a try to alter something in the subform it throws up a write conflict.
If I opt to save record it ignores my code for updating who last modified it and when and if I opt to discard the change it runs my code and updates it that it has been changed!
Anyone know what is wrong or of a better way to do this?

VBA and Access Form Filter

I have this form in access, the purpose of it is to work as a front end of a table which can be edited through this form. Initially when it loads I display in the form data from a recordset with the following query:
SELECT * FROM DATA
I want to be able to filter the data on the recordset once the form is open. I tried the following VBA code to accomplish this:
Private Sub Filter_Click()
If (IsNull(Me.Find_Field) Or Me.Find_Field = "") Then
rs.Close
Set rs = db.OpenRecordset("Select * from DATA ORDER BY ID)
rs.MoveFirst
LoadData (True)
Exit Sub
End If
Set rs = db.OpenRecordset("Select * from DATA WHERE ID = " & Me.Find_Field)
rs.MoveFirst
LoadData (True) ' Function that loads the data into the form
Exit Sub
As you all can see, I reload the recordset with a new filtered query. Up to this point it works, the problems begin when I try to modify a record.
Originally, when the form loads the recordset data, I am able to edit the data and the edited data would show in the table (which is what I want). But after I apply my filter, my code gives me the Run-Time error '3027': Cannot Update. Databse or object is read-only.
I am pretty much using the same code over and over to reload data from the table and it never gave me a problem until I 'overwrote' the source of the recordset. Any idea how can I resolve this issue? Thanks
I would prefer to use a standard Access bound form because it's simpler than what you appear to be doing.
I can change the form's RecordSource from the click event of my cmdApplyFilter button.
Private Sub cmdApplyFilter_Click()
Dim strSql As String
If Len(Me.txtFind_Field & vbNullString) > 0 Then
strSql = "SELECT * FROM tblFoo WHERE id = " & _
Me.txtFind_Field & " ORDER BY id;"
Me.RecordSource = strSql
End If
End Sub
If you're concerned someone might save the form with the filtered RecordSource, you can make the form always open with the unfiltered version.
Private Sub Form_Open(Cancel As Integer)
Dim strSql As String
strSql = "SELECT * FROM tblFoo ORDER BY id;"
Me.RecordSource = strSql
End Sub