auto-increment a field in MS Access 2016 form - ms-access

I'm building a basic form and would like an id field in the form to auto-increment when the user opens the form (or could be a different event as well, just figured this is simplest).
I've written the following vb code, but there seems to be an issue:
Private Sub Form_Load()
lngNextID = DMax("[portfolio_id]", "table1") + 1
Form 1.portfolio_id = lngNextID
End Sub
table1 is the table I want the vb to look up for the next increment.
The name of my form is 'Form 1' and the field in that form that I'm looking to autoincrement is portfolio_id.
Any advice/modifications would be helpful, thank you.

Try with:
Forms("Form 1").portfolio_id = lngNextID
or the simpler:
Me!portfolio_id = lngNextID
However, that will update the opening record, so try setting the DefaultValue (a string):
Me!portfolio_id.DefaultValue = "'" & lngNextID "'"

Related

Dynamically display Tables result into subform based on values of a combobox

I have Form in a Microsoft access application
and in that form I have 2 combo box , one that display dates and one that display query names
Also , I have a subform that I would like to dynamically display tables , based on what the user select in the combo box
Examples of what I'm trying to achieve :
Private Sub Form_Load()
Select Case comboBoxQueries.value
Case comboBoxQueries.value = query1
MySubForm.SourceObject = Select * from Table_Employee where Table_Employee.date = ComboBoxDates.Values
Case comboBoxQueries.value = query2
MySubForm.SourceObject = Select * from Table_School where Table_School .date = ComboBoxDates.Values
...
End Select
End Sub
What would be the optimal way to do that ?
Thank you
I don't believe that you can use a table as a subform, but I do this kind of thing all the time using a subdatasheet based on a table. Try the following:
On the main form's Load event, clear the subform by setting MySubForm.SourceObject = ""
In the After_Update event of the ComboQueries combobox, set MySubform.Sourceobject equal to the correct subdatasheet.
Set the .RecordSource of the subdatasheet to the sql string built from the combobox.
Here's roughly what it should look like:
Private Sub Form_Load()
Me.MySubForm.SourceObject = ""
End Sub
Private Sub ComboQueries_AfterUpdate()
Dim sql As String
Me.MySubForm.SourceObject = Me.ComboQueries.Column(1)
sql = "SELECT * FROM " & Me.ComboQueries.Column(0) & " WHERE Date = " & Me.Combo2.Value
Me.MySubForm.Form.RowSource = sql
End Sub
Also, try not to use reserved keywords such as "DATE" as field names in your tables, it's a sure way to create unnecessary headaches later on.

Track user changes in 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

How to detect same data in a datagridview column?

When a user enters data into the datagrdview, the user cannot enter data that already exists in the datagridview. If the user tries to enter the same data in the datagridview (in the same column), a message box will pop up and tell them: "cannot enter same data on datagridview."
Thank you for your help.
You will need to check the input against the database to see if it is already there. For example, run the following MySQL statement to check if the input is database:
Dim userInput As String
userInput = TextBox1.Text 'an example of user input from a textbox
Dim MySQLStatement As String = "SELECT * FROM `your_table` WHERE your_column = '" & userInput & "';"
I am unable to continue the example above without knowing how you are connecting to the database, but it may be unnecessary. However you connect, you can check the record count after you have executed the MySQL statement. If it is 1 or more, than you know the data is already in your database and you can stop the user input from going into the database.
Finally I've got the solution! This is the code I used to solve the problem. My datagridview name is DataGridView3. The code are :
Private Sub DataGridView3_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView3.CellEndEdit
For Each Row As DataGridViewRow In DataGridView3.Rows
Try
If DataGridView3.Rows(e.RowIndex).Cells(0).Value.ToString <> Row.Cells(0).Value.ToString AndAlso DataGridView3.Rows(e.RowIndex).Cells(0).Value.ToString = DataGridView3.Rows(e.RowIndex).Cells(0).Value.ToString Then
ElseIf DataGridView3.Rows(e.RowIndex).Cells(0).Value.ToString = Row.Cells(0).Value.ToString Then
If Row.Cells(0) Is DataGridView3.Rows(e.RowIndex).Cells(0) Then
Else
MsgBox("Can't Duplicate Condition Data!")
DataGridView3.Rows(e.RowIndex).Cells(0).Value = ""
Exit For
End If
End If
Catch
End Try
Next
End Sub

Combobox with LimitToList set to false with non-bound field

I have a products table and a tags table with a many-to-many relationship. I also have a pivot table that store the product id and the tag id.
I'd like to be able to show the tag text in the combo box but store the id. This on its own is simple as I can just adjust the column width of the id, however, I'm trying to set LimitToList to No so I can implement some VBA to filter the list when I type in the combo box, but this only appears to be possible if the first column is the bound column, which means the tag id appears in the combo box instead of the text.
How do I show the tag text in the combobox and allow 'LimitToList' to be false?
Leave LimitToList on Yes, and use the NotInList event of the combobox instead.
E.g.
Private Sub cboTag_NotInList(NewData As String, Response As Integer)
Dim RS As Recordset
If MsgBox("Do you want to add '" & NewData & "' as new Tag?", vbYesNo + vbQuestion) _
= vbYes Then
' Add the new tag
Set RS = CurrentDb.OpenRecordset("tbTags")
With RS
.AddNew
!Tag_Text = NewData
.Update
.Close
End With
Response = acDataErrAdded
Else
Response = acDataErrDisplay
' Or a user defined MsgBox and acDataErrContinue
End If
End Sub
(sigh) again I have misunderstood your question. :(
To filter the combobox as the user types a part of a Tag, you use the Change event. This works just fine with LimitToList = Yes.
Private Sub cboTag_Change()
Me.cboTag.RowSource = _
"SELECT Tag_ID, Tag_Text FROM tbTags WHERE Tag_Text LIKE '*" & Me.cboTag.Text & "*'"
' With the instant filtering, it is more convenient for the user
' to always see the filtered dropdown
Me.cboTag.Dropdown
End Sub
Of course at some point the user has to select a Tag from the list. Otherwise there would be no ID to store in the field.
Or if you want him to be able to add new tags, use the code from the other answer. Both events work together as written.
Search-as-you type technique described very good here, including automatic selection of items from opened dropdown combobox after typing few characters.

If [ComboBox] Is Null Statement in VBA/Access 2007

I have a form with one ComboBox (YearToBeBuilt) and two textBox fields (Cost and YearofExpenditureCost). All controls are linked to a main table and the table is updated once the selections/entries have been made on the form.
I have written a procedure in VB called ReCalcIt()which performs the following procedure when called:
Private Sub ReCalcIt()
If Me.YearToBeBuilt = "" Then
Me.YearofExpenditureCost = Me.Cost
Else
Me.YearofExpenditureCost = Me.Cost * (1 + 0.031) ^ (Me.YearToBeBuilt - 2010)
End If
End Sub
When I wrote this I thought that this would do the following:
If the ComboBox [YearToBeBuilt] is blank (e.g.-no selection made) then
the textbox [YearOfExpenditureCost] will return the value of the TextBox [Cost]. Else, the calculation for YearofExpenditureCost is performed.
But this is not working the way it should
What am I doing wrong? I am a VBA n00b so perhaps my syntax is incorrect?
Try it with
If Len(Me.YearToBeBuilt & vbNullString) = 0
So the code will look like this:
Private Sub ReCalcIt()
If Len(Me.YearToBeBuilt & vbNullString) = 0 Then
Me.YearofExpenditureCost = Me.Cost
Else
Me.YearofExpenditureCost = Me.Cost * (1 + 0.031) ^ (Me.YearToBeBuilt - 2010)
End If
End Sub
The usual way is to say:
If IsNull(MyControl) Then
See also: Access VBA: If Form Value <> NULL then run query else, end if. - not doing anything
It seems to me that this might be dependent on the format of the combo box? If it's a number, then
If Len(Me.YearToBeBuilt & vbNullString) = 0
doesn't work. Because the Me.YearToBeBuilt has a value of 0, and so the above returns 1.
I'm wondering if there is a more robust method? Maybe
Me.YearToBeBuilt.ListIndex = -1