Community
Showing results for 
Search instead for 
Do you mean 
Reply

It's Alive! ! ! Connecting VB.Net to ACT!

Copper Contributor
Posts: 51
Country: United States

It's Alive! ! ! Connecting VB.Net to ACT!

[ Edited ]

I finally got it to work by piecing together information from a dozen sources, mostly in this forum.  I thought I'd take the time to list what I learned about making this happen.

 

Objective: I am working on an external application for a client who is using ACT Premium as a repository of the stuff that ACT does well.  My application will use core tables such as Employee, Contact, and Company and so must be able to read and write to ACT.

 

Environment: It turns out that there is just no help but that ACT must be installed on the machine where the app is running.  Multiple users in the forums have inquired about this and many of us thought that just having access to the necessary DLLs would be sufficient.  But it turns out that in addition to the functionality inherent in the DLLs ACT does license and version checking as well.  So it seems that even if your application is running on Machine A and talking to an ACT DB on Machine B both machines need ACT installed.  I have this on the server which will eventually host the web application.

 

References:

 

I am testing connectivity using VB.Net and will eventually start writing in ASP.Net, also using VB.  The necessary ACT DLLs are not available from a list of references in the .Net or Com tabs of the VB Add Reference... dialog.  Instead you must use the Browse tab to find the reference DLLs.  I found them in C:\ACT!2010\PremiumEx\ACTWG\GlobalAssemblyCache\ .  There are about a hundred DLLs in this file. 

 

One writer suggests just adding all of them.  I found that, at a minium, you need to add ACT.Framework.DLL.  I also found that you can add this reference and you will see what seems to be all of the ACT capabilities in the API.  If you try to use a capability that needs another reference the VB editor will actually tell you exactly which DLL is missing and you can add it.

 

I have never used references before and I had originally expected, in part based on two sample programs in the SDK, that I would be using Imports statements in VB to enable specific functionality on a form.  You will see in my code that I added several and once the program was working I tried commenting them out to see which were necessary.  It seems that none were!!

 

Development Platform:

 

It turns out that developing using the ACT Framework needs to have x86 as the target processor for the .Net program.  If you don't have this then you get the error "vshost.exe has stopped working."  x86 does not seem to be the default target platform for modern machines and it has to be changed in the VB project.  There seem to be a couple of paths for making this happen.  I actually ended up, based on a hint provided in the forum and pointing to another post, customizing one of my Visual Studio tool bars to include a Solution Platforms list.  It worked and I'm not changing it.  There also seems to be access to this setting in the Project Properties Compile tab.

 

My Results:

 

The very simple Windows forms application code below allows the user to enter some contact information and return the newly created GUID contact ID as well as the parsed first and last names.  It works.  I can run it and see the contact in the ACT sample DB when I open it directly.  Next I need to work on adding history entries, companies, querying by criteria, and returning lists according to criteria.  But getting the VB to talk to ACT was such a drawn out process that I feel like I've reached a major milestone.

 

'* None of the Imports statements below seemed to be necessary if

'* DLLs were added as references. This code worked with all commented out

'Imports Act.Framework

'Imports Act.UI

'Imports Act.Shared.ComponentModel

'Imports Act.Framework.ComponentModel

 

Public Class Form1

  '* Declare Framework object and login string used throughout

   Dim ActFwk As New Act.Framework.ActFramework

  Const ACTPadFile As String = _

    "C:\Users\Public\Documents\ACT\ACT for Windows 12\Databases\ACT2010Demo.pad"

 

  Private Sub btnAddContact_Click(ByVal sender As System.Object, _

    ByVal e As System.EventArgs) Handles btnAddContact.Click

    '*********************************************************************

    '* Create a new ACT contact from information on the form.

    '* Return the new contact ID to a label on the form

    '*********************************************************************

 

    '* Login to the sample database using default administrator

    ActFwk.LogOn(ACTPadFile, "Chris Huffman", "")

 

    '* Create and configure new contact

     Dim actCont As Act.Framework.Contacts.Contact

    actCont = ActFwk.Contacts.CreateContact

 

    With actCont

      .Company = "TestCo"

      .FullName = txtFirstName.Text & " " & _

        txtLastName.Text

 

      '* Record contact in ACT DB and retrieve new ID and

      '* parsed name elements

      Try

        .Update()

        lblContactID.Text = .ID.ToString

        lblFirstName.Text = .FirstName

        lblLastName.Text = .LastName

 

      Catch ex As Exception '* Something unexpected happened

        MessageBox.Show(ex.Message, "Get Your Credit Card Out", _

          MessageBoxButtons.OK, MessageBoxIcon.Hand)

 

      Finally '* Logoff regardless of success or failure

         ActFwk.LogOff()

     

      End Try

 

    End With

 

  End Sub

 

End Class

 

Message Edited by lwestatbus on 05-27-2010 05:43 PM
Tuned Listener
Posts: 25
Country: France

Re: It's Alive! ! ! Connecting VB.Net to ACT!

Hi,

 

Thanks for showing a *working* piece of code... There's no better documentation than this kind of one.

 

I'll be glad if you could continue to post other samples of your project, it would surely helps a lot of newcomers like me here.

 

New Member
Posts: 6
Country: United_Kingdom

Re: It's Alive! ! ! Connecting VB.Net to ACT!

That was a big help, altho working out the 32bit on a 64bit machine and the user pwd combination took some doing.

 

But can anyone tell me how to write info to the fields that don't come up in intellisense?

 

I've managed to get this far:

 

.ContactFields("BUSINESS_LINE1") = "Address 1" '

 

Result: Invalid name format: BUSINESS_LINE1 Parameter name: realName

 

.ContactFields("TBL_CONTACT.BUSINESS_LINE1") = "Address 1"

 

 

Result: 'Invalid table name: TBL_CONTACT Parameter name: table

 

These names have been pulled out of the framework using: 

 

For Each field As Act.Framework.Contacts.ContactFieldDescriptor In cFields

 

      s += field.Name & vbCrLf

 

Next

 

So I believe they are accurate.

 

Using intellisense I have tried:

 

 

 

.ContactFields("BUSINESS_LINE1", Act.Framework.MutableEntities.FieldNameType.Real) = "Address 1"

 

 

Result: Invalid name format: BUSINESS_LINE1 Parameter name: realName

 

 

 

Now logically there is a simple way to write values to the database using the framework.  I can write to the name, company etc with ease.  But these other fields don't come up in intellisense, even after I have connected to the database, and there is no help anywhere that I can find where I can write to these values.  Altho I can write to 'Title'

 

 

 

Oh, OK.  I got it.  As I was listing all the things I had tried I decided to double check using it with table name and .fields instead of .contactfields

 

 

.Fields("TBL_CONTACT.BUSINESS_LINE1", Act.Framework.MutableEntities.FieldNameType.Real) = "Address 1"

 

 

 

And it actually worked fine!!!!

 

 

 

And seeing as I had already typed most of this I will post in the hope that some person who was pulling his hair out as I have been can find the solution rather more easily.

 

 

 

 

For the sake of completeness, I will post the full code where I have handled the logon problems, getting the field names, and writing details to the database. 

*************************************************** 

 

 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

 

Dim actFwkDB As New Act.Framework.ActFramework

 

Dim FP As String = "Z:\ACT2011Demo.PAD"

 

'this, as far as I know, allows you to log onto any instance no matter what by impersonating the system

 

Dim accountToken As IntPtr = WindowsIdentity.GetCurrent().Token

 

Dim identity As New WindowsIdentity(accountToken)

 

Dim context As WindowsImpersonationContext = identity.Impersonate

 

'so now you can log on with no credentials!

 

actFwkDB.LogOn(FP)

 

'I used the below to get the field names, I've left it in becos this took a fair bit of doing as well

 

'leave it out of the final version once you've got the names.

 

Dim s As String = ""

 

Dim cFields() As Act.Framework.Contacts.ContactFieldDescriptor

 

cFields = actFwkDB.Contacts.GetContactFieldDescriptors()

 

For Each field As Act.Framework.Contacts.ContactFieldDescriptor In cFields

 

s += field.Name & vbCrLf

 

Next

 

'create contact to write

 

Dim actCont As Act.Framework.Contacts.Contact = actFwkDB.Contacts.CreateContact

 

With actCont

 

.FullName = "FN LN"

 

.Company = "Company"

 

.Fields("TBL_CONTACT.BUSINESS_LINE1", Act.Framework.MutableEntities.FieldNameType.Real) = "Address 1"

 

.Fields("TBL_CONTACT.BUSINESS_LINE2", Act.Framework.MutableEntities.FieldNameType.Real) = "Address 2"

 

.Fields("TBL_CONTACT.BUSINESS_LINE3", Act.Framework.MutableEntities.FieldNameType.Real) = "Address 3"

 

.Fields("TBL_CONTACT.BUSINESS_PHONE", Act.Framework.MutableEntities.FieldNameType.Real) = "BUSINESS_PHONE"

 

.Fields("TBL_CONTACT.BUSINESS_COUNTRYNAME", Act.Framework.MutableEntities.FieldNameType.Real) = "BUSINESS_COUNTRYNAME"

 

.Fields("TBL_CONTACT.BUSINESS_EMAIL", Act.Framework.MutableEntities.FieldNameType.Real) = "BUSINESS_EMAIL"

 

.Fields("TBL_CONTACT.BUSINESS_STATE", Act.Framework.MutableEntities.FieldNameType.Real) = "STATE"

 

.Fields("TBL_CONTACT.BUSINESS_CITY", Act.Framework.MutableEntities.FieldNameType.Real) = "CITY"

 

.Fields("TBL_CONTACT.BUSINESS_POSTALCODE", Act.Framework.MutableEntities.FieldNameType.Real) = "POSTALCODE"

 

 

.Update()

 

 

 actFwkDB.LogOff()

End Sub

 

*************************************************** 

 

And now for the easy bit, create the webservice that obtains the customer details on the website that have yet to be downloaded, marks them as loaded, and then provides them to the requester.  And write the program that accesses that webservice and calls the above program to write it to ACT! 

 

 

 

Copper Super Contributor
Posts: 112
Country: Australia

Re: It's Alive! ! ! Connecting VB.Net to ACT!

you did need that code to work out the field names.. the ActDiag application in the install directory can create txt files with a WHOLE report of all field names, types, sizes, everything
dont forget that instead of FieldNameType.Real you can use Alias and then just pass in the label name and replace spaces with _ so for items like Address_1 etc
Copper Contributor
Posts: 51
Country: United States

Re: It's Alive! ! ! Connecting VB.Net to ACT!

Kylua, This was very, very useful.  Thanks for sharing.

 

It was very, very challenging for me to get my head around the fact that ACT! doesn't communicate directly with the underlying DB tables.  I have the complete DB structure from a link in another post and you can actually query this properly but it doesn't support direct writing.  Your technique will be very helpful.

 

Larry

New Member
Posts: 6
Country: United_Kingdom

Re: It's Alive! ! ! Connecting VB.Net to ACT!


lwestatbus wrote:

Kylua, This was very, very useful.  Thanks for sharing.

 

It was very, very challenging for me to get my head around the fact that ACT! doesn't communicate directly with the underlying DB tables.  I have the complete DB structure from a link in another post and you can actually query this properly but it doesn't support direct writing.  Your technique will be very helpful.

 

Larry


I was tempted to give up on using the Framework and write direct to the database but soon cottoned on that you cannot write to them.

To me, this short bit of code is all that is needed to do external updates of the database, it didn't take long at all to implement the rest of the system which calls the webservice and then puts the result straight into ACT!  And I've been quoted £1500 for bespoke creation of this system.  Even with the frustations of trying to get past every little obstacle it's taken me less than two days.

As for:
dont forget that instead of FieldNameType.Real you can use Alias and then just pass in the label name and replace spaces with _ so for items like Address_1 etc
That explains why I managed to get 'Title' to work but not 'Address 1'.  Becos nowhere that I looked did it tell me to replace spaces with underscores, altho I suppose that is reasonably common, just something I don't use much myself.  (I tried replacing with periods becos I saw something that hinted at that!)

All in all, the documentation for what I consider a very basic and common use of the ACT! Framework is appalling.

Which is why I have posted the solution, and I hope it helps a lot more people.  Altho obviously not the ones charging £1500 for half a day's work Smiley Happy

New Member
Posts: 6
Country: United_Kingdom

Re: It's Alive! ! ! Connecting VB.Net to ACT!

OK, now they want me to update the records, not just add new records.  Eventually, (rang Sage, no good at all), I came up with this:

Dim actCont As Act.Framework.Contacts.Contact

         Dim CR As CustRecord

         actCont = actFwkDB.Contacts.CreateContact

         Dim oFieldDescriptor As

Act.Framework.Contacts.ContactFieldDescriptor

         oFieldDescriptor =

actFwkDB.Contacts.GetContactFieldDescriptor("TBL_CONTACT.CUST_MS_ID_023344109",

True)

         Dim oSortCriteria(0) As Act.Shared.Collections.SortCriteria '= {oFieldDescriptor, System.ComponentModel.ListSortDirection.Ascending}

         oSortCriteria(0) = New

Act.Shared.Collections.SortCriteria(oFieldDescriptor,

System.ComponentModel.ListSortDirection.Descending)

 

         Dim actContacts As Act.Framework.Contacts.ContactList =

actFwkDB.Contacts.GetContacts(oSortCriteria)

         For Each actCont In actContacts

             If actCont.Fields("TBL_CONTACT.CUST_MS_ID_023344109",

Act.Framework.MutableEntities.FieldNameType.Real) = TheID Then

                 '

                

actCont.Fields("TBL_CONTACT.CUST_LicenseOrigin_025850578",

Act.Framework.MutableEntities.FieldNameType.Real) = LicenseOrigin

                 actCont.Update()

                 Exit For

             End If

 

         Next

 

But now I want to update a multi-select dropdown box, and I have no clue where to start.

 

Anyone able to help?

New Member
Posts: 6
Country: United_Kingdom

Re: It's Alive! ! ! Connecting VB.Net to ACT!

Easy!!

Set a multiple dropdown in Act!, pulled the text value out in vb.net.  It's simply the different values separated by a semicolons.

So to set it in vb.net simply set the text value to the different entries separated by semicolons.

New Member
Posts: 6
Country: United_Kingdom

Re: It's Alive! ! ! Connecting VB.Net to ACT!

It's working, but I am updating a lot more records than I thought.  This is not the end of the world but it grates on me that I am pulling out a full list of records and then looping thru them to find a matching record before updating it.

Is there not something in the Act! Framework which is the equivalent of:

'Update Contact set Licensed = true where OnlineID = 23'

Employee
Posts: 1,163
Country: USA

Re: It's Alive! ! ! Connecting VB.Net to ACT!

IFilterCriteria can be used to narrow a lookup of contacts. The ComparisonFilterCriteria class is what I believe you are looking for. Here's an example of using IFilterCriteria (albeit this is using the date filter) and setting the current contact list:

 

IFilterCriteria[] CriteriaArray = new IFilterCriteria[1];
CriteriaArray[0] = new DateFilterCriteria(EditDate, StartTime, EndTime);
ContactList cl = _ActApp.ActFramework.Contacts.GetContacts(null, CriteriaArray);
IContactSource ics = _ActApp.ActFramework.Lookups.LookupContacts(cl);
_ActApp.ApplicationState.SetCurrentContactList(cl, ics);
Matthew Wood
Act! SDK Support
Community Moderator