How to have Access VBA overwrite a file on the desktop that is not the version on the server - ms-access

I am new to Microsoft Access but have been learning as I go this past week. But now I am stuck. I am writing VBA code that checks if the user is using a current database version from their desktop compared to the database version on the server. I have established a table in the back end that holds the numerical value for each user's version and then a table that also stores the numerical value for the newest version on the server(changed by an admin when changes are made). The current code compares the values to determine if the copy that was opened is the newest version. If it is not it opens the version that is on the server and then changes the user's version in the back end table. But I want to change the copy on the desktop so the next time the user opens the copy it is the new version since the code will identify that the version was "updated".
I know that there is the My.Computer.FileSystem.CopyFile() that can be used to copy one file to a new location and write over the file that is there, but if I use this will it be able to write over the file that is open and running the code that is generating the .CopyFile() command? I already have the version on the server being accessed before the .CopyFile() command, but I just don't know if it will actually execute. I'm also not sure if I like the fact that the user will need to reenter their user name and password once the server version opens. Does anyone know of a way to overwrite the file on the desktop without the user even knowing?

I have already done that in a previous database and with some modifications I think you can make it suitable to your needs.
I will start from the point that you have checked the version and found if it is the newest available or an old one.
If Not updated Then
Select Case MsgBox("An update is available for your client!!!" _
+ " You would be able to use this client version but without new features and support!" _
+ " Do you want to update now?", vbYesNo Or vbInformation Or vbDefaultButton1, "Available Update")
Case vbYes
'Call MsgBox("Please contact your administrator to receive your new client version!!!", vbExclamation Or vbDefaultButton1, "Available Update")
Shell "cmd /c ""<whatever path you want>\doupdate.cmd"", vbHide" 'calls a cmd script to do the dirty job of copy -> see below
Application.CloseCurrentDatabase 'closes the current database
Exit Sub
Case vbNo
<whatever you want on no>
End Select
End If
You can remove the select on the above code and it will run everytime the variable updated is False without asking the user.
The cmd script code is the following:
#Echo OFF
SLEEP 3
copy "\\server\groups\<whatever path>\file.accde" "%userprofile%\Desktop\file.accde" /Y
call "%userprofile%\Desktop\file.accde"
exit
The above script is surely not perfect because of a 3sec busy waiting on the begining, but I want to be sure that access has time to close. (The problem will be big enough if acccess hangs on close.
What you can also do is to add the above or the command My.Computer.FileSystem.CopyFile() on the close event of your database, however in that case the update will happen after the user has completed his work with the old version.
Note that in that case I wanted the script that updates to be separate from the database for other reasons. The main principle is the same even if you use vba for the update, you have to close the file before overwriting it.

Related

How can Microsoft Access be restarted with VBA...from within Microsoft Access..?

How can I use VBA to restart Microsoft Access 2007 from within the same DB file..??
I'm developing a DB that will eventually be packaged & distributed with the Runtime. For development I'm changing various UI settings, and renaming the file back & forth between *.accdb and *.accdr. But I would like to use a fully programmatic method, which I would then assign to a button or keystroke.
But as anyone who's tried can tell you, one cannot easily use VBA to restart Access from within the same DB. I tried the code here: MS Access: how to compact current database in VBA, but I received the error message "You cannot compact the open database by running a macro or Visual Basic code."
I have various half-baked ideas how to "bounce" the restart off a VBS script, CMD file, or another Accdb file, but I wanted to ask who else may have done this successfully..??
What variety of ways have others done this with success..??
I had the following procedure to copy new version of frontend and then open. Unfortunately, had to abandon when IT tightened security and can no longer programmatically copy files. Don't ask me why it works, it was found code. Previously, I had VBA call a VBScript which would do the copy and reopen.
Private Sub Form_Load()
'Check for updates to the program on start up - if values don't match then there is a later version
If Me.tbxVersion <> Me.lblVersion.Caption Then
'because administrator opens the master development copy, only run this for non-administrator users
If DLookup("Permissions", "Users", "UserNetworkID='" & Environ("UserName") & "'") <> "admin" Then
'copy Access file
CreateObject("Scripting.FileSystemObject").CopyFile _
gstrBasePath & "Program\Install\MaterialsDatabase.accdb", "c:\", True
'allow enough time for file to completely copy before opening
Dim Start As Double
Start = Timer
While Timer < Start + 3
DoEvents
Wend
'load new version - SysCmd function gets the Access executable file path
'Shell function requires literal quote marks in the target filename string argument, apostrophe delimiters fail, hence the quadrupled quote marks
Shell SysCmd(acSysCmdAccessDir) & "MSAccess.exe " & """" & CurrentProject.FullName & """", vbNormalFocus
'close current file
DoCmd.Quit
End If Else
'tbxVersion available only to administrator to update version number in Updates table
Me.tbxVersion.Visible = False
Call UserLogin End If
End Sub
I use the utility provided here: http://blog.nkadesign.com/2008/ms-access-restarting-the-database-programmatically/
In a nutshell, when you run this, Access will quit. However, before it quits it will create a small batch file in the same folder as the database with a couple of commands in. Access then quits, and the batch file will then wait for the removal of the lock file (laccdb file). Once that's removed (as it should be if you're the only user in the database), the batch file then restarts the application.
There is also an option to compact the database on close, too. It works incredibly well for me in my environment, and I have successfully used this for probably somewhere in the region of 5 years.

Disabling Design View in MS Access

I'm trying to input some code that hides "Design View" as an option for our internal application unless a certain permission requirement is met.
The following code works with one exception:
On Error Resume Next
If Not GetUserInfo("ADMIN_PERMIS") = 1 Then
Dim cb As CommandBar
Dim cbCtl As CommandBarControl
For Each cb In CommandBars
If cb.type = msoBarTypePopup Then
For Each cbCtl In cb.Controls
If cbCtl.Caption = "&Design View" Then
cbCtl.enabled = True
cbCtl.visible = False
Else
cbCtl.visible = True
End If
Next
End If
Next
Set cb = Nothing: Set cbCtl = Nothing
End If
The one problem with this is that it disables Design View not only for the current database, but also for any other access database that is launched. I'm looking for a way to try and apply this code in such a way that it only affects the Access database I have the code in and not in every single instance of it.
I recommend converting the database into a compiled, executable only .accde file (File --> Save & Publish --> Make ACCDE). Doing this will prevent any design or code changes in the application. Keep a development version in the normal .accdb format. Make your changes there and then compile into the .accde version for each update.
Since your team updates the database often, you could benefit from using Peter De Baets' database starter. The database starter makes a local copy of the front end of the database, allowing uses to continue to work while design changes are being made. After the production accde front end file is updated, the users will automatically copy the new file the next time they open the database. In my office I have found that I can push out a quick fix and simply email everyone saying "Close and reopen the database guys!".
All these answers are great. If you are interested in the simplest method, I found the form holds the key, albeit in a strange spot.
In the forms properties->Other Tab->Shortcut Menu =No

Getting at VBA/Access Source Code

I'm rewriting a legacy access / VBA application in C#. While I am limited as a VBA programmer I am under the impression that the code is minimally compiled and runs almost as a script ? Obviously no security / VBA you can just hit alt + f11 to get at the source code is there a good way to decompile / get at this code?
So I tried this: http://forums.databasejournal.com/showthread.php?t=34222
which appears to be about how to decompile .mdb files.
However the program quickly recompiled itself - or at least says it is recompiling itself in the lower left status bar. Any ideas?
Here are some suggestions (some of which I'm repeating from comments I've made above):
Alt-F11 is not my usual method of opening the VBE, because I usually want to go to the Immediate Windows. Try Ctrl-G, instead.
If both Alt-F11 and Ctrl-G fail to open the VBE, then perhaps the AllowBypassKey property of the database has been changed to False. To get code to change this, search the Access help file for AllowBypassKey (in the VBE, from the help menu, search for "AllowBypassKey"). However, you won't be able to run the code within the database you're trying to investigate if AllowBypassKey is turned OFF, so you can run this code:
//
On Error GoTo Change_Err
Dim db As DAO.Database
Dim prp As Variant
Const conPropNotFoundError = 3270
Set db = DBEngine.OpenDatabase("C:\Databases\MyDatabase.mdb")
db.Properties("AllowBypassProperty") = True
exitRoutine:
If Not (db Is Nothing) Then
db.Close
Set db = Nothing
End If
Exit Sub
errHandler:
If Err = conPropNotFoundError Then ' Property not found.
' do nothing and exit
Resume exitRoutine
End If
Then you should be able to open the database when holding down the SHIFT key (which bypasses any defined startup routines, which might have been shutting off access to the VBE).
If the file is an MDE, there is no source code. You can find out if it's an MDE by checking this property:
?CurrentDB.Properties("MDE")
If it's an MDE (the file can have any extension), this will return "T". If it's not an MDE, it will throw an error (because the property doesn't exist).
Other things to check might be how many modules there are. If you have the database open and can get to the Immediate Windows (Ctrl-G), then this will tell you if there are any modules:
//
?CurrentProject.AllModules.Count
You also might be able to see what's in the database by opening up the Object Browser in the VBE (F2) and selecting the project name in the dropdown at the top (it will say "" by default
Last of all, you may think that it could be protected by Jet ULS, but starting with Access 2000, that's not a big possible, as there's nothing but a password on the VBA project available (i.e., it's no longer covered under Jet ULS). I would expect that if it were password-protected, you'd be prompted for the password somewhere along the line, so you'd already know that.
If it's an .mde you are out of luck. You need to get hold of the .mdb containing the source VBA code that was compiled to create the .mde
HOW TO VIEW SOURCE CODE (.mdb FILE)
Select the file
Hold the 'shift' key
Then double click the file without releasing the 'shift' key
Navigate to the Program Folders on your computer.
Open the MS Office Folder
Navigate to MSAccess.exe and make a shortcut of it.
Move the shortcut to where your database resides (makes life easier and you'll need to do this for each database to decompile).
(optional) Rename the shortcut to something like "decompiler for my database whose name is...." so you know that opening it blows away your compiled code
Right-click on the shortcut to view its properties. In the Target field of the properties dialog box for the shortcut you'll see something like "C:\Program Files\Microsoft Office\Office\MSACCESS.EXE"
In the target field, right-arrow to the end of the pathname, type a space, and then, in quotes, type (or paste) the full pathname of the location of your MS Access file to decompile (easiest way is to copy from the address bar on your window where the file resides, if you have the address bar showing).
Still in the Target field, type a space, and then with no quotes, type /decompile
Click OK to accept the changes and to close the dialog box.
Hold the Shift key down and keep it down.
Wiggle your ears
Double-click on the shortcut.
Go to any module in your database.

What is this Access bug? You do not have exclusive access to the database at this time

Tested on Access 2003 Pro (build 11.8321.8324) SP3.
Steps to reproduce:
create a new database.
create a new form.
put a button on the form.
paste the following code in the button's Click event procedure:
Debug.Print Workspaces.Count
Debug.Print CurrentDb.Name
close the code editor and form, saving changes.
do not skip this step: close Access.
re-open Access and your database.
open the form
click the button
click the toolbar button to switch the form to design mode.
You should see the following error dialog:
You do not have exclusive access to the database at this time. If you proceed to make changes, you may not be able to save them later.
Does anyone know what is going on here?
The simple workaround is to call CurrentDb prior to calling Workspaces for the first time:
Debug.Print CurrentDb.Name
Debug.Print Workspaces.Count
Debug.Print CurrentDb.Name
I'll take a shot at demystifying what's going on, but this is just my theory.
The relevant bits of the Access help file are as follows (for CurrentDb):
Note In previous versions of
Microsoft Access, you may have used
the syntax
DBEngine.Workspaces(0).Databases(0) or
DBEngine(0)(0) to return a pointer to
the current database. In Microsoft
Access 2000, you should use the
CurrentDb method instead. The
CurrentDb method creates another
instance of the current database,
while the DBEngine(0)(0) syntax refers
to the open copy of the current
database. The CurrentDb method enables
you to create more than one variable
of type Database that refers to the
current database. Microsoft Access
still supports the DBEngine(0)(0)
syntax, but you should consider making
this modification to your code in
order to avoid possible conflicts in a
multiuser database.
And for the Workspaces collection:
When you first refer to or use a
Workspace object, you automatically
create the default workspace,
DBEngine.Workspaces(0).
It would seem that by creating the default workspace prior to the first call to CurrentDb, you are somehow causing CurrentDb to forget how it should work. It seems that instead of creating a new instance of the current database it just uses the one that's already lying around in the default Workspace.
Of course, this is all conjecture and I'm as curious as you to know the "real answer".

How to open locked app in design mode?

Our MS Access 2000 developer left the company a year ago. We need to open his app in design mode in order to make modifications. Double-clicking the .mdb file while holding the shift key doesn't work. When I do that the developer toolbar shows for a split second, then all toolbars go away and the app opens as users would see it. No toolbars show and only a basic dashboard is visible to run the app. I tried using the password recovery tool mentioned here but the tool says there is no password. Can someone tell me how I can open this app to make code modifications?
Beth's answer worked for myself and a co-worker. I've copied the solution here from the link in case the link dies.
"...To unlock the Access DB you can use the following if you know the full path to your database.
Copy the following function into a module in ANOTHER database and call the function. You will need to set the strPath to the path of your database."
Public Function ResetExternalDatabaseBypassKey _
(Optional tfAllow As Boolean = True)
'Name: ResetExternalDatabaseBypassKey (Function)
'Purpose: Sets AllowByPassKey to true in another Access Database
'Author: John Spencer UMBC-CHPDM
'Date: May 02, 2000, 12:08:19 PM
'*******************************************
Dim dbs As Database
Dim strPath As String
On Error GoTo ResetExternalDatabaseBypassKey_ERROR
strPath = "C:/MyDatabases/SomeDataBaseName.mdb"
Set dbs = DBEngine.Workspaces(0).OpenDatabase(strPath)
dbs.Properties("AllowByPassKey") = tfAllow
ResetExternalDatabaseBypassKey_ERROR:
Select Case Err.Number
Case 3270 'Property not found
MsgBox "Allow Bypass Key property does not exist " & _
"for the chosen database."
Case Else
MsgBox Err.Number & ": " & Err.Description
End Select
End Function
Make sure there wasn't another copy left around without this code enabled.
This is typical code used to do this sort of thing, SetByPass There are instructions to hit Cntl-G to open VBA Editor and run code to unset this thing.
Have you tried creating a new blank database, and then importing everything?
It sounds like the shift key by-pass has been set, but that's as noted usually only needed for deployment. In fact, for any access developer, this is quite much a standard approach.
So, it not clear if anything at all been locked up here or the person just set things up as most access applications should be when deployed to users.
About the only thing you lose when importing to another application is the tools startup settings and the shift key. If there are custom menus, make sure you check the option to import those also. (However, be careful, as sometimes custom menus can be setup to run a macro on startup, and this was an old security trick). So, if importing once with tool bars and holding down shift key still causes startup code to run, then try creating another blank database and this time import everything except the menu+tools bars from the old application. Holding down shift key will thus then work for you.
Also, if the system not asking your for a password, then what would you expect a password recovery program to do? All you need is basic access developer skills here to deal with this problem and throwing things like password removal when you not being prompted for passwords will not move you forward here.
On the other hand, if after importing all the forms into a new database the design ability is grayed out, then this was in fact a mde file, and you are in a rather difficult situation unless you can find the original mdb file used to create the mde.