Learn Microsoft Access Advanced Programming Techniques, Tips and Tricks.

No Data and Report Error

Report Source Query or Table can end up with no output records. In that case some of the controls with formula on the Report will show #Error on them. An image of a sample report is given below:

The #Error at the right top is a control that has a formula for showing the Period for which the Report is currently prepared for. The controls to the right of the word TOTAL are Sub-Totals and Totals of detail line values and all of them ended up with Errors because the underlying Query of the Report doesn't have any record to show for the current period selected by the User.

Even though this is not a serious issue if it became necessary to show this Report to some one as a NIL REPORT or printed and kept for future references leaving the controls with errors this way is not in good taste on the part of the Database Developer.

The modified version of the above Report is given below with a Comment, Summary Controls showing Zero Values and Report period printed correctly.

I have made few modifications to the Report Design to add a hidden label at the footer of the Report with the Caption: *** Congratulations *** Nothing Pending to show up when there is no output Records for the Report. The Visible Property of the label is set to No manually. On the Detail Section Under the Description Column shows *** NIL REPORT ***. The period for which the Report is prepared is also shown to the right, above the Detail Section headings.

Report Period (DateFrom and DateTo) are normally entered into a Parameter Table and joined with the Report Source Table in a Query to use them for criteria and for displaying on the Report.

I have created two Text Controls (with the name Frm and To respectively) at the Report Header Section to the right of the Control name STAFFNAME to load the DateFrom and DateTo Values from the Report Parameter Table with DLookup() Function:

=DLookUp("DateFrom","Report_Param")

Second Control have the expression to read DateTo from the Report_Param Table and both values are used in the expression (="Period : " & [frm] & " To " & [To]) to format the values to show the output as in the second image given above.

These are all cosmetic changes for the Report. The major change is to create a temporary table with a single blank record, with the same structure of the Source Table or Query that is attached to the Report. If your Report is using a Table as Report Source Data then make a copy of the structure of the Table and add a tmp_ prefix to the table name like tmp_myReport. If it is a Query then create a Make-Table Query using the Report Source Query and create a temporary table. Add a blank record in the temporary table. If your Report Table has a Text Field that is displaying value on the Report then type *** NIL REPORT *** in that field. Keep all other fields Empty.

The trick is, when the Report is open by the User we will check whether the original Report Source Table or Query have any record in it or not. If not swap the Temporary Table with the Report Source Table or Query. The hidden Label's Visible Property will be set to Yes to display the comment *** CONGRATULATIONS *** NOTHING PENDING. Since the temporary table has one blank record in it already, the Summary Controls will not end up with errors.

We need a few lines of VBA Code in the Report_Open() Event Procedure to check and swap the Report Source Table or Query.

Private Sub Report_Open(Cancel As Integer)
Dim ii = DCount("*", "myReport")
If i = 0 Then
   Me.RecordSource = "tmp_MyReport"
   Me.lblMsg.Visible = True
End If
End Sub

Copy the above lines of Code in the Report's VBA Module and make changes to insert the correct Table/Query and tmp_myReport names.

Share:

Lost Links of External Tables

We have already learned several methods to work with external data sources. By linking them to MS-Access Database or directly opening them in Queries by setting SourceDatabase and SourceConnectStr Properties. In either case the Source Data must be present in their original location all the time.

But, there is a possibility that the links to some of these tables can be lost either by deleting or renaming the source table by mistake. We will come to know about the error only when we attempt to work with the external tables and chances are that the error pops up in the middle of some process steps.

To alleviate this problem run a check on the linked tables as soon as the Database is open for normal operations. If any of the linked Tables is not in place then warn the User about it and shut down the Application if it has serious implications.

How do we determine whether a linked external table has lost its connection with the Database or not? It is easy, attempt to open the linked table and if it runs into error you can be sure that either it got deleted or name changed.

There may be several tables in a database, local as well as linked ones. How can we single out the linked ones alone and open them to check the status? Again this is not a big issue and you already have the answer if you have gone through the earlier Articles explaining several methods of accessing external data and usage of Connection Properties of Linked Tables and Queries.

We need a small VBA routine to iterate through the Table definitions and check the Connect Property value and if it is set with a Connect String then it is a linked table otherwise it is a local table. When we encounter a linked table we will attempt to open it to read data. If this process triggers an Error then we will prepare a list of such cases and display it at the end, to inform the User so that she can initiate appropriate remedial action to rectify the error.

A sample VBA routine is given below. Copy and paste the program in a Global Module and save it.

Public Function LostLinks()
'----------------------------------------------------
'Author : a.p.r. pillai
'URL    : www.msaccesstips.com
'Date   : 21/09/2008
'----------------------------------------------------
Dim msg As String, tbldef As TableDef
Dim strConnect As String, cdb As Database
Dim rst As Recordset, strTableName As String
Dim strDatabase As String, loc As Integer
Dim loc2 As Integer

On Error Resume Next

Set cdb = CurrentDb
For Each tbldef In cdb.TableDefs
    strConnect = tbldef.Connect

    If Len(strConnect) > 0 Then
       strTableName = tbldef.NAME
       Set rst = cdb.OpenRecordset(strTableName, dbOpenDynaset)
       If Err > 0 Then
          If Len(msg) = 0 Then
             msg = "The following Linked Tables are missing:" & vbCr & vbCr
          End If
          msg = msg & strTableName & vbCr
          Err.Clear
        End If
        rst.Close
    End If
Next

If Len(msg) > 0 Then
    MsgBox msg, , "LostLinks()"
End If

End Function

Call the Routine from an Autoexec Macro or from Form_Load() Event Procedure of the Application's Startup or Main Screen.

Share:

Link External Tables with VBA

We all know how to link a Table from external data sources manually.

  1. Highlight Get External Data from File Menu.
  2. Select Link Tables. . . from the displayed options.
  3. Select the file type (dBase, Excel etc.) in the Files of Type Control.
  4. Find the location of the File and select it.
  5. Click Link to attach the selected table to the Current Database.

If you are linking an external table from a Network Location, use the UNC (Universal Naming Conventions) type location reference (like \\hosfs03\accounts\myDatabase\. . .) rather than using a mapped drive location reference like H:\MyDatabase. You can even use your Local Drive's share name in this manner \\yourPCName\C$\Databases\myDatabase.mdb.

This method ensures that even if the drive mapping changes from H:\ to K:\ or anything else, MS-Access will have no difficulty in finding the linked Table. Otherwise you have to go for the Option Tools - ->Database Utilities - ->Linked Table Manager for refreshing the changed location reference of the table.

We have already seen that we can work with external tables without linking them permanently to the current database.

Here, we will try to link external Tables using VBA to the Current Database. After linking the table we will print the contents of five records into the Debug Window and delete the link.

We have to go through the following steps to link a Table to a Database with VBA:

  1. Create a temporary Table Definition (Tabledef) without any Field Definitions in the Current Database.
  2. Load the Connect Property of tabledef. with Connection String Value
  3. Link the external Table to the temporary Table definition (Tabledef)
  4. Add the temporary Table definition to the Tabledefs Group.
  5. Rename the temporary Table to match with the Source Table Name.

We will write two VBA Functions for our examples. Copy and Paste the following VBA Codes into a Global Module of your MS-Access Database and save them:

Public Function LinkMain()
Dim strConnection As String
Dim sourceTable As String

strConnection = ";DATABASE=D:\Program Files\Microsoft office\Office\Samples\Northwind.mdb;TABLE=Orders"

sourceTable = "Orders" 'Access Table Name

LinkExternal strConnection, sourceTable

End Function
Function LinkExternal(ByVal conString As String, sourceTable As String)
Dim db As Database, i As Integer, j As Integer
Dim linktbldef As TableDef, rst As Recordset

Set db = CurrentDb
Set linktbldef = db.CreateTableDef("tmptable") 'create temporary table definition

linktbldef.Connect = conString 'set the connection string
linktbldef.SourceTableName = sourceTable 'attach the source table
db.TableDefs.Append linktbldef 'add the table definition to the group
db.TableDefs.Refresh 'refresh the tabledefinitions

linktbldef.NAME = sourceTable 'rename the tmptable to original source table name

'open the recordset and print 5 records in the debug window
Set rst = db.OpenRecordset(sourceTable, dbOpenDynaset)
i = 0
Do While i < 5 And Not rst.EOF
  For j = 0 To rst.Fields.Count - 1
     Debug.Print rst.Fields(j).Value,
  Next: Debug.Print
  rst.MoveNext
  i = i + 1
Loop
rst.Close

db.TableDefs.Delete sourceTable 'remove to stay the table linked
db.Close
Set rst = Nothing
Set linktbldef = Nothing
Set db = Nothing

End Function

The first Program LinkMain() calls the LinkExternal() Sub Routine with strConnection and SourceTable name as parameters. Northwind.mdb sample database and Orders Table are passed as parameters. Open the Debug Window (Immediate Window) by pressing Ctrl+G. Click anywhere within the LinkMain() Program and press F5 to Run the Code and to print five records of Orders table from Northwind.mdb database.

The LinkExternal() Program performs the five steps of actions explained above.

Replace the strConnection and sourceTable with the following sample values for opening a dBase Table:

strConnection = "dBase IV;HDR=NO;IMEX=2;DATABASE=D:\msaccesstips"sourceTable = "Branches" 'Access Table Name

Tip: If you don't have a dBase Table to try the Code then Export a Table from MS-Access into dBase format and run the Code with changes.

Change the Database Folder name and the Table name with your own dBase Folder and Table names.

For Excel based Tables two methods are given below.

  1. Uses Worksheet Reference (Sheet1$) as source Table location. The $ symbol is necessary with the Worksheet name.:
    strConnection = "Excel 5.0;HDR=YES;IMEX=2;DATABASE=D:\msaccesstips\Branch.xls"sourceTable = "Sheet1$" 'Excel Sheet Name Reference
    

    The topmost row contents of the table area will be used as Field Names.

    strConnection = "Excel 5.0;HDR=YES;IMEX=2;DATABASE=D:\msaccesstips\Branch.xls"sourceTable = "BranchNames" 'Excel Range Name Reference
    
  2. Excel Range Name BranchNames will be used as Table location. The first line is same as above for this example also.
Share:

Source Connect Str Property and ODBC

We have already seen that the usage of SourceConnectStr Property combined with SourceDatabase Property of MS-Access Query can be used to open external data sources, like dBase, Foxpro (Version 2.5 or 3.0) and Excel Table, directly and work with them.

We have learned how to add the above Property specifications in an IN Clause directly in the SQL of the Query.

Data Source like AS400 (iSeries), SQL Server and Foxpro needs an ODBC (Open DataBase Connectivity) Connect String to get access to these System's data.

The best way to learn and understand more about the Connection String Syntax of different ODBC Data Sources is to go through the following steps and look at the Connection String of the Linked Table:

  1. Create an ODBC DSN (Data Source Name). Refer the Post Linking with IBM AS400 Tables.
  2. Link the Table from the source directly using File - - > Get External Data- ->Link Table.
  3. Select ODBC Databases in the Files of Type control.
  4. Select the ODBC DSN that you have created from the displayed List.
  5. Click OK. If you have not created a DSN you can create a new one by selecting the New. . . Command Button.
  6. Select the Table to link with your MS-Access Database.
  7. After linking the Table, select the linked Table.
  8. Select Design from the Database Menu. You will receive a Warning message saying that the Linked Table Structure cannot be modified. Click Yes to the Prompt: Do You want to open it anyway..?
  9. Display the Property Sheet (View - ->Properties).

On the Description Property of the Table Structure you will find the ODBC String that can be used directly on Query SourceConnectStr Property.

Few examples of ODBC Connection String Values are given below:

AS400 (iSeries) Table:
  • ODBC;DSN=myData;UID=UserID;PWD=Password;TABLE=PAVUP.APC161D
SQL Server:
  • ODBC;DSN=MyData;UID=UserID;PWD=Password;DATABASE=Parts
FoxPro:
  • ODBC;DSN=Visual Foxpro Tables;UID=;PWD=;SourceDB=C:\MyFoxpro;SourceType=DBF;Exclusive=No;BackgroundFetch=Yes;Collate=GENERAL;Null=Yes;Deleted=Yes

As you can see in the above examples that the DSN Name, User ID, Password and other details are Data Source specific and must be provided correctly to get access to their respective Tables.

In the AS400 (iSeries) ODBC Connection String above the Table Name and Folder Name is separated with a dot in between. You may refer the earlier Post Linking with IBM AS400 Tables to learn how to link AS400 (iSeries) Table to MS-Access Database.

Share:

Translate



PageRank
Your email address:

Delivered by FeedBurner

Search

Infolinks Text Ads


Blogs Directory

Popular Posts

Search This Blog

Blog Archive

Powered by Blogger.

Labels

Forms How Tos Functions MS-Access Security Reports msaccess forms Animations msaccess animation Utilities msaccess controls Access and Internet MS-Access Scurity MS-Access and Internet Queries External Links msaccess reports msaccess tips Menus and Toolbars Accesstips MsaccessLinks Process Controls Art Work Downloads msaccess How Tos Graph Charts msaccessQuery List Boxes Command Buttons Emails and Alerts Query Combo Boxes Custom Wizards DOS Commands ms-access functions msaccess functions msaccess graphs msaccess reporttricks msaccessprocess security advanced Access Security Array Custom Functions Data Macros Menus Property Report Top Values VBA msaccess email msaccess menus progressmeter Access2007 Auto-Number Command Button Copy Form Join Microsoft Numbering System Records Security Split SubForm Table Utility Variables Workgroup database msaccess wizards Access2003 Accounting Year Action Animation Attachment Binary Numbers Bookmarks Budgeting Calculation ChDir Color Palette Conditional Formatting Controls Data Filtering Data Type Defining Pages Diagram Disk Dynamic Lookup Error Handler Excel Export Expression External Field Type Fields Filter Form Instances Formatting Groups Hexadecimal Numbers Import Labels List Logo Macro Mail Merge Main Form Memo Methods Monitoring Object Reference Objects Octal Numbers Operating System Paste Primary-Key Product Rank Reading Recordset Rich Text Sequence SetFocus Summary Tab-Page Tables Time Difference Union Query User Users Water-Mark Word automatically commands function hyperlinks iSeries Date iif ms-access msaccess msaccess alerts pdf files reference restore switch text toolbar tutorial updating upload vba code

Featured Post

Function Parameter Array Passing

Last week we have explored the usage of ByVal (By Value) and ByRef (By Reference),  in the Function Parameter, to pass the value from  a Va...

Labels

Blog Archive

Recent Posts