Jan Schreuder on .Net

.Net code samples, experiences, observations

View my professional profile on LinkedIn

Recent Posts

Tags

News

  • Inappropriate comments will be deleted at my discretion.

    The information and code samples in this weblog is provided "AS IS" without warranty of any kind, either expressed or implied, including but not limited to the merchantability and/or fitness for a particular purpose.

Community

Email Notifications

Tool suppliers

Tools

General

Microsoft

Favorite blogs

Archives

July 2008 - Posts

Need help with Crystal Reports? Look here!

Because I blog about Crystal Reports occasionally, and created a helper class to assist in integrating it into .Net applications, I get a lot of questions from people that have problems running their reports. Especially in production environments after they deploy the reports. Unfortunately, I'm not a Crystal Expert. I use it in my applications but that's how far it goes. I don't have all the answers people might want.

But I do know where you can find information about Crystal and where you do find answers to any problems you might have. I created a blog post a few weeks ago to sum up a number of resources that can help you find answers to almost all of your Crystal Reports issues. Click here to read that post.

Have your C# coding style analysed by Microsoft, part 2

Just as a small update on the use of StyleCop. I disagreed with some of the rules, like having to use spaces rather than tabs. It's not really an annoying rule, the only thing about it is that you have to agree on using spaces or tabs and then stick to it.

But still, I found out you can tune StyleCop to your needs. When you go the folder where the application is installed (on my machine C:\Program Files\Microsoft StyleCop 4.3) you will see a small application named StyleCopSettingsEditor.exe. Using that tool you can switch the rules supplied by the tool on or off. From a command prompt simply run the following command line:

StyleCopSettingsEditor.exe Settings.StyleCop

You will then see the following user interface:

Using this interface, you can simply select which rules are appropriate in your projects.

Coding standards, Coding rules, Coding guidelines, etc...

If there's one thing that developers usually just cannot (or will not) agree to, then it's Coding standards/rules/guidelines or whatever name you want to give it. I posted a short item about a new tool from Microsoft that checks if your code matches the Microsoft guidelines and sure enough, I'm already getting mails on the subject explaining that Microsoft's rules suck and that they use one that's better. I thought it might just be a great subject for a discussion. But let me share my views on the subject first.

Coding standards, my view

I've been working as a developer in various roles and projects now for over 20 years. Yes, I'm that old, but it's to show that I speak from experience on this subject. Each project I worked on has had one or another form of coding guidelines or standards. In one project, they even called it a coding convention in an attempt to make it more important. My reaction in most occasions was: "What ever..."

The thing with this subject is, that developers simply cannot agree to one single guideline. Every developer thinks he/she is the best in his/her area and therefor the expert to tell others how to write their code. Well, they're wrong.

A coding standard is as good as the method to enforce it. If it's not enforced, then it's useless. And in 99% of all projects you will see that coding standards are not enforced. In my view, the only standard that works is the standard that you can enforce using tools. The guidelines checked by Microsoft's FxCop are a good example. It always uses the same rules for all code and always warns in the same way. There are other tools that do that as well, like DevPartner from Compuware. You can agree to those rules or not, but at least it leaves little room for discussion and I see FxCop being more and more accepted.

And now there's StyleCop. It checks your code against the coding rules as used at Microsoft development centers. Again, you can discuss if these rules are correct, but you get a tool that validates the code and tells you were you have strayed from the narrow path. My feeling is that although I don't entire agree to all rules, at least I can force my team to stick to these rules. Simply by breaking the build if they don't comply to the coding rules.

There are tools that allow you to write your own custom rules, like ReSharper and DevPartner. Useful as this can be, what do you do with code generated by Microsoft code generators. Think only of generated code for DataSet objects and WinForms. It's highly unlikely that this code will adhere to your guidelines. But will the use the Microsoft guidelines? It's a better bet then with your custom rules.

Another misconception is that these rules improve the quality. But to be frank, this is mostly bullshit. The rules checked by FxCop (and similar tools) check for code quality with respect to the use of the .Net framework. StyleCop (and similar tools) check for style issues. But that does not improve code quality. That can only be achieved by testing your work and using defense programming techniques. But I digress.

So whatever suits you, I guess. I'll stick to using the Microsoft Guidelines and use their tools to check if I've done it right. But whatever coding standard you choose, make sure your entire team sticks to those rules, otherwise they're completely useless. Unless it's to satisfy management that you thought about code quality.

But please, feel free to comment. I will approve them as soon as possible, but with the weekend starting in the Netherlands it might take some time. But I'd love to hear how the community feels about coding standards, the new Microsoft tool, and other things regarding this subject.

Have your C# coding style analysed by Microsoft!

Or to be more specific, by Microsoft StyleCop. Now this may not be new to you, and that's very likely since StyleCop was announced in May of this year, but it was new to me.

The tool checks your code for coding style and more specific, the Microsoft coding style. It was developed outside the VSTS team and has absolutely no connections to FxCop. FxCop focusses on .Net Framework standards and correct use, StyleCop focuss on the way your code looks. Among others, it checks your code for the following items:

  • Layout of elements, statements, expressions, and query clauses
  • Placement of curly brackets, parenthesis, square brackets, etc
  • Spacing around keywords and operator symbols
  • Line spacing
  • Placement of method parameters within method declarations or method calls
  • Standard ordering of elements within a class
  • Formatting of documentation within element headers and file headers
  • Naming of elements, fields and variables
  • Use of the built-in types
  • Use of access modifiers
  • Allowed contents of files
  • Debugging text

The idea behind StyleCop, as can be read on their teamblog:

The ultimate goal of StyleCop is to allow you to produce elegant, consistent code that your team members and others who view your code will find highly readable. In order to accomplish this, StyleCop does not allow its rules to be very configurable. StyleCop takes a one-size-fits-all approach to code style, layout, and readability rules. It is highly likely that you will not agree with all of the rules and may even find some of the rules annoying at first!

 

I downloaded the tool (click here) and installed it to test drive it on my CrystalHelper class, and boy are they right. Some of those rules are annoying. I previously checked that class with FxCop and got little to comments there. From people that used the code, I always received comments that is was readable, easy to comprehend, etc. Then again, those differences make sense. FxCop looks at usage of the .Net Framework and does so by analyzing the compiled binaries. StyleCop uses the actual code. But let me give you some examples of what StyleCop has to say about my code.

Running StyleCop

The first thing I noticed when I ran StyleCop (or Source Analysis as it's called in the menu) is the enormous amount of comments. My first reaction was to remove the tool and forget about it. Actually, I had the same reaction when I first ran FxCop. I was curious enough to continue though, so let's look at what the tool had to say about the following code segment.

  489         /// <summary>
  490         /// Gets or sets the data source.
  491         /// </summary>
  492         /// <value>The data source.</value> 
  493         public DataSet DataSource 
  494         { 
  495             get 
  496             { 
  497                 return _reportDataSource; 
  498             } 
  499             set 
  500             { 
  501                 if (_reportDataSource != null) _reportDataSource.Dispose(); 
  502  
  503                 _reportDataSource = value
  504             }
  505         }

Here we have 16 lines of code which most C# developers will accept as properly styled. StyleCop however gave me remarks about almost every line of code code:

  • Tabs are not allowed. Uses spaces instead. On almost every line.
  • The call to _reportData must begin with the 'this.' prefix to indicate that the item is a member of the class. On lines 497, 501, 502 and 504.
  • Statements or elements wrapped in curly brackets must be followed by a blank line. On line 498.
  • The body of the if statement must be wrapped in opening and closing curly brackets. On line 501.

In addition to this, it also mentioned that the fieldname should not start with an underscore. This was a remark abou the _dataSource class variable I use in this property code. For this section of code, I received a total of 23 comments!

Changing the code to satisfy the tool

As I said, most C# developers will not really have a problem with the coding style used in the above segment. But apparently, this is totally unacceptable for Microsoft developers. My next step was to change the above code so that the tool would not complain about this code. And this is what it looks like after those changes:

  489         /// <summary> 
  490         /// Gets or sets the data source. 
  491         /// </summary> 
  492         /// <value>The data source.</value> 
  493         public DataSet DataSource 
  494         { 
  495             get 
  496             { 
  497                 return this.ReportDataSource; 
  498             } 
  499  
  500             set 
  501             { 
  502                 if (this.ReportDataSource != null
  503                 { 
  504                     this.ReportDataSource.Dispose(); 
  505                 } 
  506  
  507                 this.ReportDataSource = value
  508             } 
  509         }

All tabs are now replaced with spaces. The body if the if statement is now enclosed in brackets. There's an empty line after the closing brackets for the get body and the if body. All class members are now preceded by 'this.'. And yes, I removed the underscore from the class member. Not that much different, but some of the changes make sense, I guess.

Other comments found by the tool

The tool does find other things as well. Here's a short list of some other comments the tool made about my CrystalHelper class:

  • Invalid spacing around the comma. All comma's should be followed by a single space
  • Invalid spacing around the opening parenthesis. There should not be a single space after an opening parenthesis
  • Invalid spacing around the closing parenthesis. There should not be a single space before a closing parenthesis
  • The spacing around the symbol '=' is invalid. You need to add a single space before and after the '='symbol
  • All using directives must be placed inside of the namespace
  • All methods must be placed after all constructors
  • All methods must be placed after all properties
  • All private methods must be placed after all protected methods
  • All private methods must be placed after all public methods
  • All protected constructors must be placed after all public constructors
  • The method must have a documentation header
  • The summary section in the documentation header must not be empty

Should you use it?

A difficult question. My first reaction, as I said before, was to remove the tool and forget about it. But that was the same reaction I had when I first started using FxCop. And yet, that is now a tool I use on a daily basis.

I also have a problem with non-enforceable coding standards. Put 10 developers in a room to talk about coding standards and you end up with either 10 slightly different versions, or one that none of them will adhere to. My experience over the last 20 years is that, if you can't enforce coding standards, you can forget about introducing them and hope that it will all go well.

And that's exactly where this tool comes in. You can now enforce a number of rules to make code more readable and understandable. You might want to disagree to some of them (I don't agree to using spaces instead of tabs) but you can run the tool and check if your coding style matches that of the tool. And when all developers in your team use the tool and change their code accordingly, then all your code looks quite similar. Making it easier for your teammembers to work on code by other developers. And that's the main objective for any development team to create a coding standard.

The tool can also be included in MS-Build scripts, so you can easily make sure the build is broken when a developer ignores the coding standard. So yes, use it!

Some tips when using StyleCop

Once you have installed the tool and are ready to check your code using the tool, you might want to consider doing the following first:

  1. Go to the C# section in Tools -> Options -> TextEditor and change the properties for the tabs so that it inserts spaces and click the OK button
  2. Open the class file and select all code using CTRL-A
  3. Now hold the CTRL key and press K, followed by F. This automatically re-aligns the entire class and replaces any tabs in your code with spaces. Do this for all class files in your project.

When you do this, the following will happen in your code.

  • Tabs are converted into spaces
  • Spacing before and after open and closing parenthesis is adjusted
  • Spacing around symbols is adjusted

StyleCop will not give yo any comments about those items. Which leaves the more interesting items to fix.

What's next for StyleCop?

Like all Microsoft tools, this is a work in progress. New features and options will be added and bugs will be fixed. But for the near future, the following has already been announced:

  • The tool is still called Source Analysis when you look for it in the Tools menu. It will be renamed to StyleCop
  • A small SDK will be made available to allow you to extend the tool with your own rules
  • Documentation about the currently available rules (which in fact opens up the Microsoft C# coding standards to the community)
  • Automatically change your code to enforce some of the rules

So keep an eye on the StyleCop blog for future releases of this tool. I will be discussing the tool with my team as soon as possible and start using it. Finally a way to have our code look similar!

Another solution to import text files (tab, csv, custom) - FileHelpers

Some of you brought another solution for importing text files to my attention. Thank you for that!

For my current imports my previous solution works just fine. But if you are processing more complex files, then FileHelpers is an excellent library to use. (And very likely more flexible and robust then my solution). It's also an open-source library. You can even download the source code if you like. Some of the main features of this library (source http://filehelpers.sourceforge.net/)

  • Easy to use: The FileHelpers Lib is straight forward to learn and use
  • Auto Converters: The library has a set of converters for the basic types and can be easy extended to provide custom converters
  • Master-Detail: You can read and write records with a master/detail pattern
  • Multiple record format support: With the MultirecordEngine you can read files with different record layout, you can also read files with some delimited and some fixed length records
  • Event Support: The engines of the library contain some events to make you easy to extend the behavior of the library
  • Ms Excel Storage:  Are a way to extract / insert records between any source and an excel file
  • .NET Compact Framework Support From the version 1.1 you can use the FileHelpers library for you PocketPC and WindowsCE developments.
  • .NET 2.0 Generics: the cast less and strong typed version of the engines
  • .NET 2.0 Nullable Types The library supports Nullable types in his core
  • FileDiffEngine to allow compare files with the same record layout

And many more. Using the library is extremely simple, just check the EasyExample.

So if you want to build something yourself, then the solution described in my previous post will get you started. If you just want to import a variety of data files, then FileHelpers is something you should consider using.

Posted: Jul 22 2008, 11:20 AM by Jan Schreuder | with 2 comment(s)
Filed under: ,
How to: Use OleDb to import text files (tab, csv, custom)

Introduction

I have been browsing the web for a good and simple class to handle delimited file imports. My current assignment has an import option that needs to deal with that. However, the current implementation (using StreamReader) is not good enough. It doesn't handle all the exceptions you encounter with delimited files. I found a number of examples on the internet, but none of them really suited my needs. What I really missed was a simple example that I could extend so that it would suite my needs. So, being the developer that I am, I created my own class to import delimited files. After this was completed, I though I'd share it as an example to others.

Using StreamReader

The easiest way to process delimited files is to use a StreamReader object. You then simply open the file, read each line and then use the split method to get the various column values. For example:

public void ImportDelimitedFile(string filename, string delimiter)
{
    using (StreamReader file = new StreamReader(filename))
    {
        string line;
 
        while ((line = file.ReadLine()) != null)
        {
            
            if (line.Trim().Length > 0)
            {
                string[] columns = line.Split(delimiter, StringSplitOptions.None);
 
                // Add code to process the columns
            }
        }
    }
}

In a lot of cases this works just fine, but there are limitations to this scenario.

  • It's difficult to split a line into columns. For example, when you use Comma Separated File (CSV) it is well possible that a comma is in one of the columns. Using a simple string.Split is therefor not an option
  • When you only need certain columns or lines, you will need to scan all of them and handle all lines and filter what you need
  • It's not possible to return to a previous line

Using the Jet Engine

The above mentioned problems are eliminated when you use the Jet engine. The following code shows how a CSV file can be processed.

public void ImportCsvFile(string filename)
{
    FileInfo file = new FileInfo(filename);
 
    using (OleDbConnection con = new OleDbConnection(
        "Provider=Microsoft.Jet.OLEDB.4.0;Data
            Source=\"" + file.DirectoryName + "\";Extended Properties='text;HDR=Yes;FMT=Delimited(,)';"))
    {
        using (OleDbCommand cmd = new OleDbCommand(string.Format("SELECT * FROM [{0}]", file.Name), con))
        {
            con.Open();
 
            
            // Using a DataReader to process the data
            
            using (OleDbDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    // Process the current reader entry...
                }
            }
 
            
            // Using a DataTable to process the data
            
            using (OleDbDataAdapter adp = new OleDbDataAdapter(cmd))
            {
                DataTable tbl = new DataTable("MyTable");
                adp.Fill(tbl);
 
                foreach (DataRow row in tbl.Rows)
                {                   // Process the current row...
                }
            }
        }
    }
}

As you can see in the example, once you have the Command object, you have the option of using anything a command object will allow you to do. You could process the file using a DataReader object, create a DataTable object containing the data or even add a where clause to the CommandText of your Command object to specifiy better which data is to be imported.

Helper Class

Using this, and the information provided in this Microsoft Article, I created a small class that allows you to import delimited files. The class is very basic, but can easily be extended to suit your specific needs. This class will solve the most important issues when you're going to use Jet as your import engine.

Some things you need to consider when you are importing delimited files, be it with this class or using custom code:

  • The Jet engine makes assumptions about the content of the file. This can result in incorrect imports. For example, it might think a column contains date values. But in fact, you're file should treat the columns as a string. In these cases, you should create a Schema.Ini file that describes the type of value for each column. The class creates a Schema.Ini file before it opens the delimited file, but only to specify what the delimiter is. You may want to change this to use pre-defined ini files that describe your input file. Details on the Schema.Ini file can be found here .
  • The class uses an OleDbDataReader to read each line in the import file. But it is easily replaced with the option of adding the data into a DataSet or DataTable object. It's also possible to use SqlBulkCopy to instantly insert all the data into a SQL server database.
  • The above mentioned Microsoft Article is the best starting point for this type of import. You might want to read that before you start building imports for delimited files, even if this class is usefull to you. The article provides interesting background information and links to various Microsoft resources with more details and information.
  • The helper class uses an event to allow you to handle the information being read. You can, of course, also provide an overridable method.

Valuable resources

The information I used to to build this class was found on the Internet. I used the following resources:

Disclaimer

The code presented in the helper class is not an all-purpose import solution. It's just a basic class to help you build your own import class. If you need other import types, or a way to influence the content of the default Schema.ini file, you will need to do that your self. If you find any problems, please feel free to point them out to me.

You can download the file here

This article is also published on CodeProject.com.

SAP is annoying me

I never had to do anything with SAP my self, other than interfacing from a .Net application. But since SAP has purchased Business Objects, I find I have to deal with them more and more. Why? Well, since SAP bought Business Objects, who bought Crystal Decisions a while back, they are the owner of Crystal Reports. I've posted about crystal on several occasions (see link). I even posted an article on CodeProject.com where you can find my CrystalHelper class. And because of that, people ask me questions about issues they have with the helper class and Crystal Reports in general. I feel it my duty to help them as much as I can.

But SAP have thought it would be a good idea to redesign their entire site, making all my links virtually useless. And not just mine of course, but of thousands of others. The new site structure however is a fine example of making things disappear. It took me 15 minutes to find out where I could download the latest version of the merge modules for Visual Studio 2005. So for all you that are lost in the wonderfull world of SAP Crystal Reports, here are some starting points I managed to find:

Notes

Search SAP Business Objects Notes for Crystal Reports and Xcelsius products. Notes were known as Knowledge Base search and Knowledge Base Articles on the Business Objects web site.

Articles

Read SAP Business Objects articles, formerly known as Technical Papers on the Business Objects web site.

Downloads

Find Crystal Reports and Xcelsius service packs, hot fixes, critical updates, runtime packages, samples and utilities.

Product Guides

Find SAP Business Objects Product Guides on the SAP Help Portal under “Business Objects” in the top navigation.

Product Lifecycles

Find out about the Technical Support Lifecycle policy and end of life dates.

Forums: Read and post questions to the new forums.

UPDATE August 2, 2008

I found the download page for service packs, hot fixes, merge modules etc. It's here: https://websmp230.sap-ag.de/sap(bD1ubCZjPTAwMQ==)/bc/bsp/spn/bobj_download/main.htm