Wednesday, January 31, 2007

Sending Email With MAPI Components in Visual Basic

Now that we've got the layout and details of the controls on our form sorted out, let's add some code to our form to interact with our MAPI compatible mail system.
Start by opening the general declerations section in the code window. Enter the following code:
Option Explicit
Dim lPosition As Long
The long integer variable that we've created in the code snippet above will be used to remember which message we are currently viewing. This variable will also be used to check whether or not we are currently viewing the last message in the inbox.
Our next step is to add some code to the Form_Load() event. Add this code to your application:
Private Sub Form_Load()
'Sign on to the MAPI Session
MAPISession1.SignOn
MAPIMessages1.SessionID = MAPISession1.SessionID
MAPIMessages1.Fetch
If MAPIMessages1.MsgCount > 0 Then
'If there are messages, display the first one.
txtFrom.Text = MAPIMessages1.MsgOrigDisplayName
txtTo.Text = MAPIMessages1.RecipDisplayName
txtSubject.Text = MAPIMessages1.MsgSubject
txtMessage.Text = MAPIMessages1.MsgNoteText
'Enable the buttons to allow message navigation.
cmdBack.Enabled = True
cmdForward.Enabled = True
cmdSend.Enabled = True
Else
'No Messages? Tell the user immediately and Sign off!
MsgBox "You have no messages”
MAPISession1.SignOff
'Disable the buttons to avoid error messages
cmdBack.Enabled = False
cmdForward.Enabled = False
cmdSend.Enabled = False
End If
End Sub
At runtime your application will automatically sign on to a new MAPI session and check for any e-mails. If there are no e-mails, then we are informed and the session is terminated. On the other hand, if there was at least one e-mail in the Inbox, the program will show the first one in the list.
We are now going to configure the forward and backwards buttons to allow our users to navigate their way through the list of emails in their inbox. Add this code to the cmdForward_Click() event:
Private Sub cmdForward_Click()
'If the user has not reached the end of the list, show the next message.
If lPosition < MAPIMessages1.MsgCount Then
lPosition = lPosition + 1
'Change the Message number to the value in lPosition
MAPIMessages1.MsgIndex = lPosition
txtFrom.Text = MAPIMessages1.MsgOrigDisplayName
txtTo.Text = MAPIMessages1.RecipDisplayName
txtSubject.Text = MAPIMessages1.MsgSubject
txtMessage.Text = MAPIMessages1.MsgNoteText
'The 4 lines above will preview the current message.
End If
End Sub
Add the following code to the cmdBack_Click() event:
Private Sub cmdBack_Click()
'If the user hasn’t reached the beginning of the list, preview message
If lPosition > 0 Then
lPosition = lPosition – 1
'Change the Message number to the value in lPosition
MAPIMessages1.MsgIndex = lPosition
txtFrom.Text = MAPIMessages1.MsgOrigDisplayName
txtTo.Text = MAPIMessages1.RecipDisplayName
txtSubject.Text = MAPIMessages1.MsgSubject
txtMessage.Text = MAPIMessages1.MsgNoteText
'The 4 lines above will preview the current message.
End If
End Sub
Our program is now capable of previewing e-mail messages in the Inbox of our MAPI-compatible mailbox, such as Outlook Express.
Let's now take it to the next level by adding the ability to send e-mail. Don't let this frighten you off in any way, because it is actually just as easy to send email as it is to receive it and preview it by using the text boxes on the form. Add this code to the Click() method of the cmdSend button:
Private Sub cmdSend_Click()
'Start by telling the control that we are composing an e-mail
MAPIMessages1.Compose
'Use whatever is in the Textboxes as the information for our e-mail.
MAPIMessages1.RecipDisplayName = txtTo.Text
MAPIMessages1.MsgSubject = txtSubject.Text
MAPIMessages1.MsgNoteText = txtMessage.Text
MAPIMessages1.ResolveName
'Send the e-mail message to the Recipient
MAPIMessages1.Send
End Sub
Your application can now send emails, as well as receive them. To send an email, all we have to do is change the text in the To, Subject, and Message boxes. The email message will be sent using the email address defined in our outgoing mail application, so you don't need to change the text in the from box. There is still one more thing that needs to be added to your application. The "Close Session" button still doesn't have any code in it. Add the following code to the Click() event of the cmdClose button:
Private Sub cmdClose_Click()
MAPISession1.SignOff
Unload Me
End Sub
When clicked, the close session button signs the user oout of their e-mail client that he/she was connected to when MAPI called its SignOn method in for Form_Load() event. After we're signed out, our app will then unload itself from memory (exit the program).

How to auto link the two excel files using VB6.0

Private Sub AutoLinkWorkbookDemo(addressToCopy As String, destinationAddress As String)
Dim wb1 As Excel.Workbook
Dim wb2 As Excel.Workbook
Dim fileLocationWB1 As String
Dim fileLocationWB2 As String

fileLocationWB1 = ThisWorkbook.Path & "\wb1.xls"
fileLocationWB2 = ThisWorkbook.Path & "\wb2.xls"

'Opening both workbooks
Set wb1 = Workbooks.Open(fileLocationWB1)
Set wb2 = Workbooks.Open(fileLocationWB2)

'Copies required chunk of data to the clipboard
wb1.Worksheets(1).Range(addressToCopy).Copy

'Select the destination where the links will go
wb2.Worksheets(1).Range(destinationAddress).Select

'Paste the links to the required destination (i.e., at destinationAddress provided)
ActiveSheet.Paste link:=True

'Close source workbook without saving
wb1.Close savechanges:=False

'Close updated workbook with links to [wb1], saving the changes
wb2.Close savechanges:=True

'Destroy the objects
Set wb1 = Nothing
Set wb2 = Nothing
End Sub



Sub DemoTest()
AutoLinkWorkbookDemo addressToCopy:="A1:C10", destinationAddress:="D1"
End Sub

Full-Text Search Optimization Tips

Set the virtual memory size to at least 3 times the physical memory installed in the computer, and set the SQL Server 'max server memory' server configuration option to half the virtual memory size setting (1.5 times the physical memory).Because working with full-text search is very resource expensive, you should have enough physical and virtual memory.
*****
Set the "Maximize Throughput for Network Applications" option.This can increase full-text search performance, because Windows NT will allocate more RAM to SQL Server than to its file cache. To set this option, you can do the following:1. Double-click the Network icon in Control Panel.2. Click the Services tab.3. Click Server to select it, and then click the Properties button.4. Click Maximize Throughput for Network Applications, and then click OK.5. Restart the computer.
*****
Make full-text index population during periods of low database access.Because full-text index population takes some time, these updates should be scheduled during CPU idle time and slow production periods.
*****
Assign a very large table (a table that has millions of rows) to its own full-text catalog.This can improve performance, and can be used to simplify administering and monitoring.
*****
You can boost the resource usage for the full-text search service (increase the "System Resource Usage" option for the full-text search service).Run SQL Server Enterprise Manager, expand a server group then expand a server. Expand "Support Services", then right-click the "Full-Text Search" and select "Properties". Choose the "Performance" tab and increase the "System Resource Usage" option for the full-text search service.Note. Don't set the "System Resource Usage" option to the "Dedicated" value (right border of the "System Resource Usage" slider bar), because it can negatively affect your SQL Server's performance.
*****
Reduce the full-text unique key size.To create a full-text index, the table to be indexed must have a unique index. Try to select a numeric column as the full-text unique key to increase the speed of full-text population. If the table to be indexed does not have numeric unique index, consider creating numeric unique index.
*****
If you have several physical disks, create several Pagefile.sys files, so that each Pagefile.sys file will be placed on its own physical disk.Spreading paging files across multiple disk drives and controllers improves performance on most disk systems because multiple disks can process input/output requests concurrently.
*****
If you use SQL Server 2000, consider using the Change Tracking with scheduled or background update index option versus Incremental Population.The Change Tracking with scheduled propagation should be used when CPU and memory can be used at scheduled times and changes between the scheduled times are not significant. The Change Tracking with background update index option should be used when CPU and memory are available and the value of an up-to-date index is high.
*****
Consider using a full population when a large percentage of records were changed or added at once.
*****
If you work with SQL Server 7.0, consider using an incremental population when not a large percentage of records were changed or added at once.Using an incremental population instead of a full population decreases the population time and results in good performance benefits.
*****
If you have several physical disks, place the database files separately from the full-text catalog files.So, you can improve the speed of full-text queries, because multiple disks can process input/output requests concurrently.
*****
Upgrade to SQL Server 2000, in order to enhance full-text search performance and if you need to work with full-text search in clustered environment.The full text search is not available in SQL Server 7.0 clustered environment.
*****
If you work with SQL Server 2000, consider using the new top_n_by_rank parameter with CONTAINSTABLE or FREETEXTTABLE.It can be used to restrict the number of rows returned. The top_n_by_rank parameter specifies that only the n-highest ranked matches, in descending order, will be returned.
*****
Try to use the CONTAINS or FREETEXT predicates instead of the CONTAINSTABLE or FREETEXTTABLE functions to simplify the query's text.Because qualifying rows returned by the CONTAINSTABLE or FREETEXTTABLE rowset functions must be explicitly joined with the rows in the original SQL Server table, the queries that use the CONTAINSTABLE and FREETEXTTABLE functions are more complex than those that use the CONTAINS and FREETEXT predicates.

Runtime Error

A RUNTIME ERROR generally means that something is running in the background or a file is in use.
RUNTIME ERROR 7:Out of Memory errors are common in Windows environments even when a system has a large amount of memory. Programs use up a "slot" in the memory when running and do not instantly release that slot when closed. If too many slots are filled, you get a memory error.
We suggest that you uninstall any version of the program that may appear in your Add/Remove Programs list; click YES to remove the shared files that prompt for a response. Reboot your system and return to the download link. Before installing, "End Task" any other programs that are running in the background (firewalls, antivirus, cookie blockers, etc.) by hitting the CTRL + ALT + DELETE keys.
RUNTIME ERROR 13:"Type mismatch" means that you do not have the English (United States) setting in your Regional Settings.
Change Regional Settings to English (United States) under My Computer / Control Panel / Regional Settings
RUNTIME ERROR 48:There is a .dll file conflict, which means that some other program is probably using the same file. Disable all other programs that may be running in the background (anti-virus, download managers, Instant Messengers, etc.), then reinstall the program.
RUNTIME ERROR 75: "Run-time error 75: path/file access error." This error occurs when a program is installed on a network and the user does not have rights to the program directory. For the program to work properly on a network, users must be given rights by the network administrator.
RUN TIME ERROR 339:You cannot log in to the program. You receive the message "Component "file name" or one of its dependencies not currently registered: a file is missing or invalid."Below are the 2 examples of 339 error messages our customers have received. I. I am getting a Runtime Error 339: "Missing File"... The files most commonly missing or incorrectly registered are listed below: VSFLEX7L.OCX ctLstBar.ocx GTProgss.ocx II. I am getting a Runtime Error 339 "File Missing or Incorrectly Registered"...
Previously in Net Detective 7.0 (the first few releases .01 -.09 first edition prior to April 4, 2002): These errors were due to ActiveX controls that were out of date. Uninstalling completely and installing the most current version of ND resolves this issue. A Windows Update from Microsoft.com replaces outdated files as well. Uninstall our program, do a Windows update, reboot, then redownload.
RUNTIME ERROR 372:Failed to load control CommonDialog from "filename".OCX - your version of the .OCX file may be outdated. Or Run-time error "372" Failed to load control "MS Comm" from MSCOMM32.OCX. Your version of MSCOMM32.OCX may be outdated. Make sure you are using the version of the control that was provided with your application. Or OLEAUT32.dll is out of date. A newer version is required for this program. Indicates that the common control needs to be updated.
FIRST: Try searching for the file then renaming the Mswinsck.ocx (for example OldMswinsck.ocx), and reinstalling the program and choose Repair. WHEN ALL ELSE FAILS: 1. Identify the name of the control by reading the error message. Controls have file names that end in "OCX" or "DLL". Write down the name of the control. 2. Open an MS-DOS window by clicking "Start," drag to "Programs," then click on "MS-DOS Prompt." This will open the "MS-DOS Prompt" window. You should see a C:\WINDOWS> prompt. 3. Type "cd system" (do not type the quotation marks) and press This will change the prompt to C:\WINDOWS\SYSTEM>. 4. Rename the older version of the control identified in step 1 by typing "ren control control.old" for example "ren comdlg32.ocx comdlg32.old" and press (again, do not type the quotation marks.) 5. If your Run Time Error message specifies a different file, replace "comdlg32" with your specified file.] This will rename the file and return the prompt to C:\WINDOWS\SYSTEM>. 6. Close the "MS-DOS Prompt" window by clicking the X button in the top right corner. 7. Download the control updates from Microsoft for your system type under "Windows".
RUNTIME ERROR 373:"Error: 373 no such interface supported in Internet Explorer" This error occurs when the jscript.dll file is corrupted or damaged. Use the System file checker to extract a new copy of jscript.dll from their Windows cd. You can try to do a Windows & IE update. (Source: http://support.earthlink.net/mu/1/psc/img/walkthroughs/windows_9x_nt/browsers/ie_4.0/2036.psc.html)
RUNTIME ERROR 374:After running the setup.exe you receive a run-time error: '374' Fail to activate control "VB.User Control". The control may not be the correct version. Make sure you have the most recent updates for Windows and Internet Explorer, restart, then try to run the setup again.

ASP.NET New String Properties

Examining New String Properties - Part 1(and thereabouts)
There were many functions we used to parse strings in Classic ASP, like Mid, Right, Left, Instr and Len. But now there are new items - properties assigned to the strings, like Substring, IndexOf, EndsWith, and StartsWith.
Before, we had mid and right. Now we have 'SubString'. In Classic ASP, to parse just a bit of a string, from a certain position in the string, we would use :
Dim sItem
sItem="This is my String"
Mid(sItem,5)This would start 5 characters into the string, and give you what was left. The new way to do it is with the SubString Property. Here's how you use it for the same function:
Dim sItem as String
sItem="This is my String"
sItem.SubString(5)What you would end up with is 'is my String'.
One other variation of the SubString property will allow you to start at a certain character (from the left) of the string, and parse the string by a certain number of characters past that starting point. In other words, you could do this:
Dim sItem as String
sItem="This is my String"
sItem.SubString(5, 8)The text you would end up with would be 'is my st'. It started at the 5th character in from the left of the string (just before the word 'is') and proceded to crop/parse the text for another 8 characters.
We also previously had the instr function, which, by using it, could find the position in the string of another string. For instance, if the string was "Where is the big black dog?" and we wanted to find the position (in that string) of the word "the", we would use the instr function. To do this, the cleanest way possible, we'd assign the entire string to a variable (let's call it 'sItem'), then, the code would look something like this (including the use of the position, after finding it):
Dim lg
lg=instr(1, sItem, "the")
response.Write (lg)
Then, of course, we could response.Write lg or use lg in any way we wanted, from there.
Now, we have the indexof property. It's a little simpler - a little cleaner. Let's use the same string (sItem):
Response.write (sItem.IndexOf("the"))Another variation of this would be more like the original instr function, it finds the position of a particular string, based on a starting location in that string.
Response.write (sItem.IndexOf("the", 5))This would actually look for the position of the word 'the', but it would start looking at the 5th character position.
There are two new items we'll look at now. They are 'EndsWith' and 'StartsWith'. I'll only go into the explanation of 'EndsWith', because after that, 'StartsWith' will be self explanatory. The return value is a boolean in this case, and not a numeric position in the string. Let's say sItem, in this case, is 'We're really having fun now!". What these two properties do is check for certain strings or characters and, if the string ends with or starts with that character or string, the return is 'True'. Otherwise, of course, the return is 'False'. Here's how you would use it:
Response.Write (sItem.EndsWith("!"))Naturally, in this case, it would return 'True'.
One last thing we need to look at in this tutorial is the replacement for 'Len'. In Classic ASP, we'd write:
response.Write (len(sItem))In ASP.Net, it's a little different - as before, each string is an 'object'. Therefore, you assign the length property to it:
response.Write (sItem.Length)