Reputation: 21
I work for a call centre that has been using QAS Pro for near 2 years now. We use a resource DLL inside access databases to talk to the internally hosted QAS server. Its only use is to gather address details based on postcode. So the first function gets a list of address from that postcode, inserts them into a combo box in access. After the operator can select the appropriate address and it inserts it into the correct fields.
This was written by a developer who is no longer with us. Its my job to fix the code. With some testing I've been able to verify it is the c# code we use and not the addresses. As the test harness works fine.
The resource DLL uses the c# test code from QAS with an extra file for a few functions. I'm new to c# and have never worked on something like this before. Any help is appreciated.
This is the code written by an old colleague.
namespace MangoQAS
{
using com.qas.proweb;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[ComVisible(true)]
public class QAS
{
public QAS()
{
QuickAddress address = new QuickAddress("http://10.10.15.7:2021") {
Engine = QuickAddress.EngineTypes.Singleline,
Flatten = true
};
this.searchService = address;
}
private string GetMoniker(string p)
{
return this.searchService.Search("GBR", p, PromptSet.Types.Default, "Database layout").Picklist.Items[0].Moniker;
}
public string[] RefinePostcode(string p)
{
string moniker = this.GetMoniker(p);
FormattedAddress formattedAddress = this.searchService.GetFormattedAddress(moniker, "Database Layout");
return new string[] { formattedAddress.AddressLines[0].Line, formattedAddress.AddressLines[1].Line, formattedAddress.AddressLines[2].Line, formattedAddress.AddressLines[3].Line, formattedAddress.AddressLines[4].Line, formattedAddress.AddressLines[5].Line, formattedAddress.AddressLines[6].Line };
}
public string[] SearchPostcodes(string postCode)
{
SearchResult result = this.searchService.Search("GBR", postCode, PromptSet.Types.OneLine, "Database layout");
string[] strArray = new string[result.Picklist.Length];
for (int i = 0; i < result.Picklist.Length; i++)
{
strArray[i] = result.Picklist.Items[i].Text;
}
return strArray;
}
private QuickAddress searchService { get; set; }
}
}
SearchPostcodes - Brings back a list of addresses based on the postcode. RefinePostcode - takes the address line and sends back a formatted address.
The problem seems to be with RefinePostcode. I have tried formatting the address string as my first thought was it didn't like forward slashes. This did not work.
For example, Using the Postcode: PA169AE.
This gives me: 0/1 15 Brachelston Street, GREENOCK, Renfrewshire, at the top of the combobox.
If I click on this address it will send back: 1 Crossgates, Greenock Road, PA7 5JU.
Changing everything including the postcode I entered.
I believe the problem is with RefinePostcode or GetMoniker. The 2 blocks below are from the sample code and unchanged, but may be required to diagnose.
public FormattedAddress GetFormattedAddress(string sMoniker, string sLayout)
{
Debug.Assert((sMoniker != null) && (sLayout != null));
QAGetAddress qAGetAddress = new QAGetAddress {
Layout = sLayout,
Moniker = sMoniker,
QAConfig = this.m_Config,
Language = this.m_LanguageString
};
FormattedAddress address2 = null;
try
{
address2 = new FormattedAddress(this.SearchService.DoGetAddress(qAGetAddress).QAAddress);
}
catch (Exception exception)
{
this.MapException(exception);
}
return address2;
}
public SearchResult Search(string sDataID, string sSearch, PromptSet.Types tPromptSet, string sLayout)
{
Debug.Assert(sDataID != null);
Debug.Assert(sSearch != null);
QASearch qASearch = new QASearch {
Country = sDataID,
Engine = this.m_Engine
};
qASearch.Engine.PromptSet = (PromptSetType) tPromptSet;
qASearch.Engine.PromptSetSpecified = true;
qASearch.Layout = sLayout;
qASearch.QAConfig = this.m_Config;
qASearch.Search = sSearch;
qASearch.Language = this.m_LanguageString;
SearchResult result = null;
try
{
result = new SearchResult(this.SearchService.DoSearch(qASearch));
}
catch (Exception exception)
{
this.MapException(exception);
}
return result;
}
I've thoroughly searched Google and cant seem to find any reason this would happen. I can post more code samples if required.
Upvotes: 1
Views: 2934
Reputation: 1112
did you figure this out?
From the looks of it, I think the problem you have here is the context of the search. Both the QAS server, and QuickAddress class are stateless - they have no history of previous searches.
Because of this at the moment there is nothing linking your first search for postcodes, and your second search on the address line. So, when you call RefinePostcode you are not refining at all. You are instead performing a brand new search UK wide on "0/1 15 Brachelston Street, GREENOCK, Renfrewshire". Whilst QAS pro can handle this, this search generates a few possibilities so the result you are after is not the first one returned.
There are a few possibilities here to improve your workflow. To avoid making any changes to your VBA code and just limit the changes to the sample above you could introduce state to this class and change the workflow so that you are passing in the postcode with your search. Similar to the following:
public class QAS
{
public QAS()
{
// Create a new soap proxy that can talk to QAS Pro Web
QuickAddress address = new QuickAddress("http://10.10.15.7:2021")
{
Engine = QuickAddress.EngineTypes.Singleline,
Flatten = true
};
this.searchService = address;
}
/// <summary>
/// For the supplied search, get the moniker which can then be used to format the address.
/// </summary>
private string GetMoniker(string p)
{
return this.searchService.Search("GBR", p, PromptSet.Types.Default, "Database layout").Picklist.Items[0].Moniker;
}
/// <summary>
/// Return a formatted address from the supplied search.
/// </summary>
public string[] RefinePostcode(string p)
{
// Append the postcode to our address to speed up and improve searches.
string search = p + "," + Postcode;
SearchResult result = this.searchService.Search("GBR",
postCode,
PromptSet.Types.OneLine,
"Database layout");
if ( result.Picklist.Items.Length > 0 )
{
}
else
{
// What is your workflow if an address is not found?
}
string moniker = this.GetMoniker(search);
FormattedAddress formattedAddress = this.searchService.GetFormattedAddress(moniker, "Database Layout");
return new string[] { formattedAddress.AddressLines[0].Line, formattedAddress.AddressLines[1].Line, formattedAddress.AddressLines[2].Line, formattedAddress.AddressLines[3].Line, formattedAddress.AddressLines[4].Line, formattedAddress.AddressLines[5].Line, formattedAddress.AddressLines[6].Line };
}
/// <summary>
/// Once a postcode is captured by the operator, return a list of potential addresses.
/// </summary>
public string[] SearchPostcodes(string postCode)
{
Postcode = postcode;
SearchResult result = this.searchService.Search("GBR",
postCode,
PromptSet.Types.OneLine,
"Database layout");
string[] strArray = new string[result.Picklist.Length];
for (int i = 0; i < result.Picklist.Length; i++)
{
strArray[i] = result.Picklist.Items[i].Text;
}
return strArray;
}
private QuickAddress searchService { get; set; }
/// <summary>
/// Gets or sets the postcode from the initial search.
/// </summary>
private string Postcode
{
get;
set;
}
}
If you have the time though, it would be better to go a little further and properly fix your workflow. Context between searches in QAS Pro Web is handled through monikers. These are tokens that Pro Web provides after all interactions with the server that you can then use to either get formatted addresses or perform further searching with. There are more details on this in the documentation provided.
After your initial search on the postcode, you get a list of addresses and each of these has a moniker associated with it. If you are able to store these monikers and associate these with the list you put into you combo box then when an operator selects one you can pass the moniker straight into GetFormatted address and you should be able to capture addresses quicker, more accurately and with less code!
Hope that helps! Al.
Upvotes: 2
Reputation: 21
This is the code access uses.
Private Sub cmdSelect_Click()
Dim thisOne As String
thisOne = Me.lkupAddressList.Value
Dim objQAS As MangoQAS.QAS
Set objQAS = New MangoQAS.QAS
Dim finalAddress As Variant
finalAddress = objQAS.RefinePostcode(thisOne)
Form_Script.txtAddress1 = finalAddress(0)
Form_Script.txtAddress2 = finalAddress(1)
Form_Script.txtAddress3 = finalAddress(2)
Form_Script.txtTown = finalAddress(3)
Form_Script.txtCounty = finalAddress(4)
Form_Script.txtPostcode = finalAddress(5)
Set objQAS = Nothing
DoCmd.Close acForm, "frmSelectAddress_qas"
End Sub
Private Sub Form_Load()
Dim postcodeToSearch As String
postcodeToSearch = Form_Script.txtPostcode
Dim objQAS As MangoQAS.QAS
Set objQAS = New MangoQAS.QAS
Dim results As Variant
results = objQAS.SearchPostcodes(postcodeToSearch)
Dim howMany As Integer
howMany = UBound(results)
For i = 0 To howMany
Me.lkupAddressList.AddItem ("'" & results(i) & "'")
Next
Set objQAS = Nothing
End Sub
Upvotes: 0