Listbox displayMember not working - c#

I have run into an issue.
I am creating a small application for working with our phone configuration files.
I have created a Class called Phone and given it 4 properties:
private int extension;
private String sExtension;
private String userName;
private String filePath;
I have included the respective get/set methods as well as:
public String Extension
{
get
{
return sExtension;
}
}
public String Path
{
get
{
return filePath;
}
}
I have created a utility class that does most of the static work. Including a method to create a List<Phone> of phone objects to populate the ListBox.
Everything works to the point of returning the List<Phone> back as the datasource for the ListBox. I have set both the:
fileList = Directory.EnumerateFiles(path, "ext-*");
lst_Files.DataSource = Utility.populatePhoneList(fileList);
lst_Files.DisplayMember = "Extension";
lst_Files.ValueMember = "Path";
The problem I am still experiencing is the ListBox is still being populated by the object name (in reference to MSDN Article)
I have read through a couple articles on this forum and most mention the same issue that I may not be calling ListBox.DisplayMember correctly but I believe I am.
Edit: I have tried returning a List<T>, ArrayList,Array[].
Edit: Code for utility
public static List<Phone> populatePhoneList(IEnumerable<String> newFileList)
{
List<Phone> phones = new List<Phone>();
Phone p = null;
for (int i = 0; i < newFileList.Count(); i++)
{
p = getPhoneInfo(newFileList.ElementAt(i));
phones.Add(p);
}
return phones;
}
public static Phone getPhoneInfo(String newPath)
{
StreamReader sr = new StreamReader(newPath);
Phone p1 = new Phone();
p1.setFilePath(newPath);
String testLine;
while (sr.Peek() >= 0)
{
testLine = sr.ReadLine();
if (testLine.Contains("reg.1.displayName"))
p1.setUserName(testLine.Substring(testLine.IndexOf("\"") + 1, ((testLine.LastIndexOf("\"") - 1) - testLine.IndexOf("\""))));
if (testLine.Contains("reg.1.address"))
p1.setExtension(testLine.Substring(testLine.IndexOf("\"") + 1, ((testLine.LastIndexOf("\"") - 1) - testLine.IndexOf("\""))));
}
return p1;
}

After digging into this problem over the weekend I started disabling some event handlers on the ListBox and found that it is working as it should be. I found that my ListBox.SelectedIndexChanged event was catching the list before the system completely populated. My solution was to turn ListBox.SelectionMode to none then reset it once the ListBox was filled.

Related

Can you choose a random List member from a collection based on properties of objects in said List?

I wrote a program to shuffle media in a folder because the media player I have, while it does support shuffling, doesn't remember what it already played so a lot of times I get repeats. I wrote my own to ensure everything gets played at least once. So anyway, I made an object to hold the video info:
namespace MediaShuffler {
class Video {
public string filepath {get; set;}
public string filename {get; set;}
public string filetype {get; set;}
public string fullfile {get; set;}
public bool played {get; set;}
override
public bool Equals(object checkobj) {
if (!(checkobj is Video)) return false;
return ((Video)checkobj).fullfile == fullfile;
}
public Video(string file) {
fullfile = file;
filepath = Path.GetDirectoryName(file);
filename = Path.GetFileName(file);
filetype = Path.GetExtension(file).ToLower();
played = false;
}
public void Play() {
if (!Utils.cfg.ContainsKey("mediaplayer.executable") ||
!Utils.cfg.ContainsKey("mediaplayer.executable")) return;
Process proc = new Process();
proc.StartInfo.FileName = Utils.cfg["mediaplayer.executable"];
proc.StartInfo.WorkingDirectory = Utils.cfg["mediaplayer.directory"];
proc.StartInfo.Arguments = Utils.TokenizeArguments(GetTokens());
proc.Start();
played = true;
proc.WaitForExit();
OnVideoComplete(EventArgs.Empty);
}
private Dictionary<string, string> GetTokens() {
Dictionary<string, string> tokens = new Dictionary<string, string>();
tokens.Add("%filename%", filename);
tokens.Add("%filepath%", filepath);
tokens.Add("%filetype%", filetype);
return tokens;
}
protected virtual void OnVideoComplete(EventArgs e) {
EventHandler<EventArgs> handler = VideoComplete;
if (handler != null) handler(this, e);
}
public event EventHandler<EventArgs> VideoComplete;
}
}
In the main part of the program, I iterate over the path passed to the program and build a List "playlist" of all the files in the folder that are videos. I realize after I made the object that I actually don't know an efficient way to get a random List member where member#hasPlayed is false. What I ended up doing was:
while (true) {
int selection = new Random().Next(0, playlist.Count-1);
videoPlaying = true;
Write("[" + selection.ToString() + " / " + playlist.Count.ToString() + "] Playing " + playlist[selection].filename + " ...");
playlist[selection].Play();
while (videoPlaying) Thread.Sleep(500);
playlist.RemoveAt(selection);
if (playlist.Count == 0) {
if (!repeatList) break;
BuildPlaylist();
}
}
It works, but I was hoping I could actually leverage the hasPlayed bool in some manner, so that adding it wouldn't be pointless lol. I suppose since it works it doesn't matter, but I just was curious if it was possible to do. Also I wasn't sure the best way to make the process "rest" while the media player was doing its thing; is sleeping the thread momentarily the right thing to do?
Easiest way would probably be using Random and LINQ Where to select only those you haven't played yet like so:
// Select all where played == false
var notPlayed = playList.Where(x => !x.played).ToList();
// Create random Index, ensuring it is no larger than the count of unplayed songs
// Also, try not to create a new instance of random every time
var randomIndex = new Random().Next(notPlayed.Count);
// Play song
notPlayed[randomIndex].Play();
As a note: Try not create an instance of Random inside a loop, instead try to create it once, and re-use it
Here are a few more pointers to generally improve your code, not necessarily pertaining to your question:
Try and use Framework built in things, like the FileInfo class, which already has properties for fileName and filePath (Name and Directory( DirectoryName respectively). It'd be better to wrap it and use something like Path.GetExtension to return the file extension
Try and adhere to the C#/ .NET naming and style conventions (especially names of type members) (you can take a look at NET Core source to see how MS does it)

Ban a variable from a list with a "ban" list

How can I ban a variable from a list without removing it from that list by adding the variable to a list of "banned" variable?
I wish to be able to type in a string. That string is compared to the file names in a folder. If there is a match, the file is read. If I type this same string again, the file should not be read again. There for I want to have a list of "banned" string that is checked whilst typing to avoid the file to be read again.
I have tried a few ways but not getting there. Below is an example of my last attempt.
What would be the best way?
public class test
{
string scl= "test3";
List <string> lsf,lso;
void Start ()
{
lsf=//file names
new List<string>();
lso=//files open
new List<string>();
lsf.Add("test0");
lsf.Add("test1");
lsf.Add("test2");
lsf.Add("test3");
lsf.Add("test4");
lso.Add("idhtk49fngo");//random string
}
void Update ()
{
if
(
Input.GetKeyDown("a")
)
{
for
(
int i=0;
i<lsf.Count;
i++
)
{
if(lsf[i]==scl)
{
Debug.Log
(i+" is read");
for
(
int j=0;
j<lso.Count;
j++
)
{
//how can i avoid reading
//lsf[3] here the second time
//"a" is pressed (by having "test3"
//added to a "ban" list (lso) )
if(scl!=lso[j])
{
lso.Add(lsf[i]);
}
}
}
}
}
}
Michael’s answer is the way to go here but it can be improved using the more appropriate collection available to keep track of opened files; if you want uniqueness use a set, not a list:
HashSet<string> openedFiles = new HashSet<string>();
public static bool TryFirstRead(
string path,
out string result)
{
if (openedFiles.Add(path))
{
result = File.ReadAllText(path);
return true;
}
result = null;
return false;
}
Also, I’d avoid throwing vexing exceptions. Give the consumer a friendly way to know if the file was read or not, don’t make them end up having to use exceptions as a flow control mechanism.
I didn't understand although if you want to replace a value from another list.
You can use the list index to create a new list with the values which you removed.
String list1 = {"hi", "hello", "World"};
String list2 = {"bye", "goodbye", "World"};
List1[1] = list2[1];
I would suggest such way:
public static List<string> openedFiles = new List<string>();
public static string ReadFileAndAddToOpenedList(string path)
{
if (openedFiles.Contains(path))
throw new Exception("File already opened");
// Instead of throwing exception you could for example just log this or do something else, like:
// Consolle.WriteLine("File already opened");
else
{
openedFiles.Add(path);
return File.ReadAllText(path);
}
}
The idea is - on every file read, add file to list, so you can check every time you try read file, if it was already read (or opened). If it is, throw exception (or do something else). Else read a file.
You could instead of making it a string list use your own class
public class MyFile
{
public string Name;
public bool isOpen;
public MyFile(string name)
{
Name = name;
isOpen = false;
}
}
List<MyFile> lsf = new List<MyFile>()
{
new MyFile("test0"),
new MyFile("test1"),
new MyFile("test2"),
new MyFile("test3"),
new MyFile("test4")
};
Than when you read the file set isOpen to true
MyFile[someIndex].isOpen = true;
and later you can check this
// E.g. skip in a loop
if(MyFile[someIndex]) continue;
You could than also use Linq in order to get a list of only unread files:
var unreadFiles = lsf.Select(f => f.Name).Where(file => !file.isOpen);

List only devices shown in 'Devices and Printers' panel

I am writing an application in C# that will run on a users PC and I want to list only the devices that are shown in the Windows "Devices and Printers" control panel, things like monitors, keyboard, mouse, speakers etc.
I can use WMI to extract a list of all devices, but is there a way to only extract only those that are shown in that part of control panel rather than the full list?
I have searched online and found nothing relating to this and I can't even find what is the criteria for a device to appear in that list.
Is it possible to access the list of those devices that are shown in that list or, if not, is there a filter that can be applied to the full list that will only show those devices?
thanks in advance
I do it with p/invoke and COM interop by enumerating the shell items in Microsoft.DevicesAndPrinters and filtering by making sure that PKEY_Devices_CategoryIds contains an item starting with PrintFax.
There's no way to boil the necessary interop definitions down to fit in an answer, but this is the logic I use to enumerate the display name, the DEVMODE name, and images of any size:
public sealed class PrinterInfo
{
public string IdName { get; }
public string DisplayName { get; }
public Bitmap Image { get; }
private PrinterInfo(string idName, string displayName, Bitmap image)
{
IdName = idName;
DisplayName = displayName;
Image = image;
}
public static IReadOnlyList<PrinterInfo> GetInstalledPrinterNamesAndImages(Size imageSize)
{
var r = new List<PrinterInfo>();
using (var folderIdList = CreateDevicesAndPrintersIDL())
{
var folder = GetShellFolder(folderIdList);
var enumerator = folder.EnumObjects(IntPtr.Zero, SHCONTF.NONFOLDERS);
for (;;)
{
// If you request more than are left, actualCount is 0, so we'll do one at a time.
var next = enumerator.Next(1, out var relativeIdList, out var actualCount);
next.ThrowIfError();
if (next == HResult.False || actualCount != 1) break; // printerChild is junk
using (relativeIdList)
using (var absoluteIdList = ILCombine(folderIdList, relativeIdList))
{
var shellItem = GetShellItem(absoluteIdList);
var idName = GetPrinterFriendlyNameIfPrinter(shellItem);
if (idName != null)
r.Add(new PrinterInfo(idName, GetDisplayName(shellItem), GetImage(shellItem, imageSize)));
}
}
}
return r;
}
private static ItemIdListSafeHandle CreateDevicesAndPrintersIDL()
{
SHGetKnownFolderIDList(FOLDERID.ControlPanelFolder, KF_FLAG.DEFAULT, IntPtr.Zero, out var controlPanelIdList).ThrowIfError();
using (controlPanelIdList)
{
GetShellFolder(controlPanelIdList).ParseDisplayName(IntPtr.Zero, null, "::{A8A91A66-3A7D-4424-8D24-04E180695C7A}", IntPtr.Zero, out var childDevicesAndPriversIdList, IntPtr.Zero);
using (childDevicesAndPriversIdList)
return ILCombine(controlPanelIdList, childDevicesAndPriversIdList);
}
}
private static string GetPrinterFriendlyNameIfPrinter(IShellItem2 shellItem)
{
// Devices_PrimaryCategory returns "Printers" for printers and faxes on Windows 10 but "Printers and faxes" on Windows 7.
using (var categoryIds = new PropVariantSafeHandle())
{
shellItem.GetProperty(PKEY.Devices_CategoryIds, categoryIds).ThrowIfError();
if (!categoryIds.ToStringVector().Any(id => id.StartsWith("PrintFax", StringComparison.OrdinalIgnoreCase)))
return null;
}
// The canonical or "friendly name" needed to match the devmode
// https://blogs.msdn.microsoft.com/asklar/2009/10/21/getting-the-printer-friendly-name-from-the-device-center-shell-folder/
// PKEY_Devices_InterfacePaths doesn't seem to ever be found, but PKEY_Devices_FriendlyName works so...
shellItem.GetString(PKEY.Devices_FriendlyName, out var friendlyName).ThrowIfError();
return friendlyName.ReadAndFree();
}
private static string GetDisplayName(IShellItem2 shellItem)
{
return shellItem.GetDisplayName(SIGDN.NORMALDISPLAY).ReadAndFree();
}
private static Bitmap GetImage(IShellItem2 shellItem, Size imageSize)
{
return ((IShellItemImageFactory)shellItem).GetImage(new POINT(imageSize.Width, imageSize.Height), SIIGBF.SIIGBF_BIGGERSIZEOK)
.CopyAndFree(); // Bitmap.FromHbitmap is useless with alpha, so make a copy
}
private static IShellFolder GetShellFolder(ItemIdListSafeHandle itemIdList)
{
SHBindToObject(IntPtr.Zero, itemIdList, null, typeof(IShellFolder).GUID, out var objShellFolder).ThrowIfError();
return (IShellFolder)objShellFolder;
}
private static IShellItem2 GetShellItem(ItemIdListSafeHandle itemIdList)
{
SHCreateItemFromIDList(itemIdList, typeof(IShellItem2).GUID, out var objShellItem).ThrowIfError();
return (IShellItem2)objShellItem;
}
}
(C# 7)
Here's a full demo you can compile: https://github.com/jnm2/example-devices-and-printers/tree/master/src
For a C# 6 version which doesn't require ValueTuple, see https://github.com/jnm2/example-devices-and-printers/tree/master/src-csharp6.
I'm happy to answer any questions.

Unable to get a string out of a method

I am really new to coding, never studied it or something similar, just learning it myself, never done it before, but I am trying to create my first real application right new.
However, I have some problems for 2 days which I just can't figure out, so I hope you can help me out.
Alright, so before the youtubedlCurrentWorker_Process() is created, I did define 'public string CurrentYouTubeDLVersion'.
How ever, when a button in my application executes the youtubedlCompareVersion_Process(), the CurrentYouTubeDLVersion string is empty, when it comes at the compare point.
Below is just a little part of my code.
Why is the string CurrentYouTubeDLVersion empty in the CompareVersion while the GetCurrentVersion ran before it?
Even if I double click "CurrentYouTubeDLVersion" in Visual Studio, it won't show a link to the one in the GetCurrentVersion_Process.
namespace MediaDownloader
{
public partial class updates : UserControl
{
public string LatestYoutubeDLVersion;
public string CurrentYouTubeDLVersion;
public void youtubedlGetCurrentVersion_Process()
{
if (File.Exists(YouTubeDLPath))
{
//Here I get the current version of youtube-dl.exe, to get the version number, we have to run youtube-dl.exe --version
Process youtubedl = new Process();
youtubedl.StartInfo.CreateNoWindow = true;
youtubedl.StartInfo.UseShellExecute = false;
youtubedl.StartInfo.RedirectStandardOutput = true;
youtubedl.StartInfo.RedirectStandardError = true;
youtubedl.StartInfo.FileName = YouTubeDLPath;
youtubedl.StartInfo.Arguments = " --version";
youtubedl.Start();
string CurrentYouTubeDLVersion = youtubedl.StandardOutput.ReadToEnd();
this.Dispatcher.Invoke((Action)(() =>
{
CurrentYouTubeDLVersionText.Text = "Current youtube-dl.exe version: " + CurrentYouTubeDLVersion;
YouTubeDLVersionStatusText.Text = null;
UpdateYouTubeDL.IsEnabled = false;
}));
}
public void youtubedlCompareVersion_Process()
{
youtubedlGetCurrentVersion_Process();
string LatestYoutubeDLVersion = WebClient.DownloadString("https://yt-dl.org/latest/version");
MessageBox.Show("Latest:" + LatestYoutubeDLVersion + "Current " + CurrentYouTubeDLVersion);
int YouTubeDLUptodate = CurrentYouTubeDLVersion.CompareTo(LatestYoutubeDLVersion);
if (YouTubeDLUptodate < 1)
{
YouTubeDLVersionStatusText.Text = "Your youtube-dl.exe is out of date, please click the button below to update.";
UpdateYouTubeDL.IsEnabled = true;
}
else
{
YouTubeDLVersionStatusText.Text = "youtube-dl.exe is up to date!";
UpdateYouTubeDL.IsEnabled = false;
}
}
}
Inside the youtubedlGetCurrentVersion_Process method, you're creating a new CurrentYouTubeDLVersion string, and it's completely separate from the public CurrentYouTubeDLVersion you added to the top of the class.
string CurrentYouTubeDLVersion = youtubedl.StandardOutput.ReadToEnd();
Assign to the class-level variable you made, instead of creating a new string:
CurrentYouTubeDLVersion = youtubedl.StandardOutput.ReadToEnd();
Then the value will be available to you in youtubedlCompareVersion_Process.
Take out the 'string' in front of CurrentYouTubeDLVersion and it should work
public youtubedlGetCurrentVersion_Process()
{
/* removed code to make easier to read */
//string CurrentYouTubeDLVersion = youtubedl.StandardOutput.ReadToEnd();
CurrentYouTubeDLVersion = youtubedl.StandardOutput.ReadToEnd();
/* removed code to make easier to read */
}

QAS Pro. Problems with certain addresses

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.
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.
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

Categories

Resources