Can this Access VBA code be performed by an Access Macro? - ms-access

I have successfully created a VBS file that Windows Task Scheduler can use to export data from my database, by triggering an Access macro. Now i need to import - most steps are simple and can be achieved in the Access macro but I need to re-create table links first (field names and positions often change in the source files and it seems to mess things unless i first delete and re-create the links.)
Here's the VBA code - is there a corresponding macro action that i have missed?
'delete and recreate links to Account and Company
Dim db As DAO.Database
' Re-link the CSV Table
Set db = CurrentDb
On Error Resume Next: db.TableDefs.Delete "Contact": On Error GoTo 0
db.TableDefs.Refresh
DoCmd.TransferText TransferType:=acLinkDelim, TableName:="Contact", _
FileName:="c:\db\contact.csv", HasFieldNames:=True
db.TableDefs.Refresh
On Error Resume Next: db.TableDefs.Delete "Account": On Error GoTo 0
db.TableDefs.Refresh
DoCmd.TransferText TransferType:=acLinkDelim, TableName:="Account", _
FileName:="c:\db\account.csv", HasFieldNames:=True
db.TableDefs.Refresh
db.Close
Set db = Nothing

Yes, the macro action you missed is called Run Code.
The only caveat is that Run Code can only call VBA functions. So you can't just paste your code in the macro. Instead, you need to put it into a VBA function in an MS Access module, like this:
Public Function ReCreateTableLinks()
'delete and recreate links to Account and Company
Dim db As DAO.Database
'... paste the rest of your code here
End Function
By the way, are you saying that you are using Windows Task Scheduler, which calls a VBS file, which opens the Access database and executes the macro?
Am I understanding this correctly?
If yes: you don't need the VBS file at all if it does nothing but open the Access database.
You can just execute the Access database directly with Windows Task Scheduler.
If you name the macro autoexec, it will execute automatically when the Access database opens.

Related

How do I create copies of CurrentDb using VBA

I need to create copies of the CurrentDB using VBA (approx. 12 copies). The copies need to be clones of the master database containing all the same forms, queries, etc. except only a limited dataset.
DoCmd.CopyDatabaseFile seems to be made for this, but only works if you are using it to copy the DB to an MS SQL Server. As MS states on their website:
Copies the database connected to the current project to a Microsoft
SQL Server database file for export.
docmd.TransferDatabase only exports the data itself, but not the structure, forms, etc.
Code I have found on the web and adapted doesn't work and throws an error on the .CopyFile line saying:
Run-time error 52: Bad file name or number
This is the code
Sub CopyDB()
Dim external_db As Object
Dim sDBsource As String
Dim sDBdest As String
sDBsource = "\\group\bsc\groups\L\BDTP\Compliance\ComplianceData\Compliance Group Reporting.accdb"
sDBdest = "\\group\bsc\groups\L\BDTP\Compliance\ComplianceData\Compliance Group Reporting_2.accdb"""
Set external_db = CreateObject("Scripting.FileSystemObject")
external_db.CopyFile sDBsource, sDBdest, True
Set external_db = Nothing
End Sub
How can I fix the above line? Alternatively is there a direct command in Access to create a copy? The "create backup" function would be tailor made for this, but I can not find it in VBA.
Looks like you have an extra quote in sDBdest accdb"""
And for database copy you can also use
FileCopy sDBsource, sDBdest
Instead of Scripting object

How to run a code from current database and apply it on another database without opening it?

In Access 2007, I have created an auto 'dynamic table linker' program (VBA) in the Frontend database and I would like to run this code and apply it to the Backend database without opening it (or in the background without user knowing).
My current approach is to autoopen the backend database and run the program on startup from the backend. However, this will run everytime when you open the backend.
I only want to run the program when it is redirected from the frontend and possibly hide this from the users when it runs. Is there any possible way to solve this requirement?
Clarification: I need to run the prexisting code on frontend and apply it to backend, that is to eliminate code duplication.
OK, so here is what I would do (there are lots of relinking examples on-line, so I won't show any details here):
Original Code:
Public Sub RelinkTables(sOldLink As String, sNewLink As String)
Dim oLinkDb As DAO.DataBase
Set oLinkDb = CurrentDb
' do your linking for oLinkDb
New Code:
Public Sub RelinkTables(oLinkDb As DAO.DataBase, sOldLink As String, sNewLink As String)
' do your linking for oLinkDb
Call for frontend:
RelinkTables(CurrentDb, "OldLinkPath", "NewLinkPath")
Remote call for backend:
Dim objAccess As New Access.Application
objAccess.OpenCurrentDatabase "\\Path\Backend.accdb"
RelinkTables(objAccess.CurrentDb, "OldLinkPath", "NewLinkPath")
This way, you have a single routine, RelinkTables(), that can relink for any database given to it. You still have to open the backend to relink, but this can't be helped.
You could run the following code in the frontend database.
Sub ReLink
Dim objAccess As New Access.Application
objAccess.OpenCurrentDatabase "\\server\routetobackend\nameofbackenddatabase.accdb"
objAccess.Eval "Function_to_relink('parameter')"
End Sub
Where Function_to_relink is a function in the backend database,
Other info that could be useful: https://msdn.microsoft.com/en-us/library/office/aa221161%28v=office.11%29.aspx

AutoExec Module not Initiating

My data storage form has a new module (AutoExec) which is meant to test the connection to a SQL server db upon opening the form. Only it is not firing when opened. I was wondering if there was something in my code causing this, this is my first Module so I am not familiar with the proper forms yet.
Public Sub AutoExec()
Dim cnn As ADODB.Connection
Dim localrst As New ADODB.Recordset
Dim remoterst As New ADODB.Recordset
Set cnn = New ADODB.Connection
cnn.Open "Provider=SQLOLEDB; Data Source=DB\P003,49503; Initial Catalog=HRLearnDev;" _
& "User Id=USERNAME; Password=PASSWORD;"
If cnn.State = adStateOpen Then
MsgBox ("You have an established connection.")
Else
MsgBox ("Cannot connect to remote server. Data will be stored locally to CDData Table until application is opened again.")
End If
cnn.Close
Dim rst As New ADODB.Recordset
End Sub
When a database includes a macro named AutoExec, Access will run that macro at database startup.
In order for that to work, AutoExec must be an Access macro object. In your case, you have a VBA procedure named AutoExec. Since that is not a macro object, Access does not run the procedure automatically at database startup.
I suggest you create a VBA function ...
Public Function Startup()
Add the code from the body of your AutoExec procedure to the function.
Then create a new Access macro (an actual Access macro object --- on the ribbon in Access 2007, choose Create->Macro), use the macro RunCode action to run your new Startup() function. Name that macro object as AutoExec.
Here is a screenshot of my simple AutoExec example macro open in Design View.

Reattaching [Event Procedure] in Access

Due to requirements to not share data between clients, I have an MS Access 2010 data base that I use to extract data from our SQL Server into a small .accdb which we then send to a client, they modify, then I load the data back to the Server.
In my 'Master' Access database (EDIT2: I use Access as a front end to SQL Server), I have a button that will create a client specific .accdb (EDIT2: This has a local table that contains the client's specific data for them to moidify). This code simply copies a template .accdb with forms, code, etc & names it appropriately for the client.
Unfortunately when this copy is made, all the event procedure connections are lost from the properties box. The code still exists in the module, though. This is a fairly well-known issue and is well documented on Google. The general solution is to go through each form & reset the properties for every form & control that needs an event, then Access will reconnect it with the existing code. That's ok, once. I'll have this copy/loss issue dozens or hundreds of times.
I found one reference from ~2003 March, 2004 to dynamically identify missing code (EDIT2: [Event Procedure] references in the properties box) & set the property to [Event Procedure] to fix this. However, when trying to identify if an object should have an event handler, the code relies on this statement
DLookup("EventProcedureSuffix", "EventProcedures", "EventName = '" & prpCurr.Name & "'")
and that generates an error 3078 saying it cannot find a table or query named 'EventProcedures' (EDIT2: which seems to have been a system table in the older version of Access that the code was based on). Does anyone know what happened to the 'EventProcedures' table in Access 2010? Has it been renamed, is it no longer accessible, is there a replacement?
This also begs the question of how do I fire this code in the first place. I have it on the OnOpen event of the main form that is opened when the DB is opened, but if the event handler is disconnected, that won't fire, either...
EDIT: Found the link to the source of the code I'm using: http://www.accessmvp.com/djsteele/Access/AA200403.zip
Instead of trying to re-attach the Event Procedures after the fact you might try to find a method that creates a new user database in a way that preserves the Event Procedure links.
The following Access 2010 code seems to work fine for me. It creates an Access 2003 format .mdb file and then exports a Table and a Form. The form has a button with code behind it, and the button works fine when I open the form within the .mdb file.
Option Compare Database
Option Explicit
Public Function CreateUserDatabase()
Dim fd As Object ' Office.FileDialog
Dim db As DAO.Database
Dim newDbPath As String
Set fd = Application.FileDialog(2) ' msoFileDialogSaveAs
fd.Title = "Save User Database As..."
fd.InitialFileName = "UserDB.mdb"
fd.Show
If fd.SelectedItems.Count <> 0 Then
newDbPath = fd.SelectedItems(1)
If UCase(Right(newDbPath, 4)) <> ".MDB" Then
newDbPath = newDbPath & ".mdb"
End If
On Error Resume Next
Kill newDbPath
On Error GoTo 0
Set db = DBEngine(0).CreateDatabase(newDbPath, dbLangGeneral, dbVersion40)
db.Close
Set db = Nothing
DoCmd.TransferDatabase acExport, "Microsoft Access", newDbPath, acTable, "UserData", "UserData", False
DoCmd.TransferDatabase acExport, "Microsoft Access", newDbPath, acForm, "UserForm", "UserForm", False
MsgBox "The user database has been created.", vbInformation
End If
Set fd = Nothing
End Function

Code to Kill current Excel file, then Export to new Excel file without opening output file

I have a database that is linked to a few others. The db in question has some script that exports a table to an Excel ".xlsx" with a name that is linked to other databases. Basically data entry is done in one db and then the other db pulls in the information live so we have real time updating.
However, after the kill sequence completes and the new file is exported, the Excel file opens up. This causes a problem with the second db not being able to see real time updates since the new export file does not actually overwrite the previous since the previous has opened automatically. I need help telling the Excel export files not to open.
I know I should Dim the file name but I haven't :-).
Below is the code, any help is much appreciated.
Private Sub Form_Activate()
'Delete Existing File First; then create new
On Error Resume Next
Kill "\\ct13nt003\MFG\SMT_Schedule_Files\SMT Line Progress Files\SMT2Updated.xlsx"
On Error GoTo 0
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "SMT2Export", "\\ct13nt003\MFG\SMT_Schedule_Files\SMT Line Progress Files\SMT2Updated.xlsx", True
Going out on a limb here since I don't really do VBA in Access but I do a lot with Excel so try something like:
Private Sub Form_Activate()
Const xlFileName as String = "\\ct13nt003\MFG\SMT_Schedule_Files\SMT Line Progress Files\SMT2Updated.xlsx"
Const shortFileName as String = "SMT2Updated.xlsx"
Dim xlApp As Object 'Excel.Application
Dim xlWb as Object 'Excel.Workbook
'Delete Existing File First; then create new
On Error Resume Next
Kill xlFileName
On Error GoTo 0
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, "SMT2Export", xlFileName, True
'Get the Excel Application
Set xlApp = GetObject(,"Excel.Application")
'Get the specific workbook
Set xlWb = xlApp.Workbooks(shortFileName)
'Close the workbook
xlWb.Close
'Quit Excel (if needed)
'xlApp.Quit
'Clean up
Set xlWb = Nothing
Set xlApp = Nothing
End Sub
Subscript Out of Range Error
Use the file's name instead of the full path with the xlApp.Workbooks method, per revision above.
There is another potential reason for this error, but this is the most likely.
Reading through your scenario, I'm stumped since I've never had that kind of problem with "Killing" a file. Maybe like another users suggested, you should turn off "On Error Resume Next", at least until you figure out why this error is happening.
Another suggestion would be to try a different deletion method, like
myFSO.DeleteFile "\\ct13nt003\MFG\SMT_Schedule_Files\SMT Line Progress Files\SMT2Updated.xlsx"
That code has On Error Resume Next just before Kill xlFileName. That means if the Kill fails for any reason, it will fail silently.
I have no idea whether that issue contributes to your problem, but suggest you try it this way instead.
'Delete Existing File First; then create new
'On Error Resume Next
If Len(Dir(xlFileName)) > 0 Then
Kill xlFileName
Else
' xlFileName does not exist; no Kill required
End If
'On Error GoTo 0