Track user changes in MS Access - ms-access

I have a table and a Form in MS Access. Data is added through the Form. I want to be able to track user changes. I have a column User in my table where the user name will be added after update of the Form. For this purpose I have the following VBA code which will be fired After Update of the form, however it doesnt work and I dont know where the mistake is. Help will be appreciated. Thanks
Private Sub Form_AfterUpdate()
Dim UserLogin As String
Dim MyId As Integer
Dim strSQL As String
Dim rs As Recordset
UserLogin = Environ("Username")
MyId = Me!ID.Value
Set strSQL = "Update [MyTable] SET [MyTable]!User = '" & UserLogin & "' WHERE [MyTable]!ID = '" & MyId & "';"
'Set rs = dbs.OpenRecordset(strSQL)
DoCmd.RunSQL strSQL

You can track changes not only in particular form, but any change made in data will be registered, even if it was done directly on table. Just create Before Change data macro for your table ("Create Data Macro" menu in table design mode.
In Data Macro designer add the action SetField with parameters: Name = User ("User" is your field name for storing user name) and Value = GetUserName().
In any standard module create the function like this:
Public Function GetUserName() As String
GetUserName = Environ("Username")
End Function
After this any change in your table will update changed record by name of user, who did this change.
Please note, in case of split database this function should be available in front end and in back end databases if you want to edit data also in backend.
As of your code, check data type of ID field. If it's Number, remove single quotes. Also replace "!" by "." in SQL query text.

Just insert a textbox with controlsource as "User"
and then instead of after update use
Private Sub Form_BeforeUpdate()
me.user = Environ("Username")
end sub
no need for separate SQL operation

Related

How to set TextBox Comment Value Input as Table Data Insert on MS Access VBA

I have a main "final table" being updated through VBA based on many inputs of a Form and other tables data. I am trying to callout a TextBox object value that exists in a form to the VBA code so user can add a comment to all the data being inserted into the final table.
Dim strComment As String
strComment = TextBox_Comment.Value
strSQL = "INSERT INTO Main_Table (Period, Monthp, Order, Comment)"
strSQL = strSQL & "SELECT ""Weekly"" AS Period, [001_SelectedMonth].Monthp, [001_OrderTable].Order, strComment AS Comment FROM 001_SelectedMonth, 001_OrderTable;"
CurrentDb.Execute strSQL, dbFailOnError
The code works fine when I remove both the "Comment" from the Main Table insertion points and the "strComment AS Comment" part of the code. Otherwise I get the Run-Time Error '3061', Too few parameters. Expected 1.
Question: is there a way for me to callout the text box value to be inserted in the database as a field data for all the data being added or should I use another method to do this?
Example of the final table:
You need a space and proper concatenation:
strSQL = "INSERT INTO Main_Table ([Period], Monthp, [Order], [Comment]) "
strSQL = strSQL & "SELECT 'Weekly' AS [Period], [001_SelectedMonth].Monthp, [001_OrderTable].Order, '" & strComment & "' AS [Comment] FROM 001_SelectedMonth, 001_OrderTable;"
That said, use parameters to avoid the concatenation.

Unable to filter datasheet form after inserting value in 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.

vba function to return record with most recent date. given another criteria

I need to set the default value for a textbox in an ms access 2010 form. The default value needs to be the most recent date in CommunicationTable where the ClientNumber is the same as the ClientNumber associated with the current record in the form. The code below references the correct ClientNumber, but I am not sure how to get the most recent date. I am concerned that DMax might not be the appropriate function for getting the most recent date. How should I change the following to get the most recent date?
=DMax("DateOfCommunication","[CommunicationTable]","[ClientNumber]= "
& [Forms]![Main]![NavigationSubform].[Form]![ClientNumber] & "")
I realize I should also post the larger function in which the above function is nested:
=DLookUp("[Level]","[CommunicationTable]","DateOfCommunication= "
& DMax("DateOfCommunication","[CommunicationTable]","[ClientNumber]= "
& [Forms]![Main]![NavigationSubform].[Form]![ClientNumber] & ""))
Also, the form itself is bound to CommunicationTable. This VBA function is in the DefaultValue dialog box, which I get into via the property sheet for the text box. So I am not sure that creating a sql query will work in this case.
EDIT:
I have uploaded a stripped down copy of the database which reproduces the problem at this file sharing site.
To locate the code:
1.) Open the CommunicationEntryForm and
2.) open the AfterUpdate() event procedure for the ClientNumber field.
Next, to reproduce the problem:
1.) close `CommunicationEntryForm`
2.) In the Main form(which should already be open), click the View tab to open
the most recent CommunicationForm for any Client you want. Note the Level
number for that Communication.
3.) Click on the Communication tab. This will leave the form and show a list
of CommunicationForms for that Client.
4.) Click the Create New Form button. This will open up CommunicationEntryForm.
The value for Level should be the same as the value you noted in step 1 above.
The problem is that this is blank.
Can someone show me how to fix this problem?
#CodeMed - I did download the database but found you have issues other than what you are describing- such as when you 'add' a new communication you simply overwrite an existing record. I managed to get the result you were looking for, but it just changes the 3 records around. Does your non-sample program actually have the ability to create and add new records? As it is, I just changed your existing code to this:
Private Sub cmdNewCommForm_Click()
Dim cNum As Long
Dim strSQL As String
Dim rs As Recordset
Dim db As Database
Set db = CurrentDb
cNum = Forms!Main!NavigationSubform.Form!ClientNumber
strSQL = "SELECT Top 1 Co.Level AS MaxOfLevel " & _
"FROM CommunicationTable co Where Co.ClientNumber = " & cNum
Set rs = db.OpenRecordset(strSQL)
Forms!Main!NavigationSubform.Form!NavigationSubform.SourceObject = "CommunicationEntryForm"
Forms!Main!NavigationSubform.Form!NavigationSubform!ClientNumber = cNum
Forms!Main!NavigationSubform.Form!NavigationSubform!DateOfCommunication = Date
If rs.RecordCount > 0 Then
Forms!Main!NavigationSubform.Form!NavigationSubform!Level = rs!MaxOfLevel
Else
Forms!Main!NavigationSubform.Form!NavigationSubform!Level = 0
End If
Set rs = Nothing
Set db = Nothing
End Sub
What I would do is first grab the date by doing something like:
Dim db as Database
Dim rec as Recordset
Set db = CurrentDB
Set rec = db.OpenRecordset("SELECT Top 1 DateOfCommunication FROM CommunicationTable WHERE ClientNumber= " & [Forms]![Main]![NavigationSubform].[Form]![ClientNumber] & " ORDER BY DateOfCommunication DESC")
This will get the most recent date. Then, in your above VBA, you can just stick rec(0) in where your calculation was:
Me.MyDateField = DLookUp("[Level]","[CommunicationTable]","DateOfCommunication= #" & rec(0) & "#")
Substitute "MyDateField" with whatever that name of your date field actually is.
I'm pretty sure you need the pound signs (or "hashtags" as the kids call them today...) in order for Access to do the calculation on a date value.

display combobox in access vba code

I am using below code in access vba. this code give me the input box to entered the value which updates the value inputed in access table. is it possible to give combobox instate of input box. I can select desise input from that combobox. pls let me know if it is possible.
Dim qry As String
qry = "UPDATE Data_Table SET Data_Table.Workgroup = [Workgroup Name]WHERE (((Data_Table.Workgroup) Is Null));"
DoCmd.RunSQL qry
The input box that pops up when you execute your code is "created" by MS Access on the fly, because of the [Workgroup Name] value in the query.
It's not possible to make Access pop up a ComboBox directly from the query instead.
(how should Access know which options to put into the ComboBox?)
But of course you can create a ComboBox yourself (somewhere on a form) and insert the value from that ComboBox into the query.
For example, you could put your code from the question into a function which gets the workgroup name passed as a parameter, like this:
Public Function RunQuery(ByVal WorkgroupName As String)
Dim qry As String
qry = "UPDATE Data_Table SET Data_Table.Workgroup = '" & WorkgroupName & "' WHERE (((Data_Table.Workgroup) Is Null));"
DoCmd.RunSQL qry
End Function
Then you create a ComboBox in a form (and populate it with options) and pass the value of the ComboBox to the RunQuery function:
Private Sub SomeComboBox_AfterUpdate()
If Nz(Me.SomeComboBox.Value) > "" Then
RunQuery Me.SomeComboBox.Value
End If
End Sub

MS access to view all record history data with the specific input field value but it is showing only first record of criteria

I tried to display a list of all requests from a specific dept of my table
So I created a form with all the tbl fields that I want to display on the form view of "details" section like this .
dept name Totalnum req# ticket
Then I have created a combo box with pre-defined values as 'depttest' field.
Then I used the following code on change value of field but form is displaying only the first record of the category and not showing all the records .... can some one please help me with this logic..
Option Compare Database
Option Explicit
'Set default record source of form
Const strsql = "SELECT tbl.dept,tbl.name,tbl.[Totalnum],tbl.[req#],tbl.[Ticket] FROM tbl"
Private Sub depttest_Change()
Dim strFilterSQL As String
strFilterSQL = strsql & " Where [dept] = 'me.depttest.value';"
Me.RecordSource = strFilterSQL
'DoCmd.RunSQL strFilterSQL
Me.Requery
End Sub
You are passing me.depttest.value as a string not a value. Try:
strFilterSQL = strsql & " Where [dept] = '" & me.depttest.value & "';"