Friday, June 18, 2021

Software Engineering Rant

Criticizing Those Who Came Before Us 

Why is it so easy for us to criticize the developers that came before us? The newest generation of developers have written numerous blogs, articles and books to inform us how traditional approaches to software simply do not work, yet we continue to make the same mistakes that traditional software had. We try everything from overworking programmers to producing thick rims of documentation that no one follows or uses.

Still, after years of practicing software development many businesses continue to believe that developers must deliver a constant stream of code, thinking that this is of more value to their business than taking the time to create a set plan or a real design. Holding to this practice causes businesses to steadily miss out on major profitability.

This is 2021 and projects are still scrapped because of poor communication that is mistaken for poor management, unforeseen technical roadblocks and incorrect requirement gathering. Pushing developers to follow these practices causes projects to be full of dead code, hacks, bugs, and either under engineered or over engineered systems and subsystems. They continue to find that strict single phase waterfall life cycles fail, yet they follow in the same footsteps, repeating the same mistakes. Many managers have only a shallow understanding of industry buzz words like agile and enterprise design, and just as many programmers are incapable of, or uncomfortable with having direct communication with management, this causes complete disfunction.

It is both naïve and egotistical of us to think that our current process of software development is not fundamentally flawed. The view that we are better than our previous generation is not limited to software development and certainly is not a new concept.

As we continue to adopt change and grow, it is inevitable that future generation programmers will have just as many reasons why the methods we have used are inadequate.
So...What are we doing wrong?

Constantly Re-inventing Software Development


We are constantly trying to improve the way we develop software, but too many times instead of stabilizing the tools we have, someone creates a new system. These new systems bring on a different set of problems that developers are not familiar with. Where we should be able to stay focused and improve the systems we have someone comes along with an idea that focuses on one methodology, pushing for a complete change in the way software development works requiring more training and research.

Software Engineering is a Doomed Occupation

Despite years of progression on the subject, software engineering is not a profitable career path. Instead it seems to be something that developers practice in secret for fear of perception that there is lack of productivity. Software Engineers and Project Managers are just looked at as overhead. The documentation and structure they add to the project is only looked at as nice to have at best and a nuisance at worst.

The title of Software Engineer is often bestowed upon a developer with no more meaning to the company or the organization than a person who has been coding for a long time. Engineers study how to make sense of large systems, they make decisions as to how the problem should be broken into smaller pieces, and have the ability to reduce maintenance and modification cost that still make up the majority of the cost of software systems today.

However, software engineering is not recognized or valued for its accomplishments. The perception among software vendors instead is that they don't have time to wait for an engineered solution that instead they just want a few developers to do what they are told. 

Business managers, therefore take the responsibility, with no prior education or practical understanding of how software should work. And, actually we have begun sending business majors to to become certified Software Project Managers. They usually enter a software development team with a bunch of memorized terminology without having a firm understanding of what they are studying.

The Blue Collar Programmer

Whether you call yourself a Software Developer, Software Engineer, Lead Developer, System Architect. Most companies only see a programmer, a coder, a technical resource. And although you liken yourself closer to an architect who designs large buildings and structures, when you produce code you are no different than any other producer in a blue collar occupation.

The pay may be comparable or better than a structural engineer, architect or even a lawyer. When your job is to produce the product you are a low level worker and details of design are just a side note to your job. The pay may be better than say a brick layer or plumber but the company still views you the same way.

Nothing highlights the attitude more than the growing and now shrinking fad of outsourcing your programming to the lowest bidder. After all, programming is no different than any other blue collar, low skill labor. The client will reason to himself that there is a certain amount of work that will need to be done, there is a cheap source of labor and an expensive source of labor. Why would you choose the later when the company can scarcely tell the difference in the end result.

Even worse, in my humble opinion, is the absence of responsibility of the final solution. Clients are more than happy with solutions that were done quickly. Without regard for long term consequences, they glad except poor solutions that seem to do the job until they are actually used. Some are so poor in fact that the buttons and windows are there but there is no actual implementation or it was never tested.

Upper management rarely holds a programmer responsible for  poor quality work.  

The Laziness Virtue is Becoming a Hindrance

For years I have proudly proclaimed that laziness is a virtue to a programmer. By laziness I really mean that I don't want to do more work than is necessary. If I can find an api, web service or write a simpler method that reduces my code or find a way to completely eliminate the need for what I am writing than I am happy.

However, the development community as a whole has adopted this to the extreme. We are constantly attempting to pawn our work off onto open source SDKs, third party vendors and 4th generation tools. So much so that programmers no longer understand simple algorithms, data structures and design. Business programming can now be likened to being a general contractor, managing other works to make a bigger systems.

The problem with this is that we have not really made progress. Simple problems that would be obvious for us to write a custom function for 10 years ago are now available on the open market. Managers don't want the developers wasting 2 hours on writing anything they could buy or use for free.

Third party solutions often come with an equal amount of problems. Very few of them are truly stable enough to reduce our work load. What they are really good at is appearing to work. After being put in a real world test they more often than not seem to fail. And in order to find solutions to the problem with the third party tool, developers are forced to study at detail the inter working of it. It cost 2 hours of our time to download and reference a third party solution to our problem and costs the company more time to make it "really work" then it would have cost had the developer remembered how to implement a trivial algorithm.

As a solution this conundrum, businesses adopt large swiss army knife frameworks. These frameworks are often too large for the vendor to reasonably test and end up having more flaws than the tons of smaller solutions available. 

The Failure of 4th and 5th Generation Languages

Like the search for the holy grail, developers are in constant search for a next generation programming language that can increase productivity. However, our attempts at implementing them have been hindered by the instability of existing tools, and by a fundamental flaw in the logic that says we need a 4th or 5th generation toolset.

The idea that 3rd generation tools such as Eclipse and Visual Studio and programming languages like C++, C# and Java have made us more productive than languages such as pascal, ADA and ansi C is misguided at best. What these toolsets do is attempt to guide us into making a well designed solution.

However, software design in itself is not promoted in the industry. As much as the tools can help you design software, they can not design it for you. In order to design a system you must understand fundamental design methods. Methods that have remained the same since pre-1970's and have since only changed in terminology and not in meaning.

Replacing Software Design are Canned Patterns and Solutions

After decades of attempting to push fundamental software design, we have given up on designing systems and instead have taken to finding a canned set of patterns that solves problems for us. We have then pushed this on to the "great unwashed" developers of the past who simply followed traditional design methods based on logic and engineering principles.

Admittedly, these patterns in our solutions offers an improvement over non-designed systems. However, they are most often used to replace any kind of forethought in a project. Lets do a 3-tier system and let the system play out how it plays out. Make sure to put in factories and dependency injection, that usually makes better systems.

The next step inevitable, is that our toolsets push a set of patterns into your solution. In an attempt to improve code for you, frameworks such as Ruby on Rails and Microsoft MVC have made it fairly difficult to not use these patterns when using their tools. Just as C++ and C# attempt to improve code by forcing the Object Oriented Paradigm on its developers these toolset often have no effect on developers that do not understand design principles in the first place.

Non-Technical Problems are Solved with Technical Solutions

Solutions to the problems the industry faces are not hard to find. At the moment there is no lack of frameworks, toolsets, higher level programming languages, patterns or methodologies. In fact they may do too much for us.

When it comes to 3rd party tools, what is needed is a correct implementation to begin with. 3rd party vendors, are capable of producing high quality well tested, well documented frameworks. But so far they have not found it profitable. We as developers seldom hold them to a high standard. We have been more than willing to put up with any bugs and flaws in their systems.

Instead of 4th and 5th generation languages that write code for us. Would it not be more productive to give us meaningful error messages? And, instead of generating sql statements and the programming code to go with it. Could we make the database api and sdks work the way they should? Is it not more profitable to the developer to remove poorly designed classes and non-working methods in the current api then to create canned scripts to deal with generating the obscure code.

Furthermore, would it not be more profitable to simply teach fundamental design principles than to blame our poorly written systems on a lack of a new concept, pattern, tool, and or software methodology. Like sheep, the industry blindly falls for the latest snake oil. RAD, Agile, Extreme Programming, SCRUM, DevOps and any other buzz word meant to fix the current ailments all seem to address a problem that already has a viable solution.

However, the real solution to the problem is somewhat hard to swallow and is actually non-technical in its nature. The problem lies between the keyboard and the computer chair. Developers and software managers for that matter, that are properly trained and have a discipline about their work will produce high quality, easily maintained systems.





Tuesday, June 4, 2019

5 Quick Ways to be a Better Programmer

1. Take Advantage of the Debugger

If you are still using message boxes and Console.WriteLine statements to determine what is going on inside your program than stop now. You don't have to be an expert at the debugger to take advantage of the debugger.

2. Ask Someone for Help When You are Stuck

If you are the lone programmer type you may find it difficult to ask others for help. There is nothing more valuable than having other developers give insight into your problem. If you are using 3rd party libraries than you should take advantage of user support.

3. Don't be a Yes Man

Don't blindly follow management when it comes to creating software. This is the sign of a more senior developer and will help your company a great deal. Always be tactful and respectful to your non-technical boss but remember that they could not begin to understand the problems you are facing. Its up to you to give them guidance when it comes to making technical decisions. 

4. Use a Code Standard

A coding standard is one of the easiest ways you can improve your code without knowing any engineering or studying any complex theories on development methodologies. You don't need to re-invent the wheal here. Microsoft along with other large software companies publish their coding standards online. 


5. Take the Initiative

If you see bugs in the software or see areas in the code that need fixing than you should correct them. The "If it ain't broke don't fix it." mentality does not suite most projects. Don't wait for your project manager, QA or customers to report the bugs. Remember you are the first like in development. Buts that you catch and correct save the company lots of time, effort and money.
Shop Amazon Devices - Introducing the all-new Kindle

How do you program when you can't?



I woke up this morning with no desire to program a computer. Have you been there before? It's scary when you lose your job and find yourself unable to work on even the smallest task. I began to think that I would never write a program again. When you begin to feel that way it makes you feel worthless. That is how I felt because programming has been my only means to support my family.

After dedicating nearly three years of my life to a company that I love I was unexpectedly laid-off due to unforeseen medical circumstances. The lay off was coming, this was known for weeks, though I was not expecting that I would be let go.

My reaction has been to focus on my wife and our kids. If only I can build them up and make them stronger then I can, through their strength, bring our family back on top.
So all day I worked to balance my wife's needs with our kids' needs. We have had a good day, talking at length about writing a book, making plans that will help bring our family back together. Our highest priorities are to heal our kids' hearts and also heal their biological Mom's heart.

I am blessed to have my wife at my side because together we can do anything. We can not afford to lose focus. I can't keep feeling as though I am pushing with all my heart, only to find myself friendless and jobless without a dime to my name.
It's time to pull-up, defend our families' honor and rise above the world to achieve God's plan.

I Knew a Programmer that Went Completely Insane

Tuesday, April 22, 2014

Why Don't You Use Factories?

After reading and applying traditional software design techniques taught by some of the best professional developers such as Edward Yourdon, Frederick Brooks, Martin Fowler; I thought that I was fairly talented at designing and writing software systems. However, if there is a single technique that I overlooked when designing/implementing software solutions it is the factory. Factories, have been around for quite a while but they have recently, within the last 5 years or so, become an important tool for me.
If you just started reading this and you know about dependency injection...this is not an argument that factories are better than dependency injection frameworks at all. The only argument that I can come up with that they are better than DI frameworks is that factories are a lot lighter weight and you may save some time not jumping through technical hoops that a DI framework will require.

What is a Constructor?

You may have been expecting at this point that I would start off by detailing what exactly a factory is, but in fact, I can't really explain factories unless I explain what a constructor is. I assume if you are reading this then you must, at some level, understand object oriented programming. If you do not, may I suggest a good book on the subject matter as listed below:
However, as much as you may understand how to write software in an object oriented manner, you may not actually use constructors that much and might not truly understand the concept of constructors.
Constructors are where we place logic that happens when an object is allocated into memory and where any member variables are initialized.
Dependencies are anything the object needs to complete its intended purpose. A dependency can be a simple variable such as an integer, float, or string that can represent things like file names, account codes, and index keys; or... it can be another object that the object depends on to complete its purpose such as an SDK/API wrapper or a data access layer object. In general, anytime you use the new keyword it should be in the constructors.

However most of the code I have worked on, and for the most part a great majority of the code that I have created over the years, very rarely use constructors for anything. So, if constructors are how we should be handling dependencies why do we hardly ever use them?

You Just Don't Get Dependencies

If you are not doing the majority of your object initiation inside of a constructor then you probably just don't get dependencies. Your code is most likely littered with innocent looking new statements everywhere and I know exactly where they are, they are used exactly before you need them. In fact, most developers don't even have the common courtesy to put them at the beginning of their overly bloated methods.


An example application that does not use dependencies:

namespace MyApplication
{
    public class MyClass
    {
        public MyClass()
        {
            //I hardly ever put anything here...
        }
        public void DoSomethingCool()
        {
            var appSettings = new Object();
            //Code.....
            //Explain how to use emailSDK...
            //........
            var emailSDK = new Object();
            emailSDK.ServerAddress = "...";
            emailSDK.UseEncryption = true;
            emailSDK.Init();
            //Code.....
            string fileName = "C:\\temp\inputFileName";
            //Code....
            var myObject = new Object();
            //Code...
            emailSDK.Send(...);
        }
    }
}

The ideal solution is that your dependencies are properties/members of the base class and that your dependencies are initialized inside of your constructor. Sometimes (but very rarely), it makes more sense to initiate objects directly inside a method. However,  most of the time it just leads to bad code.


Moving your dependencies to your constructor:

namespace MyApplication
{
    public class MyClass
    {
        public MyClass(string fileName)
        {
            //This is where I set up my object for use
            AppSettings = new Object();

            //Here is how we setup the email sdk....
            var EmailSdk = new Object();
            EmailSdk.ServerAddress = "...";
            EmailSdk.UseEncryption = true;
            EmailSdk.Init();

            FileName = "C:\\temp\\inputFileName.txt";
        }
        //Its really clear what this class needs in order to do its job....
        private string FileName { get; set; }
        private Object MyObject { get; set; }
        private Object EmailSdk { get; set; }
        private Object AppSettings { get; set; }
        //---------------------------------------------------------------------
        public void DoSomethingCool()
        {
            EmailSdk.Send();
            WriteToFile(FileName);
            //You get the point
        }
        public void DoSomethingElseCool()
        {
            EmailSdk.Send(AppSettings.RegionManager);
            WriteToFile(FileName);
        }
    }
}

All of the dependency initiation logic that is placed directly at the method level instead of the constructor level are a major cause of method bloat. The second example above really demonstrates how small our methods become when the constructor is used to create objects rather than directly creating them as needed.
The side effect, when you really start to think using dependencies, is that you start solving your problems at the class level rather than the method level. If you do as I suggest in this article, then methods will be small and flexible and you will have more classes in your code then usual. That is, in my experience, a good thing because now you are thinking and writing code at a higher level.
There is much more information regarding dependencies then I care to cover in this article.

Factories Are Way Cooler Than Constructors

As cool as constructors are, factories are way way cooler. Interesting enough, once I started using factories to make better code it really taught me how to use constructors in a more constructive way.
Factories are basically constructors that are detached from the class they create. By using factories, a great deal of logic that is usually in the same class can be separated into different classes. Many times objects in your solution will contain similar dependencies. It is much easier to manage these dependencies by putting them into a common class. For instance, all Data Access Components could be using the same connection string.
This concept comes from industrial factories where products are put together at a common building (factory) so that the details of how they are constructed are not needed in order to begin to use the product. For instance, with a laptop you don't have to make the decision of what keyboard to purchase because it was placed/injected into your laptop at the factory and is not an external component like in desktop computers. This makes a laptop a much easier real life object to make use of then a desktop computer. I don't even need to plug it in...I flip up the screen and press the power button and I have a working computer.
In the same way, when I am writing a class suddenly things like file locations, dialog box methods, and application wide settings are just conveniently constructed and ready for me to use.

Factory Methods

Factory members are functions/methods that act as a constructor for an object. They are functions that return a fully functional ready to be used object. You do not necessarily need to put them inside of a special factory class. They can exist in a parent object that is not purely a factory class or it can be put inside of the object that it creates or in any object.


        public static AccountDataManager CreateAccountDataManager()
        {
            var adm = new AccountDataManager();
            adm.DataFileName = "Accounts.txt";
            return adm;
        }

Static Factory

Static factories may be the most common implementation of the factory pattern. The advantage of writing a static class with static factory methods, as shown below, is that it is a fairly easy approach and you don't have to think much about how to access the factories. You can simply call them like any other static function anywhere in you code without regard for initiating a new factory object.
For small projects this is a good approach because its easy for yourself and for other developers to understand. I also recommend that you become familiar with this approach because it is very common in existing frameworks and code in general. You will find it in both new and older code bases.


Declaring a single factory for the application:


namespace FactoryExample
{
    public static class AppFactory
    {
        public static AccountDataManager CreateAccountDataManager()
        {
            var adm = new AccountDataManager();
            adm.DataFileName = "Accounts.txt";
            return adm;
        }
        public static ContactDataManager ContactDataManager()
        {
            var cdm = new ContactDataManager();
            cdm.DataFileName = "Contacts.txt";
            return cdm;
        }
    }
}

Using the factory in your main program:


namespace FactoryExample
{
    class Program
    {      
        static void Main(string[] args)
        {
           var accountManager = AppFactory.CreateAccountDataManager();
           var account = new Account() { accountNumber = 23, Balance = 23.23M };
           accountManager.Create(account);

           var contactManager = AppFactory.CreateContactDataManager();
           var contact = new Contact() { CustomerId = 12, Name = "John Smith", Email = "jsmith200@yahoo.com" };
           contactManager.Create(contact);
        }
    }
}
Most of the time I actually create the main application as a separate class and create it in side of the "program" class using a factory method to create my application as I show below:

Declaring the factory method:


        public static FactoryExampleApp CreateApplication()
        {
            var app = new FactoryExampleApp();
            app.AccountDataManager = CreateAccountDataManager();
            app.ContactDataManager = CreateContactDataManager();
            return app;
        }

Usage of the factory:


namespace FactoryExample
{
    class Program
    {      
        static void Main(string[] args)
        {
            var app = AppFactory.CreateApplication();
            app.Run();
        }
    }
}

Single Factories or Multiple Factories

The above examples, mostly because its easier for me to write an example for, use a single factory for your entire program. I call that factory AppFactory in the above code.

Non-Static Factory

It might just be personal preference but I don't like static methods in my code. If I can help it, I will write the factories in non-static class and have them as common properties. The simplest approach, as shown below, will just require an extra new statement when you want to use the factory.

Declaring the non static factory:
    public class NonStaticAppFactory
    {
        public FactoryExampleApp CreateApplication()
        {
            var app = new FactoryExampleApp();
            app.AccountDataManager = CreateAccountDataManager();
            app.ContactDataManager = CreateContactDataManager();
            return app;
        }
        public AccountDataManager CreateAccountDataManager()
        {
            var adm = new AccountDataManager();
            adm.DataFileName = "Accounts.txt";
            return adm;
        }
        public ContactDataManager CreateContactDataManager()
        {
            var cdm = new ContactDataManager();
            cdm.DataFileName = "Contacts.txt";
            return cdm;
        }
    }

Simple usage of the factory:

namespace FactoryExample
{
    class Program
    {      
        static void Main(string[] args)
        {
            var app = (new NonStaticAppFactory()).CreateApplication();
        }
    }
}
The only thing I will say about static methods are that they are in fact pure evil. So unless you know why they are evil, then you shouldn't use them at all. In fact, what where they thinking when they allowed them in OO languages?

With non-static classes you can also put the factory into a property on the base class and inherit from it when ever you want to access its factory methods.
Factories using a base class:

    public class MyBase
    {
        public NonStaticAppFactory Factory
        {
            get
            {
                return new NonStaticAppFactory();
            }
        }
    }
    public class MyCoolClass: MyBase
    {
        public void DoSomeCoolStuff()
        {
            var dataManager = Factory.CreateAccountDataManager();
            var account = dataManager.Read(123);
            var balance = account.Balance;
            Console.WriteLine(balance);
        }
    }

It should be obvious that there are several other ways to declare and use factories. Some would prefer having a single Create method and just pass either a string or Type instance into the method to distinguish what type of object should be created.

Factories are also good for...

  • Factories are also good for managing the technique used for creating objects. For instance we might want to return a single object every time the factory method is called (Singleton pattern).
  • They can be used to return an interface or purely abstract class instead of a hard object. This is really important because many designers prefer to use abstract classes to hide details instead of private member variables. 

When should you not use Factories?

  • Your object is going to be used with an existing SDK/API that expects a constructor and does not understand factory methods.
  • Heavy usage of factories would violate the conceptual integrity of the software solution. Simply put adding factories to an existing, well written application, that does not use factories could make your code less maintainable because it is not like the rest of the system. 
  • Usage of factories is not generally accepted by the programming team and using the technique will simply add confusion when others look at your code. A manager or peer some place or somewhere might begin to say “you don't play well with others.”
  • Some software systems, for one reason or another, do not lend themselves well to factories. For instance some SDKs, such as the Microsoft .NET DOM library, require child objects to be created by their parent objects. XmlElements must be created using an XmlDocument object. Trying to force the framework into your own factory pattern can prove to be difficult and you may be better off just using the DOM as it was intended instead of adding your own flavor of factories on top of it. 
  • You have a more elegant dependency injection framework or approach. 
  • Your program is very small and factories would not really help because there are not that many dependencies to begin with. In this case, I would argue that usage of constructors vs factories is pretty much a wash. If you know how to use factories then it is no more difficult to write factories then it is to write constructors.
  • If your solution uses inheritance heavily then factories would be hard to implement everywhere. Instead it could be used for returning higher level objects or for certain parts of your solution.

Wednesday, January 22, 2014

Working with Views in Sage 300 ERP ( Accpac )

In Sage 300 ERP views are used as a standard way of manipulating and retrieving data. You will also need to use views in order to execute some commands. Views in Sage 300 closely resemble MVC and MVVM patterns that have been used when simplifying user interfaces. Becoming familiar with these patterns may help you to understand how things work in Sage 300.
Views match up closely to what you see on the Sage 300 user interface. However, you may find that the names for certain fields are not the same as you see on your screen. Most fields in Sage 300 are abbreviated and some are named completely different from the label on the forms.

Why not use the database?

If you are handy with SQL and know how to find the Sage 300 databases then you might be tempted to circumvent the SDK all together and go straight for accessing Sage via the database. Although this may be necessary in some situations, I recommend that you save this as a last resort for several reason.

The business logic will be bypassed

There is actually a lot going on behind the scenes when you are using the application. If you go straight to the database then the business logic can be bypassed. This can mean that you will have to recalculate calculated fields, updated other tables based on your changed values, and/or write your own data validation routines.
I would like to point out that this can be a problem with any application that you work with. It is typically poor practice to go straight to the database when an SDK is available. Again, if its the only way we can accomplish the task then it is acceptable.

You might corrupt the database

Sage 300 does things a little differently then standard SQL, so you may inadvertently insert a value that it does not expect. For instance a numeric field can be stored as a string and if an extra space or a leading zero is not populated correctly then you can cause unexpected results.

Distribution can be a little more tricky

If you are writing triggers, stored procedures etc. then you could make distributing your application a little difficult. For small one off solutions this might be a valid tradeoff. However, if you are distributing to several users then it can become a problem. What if you have credential problems? What if they revert to an old version of the database?

Using Views

Please refer to the previous example where we connected to Sage 300 and retrieved the current version information if you need help getting started. Instead of retrieving a version, this time we will retrieve all the data in the view. The code is as follows:

using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Example2
{
    class Program
    {
        static void Main(string[] args)
        {
            //Connect to the sample company
            var accpacSession = new AccpacSession();
            accpacSession.Init("", "XY", "XY1000", "61A");
            accpacSession.Open("ADMIN", "ADMIN", "SAMINC", DateTime.Now, 0, String.Empty);

            //Open the db link. This should be the Company link type and not the system. 
            var dbLink = accpacSession.OpenDBLink(tagDBLinkTypeEnum.DBLINK_COMPANY, tagDBLinkFlagsEnum.DBLINK_FLG_READONLY);

            AccpacView view;
            int result = dbLink.OpenView("AR0024", out view);

            //This just says find all records. We pass it an empty string for the search expression
            view.Browse(String.Empty, true);
            
            while (view.Fetch())
            {
                string id = view.Fields.FieldByName["IDCUST"].get_Value().ToString();
                string name = view.Fields.FieldByName["NAMECUST"].get_Value().ToString();
                string phone = view.Fields.FieldByName["TEXTPHON1"].get_Value().ToString();
                Console.WriteLine("{0}\t{1}\t{2}\t", id, name, phone);
            }

            //Strange things will happen if you do not close both the view and the db link.
            view.Close();
            dbLink.Close();
            
            //Always close the session when you are done.
            accpacSession.Close(); 
        }
    }
}
The above example shows a very simple use case were we just want to retrieve a few fields and display them. Although you can supply filter information and let the SDK filter your data, I find it useful to grab the entire view and manipulate it using LINQ or custom code. I still use the SDK to filter data if the dataset is to large. I can, for instance, only grab records that have been modified today.
You may also find it useful to refer to the Sage 300 Data Dictionary for a reference to what fields are in what view.

Thursday, December 19, 2013

Getting Started with Accpac Programming

Recently I have accepted a new position at Kerr Consulting that specializes in integrating ERP and other financial software packages such as Quick Books with existing software. Most of our work is related to Sage products and I have been specifically tasked with becoming an expert at Sage 300 ERP (Accpac) programming.


A Simple Example

I find it difficult to find simple examples when getting started programming any new platform. So I will start out with a very basic example of how to simply connect to Accpac.

Dependencies

  • We are programming with the .NET Framework version 4.5 and MS Visual Studio 2012. There is no problem with downgrading to lower versions of .NET and Visual Studio.
  • We are using Sage 300 ERP 2012/ 6.1 for the example code. This must be installed on your system in order to write software for sage.
  • Additionally you will need to install the Sage 300 ERP SDK v2012 that should be provided for you. The installation is named SDK61A.exe in my system.

References

You must make a reference to the AccPac COM library in order to access the SDK in .NET. Under your project right click on References and click Add Reference… Then click on the COM tree node on the left hand side of the form. Check the item named ACCPAC COM API Object 1.0 and then click ok to finish adding the reference. You can see where I have added the reference to my project below:



The Code

After your reference is added to your project the below code can be used to connect to Accpac and retrieve the Application Version you are programming on.

namespace Example1
{
    class Program
    {
        static void Main(string[] args)
        {
            var accpacSession = new AccpacSession();

            //Initialize the session. You will need to pass another version instead of 61A.
            //for AppVersion. I am using 6.1A so I pass 61A here.
            accpacSession.Init("", "XY", "XY1000", "61A");

            //This is the default setup for SAMINC but it might be different on your system
            accpacSession.Open("ADMIN", "ADMIN", "SAMINC", DateTime.Now, 0, String.Empty);

            //Write out the Application Version. It should be 61A just as you passed to Init.
            Console.WriteLine(accpacSession.AppVersion);

            //Always close the session when you are done.
            accpacSession.Close(); 
        }
    }
}

Where to Get More Help


  • The best resource for SDK help is Stephen Smith’s blog. There is a ton of information there that you won’t find anywhere else including the Sage documentation.
  • There is also a wiki page for Sage 300 ERP that has a variety of examples. However, you will have to be a member of the developer network to view or updated it.




Thursday, April 18, 2013

I Knew a Programmer that Went Completely Insane

Not long ago one of our programmers just lost it and he lost it good. He walked into the manager’s office and began screaming strange things. If I didn't know him as well as I did I would have thought that he was on some kind of drug. But what had really happened was nothing short of a complete mental breakdown.

He was one of the hardest workers I had seen in the industry. He would frequently stay after hours to work on projects; He was always available when management needed someone to rush a job out over the weekend. During this time the Company was not making money and they needed the work done as quickly as possible, so any software that had to be rushed to a customer was automatically assigned to him. His willingness to push himself to get a job done is what they liked about him.

However, his productivity was not so great when he landed in a mental institution. I was the one that the company sent to visit him in the hospital to check on him after his breakdown. He asked me for a pen and a piece of paper so he could write a program down. "I think I still got it" he said, as he sat there in his hospital robe. He wrote two lines of code on the piece of paper and then began to weep uncontrollably. The company let him go after about three months in a hospital and a few threatening phone calls. He ranted about how he should be the CEO and that he was going to be the new face of the company.

 Later he spoke about how the effort he put into the company should have given him more respect and a better position. Despite being well treated and paid, for his hard work, he was still looked at as just a worker that produced well. He was never considered to be a key player in the company.

It may be hard to swallow but the extra effort and hours that you put into your job as a software developer does not usually amount to someone higher up thinking you should run the company. It has been my experience that good producers are more likely to be asked to continue to produce. If they moved you to a higher position and better pay then who would produce the software?

All too often we lose site of the human factors in software. It doesn't matter if management pushes people to overwork or if it was their own bright idea to get ahead. The result is always the same. People are just people. They are not machines that can produce day after day without some kind of human interaction. In the end everyone needs a life. 

Source

LIFE

Good Reading


Peopleware: Productive Projects and Teams (Second Edition)
This was required reading when I was going to school. It is an excellent book for both programmers and managers alike.


Death March (2nd Edition)
This is another great book on the human factor of software development. After reading this, I realized that I had been on several "death marches" myself.