You have to distinguish between automating Access objects and working with recordsets in code.
In a form, this command has meaning:
DoCmd.GoToRecord , , acNext
It is nonspecific, and it is not predictable what record it will go to unless you know the ordering of the underlying recordset in the form and the starting record. It navigates you through the recordset stored in the form's edit buffer (which is loaded in the OnOpen event of the form). The command would be used, for instance, in the code behind a command button whose purpose is to navigate records loaded into the form that currentlyl has the focus. I would never leave out the optional arguments if I were to use that command (I almost never do). Instead, I'd identify the specific form I wanted it to apply to:
DoCmd.GoToRecord acForm, "MyForm", acNext
In traversing a DAO recordset, .MoveNext likewise has no predefined meaning except if you know the ordering and starting record. When you are walking a recordset (something you shouldn't do very often, since it's pretty inefficient; but it depends on the task you need to perform) and need to hit each record, you'd certainly call .MoveNext as part of your loop:
With rs
.MoveFirst ' technically not required, as it's the default starting point
Do Until .EOF
[do something]
.MoveNext
Loop
End With
Nothing mysterious there. It's most likely going to be used in code with small numbers of records (large recordsets really oughtn't be navigated sequentially).
In answer to your specific question:
What does it mean in a database
context to move to the "next" record?
This particular table uses an identity
column as the PK, so is it internally
grabbing all the IDs and then moving
to the one that is the next highest???
...as I said, the next record is determined by the ordering of the recordset being traversed and the starting position. In the case of the form, it's the edit buffer that's being traversed, and as the current record bookmark changes in the edit buffer, the form is updated to load the data for that record. The dynaset is bound to the underlying data table, and when the form's edit buffer is saved, the edited data is written back to the server. While it's being edited, locks may or may not be maintained on the record on the server, but Access/Jet/ACE does keep track of the state of the existing record on the server and the record in the edit buffer and will inform you at save time in Access if the record on the server has been changed since it was loaded into the form's edit buffer.
Now, in a comment, you say the form is bound to the whole table. This is a terrible design no matter whether your data is stored in a Jet/ACE back end data file or in a server database like SQL Server. The only reason Access can get away with it is because it and Jet are rather efficient about pulling data from the data source.
I properly-designed client/server Access front end will not load full tables in forms, but instead ask what filtered recordset you want to load, either 1 or more records at a time. This is only marginally more complicated than binding to a whole table.
As to knowing what cursor types are being used, you shouldn't be worrying about it. By default, Access forms use what Access/Jet/ACE calls dynasets. Each form has a RecordsetType property, and it's set to dynaset by default (read the help file on the meaning of the different recordset types). If you want more control of that, you can (but likely shouldn't) create your recordsets in code and assign them to the form's .Recordset property. This is useful in a few circumstances, such as when you'd like to bind a form to a disconnected recordset, but the point of Access is leveraging its capabilities working with bound data. Assigning your own recordsets still gets you bound controls, and the form events, but is more work than is usually necessary.
Basically, change your forms to load only the subset of records the user needs to work with (that may be one record at a time), and then let everything else get done with Access's default behaviors. If something causes a bottleneck, then troubleshoot that and replace the default behavior with something more efficient.
In other words, avoid premature optimization -- let Access be Access.
And don't worry about what Access is doing behind the scenes unless/until Access does something inappropriate.