Error in Form_Load of Access 2016 database - ms-access

I'm trying to get some code to run on a form load.
However, I get the message:
Compile error: Sub or Function not defined
It happens on the line: Public Sub Form_Load()
Option Compare Database
Public Sub Form_Load()
Me.txtSearch.BackColor = vbYellow
  Task = "SELECT * FROM tblTracks WHERE (ID)is null"
Me.RecordSource = Task
Me.txtSearch.SetFocus 
End Sub
I've tried Private/Public and having neither - just Sub - but they all give the same error.
I've tried adding Option Explicit and retyping the code from scratch - as suggested - now I have a Compile Error:
Could anyone help please?
Thanks, Mark

This is because of a corrupted module.
Remove the full line and retype it from scratch. No copy-n-paste.

Related

MS Access Library Template - Reference Category Value in VBA

Completely new to MS Access - I'm trying to do a simple modification to the MS Access Lending Library template using VBA.
Going into the Asset List form and clicking New Asset pops up the Asset Details form, where I can click the Save and New button. This calls the VBA code cmdSaveandNew_Click().
My question is, within this VBA method, how do I reference the values of the fields in the Asset Details form - For example getting the value that the user entered in the Category field and storing it in a variable.
I've tried several strings of code to try to get the value back, but I keep getting various errors, saying it can't find the referenced form, or Object Required, or this method is supported. I think it's likely just that I don't fully understand the structure of what I'm trying to reference or the syntax for specifying how to reference it.
Right now (after I've been trying many different combinations of things, I have:
text = Forms![Asset List].[Asset Details].Form.Category
which is giving me the "can't find the field '|1' referred to in your expression" error.
Edit - code currently looks like this:
Private Sub cmdSaveandNew_Click()
'On Error GoTo cmdSaveandNew_Click_Err
Dim someVar As String
Dim num As Integer
Dim objtf
'objtf = Forms![Asset List].[Asset Details].Form.Category
objtf = Me.Category
'num = Form.Controls.Count
Msg.Box (TypeName(objtf))
someVar = InputBox("How many?")
On Error Resume Next
If (Form.Dirty) Then
DoCmd.RunCommand acCmdSaveRecord
End If
If (MacroError.Number <> 0) Then
Beep
MsgBox MacroError.Description, vbOKOnly, ""
Exit Sub
End If
On Error GoTo 0
DoCmd.GoToRecord , "", acNewRec
DoCmd.GoToControl "Item"
MsgBox someVar
cmdSaveandNew_Click_Exit:
Exit Sub
cmdSaveandNew_Click_Err:
MsgBox Error$
Resume cmdSaveandNew_Click_Exit
End Sub
The variable must be declared global in a general module if you want to reference from various modules. Then setting it by code behind the Asset Details form would be simply: SomeVariableName = Me.Category.
Don't use reserved words as names - text is a reserved word.

DoCmd.DeleteObject acTable - The record ... specified on this form or report does not exist

Let me start by saying I am not at all familiar with Access or VBA. However, I am the IT guy and at some point someone created an MS Access database that does a thing and now I have to support it.
We have a database that upon opening deletes any old data and re-runs the external query that makes this application work. Occasionally whatever state the program exited out in that table already does not exist. This causes MS Access to hang on the delete line and I have to run the debugger, comment out the DoCmd.DeleteObject line, re run, and then un-comment the line to let the user continue with their day.
I want to add in some sort of conditional statement, but anything I've been able to google in terms of If...Then statements or 'TableExist' type functions always causes an error to be thrown that I haven't defined the function. My best guess is I'm nesting this incorrectly or I'm not calling some sort of external function correctly, but as I said my VBA knowledge is extremely limited.
This code executes on startup:
Public Function Startup() As Integer
DoCmd.Close acForm, "soLookup"
DoCmd.DeleteObject acTable, "sales_order"
DoCmd.RunSavedImportExport "Import-sales_order"
DoCmd.OpenForm "soLookup"
End Function
Its the
DoCmd.DeleteObject acTable, "sales_order"
Line that causes things to fail.
I've attempted to restructure this several times based on several examples I had found, but I'll only bother with one below
Public Function Startup() As Integer
DoCmd.Close acForm, "soLookup"
If TableExists("sales_orders") Then
DoCmd.DeleteObject acTable, "sales_orders"
Else
'Do nothing
End If
DoCmd.RunSavedImportExport "Import-sales_order"
DoCmd.OpenForm "soLookup"
End Function
Nothing I seem to try seems to give me any result other than an error of some sort. All I want to do is add a conditional statement to this 'Startup' bit that checks if the "sales_order" table even if exists, and if it doesn't, then to just move on to the next comment and forget the DoCmd.DeleteObject. How can I achieve this functionality?! Thanks!
The TableExists function is not a standard function in Access. You need to define it yourself.
There are two main ways to define such a function, by trying and error trapping, or by iterating through all tables and checking names.
Way 1 (error trapping):
Public Function TableExists(TableName As String) As Boolean
On Error Resume Next
TableExists = CurrentDb.TableDefs(TableName).Name = TableName
End Function
Way 2 (iterating collection):
Public Function TableExists(TableName As String) As Boolean
Dim td As DAO.TableDef
For Each td In CurrentDb.TableDefs
If td.Name = TableName Then
TableExists = True
Exit Function
End If
Next
End Function
Define either of these functions in a public module, and your last approach should work
I will instead modify the query to import the source data into a new table (sales_orders), which will overwrite existing data when the query runs and so I don't have to delete the table and have additional check for TableExists

Is it possible to place a sub or function on one line in vba?

I am trying to place a sub on one line in Access VBA.
Is there a setting or special syntax that can be used to accomplish this?
private sub cmd_print() docmd.printout end sub 'creates an error
vs
private sub cmd_print()
docmd.printout
end sub
Technically, yes, using the instructions separator - the colon : token:
Private Sub PrintCommand() : DoCmd.PrintOut : End Sub
I would strongly advise against it though, for obvious maintainability and readability reasons.
This particular layout is used by some add-ins such as vbWatchDog, for some generated code. Because of how it challenges the expected structure of a module, it is known to cause problems with add-ins that process the code, such as Rubberduck (which I'm heavily involved with) (parser has been updated since then; this is no longer an issue) - that's because the member attributes will be stored (you need to export the module to see them, the VBE doesn't display module and member attributes), rather counter-intuitively, outside the procedure scope:
Private Sub PrintCommand() : DoCmd.PrintOut : End Sub
Attribute PrintCommand.VB_Description = "This procedure does XYZ"
The "normal" layout looks like this, and doesn't cause issues:
Private Sub PrintCommand()
Attribute PrintCommand.VB_Description = "This procedure does XYZ"
DoCmd.PrintOut
End Sub
It's easier to read, too.

Using BatchCollisions on Form's recordset?

Hoping to get more information on what column, table or row is causing a write conflict in a MS Access 2010 project, I wrote the following code:
Private Sub Form_BeforeInsert(Cancel As Integer)
Call printCollisionInfo(Me.Recordset, Me.name)
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
Call printCollisionInfo(Me.Recordset, Me.name)
End Sub
Method printCollisionInfo is:
Public Sub printCollisionInfo(rst As Recordset, formName As String)
Dim msg As String
msg = Now & " From " & formName & ": " & rst.BatchCollisionCount & " collisions"
Debug.Print msg
End Sub
But when calling rst.BatchCollisionCount, I get
"Operation is not supported for this type of object"
Is it because a form does not perform a dbUpdateBatch but some other type of update? Can I set the form's update type? Is there another way to see the SQL (with data values) or data that triggered the conflict?
The Recordset.BatchCollisionCount property is only valid for ODBCDirect workspaces.
This is stated in the Access 2010 online help, but unfortunately not on the MSDN page:
https://msdn.microsoft.com/en-us/library/office/ff198240(v=office.14).aspx
Look at how the recordset is set up in the example on that page. This is about as far from a bound form's recordset as it can be.
Here is an intro about ODBCDirect: http://www.avdf.com/may97/art_optimist.html
This technique is old, but the fact, that your question is #11 on my google search, gives you a hint about how many people use it...
I suggest a new question where you describe your setup and the error(s) you get.

vba format function throws type mismatch error

I am trying to format a number as currency in Access VBA.
In the immediate window, when I enter:
? Format(123, "Currency")
I get the expected response: "$123.00"
However, in the code window, when I enter:
Debug.Print Format(123, "Currency")
I get an error pointing to that line: "Run-time error '13': Type mismatch"
Why does the same simple code work in the immediate window, but throw an error when run from the code window?
I don't see why your second example should cause an error. The following subroutine compiles and runs without error on my Access 2003 system:
Public Sub test_Format()
Debug.Print Format(123, "Currency")
End Sub
Try that subroutine in a new database. Perhaps your current database is corrupted.
See Tony Toews' Corrupt Microsoft Access MDBs FAQ
What do you mean by Code Window?
This works:
Private Sub Form_Load()
Debug.Print Format(123, "Currency")
End Sub
In the debug window, you just do NOT use Debug.
Print is equivalent to ?
So Debug.Print Format(123, "Currency") in code should be
Print Format(123, "Currency") in debug window or ? Format(123, "Currency")