Access MDB ,build a front end for SQL Server


Using Access to build a front end for SQL Server:

By Susan Harkins

Knowing your database system like the back of your hand is good, but only part of the battle. Coming up with an easy-to-use interface that your users can learn quickly is just as critical. Choosing the wrong tool for this process can leave you, the consultant who's supposed to know all the answers, looking somewhat incompetent. Burn users with a difficult-to-use or slow interface, and they'll toast your reputation.

You could spend a lot of time reinventing the wheel, or you could use Access—a relational database on its own. Unlike SQL Server, Access also offers a variety of development tools and controls for building a flexible and easy-to-use end product. Lots of developers depend on Access to build their front-end applications. Consider joining the ranks. You'll save time and your clients will save money. In this article, we'll discuss some of the advantages of using an Access Data Project as the front end to your SQL Server relational database.

What's an Access Data Project?
Over the years, Access has proven to be a useful front end for the big databases, even though you were limited to using pass-through queries or linked tables. Now you have the Access Data Project (ADP), which is much cleaner and easier to work with. An ADP is a specific Access file type that stores user objects such as forms, reports, macros, and Visual Basic for Applications (VBA) code modules. All the other objects—the tables, stored procedures, views, and so on—are stored on the database server. ADPs are strictly a Microsoft solution and, as such, won't function with any other relational database server except SQL Server—at least not directly.

You can continue to use Access with other relational databases using pass-through queries and linked tables; you just can't use an ADP to link to Oracle or DB2, for instance. A pass-through query allows you to speak to a non-SQL Server database.

Traditionally, a pass-through query is written in the server's native dialect and then passed to the server. You can often write more powerful queries using the native dialect of the database server being used. However, be careful, because pass-through queries are typically read-only.

When necessary, you can link Access to server tables. Unfortunately, linked tables require Open Database Connectivity (ODBC), which seems to be fading from the Microsoft communication strategy. Choose this option knowing you'll be using old technology that may not be fully supported in the future. In addition, linked tables return all records to the application, which kind of negates one of the main reasons for using a database server (returning only the data you request).

Why choose an ADP?
Many developers mistake Access for a true server database because you often find an Access database split into two files: one file contains the tables and the other file contains the interface objects. Despite what you see, Access is really a file-based database. Although you can use Access in a client-server environment, it wasn't designed as a server database.

In contrast to the original MDB file format, an ADP allows you to take advantage of the database server's power and stability in many ways:
  • Rapid Application Development (RAD) is possible using Access' graphical interface tools to develop the end-user application that interacts with SQL Server. For example, you can use the Query Builder to graphically construct stored procedures, functions, and views that act directly against SQL Server. In addition, you can quickly build your user interface forms using Access' form design graphical tools.
  • Processing is carried out by SQL Server on the database server, not in Access on the client side. As a result, you'll see a reduction in network traffic (as opposed to a split MDB).
  • Stored procedures use execution plans and are stored on the server. That means they're faster than Access queries.
  • Transact-SQL (T-SQL) provides procedural extensions to SQL, allowing you to build more sophisticated queries.
  • You can expand security by restricting SQL Server data that users can see and interact with via views or stored procedures.
  • SQL Server security is more robust than the security model Access offers. In addition, SQL Server security is inclusive of Windows' security, whereas Access security is totally on its own.
  • A more stable and powerful foundation for your SQL Server applications is provided in the form of Windows 2000 Advanced Server, an industrial-strength operating system (as compared to an MDB running on Windows).

How to create an ADP
You can use an ADP as a front end to SQL Server in three ways:
  1. Convert an MDB file to an ADP file, which will use SQL Server. All the data will be stored on SQL Server, but you'll still use Access' familiar interface to interact with the data. This choice requires a substantial investment in development time because you usually have to manually revamp forms, reports, queries, and so on.
  2. Keep your MDB file intact, but link to the server tables from inside the MDB. Doing so will use an ODBC link to the newly upsized tables on SQL Server. The resulting arrangement is slower than the previous one.
  3. Upsize data to SQL Server by creating an entirely new database on SQL Server without making changes to the actual MDB file.

Access provides all the tools you'll need for all three solutions—the Upsizing Wizard. The key to success, regardless of which route you take, is planning. Before attempting to upsize a database successfully, make a backup. Then, you may need to make a few adjustments:
  • SQL Server supports dates from Jan. 1, 1753, to Dec. 31, 9999. Access supports dates from Jan. 1, 100, to Dec. 31, 9999. You can't upsize Access tables that contain dates earlier than January 1, 1953.
  • Use saved queries as opposed to SQL statements as the data sources for Access objects. The wizard will create a corresponding SQL Server object for each saved query.
  • Remove spaces from object and field names.
  • Add at least one unique constraint or index to every table.
  • Some native functions, such as FORMAT(), won't upsize to SQL Server.

Once you're ready to begin, launch the MDB file in question, choose Database Utilities from the Tools menu, and then select Upsizing Wizard. The wizard gives you two choices: You can work with the existing database or create an entirely new database. Choosing the latter leaves the current MDB file intact, so you really end up with two databases when you're done.

The wizard will begin gathering information about the server you want to use, passwords and logins (when required), and the tables you want to upsize. Eventually, you'll reach the pane shown in Figure A. These three options correspond to the three front-end options we described at the beginning of this section. After making this final choice, you're done. The new ADP may need some work, but if you prepared properly, you should be up and running quickly.


Figure A
Choose a front-end solution for your SQL Server tables.

Split your Access database


Split your Access database into data and application

Even if all your data is in Access itself, consider using linked tables. Store all the data tables in one MDB or ACCDB file - the data file - and the remaining objects (queries, forms, reports, macros, and modules) in a second MDB - the application file. In multi-user situations, each user receives a local copy of the application file, linked to the tables in the single remote data file.

Why split?

There are significant advantages to splitting your application:
  • Maintenance: To update the program, just replace the application file. Since the data is in a separate file, no data is overwritten.
  • Network Traffic: Loading the entire application (forms, controls, code, etc) across the network increases traffic making your interface slower.
Access includes an Add-In to perform the split:
Access 95 - 97 Tools | Add-Ins | Database Splitter
Access 2000 - 2003 Tools | Database Utilities | Database Splitter
Access 2007 - 2010 Database Tools | Move Data | Access Back-End
In some cases you will link additional files:
  • Static look-up data such as postal codes might be kept in its own file.
  • Linked temporary tables might avoid the need to compact the application file.

Is the Data present?

Once split, the data may be unavailable to the application. This happens if the network is down, the data file is moved, or folder/network names are altered.
For a single-user set-up where the application and data files are in the same folder, see Peter Vukovic's tip:

Function Reconnect ()
'**************************************************************
'*     START YOUR APPLICATION (MACRO: AUTOEXEC) WITH THIS FUNCTION
'*     AND THIS PROGRAM WILL CHANGE THE CONNECTIONS AUTOMATICALLY
'*     WHEN THE 'DATA.MDB'  AND THE 'PRG.MDB'
'*     ARE IN THE SAME DIRECTORY!!!
'*                  PROGRAMMING BY PETER VUKOVIC, Germany
'*                  100700.1262@compuserve.com
'* ************************************************************
Dim db As Database, source As String, path As String
Dim dbsource As String, i As Integer, j As Integer

Set db = dbengine.Workspaces(0).Databases(0)
'*************************************************************
'*                     RECOGNIZE THE PATH                    *
'*************************************************************

For i = Len(db.name) To 1 Step -1
    If Mid(db.name, i, 1) = Chr(92) Then
        path = Mid(db.name, 1, i)
        'MsgBox (path)
        Exit For
    End If
Next
'*************************************************************
'*              CHANGE THE PATH   AND   CONNECT  AGAIN       *
'*************************************************************

For i = 0 To db.tabledefs.count - 1
    If db.tabledefs(i).connect <> " " Then
        source = Mid(db.tabledefs(i).connect, 11)
        'Debug.Print source
        For j = Len(source) To 1 Step -1
            If Mid(source, j, 1) = Chr(92) Then
               dbsource = Mid(source, j + 1, Len(source))
               source = Mid(source, 1, j)
                   If source <> path Then
                        db.tabledefs(i).connect = ";Database=" + path + dbsource
                        db.tabledefs(i).RefreshLink
                        'Debug.Print ";Database=" + path + dbsource
                    End If
                Exit For
            End If
         Next
    End If
Next
End Function

If the files are in different folders (e.g. across a network), see Dev Ashish's article:
 

(Q)    In my Front end database, I have several linked tables from multiple back end databases.  How can I make sure that all tables get connected when the front end is opened?
(A)    You can go through the TableDefs collection to see which tables have the Connect property set.  If Connect is populated, reconnect the table using the database specified in the string.
    Here's a function (fRefreshLinks) that could be run at db startup.  The function looks at each table in the database in which the code is running, and tries to find the datasource for that table if the Connect property is populated.
    If the database specified for the linked table is not present, the code brings up the GetOpenFileName dialog so that the user can select an alternative source. Note: You must include that code in your application for this example to work
'***************** Code Start ***************
' This code was originally written by Dev Ashish.
' It is not to be altered or distributed,
' except as part of an application.
' You are free to use it in any application,
' provided the copyright notice is left unchanged.
'
' Code Courtesy of
' Dev Ashish
'
Function fRefreshLinks() As Boolean
Dim strMsg As String, collTbls As Collection
Dim i As Integer, strDBPath As String, strTbl As String
Dim dbCurr As DATABASE, dbLink As DATABASE
Dim tdfLocal As TableDef
Dim varRet As Variant
Dim strNewPath As String

Const cERR_USERCANCEL = vbObjectError + 1000
Const cERR_NOREMOTETABLE = vbObjectError + 2000

    On Local Error GoTo fRefreshLinks_Err

    If MsgBox("Are you sure you want to reconnect all Access tables?", _
            vbQuestion + vbYesNo, "Please confirm...") = vbNo Then Err.Raise cERR_USERCANCEL

    'First get all linked tables in a collection
    Set collTbls = fGetLinkedTables

    'now link all of them
    Set dbCurr = CurrentDb

    strMsg = "Do you wish to specify a different path for the Access Tables?"
    
    If MsgBox(strMsg, vbQuestion + vbYesNo, "Alternate data source...") = vbYes Then
        strNewPath = fGetMDBName("Please select a new datasource")
    Else
        strNewPath = vbNullString
    End If

    For i = collTbls.Count To 1 Step -1
        strDBPath = fParsePath(collTbls(i))
        strTbl = fParseTable(collTbls(i))
        varRet = SysCmd(acSysCmdSetStatus, "Now linking '" & strTbl & "'....")
        If Left$(strDBPath, 4) = "ODBC" Then
            'ODBC Tables
            'ODBC Tables handled separately
           ' Set tdfLocal = dbCurr.TableDefs(strTbl)
           ' With tdfLocal
           '     .Connect = pcCONNECT
           '     .RefreshLink
           '     collTbls.Remove (strTbl)
           ' End With
        Else
            If strNewPath <> vbNullString Then
                'Try this first
                strDBPath = strNewPath
            Else
                If Len(Dir(strDBPath)) = 0 Then
                    'File Doesn't Exist, call GetOpenFileName
                    strDBPath = fGetMDBName("'" & strDBPath & "' not found.")
                    If strDBPath = vbNullString Then
                        'user pressed cancel
                        Err.Raise cERR_USERCANCEL
                    End If
                End If
            End If

            'backend database exists
            'putting it here since we could have
            'tables from multiple sources
            Set dbLink = DBEngine(0).OpenDatabase(strDBPath)

            'check to see if the table is present in dbLink
            strTbl = fParseTable(collTbls(i))
            If fIsRemoteTable(dbLink, strTbl) Then
                'everything's ok, reconnect
                Set tdfLocal = dbCurr.TableDefs(strTbl)
                With tdfLocal
                    .Connect = ";Database=" & strDBPath
                    .RefreshLink
                    collTbls.Remove (.Name)
                End With
            Else
                Err.Raise cERR_NOREMOTETABLE
            End If
        End If
    Next
    fRefreshLinks = True
    varRet = SysCmd(acSysCmdClearStatus)
    MsgBox "All Access tables were successfully reconnected.", _
            vbInformation + vbOKOnly, _
            "Success"

fRefreshLinks_End:
    Set collTbls = Nothing
    Set tdfLocal = Nothing
    Set dbLink = Nothing
    Set dbCurr = Nothing
    Exit Function
fRefreshLinks_Err:
    fRefreshLinks = False
    Select Case Err
        Case 3059:

        Case cERR_USERCANCEL:
            MsgBox "No Database was specified, couldn't link tables.", _
                    vbCritical + vbOKOnly, _
                    "Error in refreshing links."
            Resume fRefreshLinks_End
        Case cERR_NOREMOTETABLE:
            MsgBox "Table '" & strTbl & "' was not found in the database" & _
                    vbCrLf & dbLink.Name & ". Couldn't refresh links", _
                    vbCritical + vbOKOnly, _
                    "Error in refreshing links."
            Resume fRefreshLinks_End
        Case Else:
            strMsg = "Error Information..." & vbCrLf & vbCrLf
            strMsg = strMsg & "Function: fRefreshLinks" & vbCrLf
            strMsg = strMsg & "Description: " & Err.Description & vbCrLf
            strMsg = strMsg & "Error #: " & Format$(Err.Number) & vbCrLf
            MsgBox strMsg, vbOKOnly + vbCritical, "Error"
            Resume fRefreshLinks_End
    End Select
End Function

Function fIsRemoteTable(dbRemote As DATABASE, strTbl As String) As Boolean
Dim tdf As TableDef
    On Error Resume Next
    Set tdf = dbRemote.TableDefs(strTbl)
    fIsRemoteTable = (Err = 0)
    Set tdf = Nothing
End Function

Function fGetMDBName(strIn As String) As String
'Calls GetOpenFileName dialog
Dim strFilter As String

    strFilter = ahtAddFilterItem(strFilter, _
                    "Access Database(*.mdb;*.mda;*.mde;*.mdw) ", _
                    "*.mdb; *.mda; *.mde; *.mdw")
    strFilter = ahtAddFilterItem(strFilter, _
                    "All Files (*.*)", _
                    "*.*")

    fGetMDBName = ahtCommonFileOpenSave(Filter:=strFilter, _
                                OpenFile:=True, _
                                DialogTitle:=strIn, _
                                Flags:=ahtOFN_HIDEREADONLY)
End Function

Function fGetLinkedTables() As Collection
'Returns all linked tables
    Dim collTables As New Collection
    Dim tdf As TableDef, db As DATABASE
    Set db = CurrentDb
    db.TableDefs.Refresh
    For Each tdf In db.TableDefs
        With tdf
            If Len(.Connect) > 0 Then
                If Left$(.Connect, 4) = "ODBC" Then
                '    collTables.Add Item:=.Name & ";" & .Connect, KEY:=.Name
                'ODBC Reconnect handled separately
                Else
                    collTables.Add Item:=.Name & .Connect, Key:=.Name
                End If
            End If
        End With
    Next
    Set fGetLinkedTables = collTables
    Set collTables = Nothing
    Set tdf = Nothing
    Set db = Nothing
End Function

Function fParsePath(strIn As String) As String
    If Left$(strIn, 4) <> "ODBC" Then
        fParsePath = Right(strIn, Len(strIn) _
                        - (InStr(1, strIn, "DATABASE=") + 8))
    Else
        fParsePath = strIn
    End If
End Function

Function fParseTable(strIn As String) As String
    fParseTable = Left$(strIn, InStr(1, strIn, ";") - 1)
End Function
'***************** Code End ***************



Another Interesting Topics:Armen Stein has released a relinker that supports linking to multiple back ends :J Street Access Relinker

How to compact/compressing mdb file

This one should try'n to do when your acces to MDB database file gettin slow

in vba code:
    CommandBars("Menu Bar").Controls ("Tools") & _
    .Controls("Database utilities") & _
    .Controls("Compact and repair database...").accDoDefaultAction

by utility:
  • Run Microsoft Visual Basic® for Applications (VBA) code that uses the CompactDatabase method of either Microsoft Jet and Replication Objects (JRO) or Microsoft Data Access Objects (DAO).
Sometimes, these utilities will fail. Microsoft Product Support Services provides an additional, unsupported database-compacting utility named the Jet Compact Utility (Jetcomp.exe), which might be able to recover some databases that the standard compacting utilities cannot. This is because the standard utilities attempt to open and close a database before compacting it. If these utilities cannot reopen the database, compacting cannot proceed, and the database cannot be recovered. The Jet Compact Utility does not attempt to open and close the database before compacting, and may be able to recover some damaged databases that the standard utilities cannot.

DownLoad Jetcomp.Exe Now