0

I have a front end called PMD_FE.accdb with a table called tbl_Version. It only contains a unique field called "VERSION." PMD_FE.accdb, lives locally on everyone's machine at C:\users\public\PMDTools\PMD_FE.accdb IN PMD_FE.accdb, there's also a link to the same table TBL_VERSION, but this is the master copy which exists on the server. The name of that linked table is tbl_Version_Latest. I'm trying to write a batch script that will check tbl_Version_Latest and compare it with tbl_Version, if they match, the batch script simply launches PMD_FE.accdb from the Local Home: C:\Users\Public\PMDTools\PMD_FE.accdb. If tbl_Version_Latest is different, it downloads the file from the server which is S:\PMDTools\04_FrontEnd\PMD\PMD_FE.accdb, to C:\Users\Public\PMDTools\ prior to launching it. I have 3 public subroutines in PMD_FE.accdb:

Public Sub DownloadLatestVersion()
 dim SharedAppHome as string
 SharedAppHome = "S:\PMDTools\04_frontEnd\PMD\"

    Shell "xcopy " & SharedAppHome & " " & CurrentProject.Path & "\PMD_FE.accdb /Y"
    
    Debug.Print Shell("echo %errorlevel%", vbNormalFocus)

End Sub

Public Sub GetLocalVersionNumber()
    Dim wsh As Object
    Set wsh = CreateObject("WScript.Shell")
    Dim db As DAO.Database
    Dim rs As DAO.Recordset

    Set db = CurrentDb
    Set rs = db.OpenRecordset("tbl_Version")

    rs.MoveLast
    wsh.PopUp rs![VERSION]

    Set rs = Nothing
    Set db = Nothing
End Sub



Public Sub GetLatestVersionNumber()
    Dim wsh As Object
    Set wsh = CreateObject("WScript.Shell")

    Dim db As DAO.Database
    Dim rs As DAO.Recordset

    Set db = CurrentDb
    Set rs = db.OpenRecordset("TBL_VERSION_LATEST", dbOpenDynaset, dbSeeChanges)

    rs.MoveLast
    wsh.PopUp rs![VERSION], 0, "Latest Version", vbOKOnly

    Set rs = Nothing
    Set db = Nothing
End Sub

The batch script "LaunchPMD.bat" seems straightforward,

@echo off

rem Set the local file path
set localFile=C:\Users\Public\PMDTools\PMD_FE.accdb

rem Check if the local file exists
if not exist %localFile% (
    rem If the local file does not exist, download the latest version from the server
    echo Downloading latest version
    "C:\Program Files (x86)\Microsoft Office\root\Office16\MSACCESS.EXE" %localFile% /x DownloadLatestVersion
) else (
    rem If the local file does exist, compare the version numbers of the local and latest versions
    for /f "tokens=2 delims==" %%a in ('"C:\Program Files (x86)\Microsoft Office\root\Office16\MSACCESS.EXE" %localFile% /x GetLatestVersionNumber') do set latestVersion=%%a
    for /f "tokens=2 delims==" %%a in ('"C:\Program Files (x86)\Microsoft Office\root\Office16\MSACCESS.EXE" %localFile% /x GetLocalVersionNumber') do set localVersion=%%a

    rem If the latest version is newer than the local version, download it
    if "%localVersion%" LSS "%latestVersion%" (
        echo New version found: %latestVersion%
        msaccess.exe %localFile% /x DownloadLatestVersion
    )
)

rem Open the local file
echo Opening %localFile%
start "" %localFile%

but even after multiple re-writes I can't get it to work. There are no errors when I run the batch script in the cmd window. The only error thrown at the very end is this:

'GetLatestVersionNumber' is a new macro or macro group, make sure you have saved it and that you have typed its name correctly.

June7
  • 19,874
  • 8
  • 24
  • 34
plateriot
  • 361
  • 5
  • 23
  • I presume that tbl_Version in latest version of frontend has the current version number. My approach was to have a label on form that opens by default (Login) with version number. Form is bound to tblVersion in backend. If field and label do not match then replace file. Code I originally used - see post 4: https://www.accessforums.net/showthread.php?t=23585. However, IT did something to permissions and can no longer programmatically copy file. Had to change code to just notify user of new version, then open source file folder for them to copy from to working folder. – June7 Jan 10 '23 at 23:49

2 Answers2

0
@echo off

rem Set the local file and access executable locations
set "localFile=C:\Users\Public\PMDTools\PMD_FE.accdb"
SET "access=C:\Program Files (x86)\Microsoft Office\root\Office16\MSACCESS.EXE"

set "latestVersion=z"
set "localVersion= "

rem Check whether the local file exists
if exist "%localFile%" (
  for /f "tokens=2 delims==" %%b in ('"%access%" "%localFile%" /x GetLatestVersionNumber') do set "latestVersion=%%b"
  for /f "tokens=2 delims==" %%b in ('"%access%" "%localFile%" /x GetLocalVersionNumber') do set "localVersion=%%b"
)

IF "%latestVersion%" gtr "%localVersion%" (
  echo Downloading latest version: %latestVersion%
  "%access%" %localFile% /x DownloadLatestVersion
)
rem Open the local file
echo Opening %localFile%
start "" %localFile%

GOTO :EOF

I have no way of testing this - use caution

I'm assuming that the .vba works.

The fundamental problem is that you wish to ensure that the latest version is downloaded if the current version is not the latest.

I've also modified the code in accordance with the normally-accepted SO standards:

Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign " or a terminal backslash or Space. Build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value" is used, then the quotes become part of the value assigned.

I prefer to avoid ADFNPSTXZ (in either case) as metavariables (loop-control variables) 
ADFNPSTXZ are also metavariable-modifiers which can lead to difficult-to-find bugs 
(See `for/f` from the prompt for documentation)

So - setting the local filename and access executable name should be obvious.

Set latestvarsion to a high ASCII value and localversion to a low value. This prepares the code to perform the download.

If the file exists, then set latestvarsion and localversion to their actual values.

Download if the latest > current.

Caution: You have not revealed the format of the version number returned by your vba. Since I've used the string-comparison syntax, the strings will be compared as ASCII strings. In consequence, version "10.3.22" will be seen as earlier than "9.6.3" as 9>1. Reveal the format, and this can be corrected.

Your code's fundamental problem is that within a parenthesised series of instructions (aka "code block") any %var%, including %errorlevel%, is replaced by the then-current ("parse time") value of that variable when the block syntax is being validated. The syntax if [not] errorlevel n may be used, meaning if the CURRENT errorlevel is [not] "n" OR GREATER THAN "n". Otherwise, delayedexpansion and !var! needs to be used to access the current value of the variable, including magic variables like errorlevel time date cd and others. Stephan's DELAYEDEXPANSION link

Magoo
  • 77,302
  • 8
  • 62
  • 84
0

A simpler and proven method is to just copy the master frontend at each launch using a shortcut.

Update will be automatic, and errors from bloating or corruption of the frontend will be fixed just by a relaunch.

It requires a script to launch the application. That is described in full in my article:

Deploy and update a Microsoft Access application with one click

Gustav
  • 53,498
  • 7
  • 29
  • 55
  • Before I get excited about this and attempt to implement it, my concern is that this will be in a DOD site where IT heavily restricts certain automation. Especially access to the registry. In fact, I am kind of skeptical of using any batch script, so my original method was to first open another MS Access database that I call a 'Launcher' - for some reason, the DOD allows an MS Access database to run wscript.shell. But now I'm willing to try a .bat file. At any rate, thanks for the recomendation of Visual Studio Code. – plateriot Jan 11 '23 at 16:50
  • Originally, the method was thought out for a Citrix environment where it worked very well with zero assistance from the Citrix admins. – Gustav Jan 11 '23 at 17:45