How to search Complex Arraylist & Insert at given point - c#

I am trying to create a simple appplication that can read from a text file and write to the text file. I have a main form which is shown below, also i have a secondary form also shown below; there are also getter and setter classes for Customers, accounts and Transactions. What i would like to do is search for a Customer based on any data held, but mostly there account number. How would i get it to return the correct customer with ALL of there information. Linked to this it would be good to use the search as a point for inserting say a new account.
Below is the main form for pritning out the customer and getting the information from the file.
//create account if all ok
if (allInputOK)
{
//create Account
Account temp = new Account(tempAccSortCode, tempAccNumber, tempAccNickName, tempAccDate, tempAccCurBal, tempAccOverDraft, tempNumTrans);
//add to array
Form1.accDetails.Add(temp);
//finish up
MessageBox.Show("Success Account added ");
resetForm();
}
}
foreach (Customer c in bankDetails)
{
lstOutput.Items.Add(" ");
lstOutput.Items.Add(c.getCustomerNumber() + " " + c.getCustomerTitle() + " " + c.getFirstName()
+ " " + c.getInitials() + " " + c.getSurname() + " " + c.getDateOfBirth()
+ " " + c.getHouseNameNumber() + " " + c.getStreetName() + " " + c.getArea()
+ " " + c.getCityTown() + " " + c.getCounty() + " " + c.getPostcode()
+ " " + c.getPassword() + " " + c.getNumberAccounts());
foreach (Account a in c.Accounts)
{
lstOutput.Items.Add("\t" + a.getAccSort() + " " + a.getAccNumber() + " " + a.getAccNick() + " " + a.getAccDate()
+ " " + a.getAccCurBal() + " " + a.getAccOverDraft() + " " + a.getAccNumTrans());
foreach (Transaction t in a.Transactions)
{
lstOutput.Items.Add("\t \t" + t.getDate() + " " + t.getType() + " " + t.getDescription() + " " + t.getAmount()
+ " " + t.getBalAfter());
}
}
}
In the above code for adding an account, where is adds it to the class Account and the arraylist i think is incorrect with the rest of the program on the main form which uses an underlying list to store the customer information and there accounts/transactions.
EDIT: the above code snippet shows the adding of a new account, however it doesnt seem to be working as i need to find the correct customer by searching the customer array, and then inserting it into the correct place. The second snippet of code shows the arraylist with the underlying lists connected to each customer.

Where to begin?
Generally, for querying objects you can use Linq to Objects.
Also, I would recommend against using text files to keep track of things. They are fine at first, but quickly grow unwieldy and slow. On top of that, what if your app crashes before you saved? Look into a "light database" like SQLite (yes, that's one 'L').

Related

Display Google Analytics Data in View

I'm working on a Google Analytics Client for an MVC application that collects data from Analytics API and I'm trying display the data in a view. The ultimate goal is to display the Google Analytics Data with Google Charts.
However I'm not sure how to properly structure the Data. Each metric is a dictionary with a KeyValuePair where metric name is key and value is the actual value. For example ga:visitors, 3000. I need to organize each metric with its KeyValuePair in to a dictionary that I can return to the view.
For example, first I wrote a console application that returned 3 metrics:
ga:visitors
ga:newVisits
ga:percentNewVisits
Note: each of this metrics is a separate dictionary with KeyValuePair. Ex: [ga:visitors, 3000]
When displaying the data in the console, the code looks like this:
Console.WriteLine("VisitorStatistics" + " " +
d.Query.StartDate + " " + "-" + " " + d.Query.EndDate + "\r\n" +
"------------------------------------------" + "\r\n" +
"Visitors:" + " " + d.TotalsForAllResults["ga:visitors"] + "\r\n" +
"New Visitors:" + " " + d.TotalsForAllResults["ga:newVisits"] + "\r\n" +
"Percent New Visitors:" + " " + d.TotalsForAllResults["ga:percentNewVisits"] +"%");
I need to display this data in my MVC 4 /asp.net application but I'm not sure how to achieve this. All code is located here in my controller:
public void GAnalyticsService()
{
var serviceAccountEmail = "xxxxx.gserviceaccount.com";
var certificate = new x509Certificate2(#"C:\Users\User\Desktop\MyApp\Presentation\Nop.Web\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail) {
Scopes = new[] { AnalyticsService.Scope.Analytics }
}.FromCertificate(certificate));
// Create the service.
//NopCommerce
var GoogleAnalyticsService = new AnalyticsService(new BaseClientService.Initializer() {
HttpClientInitializer = credential,
ApplicationName = "MyApp",
});
var request = GoogleAnalyticsService.Data.Ga.Get("ProfileID", "2010-02-24", "2014-02-24", "ga:visitors,ga:newVisits,ga:percentNewVisits");
//Specify some addition query parameters
request.Dimensions = "ga:visitCount";
request.Sort = "-ga:visitors";
request.MaxResults = 10000;
//Execute and fetch the results of our query
Google.Apis.Analytics.v3.Data.GaData d = request.Execute();
}
public ActionResult GAStatistics() {
//GAnalyticsService();
return View(new GAStatisticsListModel());
}
}
Here's the data i'm recieving from Google Analytics API:
Total results with 3 metrics (each a dictionary with KeyValuePair)
The KeyValuePair:
I just need to organise this data and display it in the view, just plain data (text) is fine. How do i do this?
Any suggestions would be of great help.
Did a temporary fix just to display the data. It serves it's purpose for the time beeing.
Changed GAnalyticsService from a void to a string method.
Returned this:
return "Besöksstatistik" + " " +
d.Query.StartDate + " " + "-" + " " + d.Query.EndDate + "<br/>" +
"------------------------------------------" + "<br/>" +
"Antal besökare:" + " " + d.TotalsForAllResults["ga:visitors"] + "<br/>" +
"Antal nya besökare:" + " " + d.TotalsForAllResults["ga:newVisits"] + "<br/>" +
"Procent nya besökare:" + " " + d.TotalsForAllResults["ga:percentNewVisits"] + "%".ToString();
Got the following output in the view:
Besöksstatistik 2010-02-24 - 2014-02-24
------------------------------------------
Antal besökare: 343272
Antal nya besökare: 147693
Procent nya besökare: 42.54700702044485%

Properly formatted text output to .txt file

I'am exporting some data to a .txt file as follows:
String content;
String path=#"e:\coding\";
String name="test.txt";
path+=name;
System.IO.File.Delete(path);
for (i=0;i<row-1;i++)
{
try
{
if (r[i].points.Count() > 2)
{
content = "Route " + (i + 1).ToString() +" Truck_id:"+trk[i].truck_name.ToString()+ " Max_load="+trk[i].capacity.ToString()+ "\n";
System.IO.File.AppendAllText(path, content + Environment.NewLine);
System.IO.File.AppendAllText(path, "Points Load Reached_AT Max_load" + Environment.NewLine);
System.IO.File.AppendAllText(path, "========================================" + Environment.NewLine);
for (int j = 0; j < (r[i].points.Count()); j++)
{
content = r[i].points[j].ToString() + " " + c[r[i].points[j]].load.ToString() +" "+ r[i].time_list[j].ToString()+" "+c[r[i].points[j]].max_load.ToString()+"\n";
System.IO.File.AppendAllText(path, content + Environment.NewLine);
}
content = "Total " + r[i].ld.ToString() + "\n";
System.IO.File.AppendAllText(path, content + Environment.NewLine );
content = "Route Complete: " + r[i].reach_at.ToString();
System.IO.File.AppendAllText(path, content + Environment.NewLine+Environment.NewLine);
}
}
catch (IndexOutOfRangeException e)
{
break;
}
}
As expected the output I get is not properly formatted:
The spaces are causing the text to be jumbled and not arranged. My reputation does'nt allow me to post a screenshot but I guess It can be understood what is happening.
Is there way so that the text is properly formatted neatly column wise without looking jumbled.
If you need a text, you can use tabs:
System.IO.File.AppendAllText(path, "Points\t\tLoad\t\tReached_AT\t\tMax_load" + Environment.NewLine);
// ...
content = r[i].points[j].ToString() + "\t\t " + c[r[i].points[j]].load.ToString() +"\t\t"+ r[i].time_list[j].ToString()+"\t\t"+c[r[i].points[j]].max_load.ToString()+"\n";
Just play with amount of tabs (\t for one, \t\t for two, etc...). Hope it can help.
Another solution would be to use commas:
System.IO.File.AppendAllText(path, "Points,Load,Reached_AT,Max_load" + Environment.NewLine);
and save to CSV-file (comma-separated values). Then you can import the data to Microsoft Excel or to other software.
You can find bunch full of good information on how to format the string contents in the The format item MSDN but for quick answer, an example for your string
content = "Route " + (i + 1).ToString() + " Truck_id:" + trk[i].truck_name.ToString() + " Max_load=" + trk[i].capacity.ToString() + "\n";
If we assume,
i maximum 10 digits,
Truck_name max 45 characters
capacity max 10 digits
content = String.Format("{0,-20}{1,55}{2,20} " + Environment.NewLine, "Route " + (i + 1).ToString(), " Truck_id:" + trk[i].truck_name.ToString(), " Max_load=" + trk[i].capacity.ToString());

Loop LDAP memberOf as return to show all for single user

Pretty new to using LDAP, and C# in general, and I did more than a few searches, but most of my attempted fixes have lead nowhere.
I am pulling information from the LDAP. Everything works, except I can only pull the memberOf information if I am explicit in which array number I want. Attempts to use a foreach, or a for statement have lead nowhere. I know I am probably missing something simple, but I figured I should just ask.
public static String FindOther(String userAccount)
{
DirectoryEntry entry = GetDirectoryEntry();
DirectorySearcher search = new DirectorySearcher(entry);
try
{
search.Filter = "(SAMAccountName=" + account + ")";
search.PropertiesToLoad.Add("distinguishedName");
search.PropertiesToLoad.Add("displayName");
search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("CN");
search.PropertiesToLoad.Add("Title");
search.PropertiesToLoad.Add("sn");
search.PropertiesToLoad.Add("givenname");
search.PropertiesToLoad.Add("telephoneNumber");
search.PropertiesToLoad.Add("memberOf");
SearchResult result = search.FindOne();
if (result != null)
{
return
"Results for " + userAccount + "\n" +
" DistinguishedName..: " + result.Properties["distinguishedName"][0].ToString() + "\n" +
" Displayname........: " + result.Properties["displayname"][0].ToString() + "\n" +
" eMail..............: " + result.Properties["mail"][0].ToString() + "\n" +
" Common Name........: " + result.Properties["CN"][0].ToString() + "\n" +
" Title..............: " + result.Properties["Title"][0].ToString() + "\n" +
" Last Name..........: " + result.Properties["sn"][0].ToString() + "\n" +
" First Name.........: " + result.Properties["givenname"][0].ToString() + "\n" +
" Telephone..........: " + result.Properties["telephoneNumber"][0].ToString() + "\n" +
" Member Of..........: " + result.Properties["memberOf"][0].ToString() + "\n" +
" Member Of..........: " + result.Properties["memberOf"][1].ToString() + "\n" +
"End Transmission" + "\n";
}
else
{
return "Object not found... User ID: " + account;
}
}
catch (Exception ex)
{
return "Big Ol Error: " + ex.Message + " User ID: " + account;
}
}
Thank you all for any help you could provide.
You can enumerate through an PropertyCollection this way:
string Ret = string.Empty;
...
foreach(object memberOf in result.Properties["memberOf"])
{
Ret += " Member Of..........: " + memberOf.ToString() + "\n";
}
I'm going to give a slight disclaimer here, mostly because I've never coded to Active Directory or the Lightweight Directory Access Protocol. Some of the things that I do know, is a DirectoryEntry usage recommends:
Use GetDirectoryEntry when you want to look at the live entry instead
of the entry that was returned through DirectorySearcher, or when you
want to invoke a method on the object that was returned.
This particular method will return the information directly from Active Directory. Where DirectorySearcher will only generate through what is currently available in the collection. I mention this, because without the collection being filled it won't generate much.
I'm not sure what type of application your building, but Microsoft has an entire area within Microsoft Developer Network that mentions how to integrate several LDAP / AD features into an application.
I'm not sure of your entire goal, but I believe this is what you are seeking. If not let me know and I'll modify the code.
static void Main(string[] args)
{
string groupName = "Domain Users";
string domainName = "";
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, groupName);
if (grp != null)
{
foreach (Principal p in grp.GetMembers(false))
{
Console.WriteLine(p.SamAccountName + " - " + p.DisplayName);
}
grp.Dispose();
ctx.Dispose();
Console.ReadLine();
}
else
{
Console.WriteLine("\nWe did not find that group in that domain, perhaps the group resides in a different domain?");
Console.ReadLine();
}
}
This code was actually from a book, it was used to accomplish such a goal. But as I stated up top, I've never physically done such a task- I'm just hoping to point you in the proper direction.
Another question similar to yours can be found here, which contains good reference and answers your question I believe.

Update a OneNote page, using the developer API

I tried to update a page in OneNote with the Microsoft reference :
http://msdn.microsoft.com/en-us/library/office/jj680118.aspx
Here's my problem. When i tried to update my page with the correct ID, it throwed me an error saying : Exception from HRESULT: 0x80042000.
Here is my code :
static void UpdatePageContent()
{
ApplicationClass onApplication = new ApplicationClass();
String strImportXML;
strImportXML = #"<?xml version="+"1.0"+" encoding="+"utf-16"+"?>" +
" <one:Page xmlns:one="+"http://schemas.microsoft.com/office/onenote/12/2004/onenote\""+"" +
"ID=\"{5BE09697-903A-45DD-88D4-8AD301A3D91F}{1}{B0}\">" +
" <one:PageSettings RTL=\"false\" color=\"automatic\">" +
" <one:PageSize>" +
" <one:Automatic/>" +
" </one:PageSize>" +
" <one:RuleLines visible=\"false\"/>" +
" </one:PageSettings>" +
" <one:Title style=\"font-family:Calibri;" +
" font-size:17.0pt\" lang=\"en-US\">" +
" <one:OE alignment=\"left\">" +
" <one:T>" +
" <![CDATA[My Sample Page]]>" +
" </one:T>" +
" </one:OE>" +
" </one:Title>" +
" <one:Outline >" +
" <one:Position x=\"120\" y=\"160\"/>" +
" <one:Size width=\"120\" height=\"15\"/>" +
" <one:OEChildren>" +
" <one:OE alignment=\"left\">" +
" <one:T>" +
" <![CDATA[Sample Text]]>" +
" </one:T>" +
" </one:OE>" +
" </one:OEChildren>" +
" </one:Outline>" +
" </one:Page>";
// Update page content
try
{
onApplication.UpdatePageContent(strImportXML, System.DateTime.MinValue);
}
catch (COMException e)
{
Console.WriteLine("Error Message : " + e.Message);
}
}
I really don't know how to solve this.
Your XML is not OneNote friendly.
Here's a list of error codes:
http://msdn.microsoft.com/en-us/library/office/jj680117.aspx
You can get rid of the first line, as #Sebastian has stated it's malformed anyway and my experience is that OneNote doesn't need it.
Also, remember that you don't need to send the entire page. You just need to send the page's objId and any updated objects. So one outline needs adding then this should also work:
"<one:Page xmlns:one=\"http://schemas.microsoft.com/office/onenote/12/2004/onenote\" +
"ID=\"{5BE09697-903A-45DD-88D4-8AD301A3D91F}{1}{B0}\">" +
" <one:Outline >" +
" <one:Position x=\"120\" y=\"160\"/>" +
" <one:Size width=\"120\" height=\"15\"/>" +
" <one:OEChildren>" +
" <one:OE alignment=\"left\">" +
" <one:T>" +
" <![CDATA[New Text]]>" +
" </one:T>" +
" </one:OE>" +
" </one:OEChildren>" +
" </one:Outline>";
Just this new outline will get added.
If you still get problems (it doesn't complain but the content doesn't update) then check the extra parameters for UpdatePageContent, certainly in the 2013 API one can send a last modified date to check and also there's a parameter to force a local over-write.
There are some issues in the strImportXML string, which causes the update to fail.
Adjust
#"<?xml version="+"1.0"+" encoding="+"utf-16"+"?>" to "<?xml version=\"" + "1.0" + "\" encoding=\"" + "utf-16" + "\"?>"
Add an empty space before the page ID attribute ( + " " + "ID...
instead of + "" + "ID)
Make sure that the page ID is found/ present in your onApplication
hierarchy
Make sure that you reference the COM library with the matching
namespace defined in the one:Page element (e.g. Office 2013/ 15.0
Object Library has another namespace)

Monitoring program print

Good afternoon. I have a source program that monitors the status of the printer (start printing, stop, etc.). Here is the code that displays information about the print:
MethodInvoker invoker = () =>
{
lbSpoolChanges.Items.Add(e.JobID + " - " + e.JobName + " - " + e.JobStatus);
};
if (lbSpoolChanges.InvokeRequired)
{
Invoke(invoker);
}
else
{
invoker();
}`
You can also call the property e.JobInfo.NumberOfPagesPrinted and line will be a
lbSpoolChanges.Items.Add(e.JobID + " - " + e.JobName + " - " + e.JobStatus + " - " + e.JobInfo.NumberOfPagesPrinted);
but in debug error pops up "The calling thread can not get access to this object as the owner of this object is another thread.." Tell me where you want to call this property. Source included. And can somebody tell how to do so automatically control all the printers (eg 4), and not set in the program. Thanks in advance.
Does it work if you write the invoker as an Action like this, and pass the delegate parameters using BeginInvoke?
Action<string> invoker = (x) =>
{
lbSpoolChanges.Items.Add(x);
};
if (this.InvokeRequired)
{
this.BeginInvoke(invoker, e.JobID + " - " + e.JobName + " - " + e.JobStatus);
}
else
{
invoker(e.JobID + " - " + e.JobName + " - " + e.JobStatus);
}

Categories