For this sort of batch insert I'd normally use an unbound dialogue form rather than a bound subform of the type Scott describes as it enables you to select the subset of employees simultaneously from a list in one control rather than having to select each
individually in a separate row in the subform. Which approach you prefer to use is for you to decide of course.
Firstly, as Scott said, you need to be sure the database structure is correct. You have employees and what I'll call training events entity types so these should be modelled by tables, in broad outline, along these lines:
Employees
....EmployeeID (PK)
....FirstName
....LastName
....etc
TrainingEvents
....TrainingEventID (PK)
....TrainingEvent
....etc
Note that this table models events, not types of training. If multiple events can be of the same training type then you would also need a TrainingTypes table or similar whose primary key is referenced by a foreign key column in TrainingEvents.
The assignment of employees to a training event is a many-to-many relationship type between Employees and TrainingEvents and is modelled by a table like this which resolves the relationship type into two one-to-many relationship types:
EmployeeTraining
....EmployeeID (FK)
....TrainingEventID (FK)
The primary key of this table is a composite one of the two foreign keys. You can use a surrogate autonumber key if you wish, but if you do, you
must include the two foreign key columns in a single unique index to define them as a candidate key; otherwise invalid duplication of data would be possible The table might have other columns representing other attributes of an employee's participation
in a training event, e.g. their successful or otherwise completion of the training.
To assign an employee to a single training event requires a row to be inserted into EmployeeTraining with the relevant EmployeeID from Employees and the relevant TrainingEventID value from TrainingEvents. To do this for multiple employees it can conveniently
be done by means of an unbound dialogue form containing a multi-select list box of employees, and a combo box of training events. The list box would be set up as follows:
Name: lstEmployees
RowSource: SELECT EmployeeID, FirstName & " " & LastName FROM Employees ORDER BY LastName, FirstName;
BoundColumn: 1
ColumnCount: 2
ColumnWidths: 0cm
MultiSelect: Simple or Extended as preferred.
If your units of measurement are imperial rather than metric Access will automatically convert the ColumnWidths unit to inches. The important thing is that the dimension is zero to hide the first column. You don't need to specify a width for the second (visible)
column.
The combo box would be set up as follows:
Name: cboTraining
RowSource: SELECT TrainingEventID, TrainingEvent FROM TrainingEvents ORDER BY TrainingEvent;
BoundColumn: 1
ColumnCount: 2
ColumnWidths: 0cm
You can now select any number of employees from the list box and a single training event in the combo box.
Add a command button to the form and put the following in its Click event procedure:
Const MESSAGE_TEXT = "At least one employee and a training event must be selected"
Dim varItem As Variant
Dim strSQL As String
Dim ctrl As Control
Set ctrl = Me.lstEmployees
' ensure that at least one employee and a training event has been selected
If ctrl.ItemsSelected.Count > 0 And Not IsNull(Me.cboTraining) Then
' loop through selected items in list box and build an SQL statement
' at each iteration of loop to insert a row into table
For Each varItem In ctrl.ItemsSelected
strSQL = "INSERT INTO EmployeeTraining(EmployeeID, TrainingEventID) " & _
"VALUES(" & ctrl.ItemData(varItem) & "," & Me.cboTraining & ")"
' execute the SQL statement, ignoring error if employee
' is already assigned to the selected training event
CurrentDb.Execute strSQL
Next varItem
Else
MsgBox MESSAGE_TEXT, vbExclamation, "Invalid Operation"
End If