Introduction
There are many applications written in VB6. Now rewriting an entire application to VB.NET is a time consuming and risky task for small companies. However, with the release of Microsoft Interop Toolkit 2.0, we have the option of partial migration. We can create Forms, Controls and Libraries in VB.NET and glue them with the VB6 application using the Microsoft Interop Toolkit 2.0. This option opens us to a lot of possibilities like calling a web service, threading and more. This article will demonstrate how advanced functionality can be added to a VB6 application using the Microsoft Interop Toolkit 2.0 and VB.NET without changing existing code. The list of features we will add is as follows:
- Writing VB.Net CRM Adapter for communication with Sugar CRM
- Sugar CRM exposes its objects via the NuSoap PHP Library module
- VB.NET Project will consume the web service
- Custom screen to create incidents in Sugar CRM
- VB.NET Forms for creating incident
- Incident creation screen will be called by VB6 application
- Multi-threaded bulk upload control
- VB.NET UserControl that will upload incidents using
System.ComponentModel.BackgroundWorker
- VB6 Form will host this control.
Note: Sugar CRM is an open source CRM package based on PHP and MySQL.
High level design
In high level diagram Sections 1, 2 and 3 are VB6 Forms. Section 4 is a VB.NET WinForm. Section 5 is a VB6 Form hosting a VB.NET user control. Section 6 is the ToolKit area that provides sharing of application data, eventing framework services, etc. Section 7 is a CRM Adapter written in VB.NET to talk to the Sugar CRM SOAP Service. The application consists of the following projects:
- Manager: Visual Basic 6.0 application starting point, contains forms
- SugarCrmInteropForm: .NET assembly containing incident related forms
- HybridAppControls: .NET assembly containing custom user controls for threaded bulk upload
- SugarCrmAdapter: .NET assembly containing Adapter for Sugar CRM
Background
The application we are working with is Billing Management System. It's a Windows-based application with the Access database as its backend. Data reports are used for reporting. It is primarily used for managing customer contacts (CRUD), generating & maintaining billing information, reporting, etc.
Using the code
Sharing data between VB6 and VB.NET
Step 1. When Visual Basic 6.0 Application loads, initialize the Microsoft Interop Toolkit 2.0 Framework using following code:
Set g_InteropToolbox = New InteropToolbox
g_InteropToolbox.Initialize
g_InteropToolbox.Initialize
g_InteropToolbox.EventMessenger.RaiseApplicationStartedupEvent
Step 2. Using the Microsoft Interop Toolkit 2.0 Framework, pass all shared data to VB.NET:
Dim rsSettings As ADODB.Recordset
Set rsSettings = New ADODB.Recordset
rsSettings.Open "select * from appsetting", db, _
adOpenDynamic, adLockOptimistic
While Not rsSettings.EOF
g_InteropToolbox.Globals.Add CStr(rsSettings!Name), _
CStr(rsSettings!Value)
rsSettings.MoveNext
Wend
rsSettings.Close
Step 3. Access shared data from VB.NET:
SugarCrmSettings.crmUserId = My.InteropToolbox.Globals("crmUserId")
SugarCrmSettings.crmURL = My.InteropToolbox.Globals("crmURL")
SugarCrmSettings.crmPassword = My.InteropToolbox.Globals("crmPassword")
SugarCrmSettings.crmVer = My.InteropToolbox.Globals("crmVersion")
Multi-threaded bulk upload control in VB.NET
Step 1. Add the BackgroundWorker control from the Components ToolBox.
Step 2. In the DoWork
event, we read the file and then call Adapter to create an incident:
Private Sub BulkImportWorker_DoWork(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs_
) Handles BulkImportWorker.DoWork
Dim ReadFile As New System.IO.StreamReader(txtImportFileName.Text)
Dim ImportedIncident As String
Dim SugarCrmSettings As New SugarCrmAdapter.CrmHelper
SugarCrmSettings.crmUserId = _
My.InteropToolbox.Globals("crmUserId").ToString()
SugarCrmSettings.crmURL = _
My.InteropToolbox.Globals("crmURL").ToString()
SugarCrmSettings.crmPassword = _
My.InteropToolbox.Globals("crmPassword").ToString()
SugarCrmSettings.crmVer = _
My.InteropToolbox.Globals("crmVersion").ToString()
Dim lineno As Integer
lineno = 1
Dim importerror As Integer
importerror = 0
Try
While Not ReadFile.EndOfStream
ImportedIncident = ReadFile.ReadLine
txtStatus.Text = "Processing Line " + lineno.ToString()
Dim IncidentRequest As New SugarCrmAdapter.Incident
Dim IncidentResponse As New SugarCrmAdapter.GenericEntity
IncidentResponse =
IncidentRequest.Create(SugarCrmSettings, _
ImportedIncident)
If (IncidentResponse.IsError) Then
ExportList.Items.Add("Line # " + lineno.ToString() + _
" Error occured while creating Case " + _
ImportedIncident)
importerror = importerror + 1
End If
lineno = lineno + 1
End While
lineno = lineno - 1
Catch ex As Exception
Microsoft.VisualBasic.Interaction.MsgBox(_
"Unexpected error " + _
ex.Message, _
MsgBoxStyle.Information)
Finally
ReadFile.Close()
Dim summary As String
summary = vbCrLf + "Total records processed: " + _
lineno.ToString() + vbCrLf
summary += "Successfully inserted: " + _
CStr(lineno - importerror) + vbCrLf
summary += "Failed: " + importerror.ToString() + vbCrLf
Microsoft.VisualBasic.Interaction.MsgBox(_
"Import task complted" + _
vbCrLf + summary, MsgBoxStyle.Information)
txtStatus.Text = "Completed..."
End Try
End Sub
Writing VB.Net CRM Adapter for communication with Sugar CRM
Step 1. Call the test
method of the Sugar CRM web service to check the connection.
Step 2. Pass the credentials to the create_case
method.
Step 3. Return the response of the create_case
method, which will be a GUID:
Dim crm As New CrmService.sugarsoap
Dim auth As New CrmService.user_auth
auth.user_name = ConnectionSettings.crmUserId
auth.password = ConnectionSettings.crmPassword
auth.version = ConnectionSettings.crmVer
crm.Url = ConnectionSettings.crmURL
Dim ReturnObject As New GenericEntity
Try
Dim test As String = crm.test("test")
Dim a As Object = crm.login(auth, "SoapTest")
Catch ex As Exception
ReturnObject.IsError = True
ReturnObject.Message = "Connection to SugarCrm was unsuccessfull"
Return ReturnObject
End Try
Try
Dim caseid As String = _
crm.create_case(ConnectionSettings.crmUserId, _
ConnectionSettings.crmPassword, CaseName)
ReturnObject.Message = _
"Case created in SugarCrm with CaseID - " + caseid
Return ReturnObject
Catch ex As Exception
ReturnObject.IsError = True
ReturnObject.Message = _
"Unable to create case in SugarCrm ErrorDetails - " + _
ex.Message
Return ReturnObject
End Try
Tips for success
Before running the application, check the following:
- Check that Sugar CRM is running.
- Check that the settings like CrmURL point to the correct location.
- Note that the password stored in MD5 can be taken from the Sugar CRM user table.
- The user should have rights for creating incidents in Sugar CRM.
Happy coding...
History
- 4 July, 2007 -- Original version posted