<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LEARN MS-ACCESS TIPS AND TRICKS</title>
	<atom:link href="http://msaccesstips.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://msaccesstips.com</link>
	<description>Free MS-Access downloads</description>
	<lastBuildDate>Tue, 15 May 2012 19:35:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>ChDir and IN Clause of Access Query</title>
		<link>http://msaccesstips.com/2012/05/chdir-and-in-clause-of-access-query/</link>
		<comments>http://msaccesstips.com/2012/05/chdir-and-in-clause-of-access-query/#comments</comments>
		<pubDate>Mon, 14 May 2012 10:01:38 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Functions]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2335</guid>
		<description><![CDATA[Last week we have learned how to change the Directory Path control of VBA to the CurrentProject.Path (active database’s location) with the use of ChDrive() and ChDir() Commands, without altering the Default Database Folder settings under Access Options. If you don’t like to use DOS commands then you can change the Default Database Folder setting [...]]]></description>
			<content:encoded><![CDATA[<p>Last week we have learned how to change the Directory Path control of VBA to the <strong>CurrentProject.Path</strong> (active database’s location) with the use of <strong><a href="http://msaccesstips.com/2012/05/microsoft-dos-commands-in-vba-2/">ChDrive() and ChDir()</a></strong><strong></strong> Commands, without altering the <strong>Default Database Folder</strong> settings under <strong>Access Options</strong>.</p>
<p>If you don’t like to use DOS commands then you can change the <strong>Default Database Folder </strong>setting with the following VBA Statement:</p>
<pre class="alt1">

Application.SetOption &quot;Default Database Directory&quot;, &quot;C:\Developers\Project&quot;
</pre>
<p>The above statement will change the <strong>Default Database Folder</strong> to the location specified in the second <a href="http://www.msaccesstips.com/2008/10/multiple-parameters-for-query/">parameter</a>. The next example changes the <strong>Default Database Folder</strong> to the active database&#8217;s location:</p>
<pre class="alt1">

Application.SetOption &quot;Default Database Directory&quot;, CurrentProject.Path
</pre>
<p>You can execute the above <a href="http://msaccesstips.com/2011/10/easy-reference-access2003-commands-in-access2007/">commands</a> directly in the Debug Window. After executing any of the above commands you may open <strong>Access Options</strong> from <strong>Office Buttons</strong> and check the <strong>Default Database Folder</strong> control value under the <strong>Popular</strong> options group.</p>
<p>We have already discussed earlier about Updating/Appending data into <a href="http://www.msaccesstips.com/2008/07/opening-external-data-sources/">external Database</a> Tables (external Tables of Access, <a href="http://www.msaccesstips.com/2008/07/opening-dbase-files-directly/">dBase</a> etc. not linked to the active Access Database)&#160; by using the <strong>IN</strong> Clause in Queries.&#160; You will find that Article <a href="http://msaccesstips.com/2011/10/adding-data-directly-into-external-databases/">here</a> to refresh your memory. </p>
<p>If you have Queries in your Databases that <a href="http://www.msaccesstips.com/2009/03/ms-access-and-reference-library/">references</a> Tables in external databases to Update or Append data into them, like the sample SQL given below, it is time to take a relook at them to avoid unexpected side effects.</p>
<pre class="alt1">

INSERT INTO Employees (EmployeeID, LastName ) IN 'C:\Developers\Projects\Northwind.mdb'
SELECT 100221 AS EID, &quot;John&quot; AS LN;

</pre>
<p>If external or backend database is on a common location on Local Area Network (LAN) Server, serviced by several front-end databases from client machines that itself is asking for separate treatment of the whole issue which we will look at them later, probably next Week. I don&#8217;t want to mix them up here and confuse you.</p>
<p>Coming back to the IN Clause in the above SQL, if the external <a href="http://www.msaccesstips.com/2008/05/database-daily-backup/">database</a> and the current database is on the same Folder then you can omit the lengthy Pathname in the external database reference, like the modified SQL given below:</p>
<pre class="alt1">

INSERT INTO Employees (EmployeeID, LastName ) IN 'Northwind.mdb'
SELECT 100221 AS EID, &quot;John&quot; AS LN;

</pre>
<p>The main advantage of writing the IN Clause in this way is that you don&#8217;t have to change the PathName in all SQLs of Queries on location change of your application. The down side is that you have to ensure that the <strong>Default Database Folder</strong> location changes to the active database&#8217;s folder, otherwise the <a href="http://www.msaccesstips.com/2008/02/percentage-on-total-query/">Queries</a> will look for the external database in the old location for updating/appending data.&#160; You can do this, either using the <strong>SetOption </strong>method or using the <strong>ChDir()</strong> <a href="http://www.msaccesstips.com/2008/03/double-action-command-button/">Command</a>. Both methods are given below for reference:</p>
<p><b>SetOption Method:</b></p>
<pre class="alt1">

SetOption &quot;Default Database Directory&quot;, CurrentProject.Path
</pre>
<p>This method permanently changes the <strong>Default Database Folder</strong> control value in the <strong>Access Options</strong> area and remains intact till it is changed again.&#160; This is a global change to Access Options and may affect other <a href="http://www.msaccesstips.com/2008/06/database-open-close-event-alerts/">databases</a> when they are open.</p>
<p><b>ChDir() Method:</b></p>
<pre>Public Function ChangeDir()
Dim vDrive As String * 1, sysPath As String

'get current database Path
  sysPath = CurrentProject.Path

'extract the drive letter alone
'vDrive Variable is dimensioned to hold only one character
  vDrive = sysPath 

'change control to the Drive
  ChDrive vDrive 

'change current location to the database path
  ChDir sysPath 

End Function</pre>
<p>This method is harmless because the change is temporary and the <strong>Default Database Folder</strong> global setting remains intact. You can use the above Code in databases that requires this Function.&#160; </p>
<p>One of these methods must be run immediately on opening the database, either through an <strong>Autoexec</strong> Macro with the <strong>RunCode</strong> Action or through the <strong>Form_Load()</strong> Event Procedure of the first <a href="http://www.msaccesstips.com/2009/02/synchronized-floating-popup-form/">Form</a> opened.</p>
<ul>
<li><a href="http://msaccesstips.com/2011/10/access-security-key-diagram/">Access Security Key Diagram</a> </li>
<li><a href="http://msaccesstips.com/2011/10/updating-sub-form-recordset-from-main-form/">Updating Sub-Form Recordset from Main Form</a> </li>
<li><a href="http://msaccesstips.com/2011/10/easy-reference-access2003-commands-in-access2007/">Easy Reference: Access2003 Commands in Access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/09/iif-vs-switch-function-in-ms-access/">IIF vs Switch function in MS-Access</a> </li>
<li><a href="http://msaccesstips.com/2011/09/preparing-rank-list/">Preparing Rank List</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/05/chdir-and-in-clause-of-access-query/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft DOS Commands in VBA-2</title>
		<link>http://msaccesstips.com/2012/05/microsoft-dos-commands-in-vba-2/</link>
		<comments>http://msaccesstips.com/2012/05/microsoft-dos-commands-in-vba-2/#comments</comments>
		<pubDate>Sat, 05 May 2012 18:41:39 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Functions]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2312</guid>
		<description><![CDATA[With the MkDir() Command we were able to create a folder on disk, with the help of a small VBA routine that we have written last week.&#160; We don’t even need a separate program to do this, we can directly execute this command from the Debug Window, like the following example: MkDir &#34;C:\Developers\Projects&#34; The only [...]]]></description>
			<content:encoded><![CDATA[<p>With the <a href="http://msaccesstips.com/2012/04/microsoft-dos-commands-in-vba/">MkDir() Command</a> we were able to create a folder on disk, with the help of a small VBA routine that we have written <a href="http://msaccesstips.com/2012/04/microsoft-dos-commands-in-vba/">last week</a>.&#160; We don’t even need a separate program to do this, we can directly execute this command from the Debug Window, like the following example:</p>
<pre class="alt1">

MkDir &quot;C:\Developers\Projects&quot;
</pre>
<p>The only disadvantage of this method is that we cannot perform a validation check before executing this command.&#160; In the <a href="http://msaccesstips.com/2011/12/prepare-a-list-of-procedure-names-from-a-module/">VBA program</a> we have included the validation checks.&#160; That program uses constant values as Path, and with few modifications this program can be further improved to accept the Path string as <a href="http://www.msaccesstips.com/2008/10/multiple-parameters-for-query/">Parameter</a> to the <strong>CreateFolder()</strong> Function.&#160; The Code with improvements is given below:</p>
<p><!--INFOLINKS_OFF--></p>
<pre>Public Function CreateFolder(ByVal folderPath As String)

Dim msgtxt As String, folderName As String

'extract the new Folder Name from the folderPath Parameter
folderName = Right(folderPath, Len(folderPath) - InStrRev(folderPath, &quot;\&quot;))

'check for the new folder name, if not found proceed to create it
If Dir(folderPath, vbDirectory) = &quot;&quot; Then
   msgtxt = &quot;Create new Folder: &quot; &amp; folderPath &amp; vbCr &amp; &quot;Proceed ...?&quot;
   If MsgBox(msgtxt, vbYesNo + vbDefaultButton1 + vbQuestion, &quot;CreateFolder()&quot;) = vbNo Then
      Exit Function
   End If
   MkDir folderPath 'try to create the new folder

'check whether the folder creation was successful or not
   If Dir(folderPath, vbDirectory) = folderName Then
      msgtxt = folderPath &amp; vbCr &amp; &quot;Created successfully.&quot;
      MsgBox msgtxt
   Else
'if the code execution enters here then something went wrong
      msgtxt = &quot;Something went wrong,&quot; &amp; vbCr &amp; &quot;Folder creation was not successful.&quot;
      MsgBox msgtxt
   End If
Else
  'the validation check detected the presence of the folder
   msgtxt = folderPath &amp; vbCr &amp; &quot;Already exists.&quot;
   MsgBox msgtxt
End If

End Function</pre>
<p><!--INFOLINKS_ON--></p>
<p>In all the above and earlier examples we have provided the full path of the existing location, where we need the new folder to be created, with the new folder name at the end.&#160; If you are sure where the current location is (or active location of the current database on disk) then you can issue the MkDir() command with the new folder name alone, like the following example:</p>
<pre class="alt1">

MkDir &quot;Projects&quot;
</pre>
<p>As far as <a href="http://msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/">VBA</a> is concerned the current location is not what you have selected using the Windows Explorer. Or the one you have selected using DOS Command <strong>ChDir()</strong> run directly under the DOS <a href="http://www.msaccesstips.com/2009/01/command-button-animation-2/">Command</a> Prompt.</p>
<p>But, with a small trick we can find out which is the current folder that VBA is aware of, that is by running the <strong>Shell()</strong> command directly from the Debug Window to invoke the DOS Command Prompt from VBA, like the example given below:</p>
<pre class="alt1">

Call Shell(&quot;cmd.exe&quot;)
</pre>
<p>The above command will open the DOS <a href="http://www.msaccesstips.com/2008/04/colorfull-command-buttons/">Command</a> Prompt (if it is minimized on the task bar then click on it to make that window current), the Cursor will be positioned in the current folder. Check the sample image given below:</p>
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/dos_prompt.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DOS Prompt" border="0" alt="DOS Prompt" src="http://www.msaccesstips.com/uploaded_images/dos_prompt_thumb.jpg" width="290" height="175" /></a></p>
<p><!-- Uploaded_images--></p>
<p>If you have used <strong>MkDir &quot;Projects&quot;</strong> like command without knowing where it is going to be created then type <strong>Dir</strong> and press <strong>Enter</strong> Key to display a list of files and directory names with the label <strong>&lt;Dir&gt;</strong> to indicate they are folders.</p>
<p>That doesn’t mean that the above method is the only option to check the Default Database Folder location.&#160; Select <strong>Access Options</strong> from <strong>Office Button </strong>and select the<strong> Popular </strong>Option Group<strong>(Access2007) </strong>and you can see the <strong>Default Database Folder</strong> settings there.&#160; Check the image given below:</p>
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/access_options.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Access Options &#13;&#13;&#10;Dialog" border="0" alt="Access Options Dialog" src="http://www.msaccesstips.com/uploaded_images/access_options_thumb.jpg" width="374" height="231" /></a></p>
<p><!-- Uploaded_images--></p>
<p>Try to open a database from some other location on disk, but this setting will not change and the Default <a href="http://www.msaccesstips.com/2008/05/database-daily-backup/">Database</a> Folder will remain active as per this setting.&#160; Without touching the above Access default setting we can change the active folder to the newly opened database’s parent directory with the use of the following DOS Commands from VBA (you can try this by typing these commands directly on the Debug Window):</p>
<pre class="alt1">

? CurrentProject.Path
</pre>
<p>This is not DOS Command, but the above VBA statement retrieves the active database&#8217;s Path. Let us assume that the retrieved location of the current database is: <strong>C:\MDBS</strong></p>
<p>Using the above information in the next two DOS Commands we can change the control to the active database&#8217;s location, without changing the <strong>Default Database Path</strong> setting, we have seen earlier:</p>
<pre class="alt1">

ChDrive &quot;C&quot; 'change control to C: Drive.  This is necessary if control was on a different drive
ChDir CurrentProject.Path 'change control to the active database's folder
</pre>
<p>By combining the above statements we can write a very useful Function <strong>ChangeDir() </strong>to change the control to the current <a href="http://www.msaccesstips.com/2008/06/repairing-compacting-database-with-vba/">Database</a> Folder.&#160; Copy and Paste the following Code into a Standard <a href="http://msaccesstips.com/2012/03/centralized-error-handler-and-error-log/">Module</a> of your Database and save it:</p>
<pre>Public Function ChangeDir()
Dim vDrive As String * 1, sysPath As String

'get current database Path
  sysPath = CurrentProject.Path

'extract the drive letter alone
'vDrive Variable is dimensioned to hold only one character
  vDrive = sysPath 

'change control to the Drive
  ChDrive vDrive 

'change current location to the database folder
  ChDir sysPath 

End Function</pre>
<p>Call the above <a href="http://www.msaccesstips.com/2007/09/useful-report-functions/">Function</a> from an <strong>Autoexec </strong>macro with the <strong>RunCode</strong> Action or from the <strong>Form_Load() </strong>Event Procedure of the first Form open (like the Startup Screen or Main Switchboard) to change control to the active database folder. </p>
<ul>
<li><a href="http://msaccesstips.com/2011/10/updating-sub-form-recordset-from-main-form/">Updating Sub-Form Recordset from Main Form</a> </li>
<li><a href="http://msaccesstips.com/2011/10/easy-reference-access2003-commands-in-access2007/">Easy Reference: Access2003 Commands in Access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/09/iif-vs-switch-function-in-ms-access/">IIF vs Switch function in MS- Access</a> </li>
<li><a href="http://msaccesstips.com/2011/09/preparing-rank-list/">Preparing Rank List</a> </li>
<li><a href="http://msaccesstips.com/2011/08/restoring-disabled-full-menus-access2007/">Restoring Disabled Full Menus Access2007</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/05/microsoft-dos-commands-in-vba-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft DOS Commands in VBA</title>
		<link>http://msaccesstips.com/2012/04/microsoft-dos-commands-in-vba/</link>
		<comments>http://msaccesstips.com/2012/04/microsoft-dos-commands-in-vba/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 12:27:46 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Functions]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2290</guid>
		<description><![CDATA[Continued from last week’s Article: Disk Operating System Commands in VBA. Once we determine the presence of a file in a folder with the Dir() Command we can do certain operations on the file, like opening that file in it’s parent application through the Shell() Command or make a copy of that file to a [...]]]></description>
			<content:encoded><![CDATA[<p>Continued from last week’s Article: <a href="http://msaccesstips.com/2012/04/disk-operating-system-commands-in-vba/">Disk Operating System Commands in VBA</a>.</p>
<p>Once we determine the presence of a file in a folder with the <strong>Dir()</strong> Command we can do certain operations on the file, like opening that file in it’s parent application through the <strong>Shell()</strong> <a href="http://www.msaccesstips.com/2008/04/transparent-command-button/">Command</a> or make a copy of that file to a different location with the <strong>FileCopy()</strong> Command or delete it with the <strong>Kill()</strong> Command.</p>
<p>Example-1: Check for the presence of a text file in a folder and if found open it in <strong>Notepad.exe</strong></p>
<p> <!--INFOLINKS_OFF-->
<pre class="alt-3">Public Function OpenTextFile()
Dim txtFilePath As String
Dim NotePad As String

   txtFilePath = &quot;C:\msaccesstips\htaccess.txt&quot;
   NotePad = &quot;C:\Windows\System32\Notepad.exe&quot;

If Dir(txtFilePath, vbNormal) = &quot;htaccess.txt&quot; Then
   Call Shell(NotePad &amp; &quot; &quot; &amp; txtFilePath, vbNormalFocus)
Else
   MsgBox &quot;File: &quot; &amp; txtFilePath &amp; vbcr &amp; &quot;Not Found...!&quot;
End If

End Function</pre>
<p><!--INFOLINKS_ON--></p>
<p>Example-2: Make a copy of the file with the FileCopy() Command.</p>
<p><!--INFOLINKS_OFF--></p>
<pre class="alt-3">Public Function CopyTextFile()
Dim SourcefilePath As String
Dim TargetFilePath As String

   SourcefilePath = &quot;C:\msaccesstips\htaccess.txt&quot;
   TargetFilePath = &quot;C:\New Folder\htaccess.txt&quot;

If Dir(SourcefilePath, vbNormal) = &quot;htaccess.txt&quot; Then
   FileCopy SourcefilePath, TargetFilePath
   MsgBox &quot;File copy complete.&quot;

Else
   MsgBox &quot;File Not Found...!&quot;
End If

End Function</pre>
<p><!--INFOLINKS_ON--></p>
<p>Example-3: Find and Delete a File from specific location on Hard Disk.</p>
<p><!--INFOLINKS_OFF--></p>
<pre class="alt-3">Public Function DeleteFile()
Dim FilePath As String, msgtxt As String

   FilePath = &quot;C:\New Folder\htaccess.txt&quot;

If Dir(FilePath, vbNormal) = &quot;htaccess.txt&quot; Then
   msgtxt = &quot;Delete File: &quot; &amp; FilePath &amp; vbCr &amp; vbCr
   msgtxt = msgtxt &amp; &quot;Proceed...?&quot;
   If MsgBox(msgtxt, vbYesNo + vbDefaultButton2 + vbQuestion, &quot;DeleteFile()&quot;) = vbNo Then
      Exit Function
   End If
   Kill FilePath
   MsgBox &quot;File: &quot; &amp; FilePath &amp; vbCr &amp; &quot;Deleted from Disk.&quot;

Else
   MsgBox &quot;File: &quot; &amp; FilePath &amp; vbCr &amp; &quot;Not Found...!&quot;
End If

End Function</pre>
<p><!--INFOLINKS_ON--></p>
<p>Dir() <a href="http://www.msaccesstips.com/2007/09/useful-report-functions/">Function</a> also can be used for checking the presence of a folder in preparation for creating a new folder in a particular location on the Hard Drive.</p>
<p>The following Command checks for the presence of a particular folder on C: drive:</p>
<p>strOut =&#160; Dir(&quot;C:\Developers\Projects&quot;, vbDirectory)</p>
<p>The second parameter <strong>vbDirectory</strong> tells the Dir() command what to look for and if the folder <strong>Projects</strong> found under <strong>C:\Developers</strong> folder, then the folder name <strong>Projects</strong> returned in the <strong>strOut</strong> variable, otherwise returns an empty string.</p>
<p>The <strong>MkDir()</strong> <a href="http://www.msaccesstips.com/2008/04/colorfull-command-buttons/">Command</a> can be used for creating a new folder if the <strong>Projects</strong> folder doesn’t exists.</p>
<p>Let us write a small program to check the presence of <strong>Projects</strong> folder and if it doesn’t exists then let us create the folder.</p>
<p><!--INFOLINKS_OFF--></p>
<pre>Public Function CreateFolder()
Dim folderPath As String
Dim msgtxt As String

folderPath = &quot;C:\Developers\Projects&quot;

If Dir(folderPath, vbDirectory) = &quot;&quot; Then
   msgtxt = &quot;Create new Folder: &quot; &amp; folderPath &amp; vbCr &amp; &quot;Proceed ...?&quot;
   If MsgBox(msgtxt, vbYesNo + vbDefaultButton1 + vbQuestion, &quot;CreateFolder()&quot;) = vbNo Then
      Exit Function
   End If
   MkDir folderPath
   If Dir(folderPath, vbDirectory) = &quot;Projects&quot; Then
      msgtxt = folderPath &amp; vbCr &amp; &quot;Created successfully.&quot;
      MsgBox msgtxt
   Else
      msgtxt = &quot;Something went wrong,&quot; &amp; vbCr &amp; &quot;Folder creation was not successful.&quot;
      MsgBox msgtxt
   End If
Else
   msgtxt = folderPath &amp; vbCr &amp; &quot;Already exists.&quot;
   MsgBox msgtxt
End If

End Function</pre>
<p><!--INFOLINKS_ON--></p>
<p><strong>Dir()</strong> Command can be used to check the Volume <a href="http://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins/" rel="nofollow" target="_blank">label</a> of a Disk Drive.</p>
<p>The following <a href="http://www.msaccesstips.com/2008/03/double-action-command-button/">command</a>, run directly from the Debug window, gets the <strong>Volume Label</strong> of the Hard Drive, if exists, otherwise returns an empty string:</p>
<p>? Dir(&quot;D:&quot;, vbVolume)</p>
<p>Result: RECOVERY</p>
<ul>
<li><a href="http://msaccesstips.com/2011/10/updating-sub-form-recordset-from-main-form/">Updating Sub-Form Recordset from Main Form</a> </li>
<li><a href="http://msaccesstips.com/2011/10/easy-reference-access2003-commands-in-access2007/">Easy Reference: Access2003 Commands in Access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/09/iif-vs-switch-function-in-ms-access/">IIF vs Switch function in MS- Access</a> </li>
<li><a href="http://msaccesstips.com/2011/09/preparing-rank-list/">Preparing Rank List</a> </li>
<li><a href="http://msaccesstips.com/2011/08/restoring-disabled-full-menus-access2007/">restoring Disabled Full Menus in Access2007</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/04/microsoft-dos-commands-in-vba/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Disk Operating System Commands in VBA</title>
		<link>http://msaccesstips.com/2012/04/disk-operating-system-commands-in-vba/</link>
		<comments>http://msaccesstips.com/2012/04/disk-operating-system-commands-in-vba/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 10:40:37 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Functions]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2287</guid>
		<description><![CDATA[The first edition of Microsoft Disk Operating System (MS-DOS 1.0) was launched in 1982.&#160; The first edition of Microsoft Windows 1.0 Operating System, Disk Operating system with Graphical User Interface (GUI), released on November 20, 1985 – Source: www.wikipedia.org.&#160; The Disk operating System Version under Windows7 is 6.1.7600. Disk Operating System Commands (both Internal and [...]]]></description>
			<content:encoded><![CDATA[<p>The first edition of Microsoft Disk Operating System (MS-DOS 1.0) was launched in 1982.&#160; The first edition of Microsoft Windows 1.0 Operating System, Disk Operating system with Graphical User Interface (GUI), released on November 20, 1985 – Source: <a href="http://en.wikipedia.org/wiki/Windows_1.0">www.wikipedia.org</a>.&#160; The Disk operating System Version under <strong>Windows7</strong> is 6.1.7600.</p>
<p>Disk Operating System Commands (both Internal and External) are directly used under Command Prompt for managing Files, Folders on Disks and for retrieving information on them.</p>
<p>For example, the <strong>Dir</strong>ectory Command (Dir /S/B/P) will provide a list of all files with full Path Names (like C:\My Documents\New Folder\Resume.doc) from your C: Drive and display them on screen, one page at a time.&#160; </p>
<p>Let us try an example.</p>
<p>Click on the <strong>Start</strong> Menu.</p>
<p>Type <strong>cmd</strong> and press <strong>Enter</strong> Key, DOS Command window will open up with the Command Prompt <strong>C:\&gt;</strong>.&#160; Type the following Command to display a list of Folders/Files from your <strong>C:</strong> drive, one page at a time.&#160; You must press a Key to advance the list from one page to the other. </p>
<p><strong>Warning:</strong>&#160; The list of Folders/Files on your C: drive will run into hundreds of pages.&#160; Press <strong>Ctrl+C</strong> (break the command) to terminate the list from displaying further.</p>
<pre class="alt1">

<strong>C:\&gt;</strong> Dir /S/B/P
</pre>
<p><strong>C:\&gt;</strong> is the command prompt</p>
<p><strong>Dir</strong> (command stands for <strong>Dir</strong>ectory) </p>
<p><a href="http://www.msaccesstips.com/2009/01/command-button-animation-2/">Command</a> switch <strong>/S</strong> includes Files in Sub-directories also in the output.</p>
<p>Command switch <strong>/B</strong> provides a bare-formatted list of files, i.e. gives only file path names without creation date, file sizes or any other information of files.</p>
<p>Command switch <strong>/P</strong> displays the output on Screen one Page (one screen full) at a time.&#160; Needs to press a Key on the <a href="http://www.msaccesstips.com/2007/12/keyboard-shortcuts/">Keyboard</a> to advance the list of files to the next Page.</p>
<p>If you want to save the entire list into a <a href="http://www.msaccesstips.com/2009/12/text-search-filter-web-style/">text</a> file, without page breaks, issue the following command with the output redirection symbol (&gt;) with a text file name.&#160; The re-direction symbol will send the output of the <strong>Dir</strong>ectory command to a specified <a href="http://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins/">text</a> file, without displaying them on screen.</p>
<pre class="alt1">

<strong>C:&gt;</strong> Dir /S/B &gt; myDirList.txt
</pre>
<p>Note: Leave a space on either side of the <strong>&gt;</strong> symbol.</p>
<blockquote>
<p>You may open myDirList.txt file in Notepad and check the contents. You can display the contents of myDirList.txt file with the following DOS Command:</p>
<pre class="alt1">

C:\&gt; TYPE myDirList.txt
</pre>
<p>Press <strong>Ctrl+C</strong> to stop the runaway display. <strong>TYPE</strong> command displays the contents of a text file on screen. But, it will not display the output one screen full at a time. To do that we can seek the help of another DOS command: <strong>MORE</strong> with the use of piping symbol (<strong>|</strong>).</p>
<pre class="alt1">

C:\&gt; <strong>TYPE</strong> myDirList.txt | <strong>MORE</strong>
</pre>
<p>In the above command we are using the piping symbol (|) to join the <strong>TYPE</strong> filename.txt | <strong>MORE</strong> commands to get the required output. The TYPE command reads the text file contents and pass it on to the next command <strong>MORE</strong>, without directly sending the output to the Screen. MORE Command takes it&#8217;s input from <strong>TYPE</strong> command, through the pipe, and displays it one screen-full at a time. Press SPACEBAR to display the next screen-full of text.</p>
<p>OR</p>
<pre class="alt1">

C:\&gt; <strong>MORE</strong> &lt; myDirList.txt
</pre>
<p>If &gt; (greater than) symbol is known as re-direction symbol in DOS then &lt; (less than) symbol is known as Source symbol for the MORE command. MORE command reads data from the file name given immediately after the Source Symbol (&lt;) and displays one screen-full at a time. </p></blockquote>
<p>Let us come back to the <strong>Dir</strong> Command, it is available in VBA also. But it is used for a different purpose. We can use this command to check the presence of a particular file or the presence of any file in a folder. The usage of this command is as shown below:</p>
<pre class="alt1">

strOutput = Dir(&quot;C:\My Documents\Resume.doc&quot;, vbNormal) 
</pre>
<p>The <strong>Dir</strong> Command checks for the presence of Word File <strong>Resume.doc</strong> in Folder <em>C:\My Documents</em>, if found then the file name &#8216;Resume.doc&#8217; is returned in <strong>strOutput</strong> Variable, otherwise it will return an empty string.</p>
<pre class="alt1">

strOutput = Dir(&quot;C:\My Documents\*.*&quot;, vbNormal) 
</pre>
<p>This command will get the first file name and save it in <strong>strOutput</strong> Variable. You may try out this command in the Debug Window directly, like:</p>
<pre class="alt1">

? Dir(&quot;C:\My Documents\*.*&quot;)
</pre>
<p>This will print the first file name found in the folder <em>C:\My Documents</em> in the Debug Window. To get subsequent file names from the same folder you can run the command without any parameters to the function, like:</p>
<pre class="alt1">

? Dir()
</pre>
<p><strong>Note:</strong> First time when you run this Command you should provide a Path as parameter otherwise it will end up with error.</p>
<p>Place the insertion point on the <strong>Dir()</strong> Command and press <strong>F1</strong> to display the details of this Command in Access Help Documents.</p>
<p>There are other interesting Windows Operating System Commands like <strong>ChDrive, ChDir, MkDir, RmDir</strong> etc. and we will learn their usage in VBA Next week.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:366cebc9-883d-4c17-ada8-9f5ba991ffa1" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Microsoft" rel="tag">Microsoft</a></div>
<p>&#160;</p>
<ul>
<li><a href="http://msaccesstips.com/2011/10/easy-reference-access2003-commands-in-access2007/">Easy Reference: Access2003 Commands in Access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/09/iif-vs-switch-function-in-ms-access/">IIF vs Switch function in MS-Access</a> </li>
<li><a href="http://msaccesstips.com/2011/09/preparing-rank-list/">Preparing Rank List</a> </li>
<li><a href="http://msaccesstips.com/2011/08/restoring-disabled-full-menus-access2007/">restoring Disabled Full Menus in Access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/running-workgroup-admin-in-access2007/">Running Workgroup Admin in access2007</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/04/disk-operating-system-commands-in-vba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Happy Easter to all our Readers</title>
		<link>http://msaccesstips.com/2012/04/happy-easter-to-all-our-readers/</link>
		<comments>http://msaccesstips.com/2012/04/happy-easter-to-all-our-readers/#comments</comments>
		<pubDate>Sat, 07 Apr 2012 10:02:38 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2285</guid>
		<description><![CDATA[Easter is a good time to enjoy all of your many meaningful blessings: family, friends, and of course chocolate molded into tasty bunnies. May you be blessed with God&#8217;s warm love and trust in his living grace this Easter. Have an awesome Easter. Have fun Easter egg hunting and hanging out with family. IIF vs [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-size: 20px">
<p>Easter is a good time to enjoy all of your many meaningful blessings: family, friends, and of course chocolate molded into tasty bunnies.</p>
<p> <!-- Uploaded_images-->
<p><a href="http://www.msaccesstips.com/images/easter.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Easter Greetings" border="0" alt="Easter Greetings" src="http://www.msaccesstips.com/images/easter.jpg" width="556" height="380" /></a></p>
<p> <!-- Uploaded_images-->
<p>May you be blessed with God&#8217;s warm love and trust in his living grace this Easter.</p>
<p>Have an awesome Easter. Have fun Easter egg hunting and hanging out with family.</p>
</p>
<p> </span>
<ul>
<li><a href="http://msaccesstips.com/2011/09/iif-vs-switch-function-in-ms-access/">IIF vs Switch function in MS-Access</a> </li>
<li><a href="http://msaccesstips.com/2011/09/preparing-rank-list/">Preparing Rank List</a> </li>
<li><a href="http://msaccesstips.com/2011/08/restoring-disabled-full-menus-access2007/">restoring Disabled Full Menus in Access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/running-workgroup-admin-in-access2007/">Running Workgroup Admin in access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/apply-filter-to-table-directly/">Apply Filter to Table directly</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/04/happy-easter-to-all-our-readers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Opening Specific Page of Pdf File</title>
		<link>http://msaccesstips.com/2012/03/opening-specific-page-of-pdf-file/</link>
		<comments>http://msaccesstips.com/2012/03/opening-specific-page-of-pdf-file/#comments</comments>
		<pubDate>Fri, 30 Mar 2012 11:10:45 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2278</guid>
		<description><![CDATA[Opening an external file (Word, Excel or Adobe .pdf file) from Microsoft Access is not a big issue.&#160; We can use the HyperLink tool (Ctrl+K) to browse and find a file on disk and setup a Hyperlink on a form.&#160; We can launch the Hyperlink tool from the Hyperlink Address Property of a Label, browse [...]]]></description>
			<content:encoded><![CDATA[<p>Opening an external file (Word, Excel or Adobe .pdf file) from Microsoft Access is not a big issue.&#160; We can use the <a href="http://www.msaccesstips.com/2007/05/open-forms-with-hyperlinks-in-listbox/" target="_blank">HyperLink</a> tool (Ctrl+K) to browse and find a file on disk and setup a Hyperlink on a form.&#160; We can launch the Hyperlink tool from the <strong>Hyperlink Address</strong> Property of a <a href="http://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins/" rel="nofollow" target="_blank">Label</a>, browse and find the external file on disk and set up a hyperlink on a label.</p>
<p>When we click on the Hyperlink the file (Ms-Word, Excel or Adobe Acrobat pdf file) will open with the first page on top and whatever default view configuration of the document is set.</p>
<p>Another method used to open an external file is DOS (Microsoft <strong>D</strong>isk <strong>O</strong>perating <strong>S</strong>ystem) <strong>Shell()</strong> Command in VBA.&#160; The Shell() command needs mainly two parameters (actually three values), as the syntax shown below:</p>
<p>&#160;</p>
<p>Call Shell(“&lt;Parent Application&gt; &lt;file pathname&gt;”, &lt;window mode&gt;)</p>
<p>The first parameter of the Shell() command have two segments, separated with a space.</p>
<p>A.&#160; First Parameter</p>
<ol>
<li>The parent Application Path Name(C:\Program Files (x86)\adobe\Reader 9.0\Reader\AcroRd32.exe). </li>
<li>The path name of the pdf file to open (C:\aprpillai\Documents\dosa.pdf). </li>
</ol>
<p>B.&#160; Second Parameter</p>
<ol>
<li>open window mode </li>
</ol>
<p>Let us try an example to open a PDF file: <strong>C:\aprpillai\Documents\dosa.pdf</strong> using the Shell() Command:</p>
<ol>
<li>Open any one your <a href="http://www.msaccesstips.com/2008/05/database-daily-backup/" target="_blank">databases</a> or create a new one. </li>
<li>Create a new <a href="http://www.msaccesstips.com/2008/01/progress-bar-on-form/" target="_blank">Form</a> with a <a href="http://www.msaccesstips.com/2008/04/transparent-command-button/" target="_blank">Command Button</a> on it. </li>
<li>Select the Command Button and open it’s Property Sheet (<strong>F4</strong>). </li>
<li>Change the <strong>Name</strong> property value to <strong>cmdRun </strong>and change the <strong>Caption</strong> Property value to <strong>Open PDF File</strong>. </li>
<li>Select the <strong>Event</strong> Tab of the Property Sheet and click on the <strong>On Click</strong> Property. </li>
<li>Click on the build (. . .) button at the right end of the property to open the VBA Module. </li>
<li>Copy and paste the following <a href="http://msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/" target="_blank">VBA</a> Code overwriting the existing lines:
<pre class="alt3">Private Sub cmdRun_Click()
Dim strApplication As String
Dim strFilePath As String 

strApplication = &quot;C:\Program Files (x86)\adobe\Reader 9.0\Reader\AcroRd32.exe&quot;
strFilePath = &quot;C:\aprpillai\Documents\dosa.pdf&quot; 

Call Shell(strApplication &amp; &quot; &quot; &amp; strFilePath, vbNormalFocus) 

End Sub</pre>
</li>
<li>Change the pathname of the pdf file to select a file from your disk with few pages. If you don&#8217;t have one then you may download the dosa.pdf file from this <a href="http://www.msaccesstips.com/downloads/dosa.pdf" target="_blank">Link</a>. </li>
<li>Save the Form with the name PDF_Open_Example. </li>
<li>Open the form in normal view and click on the Command Button to open the pdf file. </li>
</ol>
<p>The above Sub-Routine opens the pdf file: C:\aprpillai\Documents\dosa.pdf with Normal Focus in the Acrobat Reader window.</p>
<p>The dosa.pdf (Dosa is Indian Pancake) file have about 51 pages, with variety of recipes. Each recipe with different ingredients like Rava Dosa (on page 7), Sweet Dosa (on page 8), Set Dosa (page 5), Quick Dosa (page 6), Vella Dosai (Page 25), Moong Dosa (page 35) and so on. After opening the Dosa.pdf file with page 1 on the top if we know a particular recipe’s exact page location then we can type the page number on the navigation control, at the bottom of the document, to jump to that page.&#160; </p>
<p>But, if we know this information in advance then we can use the page number value as open parameter to <strong>AcroRd32.exe </strong>program (..\AcroRd32.exe /A page=25 ..\dosa.pdf) to open the pdf file with that page in view. </p>
<p>We will modify the above program with the addition of <strong>Page</strong> parameter (..\AcroRd32.exe /A page=25) to jump to the 25th page of the pdf document. Modified program is given below:</p>
<pre class="alt2">Private Sub cmdRun_Click()
Dim strApplication As String
Dim strFilePath As String

strApplication = &quot;C:\Program Files (x86)\adobe\Reader 9.0\Reader\AcroRd32.exe<strong> /A page=25</strong>&quot;
strFilePath = &quot;C:\aprpillai\Documents\dosa.pdf&quot;

Call Shell(strApplication &amp; &quot; &quot; &amp; strFilePath, vbNormalFocus)

End Sub</pre>
<p>NB: Don&#8217;t leave any space on either side of the equal sign in ‘page=25’ parameter.&#160; The <strong>/A</strong> switch must be given after the program name AcroRd32.exe, followed by a space and then <strong>page=25.</strong></p>
<p>We have several recipes on the dosa.pdf file and we must be able to go to a particular one quickly with a single click.&#160; To make the task easy we must create a <a href="http://www.msaccesstips.com/2009/01/combo-box-column-values/" target="_blank">Combo box</a> on the form with a list of all recipes (with page numbers and description) so that we can select a particular recipe and jump to that quickly.</p>
<p>Image of a sample form with the list of Dosa Recipes in a Combo Box is given below:</p>
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/pdf-open-form.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PDF File Launching Pad Image" border="0" alt="PDF File Launching Pad Image" src="http://www.msaccesstips.com/uploaded_images/pdf-open-form_thumb.jpg" width="318" height="176" /></a></p>
<p><!-- Uploaded_images--></p>
<p>I will explain the second <a href="http://www.msaccesstips.com/2008/03/refresh-dependant-combo-box-contents/" target="_blank">Combo box</a> (Zoom Percentage) little later.&#160; </p>
<ol>
<li>Open the Form in Design View. </li>
<li>Select the Control <a href="http://www.msaccesstips.com/2008/12/custom-made-form-wizard/" target="_blank">Wizard</a> tool to launch it when you select the Combobox Tool. </li>
<li>Select the Combobox Tool and draw a Combobox on the Form. </li>
<li>Select the Radio Button, on the Control <a href="http://www.msaccesstips.com/2008/12/custom-report-wizard/" target="_blank">Wizard</a>, with the caption <strong>‘I will type the values that I want’</strong> and click <strong>Next.</strong> </li>
<li>Type 2 in the ‘Number of Columns’ control and press Tab Key. </li>
<li>Type a similar list of topics, shown in the image above, from your pdf file with Page Number in first column and Description in the second column, when finished click <strong>Next</strong>. </li>
<li>Select the first column and click <strong>Next</strong>. </li>
<li>Type a suitable caption for the child label and click <strong>Finish</strong>. </li>
<li>Select the Combo Box, if it is de-selected, then display the Property Sheet (<strong>F4</strong>). </li>
<li>Change the <strong>Name</strong> Property value to cboPage. </li>
<li>Display the VBA Module of the Form (<strong>Design &#8211; - &gt; Tools &#8211; - &gt; View Code</strong> or press <strong>ALT+F11</strong>). </li>
<li>Copy and paste the following VBA Code into the Module overwriting the existing code:
<pre>Private Sub cmdRun_Click()
Dim ReaderPath As String
Dim pdfFilePath As String
Dim PageNumber As Integer
Dim strOpenPDF As String

PageNumber = Nz(Me![cboPage], 1)' Get user selected page number, if empty then take 1 as default

ReaderPath = &quot;C:\Program Files (x86)\adobe\Reader 9.0\Reader\AcroRd32.exe /A &quot; &amp; &quot;page=&quot; &amp; PageNumber
pdfFilePath = &quot;C:\aprpillai\Documents\dosa.pdf&quot; 'change the path to match your file location

strOpenPDF = ReaderPath &amp; &quot; &quot; &amp; pdfFilePath
Call Shell(strOpenPDF, vbNormalFocus)

End Sub</pre>
</li>
<li>Close the VBA Module, Save the Form and open it in normal view. </li>
<li>Select one of the item from the Combobox with a larger page number. </li>
<li>Click on the <a href="http://www.msaccesstips.com/2009/01/command-button-animation-2/" target="_blank">Command Button</a> to open the pdf file displaying the selected page. Check the following imge for a sample view of the dosa.pdf file: <!-- Uploaded_images-->
<p><a href="http://www.msaccesstips.com/uploaded_images/pdfopenstate.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PDF File View Image" border="0" alt="PDF File View Image" src="http://www.msaccesstips.com/uploaded_images/pdfopenstate_thumb.jpg" width="330" height="363" /></a></p>
<p><!-- Uploaded_images--></p>
<p>As you can see from the header toolbar that the page in view is <strong>7/51</strong> and the document view is only about 60% (zoom=60) of it&#8217;s actual size of 100%. We can control the view size of a pdf document by specifying the <strong>Zoom</strong> parameter immediately after the <strong>Page</strong> parameter.</p>
<p>I have created a second Combo Box Control with the name <strong>cboZoom</strong> on the form, image shown above, and Zoom Percentage values 50,60,70,80,90,100 &amp; 120 so that one of these values can be selected along with the <strong>Page</strong> number to view the document in the desired size.</p>
</li>
</ol>
<p>The modified Code with the addition of <strong>Zoom</strong> Parameter is given below:</p>
<pre>Private Sub cmdRun_Click()
Dim ReaderPath As String
Dim pdfFilePath As String
Dim PageNumber As Integer
Dim intZoom As Integer
Dim strOpenPDF As String

PageNumber = Nz(Me![cboPage], 1)
intZoom = Nz(Me![cboZoom], 100)

ReaderPath = &quot;C:\Program Files (x86)\adobe\Reader 9.0\Reader\AcroRd32.exe /A &quot; &amp; quot;page=&quot; &amp; PageNumber &amp; &quot;&amp;zoom=&quot; &amp; intZoom
pdfFilePath = &quot;C:\aprpillai\hostgator\dosa.pdf&quot;

strOpenPDF = ReaderPath &amp; &quot; &quot; &amp; pdfFilePath
Call Shell(strOpenPDF, vbNormalFocus)

End Sub</pre>
<p>The <strong>Page</strong> parameter and <strong>Zoom</strong> parameter values must be joined with an <strong>&amp;</strong> symbol and there should not be any spaces on either side of the equal (=) sign:</p>
<pre class="alt1">


..\AcroRd32.exe /A page=7<strong>&amp;</strong>zoom=60 C:\aprpillai\Documents\dosa.pdf

</pre>
<p>When you join parameter key names (page, zoom) and control values (page number and zoom percentage) together the result of it should form like the sample value shown above.</p>
<p>You may create a text box with the name <strong>cboZoom</strong> on the form and type the zoom percentage value (not to add the % symbol along with the value) and run to test the above code.</p>
<p>NB: If you leave both controls (cboPage and cboZoom) empty the pdf file will open with the first page of the file on top and with 100% zoom value.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:3c68d229-859b-4b78-95a9-eb10364302fe" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Microsoft" rel="tag">Microsoft</a></div>
<ul>
<li><a href="http://msaccesstips.com/2011/09/iif-vs-switch-function-in-ms-access/">IIF vs Switch function in MS-Access</a> </li>
<li><a href="http://msaccesstips.com/2011/09/preparing-rank-list/">Preparing Rank List</a> </li>
<li><a href="http://msaccesstips.com/2011/08/restoring-disabled-full-menus-access2007/">restoring Disabled Full Menus in Access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/running-workgroup-admin-in-access2007/">Running Workgroup Admin in access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/apply-filter-to-table-directly/">Apply Filter to Table directly</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/03/opening-specific-page-of-pdf-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating Time Difference</title>
		<link>http://msaccesstips.com/2012/03/calculating-time-difference/</link>
		<comments>http://msaccesstips.com/2012/03/calculating-time-difference/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 16:08:58 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Functions]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2274</guid>
		<description><![CDATA[How do we calculate difference of time in Hours, Minutes and Seconds between two time period? The time period can be on the same date or across dates. Example-1: Start Time: 21-03-2012 12:30:45 End Time:&#160;&#160; 21-03-2012 13:30:15 Example-2: Start Time: 21-03-2012 12:30:45 End Time: 24-03-2012 15:15:15 In the first example the date values in the [...]]]></description>
			<content:encoded><![CDATA[<p>How do we calculate difference of time in Hours, Minutes and Seconds between two time period? The time period can be on the same date or across dates. </p>
<p><strong>Example-1:</strong></p>
<p>Start Time: 21-03-2012 12:30:45</p>
<p>End Time:&#160;&#160; 21-03-2012 13:30:15</p>
<p><strong>Example-2:</strong></p>
<p>Start Time: 21-03-2012 12:30:45</p>
<p>End Time: 24-03-2012 15:15:15</p>
<p>In the first example the date values in the <strong>Start Time</strong> and <strong>End Time</strong>, looks like it is not important, because both are same, to <a href="http://www.msaccesstips.com/2008/11/custom-calculator-and-eval-function/" target="_blank">calculate</a> the time difference between them. We can subtract the Start Time value 12:30:45 from the End Time value 13:30:15 and will get the result 00:59:30.&#160; But, if the end time is 01:30:15 past mid-night then how do we calculate the time difference?</p>
<p>But first, how the time changes to zero after 23:59:59 Hrs at night and how this value is held in computer’s memory.&#160; With this basic knowledge working with the date and time values become very easy.</p>
<p>Everybody knows that a day is equals to 24 hours, 1 hour equals to 60 Minutes, 1 Minute equals to 60 Seconds and further if we go to a smaller denomination 1 second equals to 100 milliseconds. If you would like to find out how February gets 29 days (everybody knows about it) but why every 100th Year (like 1700, 1800,1900 or 2100) is not a Leap Year, how every 400th Year become Leap Year and why every 4000th year is not Leap Year, Click <a href="http://msaccesstips.com/2008/04/days-in-month-function/" target="_blank">here</a> to find out!</p>
<p>So, keeping aside the milliseconds part <strong>1 Day = 86400</strong> Seconds (24 x 60 x 60).&#160; In other words 1 Second = 1/86400 = 0.0000115740740741 Days. Exactly 1 second after midnight the computer’s internal time value will be <strong>0.0000115740740741</strong> and this value keeps adding to the time value at every second interval.&#160; This value can be divided by 100 to get the value equal to 1 millisecond and we could say that value is added to the time value at every millisecond interval. At 12:00 Noon the internal time value is 0.5 (half a day) and at 23:59:59 the internal time value will be 0.999988425926 (in days).&#160; Again this will reset to 0 at 12:00:00 midnight.&#160; </p>
<p>To find out the time difference between time values spread across different dates the date value also should go along with the time value as shown in Example-2 above.&#160; The date-value also mapped in computer’s memory as a continuous number starting 1 from 31-12-1899.&#160; If you create a Date/Time field in your Table having 0 as default value then you will find the date appearing in that field as 30-12-1899, if not filled-in with a date.</p>
<p>The date 21-03-2012 equals to the date number 40989 and the Start Time (Example-2) in memory will be <strong>40989.521354166700</strong>, the number after the decimal point is the time value.&#160; Since, the Date and Time values held in memory are real numbers it is easy to find out the difference between them.&#160; All you have to do is to subtract one number from other.&#160; This works with Date/Time Values on the same day or on different dates.</p>
<p>Let us find out the time difference between the date and time values in Example-2:</p>
<p>StartTime = #21-03-2012 12:30:45# = <strong>40989.521354166700</strong></p>
<p>This is the kind of value (Current Date and Time) returned with the function <strong>Now()</strong>.&#160; You can format this value as date alone (dd-mm-yyyy) or time alone (hh:nn:ss) or both combined &#8211; format(now(),”dd-mm-yyyy hh:nn:ss”).</p>
<p>Use <strong>? format(StartTime,”0.000000000000”)</strong> to display the Date/Time value as a real number from StartTime Variable in the Debug Window.</p>
<p>EndTime = #24-03-2012 15:15:15# = <strong>40992.635590277800</strong></p>
<p><strong>Difference = (EndTime &#8211; StartTime</strong><strong>) = 3.114236111112 days </strong></p>
<p>So, the result value we get in days, doesn’t matter the date is same or different dates.&#160; If the date is same you will get the result in days something like 0.9999999.&#160; All we have to do is to convert this days into Hours, Minutes and Seconds.</p>
<p>Total_Seconds = <strong>Difference</strong> x 86400 (difference in days converted into total seconds) = <strong>269070.000000077</strong> Seconds</p>
<p>Hours = Int(Total_Seconds / 3600) = <strong>74 Hrs</strong>.</p>
<p>Minutes = int((Total_Second MOD 3600)/60) = <strong>44 Min.</strong>&#160;</p>
<p>Seconds = Total_Seconds MOD 60 = <strong>30 sec.</strong></p>
<p>If we assemble all these information into the form of a small function we can easily find the time difference in Hours, Minutes and Seconds&#160; by passing the Start &amp; End Date/Time Values to the <a href="http://www.msaccesstips.com/2009/12/filter-with-buildcriteria-function/" target="_blank">Function</a> as parameters.</p>
<p>Copy and paste the following Function Code into the Standard <a href="http://msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/" target="_blank">Module</a> and save it:</p>
<p>Public Function HrsMin(ByVal startDate As Date, ByVal endDate As Date) As String   <br />Dim diff As Double    <br />Dim difHrs As Integer    <br />Dim difMin As Integer    <br />Dim difSec As Integer    </p>
<p>diff = (endDate &#8211; startDate) * 86400    <br />difHrs = Int(diff / 3600)    <br />difMin = Int((diff Mod 3600) / 60)    <br />difSec = (diff Mod 60)    </p>
<p>HrsMin = Format(difHrs, &quot;00&quot;) &amp; &quot;:&quot; &amp; Format(difMin, &quot;00&quot;) &amp; &quot;:&quot; &amp; Format(difSec, &quot;00&quot;)    </p>
<p>End Function</p>
<p>You may call the Function HrsMin() directly from the Debug Window, as shown below, to test the code:</p>
<pre class="alt1">

? HrsMin(#21-03-2012 12:30:45#,#24-03-2012 15:15:15#)
</pre>
<p>&#160;</p>
<p>Result: 74:44:30 </p>
<p>&#160;</p>
<p>You may call the function from a Textbox in the Form like:</p>
<pre class="alt1">

 = HrsMin([StartDate],[EndDate])
</pre>
<p>Or from the Query Column like:</p>
<pre class="alt1">

 HMS:HrsMin([StartDate],[EndDate])
</pre>
<p>Or you may run it from VBA Code:</p>
<pre class="alt1">

 strHMS = HrsMin(dtSDate,dtEDate)
</pre>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:80adf70f-7865-44f7-83bc-3224c690cc70" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Functions" rel="tag">Functions</a></div>
<ul>
<li><a href="http://msaccesstips.com/2011/09/preparing-rank-list/">Preparing Rank List</a> </li>
<li><a href="http://msaccesstips.com/2011/08/restoring-disabled-full-menus-access2007/">restoring Disabled Full Menus in Access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/running-workgroup-admin-in-access2007/">Running Workgroup Admin in access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/apply-filter-to-table-directly/">Apply Filter to Table directly</a> </li>
<li><a href="http://msaccesstips.com/2011/07/dynamic-dlookup-in-query-column/">Dynamic Lookup in Query Column</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/03/calculating-time-difference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Centralized Error Handler and Error Log</title>
		<link>http://msaccesstips.com/2012/03/centralized-error-handler-and-error-log/</link>
		<comments>http://msaccesstips.com/2012/03/centralized-error-handler-and-error-log/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 17:28:39 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2268</guid>
		<description><![CDATA[In an earlier article with the VBA Utility program we have seen how to scan through a VBA Module (both Standard Module and Form/Report Modules – Class Modules) and insert Error Handler lines automatically, wherever they are found missing.&#160; Find the link to that Article here. I am sure that Utility Program will help you [...]]]></description>
			<content:encoded><![CDATA[<p>In an earlier article with the VBA Utility program we have seen how to scan through a <a href="http://msaccesstips.com/2011/11/writing-vba-code-with-vba/" target="_blank">VBA Module</a> (both Standard Module and Form/Report Modules – Class Modules) and insert Error Handler lines automatically, wherever they are found missing.&#160; Find the link to that Article <a href="http://msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/" target="_blank">here</a>.</p>
<p>I am sure that Utility Program will help you to save time, otherwise you spent on typing/copy pasting and modifying hundreds of lines of error-trap code in your sub-routines or functions.&#160; The whole idea behind the error handler is to take care of unexpected errors and if necessary report it to the developer so that the logical error can be rectified once and for all.&#160; Besides that the program should not break the code unexpectedly. If it is a minor issue the user can ignore and continue to do what he/she is doing.</p>
<p>A particular Project will have hundreds of Sub-Routines/Functions in Standard Modules and Form/Report Modules.&#160; When the error message pops up the message will carry the <strong>Error Number</strong> and <strong>Error Description</strong>.&#160; The message box’s title will carry the Function/Sub-Routine name, if this is included in the title parameter of the MsgBox() Function.&#160; But, the user may not notice this valuable information to pass on to the programmer so that he can go directly into that program and do what he needs to do to rectify the error.&#160; </p>
<p>A better approach to these kind of issues is to create a common Error Handler Program and maintain an Error Log Text File on disk.&#160; When an error occurs in a Function/Sub-Routine call the common Function with the necessary parameters (Error Number, Error Description, Function/Sub-Routine Name, Module Name, Database Name).&#160; The common error handler program will not only display the error message but also write out the details into a <a href="http://www.msaccesstips.com/2006/12/create-text-file-from-msaccess/" target="_blank">Text File</a> on Disk.</p>
<p>If you have several Microsoft Access based Applications installed on Local Area Network all of them can save the error log information into a single text file on Server’s common location.&#160; The error log will carry the Date, Time, Module Name and Database name, besides the normal error values Error Number and Error Description.</p>
<p>A Text file image with sample error log entries is given below:</p>
<p> <!-- Uploaded_images-->
<p><a href="http://www.msaccesstips.com/uploaded_images/error-log.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Error Log" border="0" alt="Error Log" src="http://www.msaccesstips.com/uploaded_images/error-log_thumb.jpg" width="398" height="284" /></a></p>
<p> <!-- Uploaded_images-->
<p>The error log entry have all the details (Date &amp; Time of Error, <a href="http://www.msaccesstips.com/2008/06/database-open-close-event-alerts/" target="_blank">Database</a> Path, Module Name, Procedure name etc. to pin-point the location of the Error.&#160; Even if the user doesn’t bother to report the problem to the Administrator, the Administrator can periodically check this log file to monitor his application’s health.</p>
<p>The following sample data processing program DataProcess<strong>() </strong>attempts to open the input table <strong>Table_1,</strong> but the table doesn’t exist (got deleted or renamed by mistake) and the program runs into error:</p>
<p> <!--INFOLINKS_OFF-->
<pre>Public Function DataProcess()
Dim db As Database, rst As Recordset, x
On Error GoTo DataProcess_Error

Set db = CurrentDb
Set rst = db.OpenRecordset(&quot;Table_1&quot;, dbOpenDynaset)

Do While Not rst.EOF
 x = rst.Fields(0).Value
Loop
rst.Close

DataProcess_Exit:
Exit Function

DataProcess_Error:
<b>BugHandler Err, Err.Description, &quot;DataProcess()&quot;, &quot;Module4&quot;, CurrentDb.Name</b>
Resume DataProcess_Exit
End Function</pre>
<p>When the above program runs into error it calls the <strong>BugHandler() </strong>Program and passes the Module Name and Database Path as last two parameters in addition to Error Number, Error Description and Program name.&#160; The VBA Code of <strong>BugHandler() </strong>main program is given below:</p>
<pre>Public Function BugHandler(ByVal erNo As Long, _
                           ByVal erDesc As String, _
                           ByVal procName As String, _
                           ByVal moduleName As String, _
                           ByVal dbName As String)
On Error GoTo BugHandler_Error
Dim logFile As String
Dim msg As String

'Error Log text file pathname, change it to the correct path
'on your Local Drive or Server Location
logFile = &quot;c:\mdbs\bugtrack\acclog.txt&quot;

'Open log file to add the new error log entry
Open logFile For Append As #1
  'write the log details to log file
  Print #1, Now() &amp; vbCr
  Print #1, &quot;Database : &quot; &amp; dbName &amp; vbCr
  Print #1, &quot;Module   : &quot; &amp; moduleName &amp; vbCr
  Print #1, &quot;Procedure: &quot; &amp; procName &amp; vbCr
  Print #1, &quot;Error No.: &quot; &amp; erNo &amp; vbCr
  Print #1, &quot;Desc.    : &quot; &amp; erDesc &amp; vbCr
  Print #1, String(80, &quot;=&quot;) &amp; vbCr
  Close #1

msg = &quot;Procedure Name: &quot; &amp; procName &amp; vbCr &amp; &quot;Error : &quot; &amp; erNo &amp; &quot; : &quot; &amp; erDesc
  MsgBox msg, , &quot;BugHandler()&quot;

BugHandler_Exit:
Exit Function

BugHandler_Error:
MsgBox Err &amp; &quot; : &quot; &amp; Err.Description, , &quot;BugHandler()&quot;
Resume BugHandler_Exit
End Function</pre>
<p>You can save the above Code into a common <a href="http://www.msaccesstips.com/2009/03/ms-access-and-reference-library/" target="_blank">Library Database</a>, where you have saved your own common library functions, so that it can be attached to your Projects.&#160; </p>
<p>This method will write out the details of errors from your <a href="http://www.msaccesstips.com/2008/05/database-daily-backup/" target="_blank">databases</a> into a common place accessible to you all the time.&#160; When an Error is reported by the User you can directly check the details of it without asking the user to spell out.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ea519bb8-409b-49c2-8c0e-0fa8e3c53038" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Databases" rel="tag">Databases</a>,<a href="http://technorati.com/tags/Error+Handler" rel="tag">Error Handler</a></div>
<ul>
<li><a href="http://msaccesstips.com/2011/07/creating-watermark-on-ms-access-reports/">Creating Watermark on Reports</a> </li>
<li><a href="http://msaccesstips.com/2011/08/running-workgroup-admin-in-access2007/">Running Workgroup Admin in access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/apply-filter-to-table-directly/">Apply Filter to Table directly</a> </li>
<li><a href="http://msaccesstips.com/2011/07/dynamic-dlookup-in-query-column/">Dynamic Lookup in Query Column</a> </li>
<li><a href="http://msaccesstips.com/2011/07/creating-watermark-on-ms-access-reports/">Creating Water-mark on Ms-Access Reports</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/03/centralized-error-handler-and-error-log/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Changing Font Color Conditional Formatting</title>
		<link>http://msaccesstips.com/2012/02/changing-font-color-conditional-formatting/</link>
		<comments>http://msaccesstips.com/2012/02/changing-font-color-conditional-formatting/#comments</comments>
		<pubDate>Wed, 29 Feb 2012 02:50:09 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[How Tos]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2265</guid>
		<description><![CDATA[With conditional formatting feature of Microsoft Access we can apply up to three colors to the font or background of a Textbox, because only three set of conditions can be set on a field at one time.&#160; If we need more than that then what?&#160; Well, we can do that job ourselves by checking for [...]]]></description>
			<content:encoded><![CDATA[<p>With conditional <a href="http://www.msaccesstips.com/2009/01/cardinal-text-format-in-access/">formatting</a> feature of Microsoft Access we can apply up to three colors to the font or background of a Textbox, because only three set of conditions can be set on a field at one time.&#160; If we need more than that then what?&#160; Well, we can do that job ourselves by checking for the specific condition and apply whatever color we want to the font.</p>
<p>For example, we have a Category Code <a href="http://www.msaccesstips.com/2008/03/refresh-dependant-combo-box-contents/">Combo Box</a> Field on the Form having values range from A to F. When the user selects one of this code from the Combo box the item Description Field’s Font Color should change as per the following color table:</p>
<table cellspacing="0" cellpadding="10" width="400" bgcolor="#f0f2ff" border="1">
<caption>Color Table</caption>
<tbody>
<tr>
<th width="20%">Category</th>
<th width="30%">Color</th>
<th width="25%">Decimal</th>
<th width="25%">Hex</th>
</tr>
<tr>
<td align="center" width="20%">A</td>
<td width="30%"><font color="#008000"><strong>GREEN</strong></font></td>
<td align="right" width="25%">32768</td>
<td width="25%">#008000</td>
</tr>
<tr>
<td align="center" width="20%">B</td>
<td width="30%"><font color="#000080"><strong>BLUE</strong></font></td>
<td align="right" width="25%">10485760</td>
<td width="25%">#000080</td>
</tr>
<tr>
<td align="center" width="20%">C</td>
<td width="30%"><font color="#0000ff"><strong>LIGHT BLUE</strong></font></td>
<td align="right" width="25%">16711680</td>
<td width="25%">#0000FF</td>
</tr>
<tr>
<td align="center" width="20%">D</td>
<td width="30%"><font color="#00ff00"><strong>LIGHT GREEN</strong></font></td>
<td align="right" width="25%">65280</td>
<td width="25%">#00FF00</td>
</tr>
<tr>
<td align="center" width="20%">E</td>
<td width="30%"><font color="#800000"><strong>RED</strong></font></td>
<td align="right" width="25%">128</td>
<td width="25%">#800000</td>
</tr>
<tr>
<td align="center" width="25%">F</td>
<td width="25%"><font color="#ff0000"><strong>LIGHT RED</strong></font></td>
<td align="right" width="25%">255</td>
<td width="25%">#FF0000</td>
</tr>
</tbody>
</table>
<p>Let us try this out on a sample <a href="http://www.msaccesstips.com/2008/08/display-excel-value-directly-on-form/">Form</a>.</p>
<ol>
<li>Open a new Form in Design View. </li>
<li>Click on the <strong>Control Wizards</strong> button on the <strong>Toolbox</strong> to enable it. </li>
<li>Select the <strong>Combo box Tool</strong> and draw a <a href="http://www.msaccesstips.com/2010/06/limit-to-list-combo-box/">Combo box</a> in the Detail Section of the Form. </li>
<li>Select the Radio Button with the Caption: <em>I will Type in the Values that I want </em>then Click<em> Next</em>. </li>
<li>Type A, B, C, D, E &amp; F in separate rows under <strong>Col1 </strong>and Click on <strong>Finish </strong><a href="http://www.msaccesstips.com/2008/04/transparent-command-button/">Command Button</a>. </li>
<li>While the Combo box is still in selected state display the <a href="http://www.msaccesstips.com/2008/09/source-connect-str-property-and-odbc/">Property</a> Sheet<strong> (F4).</strong> </li>
<li>Click on the <strong>Other</strong> Tab of the Property Sheet. </li>
<li>Change the <strong>Name</strong> <a href="http://www.msaccesstips.com/2009/11/creating-using-form-custom-property/">Property</a> Value to <strong>cboCat</strong>. </li>
<li>Select the <strong>Event</strong> Tab on the Property Sheet. </li>
<li>Select <strong>[Event Procedure]</strong> from the <strong>After Update</strong> Event Property. </li>
<li>Click on the Build (. . .) button at the right edge of the <strong>After Update</strong> Event property to open the <a href="http://msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/">VBA Module</a> of the Form. </li>
<li>Copy and paste the following Code overwriting the empty lines of the After Update Event Procedure:
<pre>Private Sub cboCat_AfterUpdate()
Dim strtxt, num As Integer
Dim colr As Long

strtxt = Nz(Me![cboCat], &quot;&quot;)
If Len(strtxt) &gt; 0 Then
  num = Asc(strtxt) - 64

  colr = Choose(num, 32768, 10485760, 16711680, 65280, 128, 255)
  With Me!Desc
     .ForeColor = colr
  End With

End If
End Sub</pre>
</li>
<li>Close the <a href="http://msaccesstips.com/2011/12/prepare-a-list-of-procedure-names-from-a-module/">VBA Editing</a> Window to come back to the Form Design. </li>
<li>Create a <a href="http://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins/">Textbox</a> to the right of the Combobox. </li>
<li>Display it’s Property Sheet (<strong>F4</strong>) and select the <strong>Other</strong> Tab. </li>
<li>Change the <strong>Name</strong> Property Value to <strong>Desc.</strong> </li>
<li>Save and Close the Form with the name <strong>Sample.</strong> </li>
<li>Open the <strong>Sample</strong> Form in Normal View. </li>
<li>Type your name in the Text box. </li>
<li>Try out our creation by selecting the Category Code (A,B,C,D,E,F) one after the other or in random order and watch the color of your name changes. </li>
</ol>
<div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:47454785-2035-409a-8f07-56975d88844d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati Tags: <a href="http://technorati.com/tags/Microsoft" rel="tag">Microsoft</a></div>
<hr /><a href="http://www.msaccesstips.com/2009/08/microsoft-excel-power-in-ms-access/">Microsoft Excel Power in MS-Access</a></p>
<p><a href="http://msaccesstips.com/2010/07/change-secure-db-to-unsecured/">Change Secure DB to Unsecured</a></p>
<p><a href="http://www.msaccesstips.com/2010/07/date-and-time-values/">Date and Time Values</a></p>
<p><a href="http://www.msaccesstips.com/2010/06/limit-to-list-combo-box/">Limit to List Combo Box</a></p>
<p><a href="http://www.msaccesstips.com/2010/06/input-masks-and-data-entry/">Input Masks and Data Entry</a></p>
<p></p>
<hr />
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/02/changing-font-color-conditional-formatting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Duplicating fields with Conditional Formatting</title>
		<link>http://msaccesstips.com/2012/02/duplicating-fields-with-conditional-formatting/</link>
		<comments>http://msaccesstips.com/2012/02/duplicating-fields-with-conditional-formatting/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 11:49:39 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Forms]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2248</guid>
		<description><![CDATA[To make data entry task faster in Microsoft Access we duplicate certain field values (Ctrl+”) to bring them forward to the current record from previous record field, wherever it become necessary.&#160; If there are more than one field and needs to duplicate the same into more than one record then repeating Ctrl+” everywhere is asking [...]]]></description>
			<content:encoded><![CDATA[<p>To make data entry task faster in Microsoft Access we duplicate certain field values (Ctrl+”) to bring them forward to the current record from previous record field, wherever it become necessary.&#160; If there are more than one field and needs to duplicate the same into more than one record then repeating Ctrl+” everywhere is asking for more manual action, even though it is quicker than typing all the information literally.</p>
<p>For example, let us assume that we are creating a Mailing List of all Family members of all the residents in our locality and the sample data entry Form looks like the image given below:</p>
<p> <!-- Uploaded_images-->
<p><a href="http://www.msaccesstips.com/uploaded_images/de-before-update.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Before Update screen image" border="0" alt="Before Update screen image" src="http://www.msaccesstips.com/uploaded_images/de-before-update_thumb.jpg" width="290" height="254" /></a></p>
<p><sup>Click to Enlarge the image</sup></p>
<p> <!-- Uploaded_images-->
<p>If there are five members in a family then the data fields <strong>Family Code</strong> and <strong>Address</strong> line field values must be repeated for&#160; each member of the family in next four records, as shown in the next image.&#160; Only the unique information needs to be keyed in.</p>
<p> <!-- Uploaded_images-->
<p><a href="http://www.msaccesstips.com/uploaded_images/dup-field-contents.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Before Update screen image" border="0" alt="Before Update screen image" src="http://www.msaccesstips.com/uploaded_images/dup-field-contents_thumb.jpg" width="290" height="254" /></a></p>
<p><sup>Click to Enlarge the image</sup></p>
<p> <!-- Uploaded_images-->
<p>Let us try this out.</p>
<ol>
<li>create a new Table with the following structure and save it with the name FamilyDetails:<br />
<table border="1" cellspacing="0" cellpadding="5" width="400" bgcolor="#f0f7ff">
<tbody></tbody>
<caption>Table: FamilyDetails </caption>
<tbody>
<tr>
<th valign="top" width="100">Srl</th>
<th valign="top" width="100">Field Name</th>
<th valign="top" width="100">Data Type</th>
<th valign="top" width="100">Field Size</th>
</tr>
<tr>
<td valign="top" width="100">1</td>
<td valign="top" width="100">ID</td>
<td valign="top" width="100">AutoNumber</td>
<td valign="top" width="100">&#160;</td>
</tr>
<tr>
<td valign="top" width="100">2</td>
<td valign="top" width="100">FamilyID</td>
<td valign="top" width="100">Integer</td>
<td valign="top" width="100">&#160;</td>
</tr>
<tr>
<td valign="top" width="100">3</td>
<td valign="top" width="100">Title</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">15</td>
</tr>
<tr>
<td valign="top" width="100">4</td>
<td valign="top" width="100">FName</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">25</td>
</tr>
<tr>
<td valign="top" width="100">5</td>
<td valign="top" width="100">LName</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">25</td>
</tr>
<tr>
<td valign="top" width="100">6</td>
<td valign="top" width="100">Add1</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">50</td>
</tr>
<tr>
<td valign="top" width="100">7</td>
<td valign="top" width="100">Add2</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">50</td>
</tr>
<tr>
<td valign="top" width="100">8</td>
<td valign="top" width="100">City</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">50</td>
</tr>
<tr>
<td valign="top" width="100">9</td>
<td valign="top" width="100">State</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">50</td>
</tr>
<tr>
<td valign="top" width="100">10</td>
<td valign="top" width="100">Country</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">50</td>
</tr>
<tr>
<td valign="top" width="100">11</td>
<td valign="top" width="100">PIN</td>
<td valign="top" width="100">Text</td>
<td valign="top" width="100">10</td>
</tr>
</tbody>
</table>
</li>
<li>Use the <a href="http://www.msaccesstips.com/2008/12/custom-made-form-wizard/" target="_blank">Form Wizard</a> and create a Form in Column format, as shown in the image above, using the FamilyDetails Table and save the <a href="http://www.msaccesstips.com/2008/10/wave-shaped-reminder-ticker/" target="_blank">Form</a> with the name <strong>frmFamilyDetails</strong>. </li>
<li>Create a <a href="http://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins/" target="_blank">Textbox</a> (wide enough to type a list of field names separated with commas) on the header of the Form as shown in the image above. </li>
<li>Click on the Textbox to select it and display it’s Property Sheet (F4). </li>
<li>Change the <strong>Name</strong> Property Value to <strong>FieldList</strong>. </li>
<li>Create a <a href="http://www.msaccesstips.com/2008/04/colorfull-command-buttons/" target="_blank">Command Button</a> below the Textbox, change it’s <strong>Name</strong> Property Value to <strong>cmdDup</strong> and change the <strong>Caption</strong> Property Value to <strong>Set Carry Forward</strong>. </li>
<li>Display the Form’s VBA Module (<strong>Design</strong> &#8211; - &gt; <strong>Tools</strong> &#8211; - &gt; <strong>View Code</strong>). Copy and paste the following Code into the Form <a href="http://msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/" target="_blank">Module</a> and save the form:<br />
<!--INFOLINKS_OFF--></p>
<pre>Private Sub cmdDup_Click()
'Set 'CarryForward' Text in the submitted field's TAG property
SetTagValue Me, &quot;FieldList&quot;

End Sub

Private Sub Form_AfterUpdate()
'Set Default Property Value
SetDefaultValue Me

End Sub

Private Sub Form_Current()
'Change color of Duplicated field to Red.
SetColorChange Me

End Sub</pre>
<p><!--INFOLINKS_ON-->
  </li>
<li>Save and close the Form. </li>
<li>Open the VBA Editing Window (ALT+F11). </li>
<li>Create a new Standard Module (<strong>Insert</strong> &#8211; - &gt; <strong>Module</strong>). </li>
<li>Copy and paste the following VBA Code (consisting of three Functions) into the new Module and save it: <!--INFOLINKS_OFF-->
<pre>Public Function SetTagValue(ByVal frm As Form, ByVal fldList As String)
'---------------------------------------------------------------------
'Author: a.p.r. pillai
'Date  : Feb 2012
'Rights: All Rights Rserved by www.msaccesstips.com
'---------------------------------------------------------------------
Dim txt, splt, ctl As Control
Dim ctlName As String, ctlType As Integer, j As Integer
Dim resetFlag As Boolean, ctrl_name As String

resetFlag = False
txt = Nz(frm.Controls(fldList).Value, &quot;&quot;)
ctrl_name = frm.Controls(fldList).Name
If Len(txt) = 0 Then
   resetFlag = True
Else
   'split the field list sepparate with commas
   'and load them into the Array: splt()
   splt = Split(txt, &quot;,&quot;)
End If
'   Set frm = Me
   'initialize all Textboxes and Combobox Tag &amp; Default Value
   'Properties, except the <i>FieldList</i> textbox.
   'and change all field's Forecolor to black.
   For Each ctl In frm.Controls
      ctlType = ctl.ControlType
      ctlName = ctl.Name
      If ctlName = ctrl_name Then GoTo nextitem

      If ctlType = 109 Or ctlType = 111 Then
         ctl.Tag = &quot;&quot;
         ctl.DefaultValue = &quot;&quot;
         ctl.ForeColor = vbBlack
      End If
nextitem:
   Next

   frm.Repaint 'show the change color on the form
   If resetFlag Then 'if the fieldlist textbox was empty then exit
     Exit Function
   End If

'Compare each field's name on the form with the field names
'selected and stored in the 'FieldList' Array.
   For Each ctl In frm.Controls
      ctlName = ctl.Name
      ctlType = ctl.ControlType
      'control-type 109 is Textbox and 111 is combobox
      'only these controls are duplicated
      If ctlType = 109 Or ctlType = 111 Then
         For j = 0 To UBound(splt)
            'if a match found then change it's Tag Property Value to 'CarryForward'.
            If Trim(splt(j)) = ctlName Then
               ctl.Tag = &quot;CarryForward&quot;
            End If
         Next

      End If
   Next

End Function

Public Function SetDefaultValue(ByVal frm As Form)
'---------------------------------------------------------------------
'Author: a.p.r. pillai
'Date  : Feb 2012
'Rights: All Rights Rserved by www.msaccesstips.com
'Run this Procedure when the Form_Update() Event Procedure fires.
'---------------------------------------------------------------------
Dim ctl As Control
For Each ctl In frm.Controls
If ctl.ControlType = 109 Or ctl.ControlType = 111 Then
      'if a control found with it's Tag Property set with the text 'CarryForward'
      'copy the current field value into the Default Property.
      'When the new record is created the Default Value will automatically
      'appear in the new record.
      If ctl.Tag = &quot;CarryForward&quot; Then
          ctl.DefaultValue = Chr$(34) &amp; ctl.Value &amp; Chr$(34)

      End If
           'change the color of the data to black
           ctl.ForeColor = vbBlack
End If

Next ctl
frm.Repaint

End Function

Public Function SetColorChange(ByVal frm As Form)
'---------------------------------------------------------------------
'Author: a.p.r. pillai
'Date  : Feb 2012
'Rights: All Rights Rserved by www.msaccesstips.com
'Note  : This Function is run from the Form_Current() Event Procedure.
'---------------------------------------------------------------------

Dim ctl As Control
If frm.NewRecord Then
     For Each ctl In frm.Controls
         If ctl.ControlType = 109 Or ctl.ControlType = 111 Then
            'Format the copied values with Red Color.
            If ctl.Tag = &quot;CarryForward&quot; Then
               ctl.ForeColor = vbRed
            End If
         End If
     Next
frm.Repaint
End If

End Function</pre>
<p><!--INFOLINKS_ON-->
  </li>
<li>Open the <strong>FamilyDetails </strong>Form in Design View. </li>
<li>Key in your own personal information (or the sample data from the first image above), but don&#8217;t move to the next new record now. </li>
<li>Key in the following data field names into the text box ,in the header of the Form, separated with commas.
<pre class="alt1">

FamilyID,Add1,Add2,City,State,Country,PIN
</pre>
<p>Set the Child Labels of Text Boxes with the actual fields names (as shown in the above image) so that <a href="http://msaccesstips.com/2011/10/users-and-groups-listing-from-workgroup-information-file/" target="_blank">Users</a> can type the required field names correctly from these labels.</p>
</li>
<li>Click on the <a href="http://www.msaccesstips.com/2009/01/command-button-animation-2/" target="_blank">Command Button</a>.
<p>Note: <i>The Command Button Click Event Procedure calls the <strong>SetTagValue()</strong> Function, with the <strong>Form object</strong> and the Textbox name: <strong>FieldList </strong>as parameters, that reads the Field List and records the text &#8216;CarryForward&#8217; in each field&#8217;s <strong>Tag</strong> Property. Remember, we have not yet updated the current record into the Table.</i></p>
</li>
<li>Press <strong>Ctrl+S</strong> to update the current record and run the <strong>Form_AfterUpdate()</strong> Event Procedure that runs SetDefaultValue() function.
<p>Current record field (having their <strong>Tag</strong> Property set with the text &#8216;CarryForward&#8217;) values are copied into the Default Value Property of that field. The default values will appear in those fields in a new record automatically.</p>
<p><i>Note: The <strong>Tag</strong> Property Value &amp; Default Value are saving in those properties in Form View, not in design view. When you close the Form these settings are lost from these Properties. If you open the Form again you must specify the list of fields in the text box and click the Command Button to set the &#8216;CarryForward&#8217; text in the Tag Property again.</i> </p>
<p>But, if you want certain fields to be assigned with permanent duplication feature on new records then open the form in design view and type the text <strong>CarryForward</strong> in the Tag Property manually and save the Form. In that case you don&#8217;t need the Text Box for the field list and Command Button on the header of the Form.</p>
</p>
</li>
<li>Press Ctrl++ to create a new record.
<p>The values we have saved in the Default Value Property (through the Form_AfterUpdate() event procedure) appears in the new record. The Form_Current() event procedure runs too and the color of the duplicated text changes to red. Now, all that left to do is to key in the rest of the information.</p>
<p>The <strong>Ctrl+S</strong> first to update the current record and then the <strong>Ctrl+Plus</strong> next to create a new record steps we have taken only to explain what happens at each stage. </p>
<p>After keying in the data on a record the User can directly press Ctrl+Plus (click on the <strong>New (Blank) Record</strong> control on the navigation control at the bottom of the form) to create a new record. This action will also fire the <strong>Form_AfterUpdate()</strong> event first and then the <strong>Form_Current()</strong> event next.</p>
</li>
</ol>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4d798c32-8a37-4cd3-81a5-8c2e06d0088a" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Microsoft" rel="tag">Microsoft</a></div>
<ul>
<li><a href="http://msaccesstips.com/2011/08/running-workgroup-admin-in-access2007/">Running Workgroup Admin in access2007</a> </li>
<li><a href="http://msaccesstips.com/2011/08/apply-filter-to-table-directly/">Apply Filter to Table directly</a> </li>
<li><a href="http://msaccesstips.com/2011/07/dynamic-dlookup-in-query-column/">Dynamic Lookup in Query Column</a> </li>
<li><a href="http://msaccesstips.com/2011/07/creating-watermark-on-ms-access-reports/">Creating Water-mark on Ms-Access Reports</a> </li>
<li><a href="http://msaccesstips.com/2011/07/iseries-date-in-exported-data/">iSeries Date in exported Data</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/02/duplicating-fields-with-conditional-formatting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Use Form Filter on Report</title>
		<link>http://msaccesstips.com/2012/01/how-to-use-form-filter-on-report/</link>
		<comments>http://msaccesstips.com/2012/01/how-to-use-form-filter-on-report/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 13:08:24 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Reports]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2245</guid>
		<description><![CDATA[Normally we use a Query or processed data table as Report Source for printing selected data items, like Customer Invoices or Customer Ledger Statement etc. How do we take a print out of the current record on the Form? Let us try this simple method to start with, before using the Form Filter on Report.&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Normally we use a <a href="http://msaccesstips.com/2011/03/top-n-records-in-query/">Query</a> or processed data table as <a href="http://msaccesstips.com/2011/07/creating-watermark-on-ms-access-reports/">Report</a> Source for printing selected data items, like Customer Invoices or Customer Ledger Statement etc.</p>
<p>How do we take a print out of the current record on the Form?</p>
<p>Let us try this simple method to start with, before using the <a href="http://msaccesstips.com/2011/10/updating-sub-form-recordset-from-main-form/">Form</a> Filter on Report.&#160; We need some sample data, a Form and a Report to try this out.</p>
<ol>
<li>Import the <strong>Order details</strong> and <strong>Products</strong> Tables from the Northwind.accdb sample database. </li>
<li>Use the <a href="http://www.msaccesstips.com/2008/12/custom-report-wizard/">Report Wizard</a> and design a Report using the <strong>Order Details</strong> Table as Record Source (sample report view is given below) and save the Report with the name <strong>Rpt_OrderDetails</strong>. <!-- Uploaded_images-->
<p><a href="http://www.msaccesstips.com/uploaded_images/filter-report.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Report Preview" border="0" alt="Report Preview" src="http://www.msaccesstips.com/uploaded_images/filter-report_thumb.jpg" width="403" height="235" /></a></p>
<p> <!-- Uploaded_images--></li>
<li>Use the <a href="http://www.msaccesstips.com/2008/12/custom-made-form-wizard/">Form Wizard</a> and design a multiple items (continuous) Form using the <strong>Order Details</strong> Table (sample data view image is given below) and save it with the name Frm_OrderDetails. <!-- Uploaded_images-->
<p><a href="http://www.msaccesstips.com/uploaded_images/filter-form.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Filter Form View" border="0" alt="Filter Form View" src="http://www.msaccesstips.com/uploaded_images/filter-form_thumb.jpg" width="366" height="253" /></a></p>
<p> <!-- Uploaded_images--></li>
<li>Open the Form Frm_OrderDetails in design view. </li>
<li>Select the Command Button Tool from the <strong>Toolbox</strong> and draw a Command Button on the Header Section of the Form. </li>
<li>While the Command Button is still in selected state display the Property Sheet (<strong>Design</strong> &#8211; - &gt;<strong>Tools</strong> &#8211; - &gt; <strong>Property Sheet</strong> or use <strong>F4</strong>) and select <strong>All </strong>Tab on the <a href="http://www.msaccesstips.com/2009/11/creating-using-form-custom-property/">Property</a> Sheet. </li>
<li>Change the <strong>Name</strong> Property Value to <strong>cmdRpt</strong> and change the <strong>Caption</strong> Property Value to <strong>Run Report </strong>(see the Form image above). </li>
<li>Select the <strong>Event</strong> Tab of the Property Sheet. </li>
<li>Select <strong>[Event Procedure] </strong>from the drop-down list of the <strong>On Click</strong> event property and&#160; click on the Build (<strong>. . .</strong>) button at the right edge of the property to open the VBA window with the skeleton of the <a href="http://www.msaccesstips.com/2008/04/colorfull-command-buttons/">Command Button</a> Click Event Procedure. </li>
<li>Copy and paste the middle line of Code between the existing header and footer lines of the <a title="Double Action Command Button" href="http://www.msaccesstips.com/2008/03/double-action-command-button/" target="_blank">Command Button</a> Click event procedure:
<pre class="alt2">


Private Sub cmdRpt_Click()

   DoCmd.OpenReport &quot;Rpt_OrderDetails&quot;, acViewPreview, , &quot;[order id] = &quot; &amp; Me![order id]

End Sub
</pre>
<p>Check the middle line of the above code. The last parameter to the DoCmd.OpenReport command is a <a title="Find or Filter Data on Form" href="http://www.msaccesstips.com/2007/12/find-or-filter-data-on-form/" target="_blank">Filter</a> condition to select the current record’s <strong>Order ID</strong> number to filter all records with the same Order ID number. We have inserted one extra comma between the printing option and the filter condition to skip the choice of using the name of a <a href="http://www.msaccesstips.com/2008/03/filtering-data-for-different-users/" target="_blank">Query</a> as Report Source Data.</p>
<p>The filter condition <strong>&quot;[Order Id] = &quot; &amp; Me![Order Id]</strong> states that take all the records with the current record <strong>Order ID</strong> Number as source data for the Report.</p>
</p>
</li>
<li>Save the form <strong>Frm_OrderDetails</strong> and open it in normal view </li>
<li>Click on any record with the same <strong>Order ID</strong> in more than one record or any record you like. </li>
<li>Click on the <strong>Run Report</strong> <a href="http://www.msaccesstips.com/2009/01/command-button-animation-2/" target="_blank">Command Button</a> to open the <strong>Rpt_OrderDetails</strong> with the selected record. </li>
<li>Close the Report and you may try it again after selecting some other record on the Form. </li>
</ol>
<p>The above example uses only a single record or several records with the same Order ID to print on the Report.&#160; </p>
<p>Next, we will do it with more flexibility after setting the <strong>Filter</strong> Property Value of the Form. This can be done after selecting one or more Order IDs for filtering the data on the <a href="http://www.msaccesstips.com/2009/01/drill-down-inquiry-screen-2/" target="_blank">Form</a>, before we open the <a href="http://www.msaccesstips.com/2009/06/network-and-print-page-setup-3/" target="_blank">Report</a> for printing the data on the Form.&#160; We must set a reference to the <strong>Filter</strong> Property of the Form replacing the criteria setting we have used earlier: <strong>&quot;[order id] = &quot; &amp; Me![order id], </strong>on the <strong>DoCmd.OpenReport</strong> command.<strong>&#160;</strong>&#160;</p>
<p>With this change the user can filter data based on any column value on the Form (like <strong>Order Id</strong> or <strong>Quantity</strong> or <strong>UnitPrice</strong> etc.) and use the result set to print the Report.</p>
<ol>
<li>Make a copy of the form <strong>Frm_OrderDetails </strong>and paste it with the name <strong>Frm_Orderdetails2</strong>. </li>
<li>Open the form <strong>Frm_Orderdetails2 </strong>in design view. </li>
<li>Click on the Command Button to select and display it’s property sheet (F4). </li>
<li>Select&#160; the <strong>Event</strong> Tab and select the <strong>On Click</strong> property. </li>
<li>Click on the Build (. . .) button to open the VBA window. </li>
<li>Copy the following Code and paste replacing the existing lines of code on the Form Module:
<pre class="alt2">Private Sub cmdRpt_Click()
    If Me.Filter = &quot;&quot; Then
        MsgBox &quot;Apply a filter to the Form first.&quot;
    Else
        DoCmd.OpenReport &quot;Rpt_OrderDetails&quot;, acViewPreview, , Me.Filter
    End If
End Sub</pre>
</li>
<li>Check the last parameter setting in the DoCmd.OpenReport statement. We are asking the Report to use whatever criteria setting is available in the current Form’s (<strong>Me</strong>) <strong>Filter </strong>Property Value (like <strong>([Order Details].[Order ID] In (30,31,32))</strong>) to pick records for the Report<strong>. </strong>Save the Form and open it in normal view. </li>
<li>Click on the Command Button to open the <a href="http://www.msaccesstips.com/2009/07/hiding-report-lines-conditionally-3/" target="_blank">Report</a>.
<p>You will be greeted with a message asking to &#8216;<em>Apply a filter to the Form first</em>&#8216;. When you click on the <a href="http://www.msaccesstips.com/2006/09/command-button-animation/" target="_blank">Command Button</a> the program checks whether the Form&#8217;s <strong>Filter</strong> Property is set with a Filter condition or not, like the text we have used in the first example above, or like the sample shown in <strong>Step-7</strong> above.</p>
<p><strong>Note:</strong> Remember, once you apply a filter on the form the text of the last filter condition remains saved on the Filter Property.&#160; The Filter action is supported with another property value setting: <strong>FilterOn</strong> <strong>= True/False</strong>. When you <strong>Toggle</strong> the filter action on the Form the <strong>FilterOn </strong>property value changes but the Filter property value criteria text is not removed. You will be greeted with the above message only when the <strong>Filter</strong> Property Value is empty.</p>
</li>
<li>Click on the <strong>Order ID</strong> column on any record. </li>
<li>Click on the Filter Toolbar button (see the image below)to display the Filter selection control. <!-- Uploaded_images-->
<p><a href="http://www.msaccesstips.com/uploaded_images/filter-button-click.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Filter Button Action" border="0" alt="Filter Button Action" src="http://www.msaccesstips.com/uploaded_images/filter-button-click_thumb.jpg" width="367" height="267" /></a></p>
<p><!-- Uploaded_images--></p>
<p>A list of the selected field values (Order ID numbers) are displayed and shows all the values are check marked, indicating that all the values are in selected state.</p>
</li>
<li>Click on the <strong>Select All </strong>Option to de-select all the items. </li>
<li>Now, put check marks on the Order ID Numbers 30, 31 &amp; 32 and Click <strong>OK </strong>to close the Filter Control.
<p>The form now shows only records of Order ID numbers 30, 31 &amp; 32.</p>
</li>
<li>Click on the <strong>Run Report</strong> Command Button on the Header of the Form to open the Report in Print Preview with the records filtered on the Form. </li>
<li>Close the Report. </li>
<li>Place the cursor on the <strong>Quantity</strong> Field on any record on the Form. </li>
<li>Click on the <strong>Filter</strong> Toolbar Button to display the Filter Control. </li>
<li>Select the items with the Quantity values <strong>100,200 &amp; 300</strong> and click <strong>OK</strong> button to close the control and filter the records you have selected. </li>
<li>Open the Report by clicking on the Run Report Command Button and check the report contents. </li>
<li>Close the Report. </li>
<li>Click on the <strong>Toggle Filter </strong>Toolbar button<strong>.&#160; </strong>The Filter action is reversed and all the records are back on the Form (or the <strong>FilterOn </strong>Property Value is set as <strong>False </strong>now). </li>
<li>Now, Click on the <strong>Run Report </strong>Command Button to preview the Report.&#160; </li>
</ol>
<p>The <a href="http://www.msaccesstips.com/2009/07/msaccess-report-and-page-totals/" target="_blank">Report</a> shows the last filtered records only, rather than all the records from the Form.&#160; When we toggle the filter Microsoft Access sets the <strong>FilterOn </strong>Property Value to <strong>False</strong> nullifying the effect of the filter action on the form, without removing the filter condition string inserted in the <strong>Filter </strong>Property, because the User may click the <strong>Toggle Filter</strong> button again to bring back data filtered by the last set filter condition. Our program keep using it because the Filter Property value is not empty and we are not checking the status of the <strong>FilterOn </strong>Property setting.</p>
<p>But, we can solve this issue with few changes in our program as follows:</p>
<pre class="alt3">

Private Sub cmdRpt_Click()
    If Me.FilterOn Then
        DoCmd.OpenReport &quot;Rpt_OrderDetails&quot;, acViewPreview, , Me.Filter
    Else
        DoCmd.OpenReport &quot;Rpt_OrderDetails&quot;, acViewPreview
    End If
End Sub
</pre>
<p>Change the program as shown above and try the effect of the Filter and Toggle Filter action on the Form as well as on the <a href="http://www.msaccesstips.com/2009/07/detail-and-summary-from-same-report/" target="_blank">Report</a>.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:6fe31042-1830-48b8-a5df-67648a231bab" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Reports" rel="tag">Reports</a>,<a href="http://technorati.com/tags/Microsoft" rel="tag">Microsoft</a></div>
<ul>
<li><a href="http://msaccesstips.com/2011/08/apply-filter-to-table-directly/">Apply Filter to Table directly</a> </li>
<li><a href="http://msaccesstips.com/2011/07/dynamic-dlookup-in-query-column/">Dynamic Lookup in Query Column</a> </li>
<li><a href="http://msaccesstips.com/2011/07/creating-watermark-on-ms-access-reports/">Creating Water-mark on Ms-Access Reports</a> </li>
<li><a href="http://msaccesstips.com/2011/07/iseries-date-in-exported-data/">iSeries Date in exported Data</a> </li>
<li><a href="http://msaccesstips.com/2011/06/change-query-top-values-property-with-vba/">Change Query Top Values property with VBA</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/01/how-to-use-form-filter-on-report/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Saving Report Pages as separate PDF Files</title>
		<link>http://msaccesstips.com/2012/01/saving-report-pages-as-separate-pdf-files/</link>
		<comments>http://msaccesstips.com/2012/01/saving-report-pages-as-separate-pdf-files/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 06:47:05 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2242</guid>
		<description><![CDATA[You are printing several Customer Invoices as a single Report, running into several pages.&#160; You have problems with this kind of Reports in segregating the Invoices and physically mailing them to the customers.&#160; If all Invoices can be saved on disk in separate PDF Files then it is easy to send them through emails to [...]]]></description>
			<content:encoded><![CDATA[<p>You are printing several Customer Invoices as a single Report, running into several pages.&#160; You have problems with this kind of <a href="http://msaccesstips.com/2011/05/continued-on-page-2-on-report/">Reports</a> in segregating the Invoices and physically mailing them to the customers.&#160; </p>
<p>If all Invoices can be saved on disk in separate PDF Files then it is easy to send them through emails to the customers.&#160; This will not only save the cost of stationery but also delivers the invoices to the customers’ mailbox instantly without delay.&#160; Besides that customers can easily view the Invoices on their machines or take printouts at their end, if that become necessary.&#160; In short, part of our tasks are passed on to the customers, saving our time and money.&#160; I don’t think I can stretch it any more.</p>
<p>Let us try this with one or two Tables from the Northwind.mdb sample database.</p>
<ol>
<li>Import the following Tables from the Northwind.mdb (or Access2007 Northwind.accdb) sample <a href="http://www.msaccesstips.com/2008/08/database-connection-string-properties/">database</a>:
<ul>
<li>Order Details </li>
<li>Products&#160; </li>
</ul>
<p>NB: I will be using Tables from the Northwind.mdb database. But, the queries, Report and Code will be running under Access2007. The <strong>Products</strong> Table is not used directly in our <a href="http://www.msaccesstips.com/2010/01/auto-numbering-in-query-column/">Query</a> or Report but the ProductID <a href="http://www.msaccesstips.com/2009/01/combo-box-column-values/">combobox</a> in the <strong>Order Details</strong> table references this table for product description.</p>
</li>
<li>Open a new <a href="http://www.msaccesstips.com/2009/12/filter-with-buildcriteria-function/">Query</a> in SQL View without selecting any Table/Query from the displayed list. </li>
<li>Copy and Paste the following SQL string into the new Query’s SQL editing window and save the Query with the name <strong>Invoice_Orders_0:</strong>
<pre class="alt3">SELECT [Order Details].OrderID,
 [Order Details].ProductID,
 [Order Details].Quantity,
 [Order Details].UnitPrice,
 [Order Details].Discount,
 [Quantity]*((1-[Discount])*[UnitPrice]) AS TotalValue
FROM [Order Details];</pre>
</li>
<li>After saving and closing the above Query create another Query, using <strong>Invoice_Orders_0</strong> as source, with the following SQL:
<pre class="alt2">SELECT Invoice_Orders_0.*
FROM Invoice_Orders_0
WHERE (((Invoice_Orders_0.OrderID)=10258));</pre>
</li>
<li>Save the new Query with the name <strong>Invoice_Orders_1</strong>. </li>
<li>Design a Report to print Sales Invoice using <strong>Invoice_Orders_1</strong> Query as Record Source.
<p>Sample Report Design Image is given below:</p>
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/invoice-design.jpg"><img style="display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Invoice Design View" border="0" alt="Invoice Design View" src="http://www.msaccesstips.com/uploaded_images/invoice-design_thumb.jpg" width="394" height="251" /></a></p>
<p><!-- Uploaded_images--></p>
<p>Sample Report Preview Image is the next one:</p>
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/invoice-preview.jpg"><img style="display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Invoice Preview" border="0" alt="Invoice Preview" src="http://www.msaccesstips.com/uploaded_images/invoice-preview_thumb.jpg" width="461" height="249" /></a></p>
<p><!-- Uploaded_images--></li>
<li>Copy and paste the following <a href="http://www.msaccesstips.com/2008/06/repairing-compacting-database-with-vba/">VBA</a> Code into a Standard <a href="http://msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/">Module</a> and save it:<!--INFOLINKS_OFF-->
<pre>Public Function Create_PDF(ByVal OrderStart As Integer, ByVal OrderEnd As Integer, ByVal strPath As String)
'--------------------------------------------------------------------------------
'Author : a.p.r. pillai
'Date   : January 2012
'Rights : All Rights(c) Reserved by www.msaccesstips.com
'--------------------------------------------------------------------------------
'Function Parameters:
' 1. - OrderID Start Number
' 2. - OrderID End Number
' 3. - Target Folder Address, sample: C:\My Documents
'--------------------------------------------------------------------------------
Dim strsql_1 As String, strsql As String, criteria As String
Dim db As Database, rst As Recordset, QryDef As QueryDef
Dim int_Order As Integer, outFile As String, T As Date
Dim SQLParam As String, i As Integer, msg As String

'Invoice Query Definition, Order Number must be added at the end as criteria
strsql_1 = &quot;SELECT Invoice_Orders_0.*  FROM Invoice_Orders_0 &quot;
strsql_1 = strsql_1 &amp; &quot; WHERE (((Invoice_Orders_0.OrderID)=&quot;

'Query definition for Order Numbers between OrderStart and OrderEnd numbers
SQLParam = &quot;SELECT DISTINCT [Order Details].OrderID FROM [Order Details] &quot;
SQLParam = SQLParam &amp; &quot;WHERE ((([Order Details].OrderID) Between &quot; &amp; <strong>OrderStart</strong> &amp; &quot; And &quot; &amp; <strong>OrderEnd</strong> &amp; &quot;)) &quot;
SQLParam = SQLParam &amp; &quot; ORDER BY [Order Details].OrderID;&quot;

Set db = CurrentDb
'open the OrderIDs parameter list to process one by one
Set rst = db.OpenRecordset(SQLParam, dbOpenDynaset)
'open the Report Query definition to incorporate OrderID criteria
Set QryDef = db.QueryDefs(&quot;Invoice_Orders_1&quot;)

i = 0 'take a count of invoices printed
Do While Not rst.EOF 'cycle through the parameter list
  'get the order number
  int_Order = Nz(rst!OrderID, 0)
  If int_Order &gt; 0 Then 'if any blank record ignore
     i = i + 1
     'create the criteria part for the Invoice Query
     criteria = int_Order &amp; &quot;));&quot;
     'complete the Invoice SQL by adding the criteria.
     strsql = strsql_1 &amp; criteria
     'Redefine the Invoice Query to print the Invoice
     QryDef.sql = strsql
     db.QueryDefs.Refresh

     'PDF file's target path and Order Number is the file name.
     outFile = strPath &amp; &quot;\&quot; &amp; int_Order &amp; &quot;.PDF&quot;

     'Save the report as pdf file.
     DoCmd.OutputTo acOutputReport, &quot;Rpt_Invoice&quot;, &quot;PDFFormat(*.pdf)&quot;, outFile, False, &quot;&quot;, 0, acExportQualityPrint

  '2 seconds delay loop to give enough time for Access to create the file on disk.
  T = Timer
  Do While Timer &lt; T + 2
    DoEvents
  Loop
 End If
  rst.MoveNext
Loop
rst.Close

msg = &quot;Order Start Number: &quot; &amp; OrderStart &amp; vbCr &amp; vbCr
msg = msg &amp; &quot;Order End Number: &quot; &amp; OrderEnd &amp; vbCr &amp; vbCr
msg = msg &amp; &quot;Invoices Printed: &quot; &amp; i &amp; vbCr &amp; vbCr
msg = msg &amp; &quot;Target Folder: &quot; &amp; strPath

MsgBox msg, , &quot;Create_PDF()&quot;

Set rst = Nothing
Set db = Nothing
Set QryDef = Nothing

End Function</pre>
</li>
</ol>
<p><!--INFOLINKS_ON--></p>
<p>Now, let us take a look at what preparations we have made so far:</p>
<p>The first Query (<strong>Invoice_Orders_0</strong>) selects the required fields from <strong>Order Details</strong> Table for the Customer Invoice Report. Besides that it calculates the <strong>Total Value</strong> after Discount of each record in the Query. But, in this Query we have not set any criteria to select any specific <strong>OrderID</strong>&#160; or Range of OrderIDs for printing the Invoices. </p>
<p>We are setting criteria to select specific OrderID in the second Query (<strong>Invoice_Orders_1</strong>),&#160; created using the earlier Query (<strong>Invoice_Orders_0</strong>) as Source. The two step query simplifies the SQL and we must take the SQL into the VBA Code to redefine the Query, with changing OrderIDs, so that each OrderId level Invoice is saved in separate PDF file on Disk.&#160; </p>
<p>We have one more Query (the third Query saved in SQLParam String Variable is used directly in the <font class="colrgreen">Set rst = db.OpenRecordset(SQLParam, dbOpenDynaset)</font> statement) that is totally confined into the <strong>Create_PDF()</strong> Function.&#160; When the Create_PDF() Function is called you must give the <strong>Order Start Number,</strong>&#160;<strong>Order End Number</strong> and <strong>Target Folder Address</strong>, where the PDF Files are to be saved, as function parameters. The third Query extracts all the Order Numbers within the Start Number and End Number range.&#160; These will be taken one by one to print Invoices in individual files.</p>
<p><em><strong>NB</strong>:&#160; To make this sample exercise simple we are using only the transaction file to print the Invoices.&#160; As you can see from the Report specimen shown above it doesn’t have any Customer Address printed on it.&#160; If this is required then we must consider setting relationships with the Customer Address Table in the Report Query and include the address fields also. The main idea behind this whole exercise is to save the report of individual Invoices in separate pdf files, rather than going into its’ details or refinement. </em></p>
<p>Keeping that in focus let us continue to review what we are doing in the <a href="http://www.msaccesstips.com/2008/06/working-with-chart-object-in-vba/">VBA</a> Code lines.&#160; You must call the Function using the following</p>
<p>Syntax:</p>
<p><font class="colrgreen">Create_PDF&#160; StartNumber,&#160; EndNumber, ”PDF Files Target Folder”)</font></p>
<p>Example-1:</p>
<pre class="alt1">

Create_PDF 10248,10265,”C:\My Documents”

&#160;

Example-2:

&#160;

x = Create_PDF(10248,10265,”C:\My Documents”)

&#160;
</pre>
<p>You may call the function from a <a href="http://www.msaccesstips.com/2008/04/colorfull-command-buttons/">Command Button</a> Click Event Procedure, after setting the Parameter values in <a href="http://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins/">Text Boxes</a> on the <a href="http://www.msaccesstips.com/2008/10/form-menu-bars-and-toolbars/">Form</a></p>
<pre class="alt1">

Example-3:

Create_PDF Me![txtSNumber], Me![txtENumber], Me![txtPathName]</pre>
<p>With the <strong>Start Number</strong> and <strong>End Number </strong>values the Parameter Query is redefined to extract all the Order Numbers between those two numbers from the Order Details Table so that they can be used for extracting Order-wise items for printing individual Invoices.&#160; The SELECT DISTINCT clause suppresses duplicates from the parameter list.</p>
<p>The data source of <strong>Rpt_Invoice </strong>Report is <strong>Invoice_Orders_1 </strong>Query<strong>. </strong>This<strong> </strong>is redefined for each <strong>OrderId</strong> as criteria for printing the <strong>Rpt_Invoice</strong> in PDF format.&#160; The PDF files are saved in the location specified as third parameter <strong>C:\My Documents.</strong></p>
<p>Each line in the <a href="http://www.msaccesstips.com/2008/09/link-external-tables-with-vba/">VBA</a> Code is commented to indicate what it does in each step, please go through them to understand the code better.</p>
<p>Key Words:<a ref="http://msaccesstips.com/2012/01/saving-report-pages-as-separate-pdf-files/#">PDF Files, </a><a ref="http://msaccesstips.com/2012/01/saving-report-pages-as-separate-pdf-files/#">Invoice, </a><a ref="http://msaccesstips.com/2012/01/saving-report-pages-as-separate-pdf-files/#">Report, </a><a ref="http://msaccesstips.com/2012/01/saving-report-pages-as-separate-pdf-files/#">Access2007</a> </p>
<ul>
<li><a href="http://msaccesstips.com/2011/07/dynamic-dlookup-in-query-column/">Dynamic Lookup in Query Column</a> </li>
<li><a href="http://msaccesstips.com/2011/07/creating-watermark-on-ms-access-reports/">Creating Water-mark on Ms-Access Reports</a> </li>
<li><a href="http://msaccesstips.com/2011/07/iseries-date-in-exported-data/">iSeries Date in exported Data</a> </li>
<li><a href="http://msaccesstips.com/2011/06/change-query-top-values-property-with-vba/">Change Query Top Values property with VBA</a> </li>
<li><a href="http://msaccesstips.com/2011/06/creating-animated-command-button-with-vba/">Creating Animated Command Buttons</a>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1b4dd8b8-1383-4f91-973a-4372c9f102bd" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Utility" rel="tag">Utility</a></div>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/01/saving-report-pages-as-separate-pdf-files/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AutoNumber with Date and Sequence Number</title>
		<link>http://msaccesstips.com/2012/01/autonumber-with-date-and-sequence-number/</link>
		<comments>http://msaccesstips.com/2012/01/autonumber-with-date-and-sequence-number/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 13:16:22 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[How Tos]]></category>
		<category><![CDATA[Auto-Number]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2238</guid>
		<description><![CDATA[We always make use the Autonumber feature in tables to create a unique ID field for the table. It is easy to define and always starts the auto-number with 1 and increments by 1 for each record, unless you set the New Values property to Random rather than the default value Increment. What is the [...]]]></description>
			<content:encoded><![CDATA[<p>We always make use the <a href="http://www.msaccesstips.com/2010/01/auto-numbering-in-query-column/">Autonumber</a> feature in tables to create a unique ID field for the table. It is easy to define and always starts the auto-number with 1 and increments by 1 for each record, unless you set the <strong>New Values</strong> property to <strong>Random</strong> rather than the default value <strong>Increment.</strong></p>
<p>What is the solution if we need different sequence numbers for the records that we create on each day?</p>
<p>For example, assume we are working on a Hospital Project and patients getting registered in the hospital on a particular day should have a unique <strong>Registration Card Number</strong> consisting of current date and a three digit sequence number in the format: yyyymmdd000. The sequence number must reset to 001 when the date changes.</p>
<p>If the Hospital maintains history records of the patients in physical files, organized by Date, Month and Year-wise order it is easy for them to locate any file with the Registraion Card Number.</p>
<p>We can generate this number automatically with a Function.&#160; Let us try it with a sample Table and <a href="http://www.msaccesstips.com/2009/09/dynamic-listbox-combobox-contents/">Form</a>.</p>
<p>Before that copy and paste the following Function Code into a Standard VBA Module and save it:</p>
<p> <!--INFOLINKS_OFF-->
<pre>Public Function Autonum(ByVal strField As String, ByVal strTable As String) As String
Dim dmval As String, dt1 As String, dt2 As String, Seq As Integer, dv As String

'get the highest existing value from the table
dmval = Nz(DMax(strField, strTable), 0)

'if returned value is 0 then the table is new and empty
'create autonumber with current date and sequence 001
If Val(dmval) = 0 Then
   dv = Format(Now(), &quot;yyyymmdd&quot;) * 1000 + 1
   Autonum = dv
   Exit Function
End If

'format the number as an 11 digit number
dv = Format(dmval, &quot;00000000000&quot;)
'take the 3 digit sequence number separately
Seq = Val(Right(dv, 3))
'take the date value separately
dt1 = Left(dv, 8)
'get today's date
dt2 = Format(Now(), &quot;yyyymmdd&quot;)
'compare the latest date taken from the table
'with today's date
If dt1 = dt2 Then 'if both dates are same
   Seq = Seq + 1 'increment the sequence number
   'add the sequence number to the date and return
   Autonum = Format(Val(dt1) * 1000 + Seq)
   Exit Function
Else 'the dates are different
   'take today's date and start the sequence with 1
   Autonum = Format(Val(dt2) * 1000 + 1)
End If

End Function</pre>
<p><!--INFOLINKS_ON--></p>
<ol>
<li>Create a sample Table with the following Structure, as shown in the image given below:
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/autonum-struct.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Sample Table Structure" border="0" alt="Sample Table Structure" src="http://www.msaccesstips.com/uploaded_images/autonum-struct_thumb.jpg" width="239" height="218" /></a></p>
<p><!-- Uploaded_images--></p>
</li>
<li>The <strong>CardNo</strong> Field is a text type with 11 characters in length.&#160; Both second and third fields are also text fields with sizes 10 and 50 characters respectively. </li>
<li>Save the Table with the name <strong>Patients</strong>. </li>
<li>Use the <a href="http://www.msaccesstips.com/2008/12/custom-made-form-wizard/">Form Wizard</a> to design a <a href="http://www.msaccesstips.com/2008/11/event-trapping-summary-on-datasheet/">Datasheet Form</a> for the Patients Table and name the Form as <strong>frm_Patients</strong>. </li>
<li>Open the Form in Design View. </li>
<li>Click on the <strong>CardNo </strong>Field to select it. </li>
<li>Display the Property Sheet (<strong>F4</strong>). If you are using Access2007 then you can select CardNo from the Selection Type drop-down list. </li>
<li>Select the <strong>Data</strong> Tab and set the following <a href="http://www.msaccesstips.com/2008/09/source-connect-str-property-and-odbc/">Property</a> Values as shown below:
<ul>
<li>Enabled = Yes </li>
<li>Locked = Yes </li>
</ul>
</li>
<li>Access2007 users select <strong>Form</strong> from the <strong>Selection Type</strong> drop-down control<strong>.</strong> Earlier version users click on the top left corer of the Form (in the intersection where a black rectangle is shown) to ensure that the <a href="http://www.msaccesstips.com/2009/11/creating-using-form-custom-property/">Property Sheet</a> belongs to the Form and not of any other control on the Form. </li>
<li>Select the <strong>Event </strong>Tab on the Property Sheet. </li>
<li>Select the <strong>Before Insert</strong>&#160; event property and select <strong>Event Procedure</strong> from the drop-down list. </li>
<li>Click on the Build (. . .) button to open the VBA Module of the Form. </li>
<li>Copy the middle line of the following procedure and paste it in the middle of the empty <strong>Form_BeforeInsert()</strong> lines of Code in the Form <a href="http://msaccesstips.com/2011/11/vba-module-object-and-methods/">module</a>. <!--INFOLINKS_OFF-->
<pre class="alt1">Private Sub Form_BeforeInsert(Cancel As Integer)
  Me![CARDNO] = Autonum(&quot;CardNo&quot;, &quot;Patients&quot;)
End Sub</pre>
<p><!--INFOLINKS_ON--></li>
<li>Save the Form <strong>frm_Patients </strong>with the changes made. </li>
<li>Open the form in normal view and type <strong>Mr.</strong> in the <strong>Title</strong> Field and type some name in the <strong>Patient Name</strong> field.&#160; You can see that the first field is filled with current date in yyyymmdd format and the sequence number <strong>001</strong> as suffix. </li>
<li>Type few more records.&#160; Since, we have locked the <strong>CardNo </strong>field Users cannot edit this field’s contents. Sample image is given below: </li>
</ol>
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/autonum-in-action.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Autonum Data Entry" border="0" alt="Autonum Data Entry" src="http://www.msaccesstips.com/uploaded_images/autonum-in-action_thumb.jpg" width="375" height="147" /></a></p>
<p><!-- Uploaded_images--></p>
<ol>
<li>Now, we will test whether the sequence number resets to 001 or not when the date changes. To do that first close the <strong>frm_Patients</strong> Form. </li>
<li>Open the Patients Table directly in Datasheet View. </li>
<li>Change the 7th and 8th digit from left (the dd digits of the date) to previous date in all the records that you have entered so far.&#160; </li>
<li><strong>For example</strong>: if the date displayed is 201201<strong>09</strong>001<strong> </strong>then change it to previous day like: 201201<strong>08</strong>001. </li>
<li>When you have completed changing all the records close the Table. </li>
<li>Open the Form <strong>frm_Patients</strong> in normal view and try adding few more records on the Form.&#160; </li>
</ol>
<p><em>Tip:&#160; If you prefer to test it on different dates on next few days you may do so rather than changing the dates and trying it now itself.</em></p>
<p>You can see that the Sequence number at the end of the CardNo resets to <strong>001</strong> with current date and subsequent records’ last three digits gets incremented automatically.&#160; </p>
<p>The user cannot change the CardNo manually because we have set the <strong>Locked</strong> Property Value of the field to <strong>Yes.&#160; </strong>Since, the <strong>Enabled</strong> Property Value also set to <strong>Yes </strong>the <a href="http://msaccesstips.com/2011/04/user-level-access-security-and-access2007/">User</a> can select this field and search for a specific CardNo, if needed.</p>
<p>If you would like to display the sequence number part separate from the date with a dash, (like: 20120109-005) we can do that by changing the <strong>Input Mask</strong> Property of the field, without affecting how it is recorded on the table.</p>
<ol>
<li>Open the <strong>frm_Patients</strong> in Design View. </li>
<li>Click on the CardNo field to select it. </li>
<li>Display the Property Sheet (<strong>F4</strong>) of the Field. </li>
<li>Type <strong>99999999-999;;_</strong> in the <strong>Input Mask</strong> Property.&#160;
<p><em>Tip: When you set the input mask this way the dash character between the date and sequence number is never stored in the table, it is used for display purposes only.&#160; But, if you enter a <strong>0</strong> between the two semi-colons like 99999999-999;0;_ then the dash character also will be stored in the CardNo field on the table.&#160; It is better if we don’t do that.</em></p>
</li>
<li>Save the Form and open it in normal view.&#160; Now you can distinguish the date and sequence number very easily. </li>
</ol>
<p>Assume that a Patient approaches the registration desk with her Registration Card, the staff member at the desk should search for the patient’s record with the CardNo to retrieve her history record, to know the location of her personal file, to know which doctor the patient attended last etc.&#160; You have two search options when the search control is displayed.&#160; </p>
<p>Try the following:</p>
<ol>
<li>Click on the CardNo field to select it. </li>
<li>Press <strong>Ctrl+F</strong> to display the search control (search control image is given below). </li>
</ol>
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/CardNo-Search.jpg"><img style="display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Autonum Data Search" border="0" alt="Autonum Data Search" src="http://www.msaccesstips.com/uploaded_images/CardNo-Search_thumb.jpg" width="286" height="210" /></a></p>
<p><!-- Uploaded_images--></p>
<p>As shown on the image above you can search for the CardNo without the dash if you remove the check mark from the search option <strong>Search Field as Formatted.&#160; </strong>Put the check-mark on when searched with the dash separating date and sequence number.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2156e8da-af14-4714-bb92-97571cec90bd" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Autonumber" rel="tag">Autonumber</a>,<a href="http://technorati.com/tags/Forms" rel="tag">Forms</a>,<a href="http://technorati.com/tags/Property" rel="tag">Property</a></div>
<ul>
<li><a href="http://msaccesstips.com/2011/07/creating-watermark-on-ms-access-reports/">Creating Water- mark on Ms-Access Reports</a> </li>
<li><a href="http://msaccesstips.com/2011/07/iseries-date-in-exported-data/">iSeries Date in exported Data</a> </li>
<li><a href="http://msaccesstips.com/2011/06/change-query-top-values-property-with-vba/">Change Query Top Values property with VBA</a> </li>
<li><a href="http://msaccesstips.com/2011/06/creating-animated-command-button-with-vba/">Creating Animated Command Buttons</a> </li>
<li><a href="http://msaccesstips.com/2011/05/data-change-monitoring/">Data Change Monitoring</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2012/01/autonumber-with-date-and-sequence-number/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Assigning Module Level Error Trap Routines</title>
		<link>http://msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/</link>
		<comments>http://msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 17:12:13 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/?p=2226</guid>
		<description><![CDATA[Last week I have introduced a Function to insert Error Handling lines into a VBA Function or Sub-Routine automatically.&#160; Readers commented saying that it is a good utility but its usage is somewhat cumbersome.&#160; Before running that function the user has to spot some text to search for and then run the function with that [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I have introduced a <a href="http://www.msaccesstips.com/2007/09/useful-report-functions/">Function</a> to insert Error Handling lines into a VBA Function or Sub-Routine automatically.&#160; Readers commented saying that it is a good utility but its usage is somewhat cumbersome.&#160; </p>
<p>Before running that function the user has to spot some text to search for and then run the function with that search text as parameter. The utility function searches for the text, with <strong>.Find()</strong> method of the Module Object, to find the search text and select that line within the target Function/Sub-Routine.&#160; Based on the selected line we can read other details of the function/sub-routine, like total number of lines within that function/sub-routine, function header line number and function ending line number.&#160; These <a href="http://www.msaccesstips.com/2009/12/save-user-specific-parameter-values/">parameters</a> must be available to insert the error handling lines in appropriate locations within the procedure.</p>
<p>If there are several functions or sub-routines to insert error handling lines then this method takes some time to cover all of them, one by one.</p>
<p>Here, we will look at a different version of the same function that scans through the entire Module and inserts error handling lines in all of the Functions/Sub-Routines at one go.</p>
<p>Before that,</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b2592e4c-cf13-4b8e-95b7-fa5da9ee0d83" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Utility" rel="tag">Utility</a></div>
<p> Links to the earlier Articles are given below, just in case if you would like to take a look at the simple methods of the Module Object we have tried earlier:</p>
<p><a href="http://msaccesstips.com/2011/11/writing-vba-code-with-vba/">Write VBA Code with VBA</a></p>
<p><a href="http://msaccesstips.com/2011/11/vba-module-object-and-methods/">VBA Module Object and Methods</a></p>
<p><a href="http://msaccesstips.com/2011/12/prepare-a-list-of-procedure-names-from-a-module/">Prepare a list of Procedure Names from a Module</a></p>
<p><a href="http://msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/">Utility for inserting VBA Error Handler Code</a></p>
<p>The new function is much simpler to use.&#160; Copy and paste the following Code into a new Standard Module and save it:</p>
<pre>Public Function ErrorTrap(ByVal str_ModuleName As String)
On Error GoTo ErrorTrap_Error
'--------------------------------------------------------------
'Program : Inserting Error Handler Lines automatically
'        : in a VBA Module
'Author  : a.p.r. pillai
'Date    : December, 2011
'Remarks : All Rights Reserved by www.msaccesstips.com
'--------------------------------------------------------------
'Parameter List:
'1. strModuleName - Standard Module or Form/Report Module Name
'--------------------------------------------------------------

Dim objMdl As Module, x As Boolean, h As Long, i As Integer
Dim w As Boolean, lngR As Long, intJ As Integer, intK As Integer
Dim linesCount As Long, DeclLines As Long, lngK As Long
Dim str_ProcNames(), strProcName As String, strMsg As String
Dim start_line As Long, end_line As Long, strline As String
Dim lng_StartLine As Long, lng_StartCol As Long
Dim lng_EndLine As Long, lng_EndCol As Long, procEnd As String
Dim ErrHandler As String, lngProcLineCount As Long
Dim ErrTrapStartLine As String, lngProcBodyLine As Long

Set objMdl = Modules(str_ModuleName)

linesCount = objMdl.CountOfLines
DeclLines = objMdl.CountOfDeclarationLines
lngR = 1
strProcName = objMdl.ProcOfLine(DeclLines + 1, lngR)
If strProcName = &quot;&quot; Then
   strMsg = str_ModuleName &amp; &quot; Module is Empty.&quot; &amp; vbCr &amp; vbCr &amp; &quot;Program Aborted!&quot;
   MsgBox strMsg, , &quot;ErrorTrap()&quot;
   Exit Function
End If
strMsg = strProcName
intJ = 0

'Determine procedure Name for each line after declaraction lines
For lngK = DeclLines + 1 To linesCount

  'compare procedure name with ProcOfLine property
  If strProcName &lt;&gt; objMdl.ProcOfLine(lngK, lngR) Then
     'increment by one
     intJ = intJ + 1
     'get the procedure name of the current program line
     strProcName = objMdl.ProcOfLine(lngK, lngR)
  End If
Next lngK

ReDim str_ProcNames(intJ)

strProcName = strMsg: intJ = 0
str_ProcNames(intJ) = strProcName
For lngK = DeclLines + 1 To linesCount
  'compare procedure name with ProcOfLine property

  If strProcName &lt;&gt; objMdl.ProcOfLine(lngK, lngR) Then
     'increment array index by one
     intJ = intJ + 1
     'get the procedure name of the current program line
     strProcName = objMdl.ProcOfLine(lngK, lngR)
     str_ProcNames(intJ) = strProcName

  End If
Next

For intK = 0 To intJ
    ErrHandler = &quot;&quot;
    ErrTrapStartLine = &quot;&quot;
    'Take the total count of lines in the module including blank lines
    linesCount = objMdl.CountOfLines

    strProcName = str_ProcNames(intK) 'copy procedure name
    'calculate the body line number of procedure
    lng_StartLine = objMdl.ProcBodyLine(strProcName, vbext_pk_Proc)
    'calculate procedure end line number including blank lines after End Sub
    lng_EndLine = lng_StartLine + objMdl.ProcCountLines(strProcName, vbext_pk_Proc) + 1

    lng_StartCol = 0: lng_EndCol = 150
    start_line = lng_StartLine: end_line = lng_EndLine

    'Check for existing Error Handling lines in the current procedure
    x = objMdl.Find(&quot;On Error&quot;, lng_StartLine, lng_StartCol, lng_EndLine, lng_EndCol)
    If x Then
         GoTo NxtProc
    Else
     'Create Error Trap start line
         ErrTrapStartLine = &quot;On Error goto &quot; &amp; strProcName &amp; &quot;_Error&quot; &amp; vbCr
    End If

    ErrHandler = vbCr &amp; strProcName &amp; &quot;_Exit:&quot; &amp; vbCr

    lngProcBodyLine = objMdl.ProcBodyLine(strProcName, vbext_pk_Proc)

    'Set procedure start line number to Procedure Body Line Number
    lng_StartLine = lngProcBodyLine
    'calculate procedure end line to startline + procedure line count + 1
    lng_EndLine = lng_StartLine + objMdl.ProcCountLines(strProcName, vbext_pk_Proc) + 1

    'Save end line number for later use
    'here lng_endline may include blank lines after End Sub line
    lngProcLineCount = lng_EndLine

    'Instead of For...Next loop we could have used the .Find() method
    'but some how it fails to detect End Sub/End Function text
    For h = lng_StartLine To lng_EndLine
      strline = objMdl.Lines(h, 1)
      i = InStr(1, strline, &quot;End Sub&quot;)
      If i &gt; 0 Then
          'Format Exit Sub line
          ErrHandler = ErrHandler &amp; &quot;Exit Sub&quot; &amp; vbCr &amp; vbCr
          lngProcLineCount = h 'take the correct end line of End Sub
          h = lng_EndLine + 1
          GoTo xit
      Else
         i = InStr(1, strline, &quot;End Function&quot;)
         If i &gt; 0 Then
          'Format Exit Function line
          ErrHandler = ErrHandler &amp; &quot;Exit Function&quot; &amp; vbCr &amp; vbCr
          lngProcLineCount = h 'or take the correct endline of End Function
          h = lng_EndLine + 1
          GoTo xit
        End If
      End If
xit:
    Next

   'create Error Handler lines
   ErrHandler = ErrHandler &amp; strProcName &amp; &quot;_Error:&quot; &amp; vbCr
   ErrHandler = ErrHandler &amp; &quot;MsgBox Err &amp; &quot; &amp; Chr$(34) &amp; &quot; : &quot; &amp; Chr$(34) &amp; &quot; &amp; &quot;
   ErrHandler = ErrHandler &amp; &quot;Err.Description,,&quot; &amp; Chr$(34) &amp; strProcName &amp; &quot;()&quot; &amp; Chr$(34) &amp; vbCr
   ErrHandler = ErrHandler &amp; &quot;Resume &quot; &amp; strProcName &amp; &quot;_exit&quot;

  'Insert the Error catch start line immediately below the procedure header line
   objMdl.InsertLines lngProcBodyLine + 1, ErrTrapStartLine

 'Insert the Error Handler lines at the bottom of the Procedure
 'immediately above the 'End Function' or 'End Sub' line
   objMdl.InsertLines lngProcLineCount + 2, ErrHandler

NxtProc:
Next

strMsg = &quot;Process Complete.&quot; &amp; vbCr &amp; &quot;List of Procedures:&quot; &amp; vbCr
For intK = 0 To intJ
  strMsg = strMsg &amp; &quot;  *  &quot; &amp; str_ProcNames(intK) &amp; &quot;()&quot; &amp; vbCr
Next
MsgBox strMsg, , &quot;ErrorTrap()&quot;

ErrorTrap_Exit:
Exit Function

ErrorTrap_Error:
MsgBox Err &amp; &quot; : &quot; &amp; Err.Description, , &quot;ErrorTrap()&quot;
Resume ErrorTrap_Exit
End Function</pre>
<p>You can run this function from the Debug Window or from a <a href="http://www.msaccesstips.com/2008/04/colorfull-command-buttons/">Command Button</a> Click Event Procedure.&#160; Sample run Syntax on Standard Module:</p>
<p>ErrorTrap “Module Name”</p>
<p>Example-1:</p>
<p><font class="colrgreen">ErrorTrap &quot;Module3&quot;</font></p>
<p>Module3 will be scanned for Procedure Names and each procedure is checked for the presence of existing Error Handling lines.&#160; If ‘On Error Goto’ statement is encountered anywhere within a procedure then that procedure is skipped and goes to the next one to check.</p>
<p>To run on <a href="http://www.msaccesstips.com/2009/08/microsoft-excel-power-in-ms-access/">Form</a> or <a href="http://www.msaccesstips.com/2009/07/msaccess-report-and-page-totals/">Report</a> Module use the following Syntax:</p>
<p>ErrorTrap &quot;Form_FormName&quot;</p>
<p>Example-2:</p>
<p><font class="colrgreen">ErrorTrap &quot;Form_Employees&quot;</font></p>
<p>Example-3:</p>
<p><font class="colrgreen">ErrorTrap &quot;Report_Orders&quot;</font></p>
<p>When the ErrorTrap() function completes working with a module it displays the list of procedures found in that Module. Sample run image is given below:</p>
<p><!-- Uploaded_images--></p>
<p><a href="http://www.msaccesstips.com/uploaded_images/errortrap05.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Error Trap run result" border="0" alt="Error Trap run result" src="http://www.msaccesstips.com/uploaded_images/errortrap05_thumb.jpg" width="166" height="268" /></a></p>
<p><!-- Uploaded_images--></p>
<p>If you run the ErrorTrap() Program on a <a href="http://www.msaccesstips.com/2010/05/label-animation-zoom-out-fade/">Form</a>/<a href="http://www.msaccesstips.com/2009/07/hiding-report-lines-conditionally-3/">Report</a> that doesn’t have a VBA Module ( or its <strong>Has Module</strong> Property value is set to <strong>No</strong>) then a <strong><em>Subscript out of Range</em></strong> message is displayed and the program will be aborted.</p>
<p>It is better if you save this Program in your Library Database and link the Library <a href="http://www.msaccesstips.com/2009/07/unsecured-database-and-users-log/">Database</a> to your Project.&#160; Visit the Link: <a href="http://www.msaccesstips.com/2006/09/command-button-animation/">Command Button Animation</a> for details on how to use a database as a Library Database with your own Custom Functions.</p>
<p>I tried to take the ErrorTrap() Function one step further to scan through the entire database Modules and insert error trap routines in all of them, saving each module immediately after changes.&#160; But, Access2007 keep crashing every time and finally I have discarded the idea.&#160; Besides, the above function gives the User more control to review the module subjected to this function for any kind of side effects.</p>
<p>I have test run this function several times and found ok, but field testing may be required under different environment to detect logical errors.&#160; If you find any such errors please give me a feed back through the comment section of this page.&#160; Review each module immediately after running this function for accuracy and use it at your own risk.&#160; </p>
</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:9409deac-978f-4d8f-a26f-2dde1c7236f7" class="wlWriterSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Utility" rel="tag">Utility</a>,<a href="http://technorati.com/tags/Microsoft" rel="tag">Microsoft</a></div>
</p>
<div><font style="font-family: arial; color: black; size: 10 pt">Key Words: </font><font style="font-family: arial; color: blue; font-weight: bold"><a href="http://www.msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/#">Error, </a><a href="http://www.msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/#">Function, </a><a href="http://www.msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/#">Sub-Routine, </a><a href="http://www.msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/#">Form, </a><a href="http://www.msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/#">Module </a></font></div>
</p>
<ul>
<li><a href="http://msaccesstips.com/2011/07/iseries-date-in-exported-data/">iSeries Date in exported Data</a> </li>
<li><a href="http://msaccesstips.com/2011/06/change-query-top-values-property-with-vba/">Change Query Top Values property with VBA</a> </li>
<li><a href="http://msaccesstips.com/2011/06/creating-animated-command-button-with-vba/">Creating Animated Command Buttons</a> </li>
<li><a href="http://msaccesstips.com/2011/05/data-change-monitoring/">Data Change Monitoring</a> </li>
<li><a href="http://msaccesstips.com/2011/05/continued-on-page-2-on-report/">Continued on Page-2 on Report</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2011/12/assigning-module-level-error-trap-routines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Utility for inserting VBA Error Handler Code</title>
		<link>http://msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/</link>
		<comments>http://msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 19:59:45 +0000</pubDate>
		<dc:creator>a.p.r.pillai</dc:creator>
				<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/</guid>
		<description><![CDATA[We have tried few examples on working with VBA Module Object Properties and Methods. We have learned how to insert a Sub-Routine into a Form Module with expression.InsertLines() method of Module Object with Program. We have also seen how to upload VBA Programs from a Text File into a Form Module with expression.AddFromFile() method of [...]]]></description>
			<content:encoded><![CDATA[<p>We have tried few examples on working with VBA Module Object <strong>Properties</strong> and <strong>Methods.</strong> We have learned how to insert a Sub-Routine into a Form Module with <a href="http://www.msaccesstips.com/2011/11/writing-vba-code-with-vba/">expression.InsertLines()</a> method of Module Object with Program. We have also seen how to upload VBA Programs from a Text File into a Form Module with <a href="http://www.msaccesstips.com/2011/11/vba-module-object-and-methods/">expression.AddFromFile()</a> method of Module Object. We have prepared a <a href="http://www.msaccesstips.com/2011/12/prepare-a-list-of-procedure-names-from-a-module/">list of Functions and Sub-routines</a> from a particular Module through program.</p>
<p>Now, we are going to write a very useful Utility Program for inserting general Error Handler Code Lines into VBA Functions or Sub-Routines automatically. Let us take a look at the Error Trap Routine that we normally write in a Sub-Routine to take care of unexpected errors and to exit the program gracefully, without stopping the code and giving trouble to the User in the middle of normal operations.</p>
<pre>Private Sub cmdRunReport_Click()
<font style="color: blue">On Error Goto cmdRunReport_Click_Error</font>
.
.
.
.
<font style="color: blue">cmdRunReport_Click_Exit:
Exit Sub

cmdRunReport_Click_Error:
MsgBox Err &amp; &quot; : &quot; &amp; Err.Description,,&quot;cmdRunReport_Click()&quot;
Resume cmdRunReport_Click_Exit</font>

End Sub</pre>
<p>The blue colored lines are the Error Handler Lines and the dotted area will hold the actual program.&#160; Normally, we concentrate on writing code for the actual action we intended to execute within the procedure (the dotted line area) and the Error Handler part can wait for later finishing touches stage.&#160; File handling programs or areas where validation checks are performed gets more attention in setting up error trap routines.</p>
<p>Our idea is to insert the Error Handler lines at the beginning and end of the program automatically.&#160; Any serious program that you will write needs these lines of code and writing them manually everywhere will take some of your valuable time in a busy schedule.&#160; If you left out some of your programs without adding the Error Handler lines earlier, you can add them now very easily with the Utility Program that we are going to write.</p>
<p>As you can see in the above code that the lines suffixed with <strong>_Exit</strong>:, <strong>_Error</strong>: etc. have the program name attached to them like <strong>cmdRunReport_Click_Exit: </strong>and these values are taken from the Sub-Routine or Function Names.&#160; The first line of the error handler will be inserted immediately after the Program Name and other lines at the end of the Program.&#160; So we must know few details about the program before we are able to insert the Error Trap Lines into appropriate locations in the program.&#160; For that we must address few Property Values of any line of code located within the Function or Sub-Routine and get the property values from the Module Object.</p>
<p>To make it more clear let us draw out a plan for our program as below:</p>
<ol>
<li>First, search for some unique text within the VBA Module, located within our target Function or Sub-Routine.&#160; For this we can use the <strong>.Find()</strong> method of the Module Object. </li>
<li>Once the search stops on the target line within the Function or Sub-Routine we can read several details of the program we are in now.&#160; The .Find() method not only finds the target line of our program with the search text but also the program line number within the Module (all the lines within a Module is sequentially numbered including blank lines), the Column Number at which the search text starts, which column the search text ends etc.&#160; The Find() method Syntax is as given below: </li>
</ol>
<pre class="alt1">Modules(ModuleName).Find strSearchText, lngStart_Line, lngStart_Column, lngEnd_line, lngEnd_Column, [[WholeWord], [MatchCase], [PatternSearch]]</pre>
<p>Sample Code: </p>
<pre class="alt2">Set mdl = Modules(&quot;Form_Employees&quot;)

With mdl
  .Find “myReport”, lngStart_Line, lngStart_Column, lngEnd_line, lngEnd_Column, False
End With</pre>
<ul>
<li>The first parameter is the search text to find. </li>
<li>The next four parameters tells from where to start and where to stop looking for the search text.&#160; For example, you want to search for the second occurrence of the text “myReport” located somewhere beyond line number 25 then you will set <strong>lngStart_Line=25.&#160; </strong>If “myReport” is in Docmd.OpenReport “myReport” then the lngStart_Column value can be about 10 or leave it as 0 to start searching from beginning of the line.&#160; Once the search text is located by the Find() method all four variables will be loaded with the search text related values as below:
<ul>
<li><strong>lngStart_Line</strong> = line number on which the search text is located. </li>
<li><strong>lngStart_Column</strong> = Column Number (or first character of the search text starts on which character position from left) </li>
<li><strong>lngEnd_Line</strong> = Line on which the Search Text found and search stoped. </li>
<li><strong>lngEnd_Column</strong> = Column on which the search text ends. </li>
</ul>
</li>
<li>Once the search text is located on a line the <strong>lngStart_Line</strong> and <strong>lngEnd_line</strong> will refer to the same program line on which the search text is located.&#160; The start and end column values will be loaded into<strong> lngStart_Column</strong> and<strong> lngEnd_Column</strong> variables. </li>
<li>When the search operation is successful we can extract several information related to that program line to use for working within that particular Function or Sub-Routine. We will read the following information of a particular program to insert the Error Handler lines of Code at appropriate locations in the Program:
<ul>
<li>Get the Program Name from the <strong>.ProcOfLine</strong> Property (or in expanded form <strong>Proc</strong>edure name <strong>Of </strong>the<strong> Line</strong> we found through search) of the program line. </li>
<li>Get the Procedure Body Line Number from the <strong>.ProcBodyLine</strong> Property. The line number on which the program <strong>Private Sub cmdRunReport_Click() </strong>starts. This line number + 1 is the location where we can insert the first line (On Error Goto <a href="http://www.msaccesstips.com/2008/10/textbox-and-label-inner-margins/" rel="nofollow" target="_blank">label</a> statement) of Error Handler. </li>
<li>Get the Number of Lines in this particular procedure we are in, from <strong>.ProcCountLines</strong> Property.&#160; Even though this is a useful information this has some draw backs.&#160; If there are blank lines above the procedure Name or below the End Sub or End Function line (if it is the last procedure in a Module then it can have blank lines at the end) they are also included in the count.&#160; So we must take corrective action or take alternative measures to take correct values. </li>
<li></li>
</ul>
</li>
<li>Once the above information is available we can write the Error Handler lines into String Variables and use the <strong>.InsertLines()</strong> method of the Module Object to place them in the beginning and end of the procedure. </li>
</ul>
<ol>
<li>Open the VBA Editing Window (ALT+F11). </li>
<li>Insert a new Standard Module. </li>
<li>Copy and Paste the following VBA Code into the Module and Save it: </li>
</ol>
<pre>Public Function ErrorHandler(ByVal strModuleName As String, _
                                ByVal strSearchText As String, _
                                Optional ByVal lng_StartLine As Long = 1)
On Error GoTo ErrorHandler_Error
'--------------------------------------------------------------------------------
'Program : Inserting Error Handler Lines automatically
'        : in VBA Functions or Sub-Routines
'Author  : a.p.r. pillai
'Date    : December, 2011
'Remarks : All Rights Reserved by www.msaccesstips.com
'--------------------------------------------------------------------------------
'Parameter List:
'1. strModuleName - Standard Module or Form/Report Module Name
'2. strSearchText - Text to search for within a
'   Function or Sub-Routine
'3. lng_StartLine - Text Search Start line Number, default=1
‘Remarks: Standard/Form/Report Module must be kept open before running this Code
'--------------------------------------------------------------------------------
Dim mdl As Module, lng_startCol As Long
Dim lng_endLine As Long, lng_endCol As Long, x As Boolean, w As Boolean
Dim ProcName As String, lngProcLastLine As Long
Dim ErrTrapStartLine As String, ErrHandler As String
Dim sline As Long, scol As Long, eline As Long, ecol As Long
Dim lngProcBodyLine As Long, lngProcLineCount As Long
Dim lngProcStartLine As Long, start_line As Long, end_line As Long

Set mdl = Modules(strModuleName)
lng_startCol = 1
lng_endLine = mdl.CountOfLines
lng_endCol = 255

With mdl
    .Find strSearchText, lng_StartLine, lng_startCol, lng_endLine, lng_endCol, False
End With

'lng_StartLine - line number where the text is found
'lng_StartCol  -  starting column where the text starts
'lng_EndCol    - is where the search text ends
'lng_EndLine   - end line where the text search to stop
'if search-text is found then lng_StartLine and lng_EndLine will
'point to the same line where the search-text is found
'otherwise both will be zero

If lng_StartLine &gt; 1 Then
  'Get Procedure Name.
  'The vbext_pk_Proc system constant
  'dictates to look within a Function or Sub Routine
  'Not to consider Property-Let/Get etc.
   ProcName = mdl.ProcOfLine(lng_endLine, vbext_pk_Proc)

   'Get Procedure Body Line Number
   lngProcBodyLine = mdl.ProcBodyLine(ProcName, vbext_pk_Proc)

   'Look for existing Error trap routine, if any
   'if found abort the program
   sline = lngProcBodyLine: scol = 1: ecol = 100: eline = lng_endLine
   x = mdl.Find(&quot;On Error&quot;, sline, scol, eline, ecol)
   If x Then
      MsgBox &quot;Error Handler already assigned, program aborted&quot;
      Exit Function
   End If

 'Get Line Count of the Procedure, including
 ' blank lines immediately above the procedure name
 'and below, if the procedure is the last one in the Module
   lngProcLineCount = mdl.ProcCountLines(ProcName, vbext_pk_Proc)

 'Create Error Trap start line
   ErrTrapStartLine = &quot;On Error goto &quot; &amp; ProcName &amp; &quot;_Error&quot; &amp; vbCr
 'Compose Error Handler lines
   ErrHandler = vbCr &amp; ProcName &amp; &quot;_Exit:&quot; &amp; vbCr

'determine whether it is a Function procedure or a Sub-Routine
'lng_StartLine = lng_endLine:
lng_startCol = 1: lng_endCol = 100: lng_endLine = lngProcBodyLine + lngProcLineCount
'save the startline and lng_EndLine values
start_line = lng_StartLine: end_line = lng_endLine

'Check whether it is a Function Procedure or a Sub-Routine
w = mdl.Find(&quot;End Function&quot;, lng_StartLine, lng_startCol, lng_endLine, lng_endCol, False)

If w Then 'Function Procedure
   'Take correct procedure line count excluding
   'blank lines below End Sub or End Function line
   lngProcLineCount = lng_StartLine
   ErrHandler = ErrHandler &amp; &quot;Exit Function&quot; &amp; vbCr &amp; vbCr
Else
   lng_StartLine = start_line: lng_endLine = end_line: lng_startCol = 1: lng_endCol = 100
   w = mdl.Find(&quot;End Sub&quot;, lng_StartLine, lng_startCol, lng_endLine, lng_endCol, False)
   If w Then 'Sub-Routine
     lngProcLineCount = lng_StartLine
     ErrHandler = ErrHandler &amp; &quot;Exit Sub&quot; &amp; vbCr &amp; vbCr
   End If
End If
   'create Error Handler lines
   ErrHandler = ErrHandler &amp; ProcName &amp; &quot;_Error:&quot; &amp; vbCr
   ErrHandler = ErrHandler &amp; &quot;MsgBox Err &amp; &quot; &amp; Chr$(34) &amp; &quot; : &quot; &amp; Chr$(34) &amp; &quot; &amp; &quot;
   ErrHandler = ErrHandler &amp; &quot;Err.Description,,&quot; &amp; Chr$(34) &amp; ProcName &amp; &quot;()&quot; &amp; Chr$(34) &amp; vbCr
   ErrHandler = ErrHandler &amp; &quot;Resume &quot; &amp; ProcName &amp; &quot;_exit&quot;

  'Insert the Error catch start line immediately below the header line
   mdl.InsertLines lngProcBodyLine + 1, ErrTrapStartLine

 'Insert the Error Handler lines at the bottom of the Procedure
 'immediately above the 'End Function' or 'End Sub' line
   mdl.InsertLines lngProcLineCount + 2, ErrHandler

End If

ErrorHandler_Exit:
Exit Function

ErrorHandler_Error:
MsgBox Err &amp; &quot; : &quot; &amp; Err.Description, , &quot;ErrorHandler()&quot;
Resume ErrorHandler_Exit

End Function</pre>
<p>Since, this program itself is a Coding aide you must keep the target Module (Standard/<a href="http://www.msaccesstips.com/2008/01/progress-bar-on-form/">Form</a>/<a href="http://www.msaccesstips.com/2009/06/network-and-print-page-setup-3/">Report</a>) open before running this program to insert the Error Handling code segment into the target Function/Sub-Routine.</p>
<p>You may call the <strong>ErrorHandler()</strong> Function from the <strong>Debug Window</strong> or from a <a href="http://www.msaccesstips.com/2008/04/colorfull-command-buttons/">Command Button</a> Click Event Procedure as shown below:</p>
<pre class="alt1">'The third parameter is optional, you may omit it
ErrorHandler &quot;Form_Employees&quot;,&quot;myReport&quot;,1</pre>
<p>This will start searching for the text <strong>myReport</strong> from the beginning of the Employees Form Module, stops within the program where the search finds a text match and inserts the Error Handling Code lines at the beginning and end of the program.</p>
<p>If the text &#8216;myReport&#8217; appears in more than one Function/Sub-Routine in the Module then you must give the third parameter (Search start line number) to start searching for the text beyond the area wherever exclusion is required. Example: </p>
<pre class="alt1">'Look for text 'myReport' from line 20 onwards only
ErrorHandler &quot;Form_Employees&quot;,&quot;myReport&quot;,20</pre>
<p>When the ErrorHandler() Function is run, first it will look for the presence of existing error handling lines starting with &#8216;On Error&#8217; and if found assumes that the error handling lines are already present in the Function/Sub-Routine and stops the program after displaying the following message: </p>
<blockquote><p>‘Error Handler already assigned, program aborted.&#8217; </p></blockquote>
<p>Comment lines are added for clarity above the program lines explaining what happens next.&#160; </p>
<p>If you find any logical error in the program please give me feed back through the comment section of this page. To protect from spam we insist on joining the site before you are able to post comments.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:9409deac-978f-4d8f-a26f-2dde1c7236f7" class="wlWriterEditableSmartContent">Technorati Tags: <a href="http://technorati.com/tags/Utility" rel="tag">Utility</a>,<a href="http://technorati.com/tags/Microsoft" rel="tag">Microsoft</a></div>
<p></p>
<div><font style="font-family: arial; color: black; size: 10 pt">Key Words: </font><font style="font-family: arial; color: blue; font-weight: bold"><a href="http://www.msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/#">Error, </a><a href="http://www.msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/#">Function, </a><a href="http://www.msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/#">Sub-Routine, </a><a href="http://www.msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/#">Form, </a><a href="http://www.msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/#">Module </a></font></div>
<p></p>
<ul>
<li><a href="http://msaccesstips.com/2011/06/change-query-top-values-property-with-vba/">Change Query Top Values property with VBA</a> </li>
</ul>
<li><a href="http://msaccesstips.com/2011/06/creating-animated-command-button-with-vba/">Creating Animated Command Buttons</a> </li>
<li><a href="http://msaccesstips.com/2011/05/data-change-monitoring/">Data Change Monitoring</a> </li>
<li><a href="http://msaccesstips.com/2011/05/continued-on-page-2-on-report/">Continued on Page-2 on Report</a> </li>
<li><a href="http://msaccesstips.com/2011/05/product-group-sequence-with-auto-numbers/">Product Group Sequence with Autonumbers</a>
</p>
</li>
]]></content:encoded>
			<wfw:commentRss>http://msaccesstips.com/2011/12/utility-for-inserting-vba-error-handler-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

