Scheduling MSAccess DB VBA module automatically for every 10 minutes - ms-access

I have a module created "Sub Split()" in MSAccess DB VBA and I want to schedule this module to execute automatically after every 10 minutes . I did check out the code which says Application.OnTime Now + TimeValue("00:00:10"), "Split" but its throwing an error . Is it that this function is applicable only in Excel and not in Access and If I want the same function in Access is there any way to do it?

Create a form to b opened in the background, and in it's code section paste this code:
Sub Form_Load()
Me.TimerInterval = 600000
End Sub
Sub Form_Timer()
Split
End Sub
Open the Form, and Split will run every 10 minutes.

Related

Upgrade Access 2000 to 2010 then 2016 VB question

Help please...I have successfully upgraded from Access 2000 to 2010 then to 2016 with no compile errors however I have an exe file within a form in the VB code and it doesn't run anymore or send an error message. The project is a weighbridge and has been operating on access 2000 for 15 or more years with many changes to the design, where the exe file captures the data from the weighbridge "signal" box and sends it to my form. This exe no longer works in Access 2010 (the go between program during upgrade) or in Access 2016. This is crucial to the project, I no longer have the original code in VB or a copy of VB on my computer although I do have a copy in a text file left by the original programmer. Can anyone tell me Why Access 2016 does not acknowledge this exe. Is there a reference that needs to be clicked? I am lost.
The code is
Private Sub Form_Load()
On Error GoTo Err_Form1
Select Case strDocName
Case "GetGrossWeight"
Set objFrmCtrl = Forms!ConsignmentsIN.GrossWeight
Warning.Caption = "Get Gross Weight In"
Case "GetTareWeight"
Set objFrmCtrl = Forms!ConsignmentsContractIN.TareWeight
Warning.Caption = "Get Tare Weight In"
Case "GetGrossWeightcontract"
Set objFrmCtrl = Forms!ConsignmentsContract.GrossWeight
Warning.Caption = "Get Gross Weight In"
Case "GetTareWeight"
Set objFrmCtrl = Forms!ConsignmentsContract.TareWeight
Warning.Caption = "Get Tare Weight In"
End Select
OpenEXE
Exit_Form2:
Exit Sub
Err_Form1:
MsgBox Error$
Resume Exit_Form2
End Sub
Private Sub OpenEXE()
On Error Resume Next
GrossValue = Shell("c:\weighbr\auto\Weight.exe", 6)
If Err.Number = 53 And GrossValue = 0 Then
MsgBox "Can't find program 'Weight.exe'", vbInformation, "Alert"
End If
' ...
End Sub
According to the documentation for SHELL:
Runs an executable program and returns a Variant (Double) representing the program's task ID if successful, otherwise it returns zero.
Your code gets a task ID, not the result of executing the .exe program (if nothng else prevents execution). So, you shouldn't expect, in any case, to get a value generated by this program.
You should use the debugging tools to step into this Sub and actually figure out what it does.
Check if Alternative to Call Shell() ? (2000) can help you out, and also Access 2000 to 2002 (Shell command).
It seems that the Shell function might have changed a looong time ago.

Can I programatically open a new query window?

I'm trying to figure out if/how I can generate a new query window in the Design View either via a macro or VBA code.
Specifically, I want to open a new, blank query in SQL View so I can quickly test SQL code. This is a common activity for me.
I usually create a new query manually via the Ribbon: Create tab > Query Design button > Close (Show Table window) button > SQL View button. This results in a new window called Query1 (or Query2, etc.).
I'd like to condense all of those multiple clicks into a keyboard shortcut or a single macro button on the Quick Access Toolbar. Note that I'm using Access 2010.
Possible?
Add this to a module:
Function NewQueryInSqlView()
' Send the ESC key, without waiting for processing,
' to cancel the select table dialog that occurs when designing new query
SendKeys "{ESC}", False
DoCmd.RunCommand acCmdNewObjectDesignQuery ' create new query
DoCmd.RunCommand acCmdSQLView ' switch to SQL view
End Function
To execute the code by way of a keyboard shortcut, create a new macro, and ensure "Macro Names" column is visible.
Add the following row to macro with the following values in the specified columns:
Macro Name: +{F3}
Action: RunCode
with Function Name argument: NewQueryInSqlView()
Save this macro as "AutoKeys". This macro will map SHIFTF3 to the execution of NewQueryInSqlView(). Note that choosing a key mapping starting with CTRL (the ^ character) will be problematic due to the SendKeys statement in NewQueryInSqlView().
Write a function and call it from a macro:
Public Function foo()
Dim qdf As QueryDef
Set qdf = CurrentDb.CreateQueryDef("qNew", "SELECT 'd' as foo")
DoCmd.OpenQuery qdf.Name
End Function
This will create the query and open it
The macro is a RunCode command that runs the above function.
Try This code:
Sub EmptyQuery()
Dim Qname As String
Qname = "mQname"
On Error Resume Next
CurrentDb.CreateQueryDef Qname
On Error GoTo 0
DoCmd.OpenQuery Qname, acViewDesign
End Sub

Why does Access VBA prompt me for a Macro when I press F5 or Run Sub?

I found this question Why does Excel VBA prompt me for a Macro name when I press Run Sub but the answers don't help me because my sub doesn't have arguments and is not triggered by an event.
I have two subs. One in a Module and one in a Form.
Sub ModuleSub()
MsgBox ("Hello World")
End Sub
Sub FormSub()
MsgBox ("Hello World")
End Sub
The Module Sub DOES RUN when I press F5, but the Form Sub doesn't. It brings up the Macro dialog. What is the problem here?
Macros stored in modules are independent and can be ran just like that.
However, all the functions/subs stored in Form modules or in Class modules are in fact the methods of this form/class and they cannot be ran without instance of this form/class.
If you open Immediate window (CTRL + G) you can run this code:
Call ModuleSub
without any issues.
This code:
Call FormSub
will return Compile error: Sub or function not defined.
However, if you add the name of form before the name of the function (like below):
call Form_FormName.FormSub 'replace FormName with the name of your form.
this sub will be also invoked without any issues, since you dynamically create an instance of form and VBA compiler can use its methods.

Delete a table on report close with slight delay

I want to keep my database performance at the top, reducing the number of objects and creating stuff just temporarily. I have a table that should be automated from the code:
There is a report that needs data from that table - (works fine), so this is the flow:
'-> form is opened -> onClick find-button
'-> table of dates is created -> table of dates is populated
'-> Report is opened -> onReportClose (I want the table of dates to be deleted).
The code is written, it works fine on its own:
CurrentDb.TableDefs.Refresh
DoCmd.DeleteObject acTable, "temp-table"
So I added a macro on report close to run the above code: which is a function. But I get the error below:
Run-time error '3211': The database engine could not lock table
'temp-table' because it is already in use by another person or
process.
I believe this is because the report is probably using it. So I added a ten seconds delay to my code:
Dim PauseTime As Variant
Dim Start As Variant
Dim Elapsed As Variant
PauseTime = 10
Start = Timer
Elapsed = 0
Do While Timer < Start + PauseTime
Elapsed = Elapsed + 1
Loop
CurrentDb.TableDefs.Refresh
DoCmd.DeleteObject acTable, "temp-table"
Instead, It seems to be holding the whole database for 10 seconds and the same issue is still occurring. Any Ideas/suggestions on how to delete this table on report close, or force table delete in Ms-Access (maybe?) or how to work around this are welcomed.
You must clean the RecordSource of the Report, and run the method Requery in the Unload event. Right after that you can DROP the data table.
Private Sub Report_Unload(Cancel As Integer)
'Desvinculo la tabla del reporte
Me.RecordSource = ""
Me.Requery
'Borro las tablas de datos
DoCmd.RunSQL "DROP TABLE name_of_table"
End Sub

Is there a way to execute VBA code when specific tables and fields in a Microsoft Access database are updated?

I have a program that uses a Microsoft Access database for its back-end. I need to have some VBA code (that calls a web service) execute whenever specific tables/fields are updated by the program. I see this working just like a trigger in SQL Server.
Is it possible to monitor for and act upon changes like this in Access?
Update
The program in question does not run inside of Access (i.e. not a VBA app), it simply uses an MDB file as its back-end storage. Unfortunately I don't have access to the program's code as it is a closed third party application.
This question is old, but the answers are no longer correct. Access 2010 added data macro events that can be run when data is inserted, updated or deleted. The following events are available while using either the table datasheet view or table design view (events are attached directly to table and not through the form macro button):
After Delete Macro Event
After Insert Macro Event
After Update Macro Event
Before Change Macro Event
Before Delete Macro Event
More information is located here:
https://msdn.microsoft.com/en-us/library/office/dn124692.aspx
https://support.office.com/en-us/article/Create-a-data-macro-b1b94bca-4f17-47ad-a66d-f296ef834200
Access the GUI environment vs Jet the database format are separate things.
If you are using an Access database as a backend - it's just the JET functionality you can work with. Access the GUI (which includes VBA) runs on the client machine and there is no automated trigger functionality.
If your program is the only program using the Access file, then it should know when a table is being updated and execute some code in place of a trigger.
Otherwise, you need another application/service running all the time that is checking the access file tables for updates (maybe you have some update_date type of field on your tables?).
When an Access database file gets written to, it's date/time stamp changes. I suppose you could try using a file monitor to detect changes to the file, and then examine the file to see what has changed.
It would help if the Access database has LastModified date/time columns in the tables.
If you are using Jet (i.e. the data is stored in an MDB file back end) then the only places you can run code would be in the After Update Event in a Form. The problem here of course is if the data is changed without using the form then the event will not fire.
If you are using MS Access 2003 then to run a Web Service you can download the Microsoft Office 2003 Web Services Toolkit Click Here to download
If you are stuck in VBA it gets a little rough. One way to go would be to have a form with timer in it (you could have it open invisibly. The timer could check the table, say once a minute (or whatever interval seems suitable) for changes in record count, and verify the table still exists. (code below)
But personally this isn't what I would recommend that you do. Access is notorious for corruption. When used as a simple back end you are fairly safe most of the time, but to have it running a monitor, means the file is always open. This is basically playing Russian Roulette with your database. At minimum I would link to your database from another Access file and monitor the linked tables, that way if your monitor crashes, you don't take the production DB with you. Finally, make sure that you don't query too often, as I'd hate to see you be the sole cause of the website timing out:)
Option Explicit
Private m_lngLstRcrdCnt_c As Long
Private Sub Form_Open(Cancel As Integer)
Const lngOneMinute_c As Long = 60000
Me.TimerInterval = lngOneMinute_c
End Sub
Private Sub Form_Timer()
Const strTblName_c As String = "Foo"
Const strKey_c As String = "MyField1"
Dim rs As DAO.Recordset
Dim lngRcrdCnt As Long
If TableExists(strTblName_c) Then
Set rs = CurrentDb.OpenRecordset("SELECT Count(" & strKey_c & ") FROM " & strTblName_c & ";", dbOpenSnapshot)
If Not rs.EOF Then lngRcrdCnt = Nz(rs.Fields(0&).Value, 0&)
rs.Close
If lngRcrdCnt <> m_lngLstRcrdCnt_c Then
m_lngLstRcrdCnt_c = lngRcrdCnt
'Number of records changed, do something.
End If
Else
'Table is deleted, do something.
m_lngLstRcrdCnt_c = -1
End If
End Sub
Private Function TableExists(ByVal name As String) As Boolean
Dim tdf As DAO.TableDef
On Error Resume Next
Set tdf = CurrentDb.TableDefs(name)
If LenB(tdf.name) Then 'Cheap way to catch broken links.
Set SafeGetTable = tdf
End If
End Function