Caching Locally

One of the applications I have been working recently is a windows based application. Most things that the user keys into the system results in a database hit validation. To cut back on this I have implemented classes that assist in caching to the user’s local system. Based on the user’s habits, it will cache what the user uses commonly.

I am using a datatable in this example, but you could use a dictionary object. Should you choose to use a dictionary object, you could use LINQ to query the object. You could also make the caching class an extension which could cut down on some code an make it a little cleaner.

At the end of the day, this is one example only of what could be done.

Class Example

public class CurrencyCodes
private static CurrencyCodes _instance; // Instance Of Self

private static DataTable dt = new DataTable("CurrencyCodes");

public static CurrencyCodes Instance
{
get
{
if (_instance == null)
{
_instance = new CurrencyCodes();
}
return _instance;
}
}

private CurrencyCodes()
{
dt.Columns.Add("CurrencyCode", typeof(String));
dt.Columns.Add("LastUpdated", typeof(DateTime));
}

public String Search(String value)
{
DataRow[] rows = dt.Select("CurrencyCode='" + value + "'");
if (rows.Count() == 1) return value;
return "";
}

public void Add(String value)
{
DataRow row = dt.NewRow();
row["CurrencyCode"] = value;
row["LastUpdated"] = DateTime.Now;
dt.Rows.Add(row);
}

public void ClearCache()
{
dt.Rows.Clear();
}

public void LoadCache(String xml)
{
StringReader theReader = new StringReader(xml);
dt.ReadXml(theReader);
}

public String SaveCache()
{
using (MemoryStream ms = new MemoryStream())
{
dt.WriteXml(ms);
ms.Position = 0;

StreamReader sr = new StreamReader(ms, System.Text.Encoding.UTF8);

return sr.ReadToEnd();
}
}
}

Calling the class

Directory.SetCurrentDirectory(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
if (!Directory.Exists("YourSoftwareCache"))
{
Directory.CreateDirectory("YourSoftwareCache");
}

if (File.Exists("CurrencyCodes.XML"))
CurrencyCodes.Instance.LoadCache(File.ReadAllText("CurrencyCodes.XML"));

CachedCurrencyCodes cachedCurrencyCodes = CachedCurrencyCodes.Instance;
CurrencyCode = cachedCurrencyCodes.Search(Criteria);

Note Comments have been stripped to clean up the posting. Always Comment Your Code.

Publishing Using VisualStudio

I have often had the glorious opportunity to watch someone try to deploy a project by picking compiled libraries that they had thought had changed.  Every time they deployed by using this method, their live project would not run.  When they run their project on the development machine, it runs no problem.  This confuses the developer to no end resulting in a multitude of profanities.

This is a bit painful to watch.   I really do not understand why developers do not deploy by using installation packages or deployment methods provided by their development environment.

Today, I had offered to deploy the project for them and used the VisualStudio deployment utility.  This was a web-based project so it was very easy.  The deployment wizard walks you through the process starting at where you would like to deploy to.  The deployment results in only deploying the files necessary to run the program or website.  I had learned this principal while working for a London company; ICINITI.

ICINITI would use a packaging tool to deploy products to customer machines including websites.  Their projects would often automate part of the process including site setup, run batch files and deploy other required files.  Deployment to customer’s computer systems would go pretty quick.  Sometimes it was so smooth the customer was able to conduct the deployments themselves.

Today’s deployment took about 5 minutes or less.   I had later demonstrated how and what I had done.   I believe this will be used a little more often as a deployment technique.

Why Not To Choose a Web Interface

For some applications it seems to me that the web interface may be at it is limits. For those applications that need large amounts of data on display on a single screen that also include calculations and database updates a Single Click Deployment may be a better option. With more updates, calculations and data on a web interface, the more bloated the page becomes. When the page is bloated, it means the updates and page refreshes become slower. It doesn’t matter if the page is using AJAX, it is still bloated. As a test, load all the data the user needs and check the page size. Most of the page size will probably be found in the ViewState.

In my cases, I had applications that needed ViewState to exist and placing the ViewState in the database or at the server levels did not help the load or refresh times.

Single Click Deployments are a method of deploying a desktop application to multiple workstations on a network. This means when the developer deploys an update, the update gets pushed out when the application starts on the workstation. This works well on a closed network or VPN, but it can be rolled out to internet users. Generally speaking the web interface is stateless while the desktop version is live data and holds state. The advantage is the Single Click Deployment allows for heavy calculations and heavy data displays to take outside the confines of a web browser and to use the users resources instead of the IIS (Web Server) resources. This means the user does not have to wait for updates and refreshes.

Note: If rolled out to internet users, you will have to deploy using WebServices to fetch and update data.

I am not saying to stop using the Web Interface.   In fact I do use it; however, for those applications that require large amounts of data, calculations, look-ups and updates, I tend to push towards a desktop application using Single Click Deployments.   The user has been found to be much happier and less support calls.

More to come…

Converting a PDF to Excel

Converting a PDF to Excel using InvestInTech.com’s PDF to Excel SDK.

PDF Sharp and other SDKs had the ability to read text from a PDF; however, I had found that InvestInTech’s PDF to Excel kept data in grid form.
This made it easier to use OLEDB to query the excel and strip the data as needed. I had tried InvestInTech’s XML conversion, but it did not have the same clean results.

Here is a sample of how I had accomplished the conversion.

String name = Path.GetFileNameWithoutExtension(filename);
String directory = @"C:temp";

String[] files = Directory.GetFiles(directory);

Int32 iCount = 0;
foreach (String file in files)
{
iCount++;
toolStripStatusLabel2.Text = " - Converting PDF to Excel File# " + iCount + " of " + files.Count();
Application.DoEvents();

CPDF2ExcelClass pdf2Excel = new CPDF2ExcelClass();
IPDF2Excel iPDF2Excel = pdf2Excel;

iPDF2Excel.PDF2Excel(file, file.Replace(".pdf", ".xls"));

toolStripStatusLabel2.Text = " - Converting PDF to Tiff File# " + iCount + " of " + files.Count();
Application.DoEvents();
ConvertPDFToTiff(file);

File.Delete(file);
}

How To Split A PDF Using PdfSharp

I recently completed a project which broker a PDF file into multiple files from which I converted to a MS Excel file and ultimately processed the data into a database.

This segment is dealing with the portion for splitting a multi-page Adobe PDF file into multiple pages. I mostly do this step, because we will be storing the individual page into a document management system along with the data that we strip from it. This page will be used later by our data entry clerks.

When breaking down to individual pages, we need to ensure that we keep the integrity of the original page. This ensures we can still convert to an Excel file to get the data from it.

There are many open-source and free PDF SDK kits that you can try. I had best luck doing most any PDF work using PdfSharp ( http://pdfsharp.com/PDFsharp/ ). Here is a modified code segment of how you can use PdfSharp to split.

Int32 iCount = 0;

PdfDocument inputDocument = PdfReader.Open(filename, PdfDocumentOpenMode.Import);
String directory = @"C:temp";
string name = Path.GetFileNameWithoutExtension(filename);
for (int idx = 0; idx < inputDocument.PageCount; idx++)
{
iCount++;
toolStripStatusLabel2.Text = " - Processing File# " + iCount + " of " + inputDocument.PageCount;
Application.DoEvents();

// Create new document
PdfDocument outputDocument = new PdfDocument();
outputDocument.Version = inputDocument.Version;
outputDocument.Info.Title = String.Format("Page {0} of {1}", idx + 1, inputDocument.Info.Title);
outputDocument.Info.Creator = inputDocument.Info.Creator;

// Add the page and save it
outputDocument.AddPage(inputDocument.Pages[idx]);
outputDocument.Save(Path.Combine(directory , String.Format("{0} - Page {1}.pdf", name, idx + 1)));
}

Using LINQ to find a control in the ControlCollection

While writing a windows application in C#, I realized that there was no find control method in the ControlCollection class. This was a problem as it would create a significant amount of code to find a control. Well it turns out you can do it using LINQ. I had found a blog that I was able to implement the code fairly cleanly. The original code limited me a little bit, but with a very minor modification I came up with this code.

Original Blog: linq-the-uber-findcontrol

public static class PageExtensions
{
public static IEnumerable All(this Control.ControlCollection controls)
{
foreach (Control control in controls)
{
if (control.HasChildren)
{
foreach (Control child in control.Controls.All())
{
yield return child;
}
}
else
{
yield return control;
}
}
}
}

private Control GetControlByName(string name)
{
Control firstEmpty = this.Controls.All()
.OfType()
.Where(tb => tb.Name.Trim().Equals(name))
.FirstOrDefault();
return firstEmpty;
}

String Comparison using Equals

s.equals(x);

Will return true if the strings s and x contain the same character sequence. So:

String s = new String(“foobar”);
String x = new String(“foobar”);

Then s.equals(x) will return true, but s == x will be false, because s and x are not the same String Object.

If you then do:

String y = s;
String t = x;

You have a case where any string of the 4, .equals() any other string of the 4 (s, t, x, y) will return true, but only s == y or t == x will return true. That is because they refer to the same object.

The Art of Task Delegation

Delegation is a tough skill to master.  Many mangers have trouble delegating tasks to employees because they have trouble giving up control.   A good manager knows their strengths and the amount of work load they can handle without stressing.   A good manager also knows their employees strengths.  Use those strengths to your advantage.  Through the art of delegation, you can harness the skills you don’t have and reduce your stress by reducing your work load.  Delegation of tasks does not mean you are no longer responsible for the task, it only means that you are now managing.  You are still responsible for quality of the work done by the person you delegated the task to.  You still deserve credit for getting the work done, the only difference is you should be sharing the credit with the people who helped you.

Tips for Delegating Work

  • Know everyone’s strengths
  • Follow up with everyone who you delegated work to.   Ensure they are on task and the quality it to your desire.
  • Delegate tasks only to the people you trust.
  • Use a calendar.   Make sure you are following a schedule and that everyone knows the schedule.
  • Make sure everyone has the resources to get the job done. 
  • Provide your knowledge and share your experience.
  • Manage, manage, manage – this doesn’t mean you do the work. 
  • Share the glory, if you get praise, share the praise with those who helped. 

Importance of Tracking Daily Activities – A Personal Perspective

When the cat is away the mice will play.

This famous saying suggests that when a person in authority is not present, the people under his rule will enjoy their freedom. However; this should not be the case. The employee should be relied upon to get work done that was assigned as well as conduct themselves professionally and with dignity. “Farting Around”, should not occur. There is always something to be done in every organization. Push a broom, re-index a database, setup a new help desk system, sort papers, refill the toner in a printer. Even researching a new technology or idea can be beneficial.

We as paid workers with self worth, should be keeping a log when the boss is away of our daily activities. This log should include all interruptions, lunch, breaks, and tasks. Do not spend a lot of time, but spend enough time to make yourself look productive. The activity log could be in the form of a blog or a text file and should be easily printed in a readable format.

There is two main reasons for the log. It keeps you as the employee focused on activities that require your focus and it keeps the bosses informed.

If done on a daily basis it can show the boss weakness and strengths in the team that he/she is responsible for. It can help allocate tasks to those who are best suited for the task. It can also point out where time is being spent, which can be either allocated to someone else or reviewed closer. It is mostly about following trends in the logs in which we can extrapolate productivity value.

For the employee, it should be considered a review of one’s self worth within the organization. Even if the boss never sees it; review it yourself and see what you have done. I would bet you have been doing more than you had thought. Often it can be used to improve your resume, your feeling about the work you can do. I know myself I sometimes think I should have gotten things done faster, but in review of my day, it makes sense why I did not.

I believe every employee should want to do this at least on a part time bases, and every boss should want to have the ability to review the work logs weekly of their employees.

Creating a Collection of Top-Level Class From Base Level Class

When you have a class inherit another class, sometimes you want the base level class to create a collection of the top-level class.  In this blog I will demonstrate some basic inheritance and a little reflection trick.  Note the examples are in C#, but could easily be done in VB.NET

Why you may want to do this?  You may want to create a base class to handle all of your basic database functions from which your data layer classes will inherit to limit duplicate code.  In the base class you may create a “SELECT” function to return multiple rows of data.  The rows of data being returned are represented by the top-level class, for which you need a collection of the base level class.

You need two components or classes.  The first is to create your base class from which you will inherit later on.  In the base class you will create a method to generate a collection of the top-level class.  The example being used is passing in the size of collection to be returned, but you could have it being auto generated based on number of database rows.



public class BaseClass
{
public String FirstName { get; set; }

public BaseClass()
{
}

public ArrayList getCollection(String className, int limit)
{
ArrayList collection = new ArrayList();

Type t = Type.GetType(className); 
for ( int icount=0; icount < limit; icount++ )
{
object clss = Activator.CreateInstance(t);
((BaseClass)clss).FirstName = "Bob"; 
collection.Add(clss);
}

return collection;
}
}

The next part is to create a class that inherits the base class.  From this new class we are going to make a public function that will return the requested collection.  Remember; you could be returning class collection of data rows or another single purpose that could be represented by a class.


public class ClassInherit : BaseClass
{
public ClassInherit()
{
}

public ArrayList BuildCollection()
{
return getCollection("ClassInherit", 4);
}
}

If you have questions regarding this blog or the purpose of this blog, please feel free to contact me at www.unlatched.com or www.andrewpallant.com.