Powered By

Powered by Blogger

Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Is Software Hard?

Systems are logical, programming is physical."
- Bryce's Law

For something that is supposed to be "soft", software exhibits
some pretty "hard" characteristics. The original premise behind the
COBOL programming language was to devise a language that could
be easily ported to several computers. As we all know, this never
truly happened due to computer manufacturers who tweaked the language
to suit their particular needs. What ran on an IBM machine, for
example, didn't necessarily run the same on Honeywell, UNIVAC, or
the rest of the BUNCH. Consequently, software developers had to
maintain different versions of source code to suit the particular
needs of the various computer compilers. This plagued all third
generation languages until Sun introduced JAVA in the 1990's. The
JAVA premise that a programmer should "write once, run everywhere"
was the right idea and the language began to gain momentum, until
it ran into Microsoft who didn't want to turn the operating system
into an inconsequential afterthought. JAVA lives on, but not to
the extent it should have, and developers are back to managing
separate versions of source code.

The point is, software does in fact exhibit some very "hard"
characteristics as it is married to the host computer configuration
making it not very portable. As mentioned, this creates headaches
for those of us, particularly commercial software vendors, in
terms of maintaining consistency in the different versions of
our products.

What to do?

Back in the 1970's and 1980's we were faced with the dilemma of
managing a single product on over a dozen different platforms. We
quickly came to the realization we would go stark raving mad
managing multiple versions of source code and came to the conclusion
we had better come up with a solution pretty quick. Because of our
experience in converting software, we became well versed in the
nuances of the various compilers and devised a Repository (we
called it a "filter program" at the time) which maintained the rules
of the various compilers. We were also very disciplined in writing
code to specific standards and embedded certain switches in the
base source code. When we were ready to produce a new release of
our product, we would feed the base code into our "filter program"
which would then create the different versions of the source
code ready for compilation. This saved us an incredible amount
of time and brought consistency to all of the versions of the
product. In other words, our programming staff worked with only
one set of code (not multiple variations), the "filter program"
then analyzed it and created the necessary permeation for a targeted
platform. As compilers changed, we would update the "filter
program" accordingly.

We also learned to maintain print maps, screen panels, messages
and help text separate from the source code, which greatly
enhanced our ability to create a new version of the product to
suit a foreign language and culture; see "Creating Universal
Systems" at:

http://www.phmainstreet.com/mba/pride/isspus.htm

Let us take it a step further, for years we have touted
there are logical and physical dimensions to Information
Systems. Using the "PRIDE" Standard System Structure concept
in "PRIDE"-ISEM, we look upon Systems and Sub-Systems (business
processes) as logical constructs, and Procedures and Programs
as physical constructs. Further, data components such as inputs,
outputs, files, records and data elements can be specified
logically and implemented physically many different ways. Let
me give you an example; back in the 1980's one of our "PRIDE"
users (a large Fortune 500 electronic conglomerate) bought
into our logical/physical concept and decided to put it to the
test. Working from their corporate offices, they designed a
complete Payroll System which they wanted to implement as the
corporate standard across all of their divisions and
subsidiaries. They completed the system with a recommended
programming solution they wrote themselves (no packages were
used) which I believe was an IBM MVS solution using COBOL. However,
they recognized early on this implementation wouldn't work
across the board in the company. Consequently, they gave the
system specifications to all of their divisions who would then
program it themselves in-house. The project turned out to be
a major success and the company ended up with multiple
implementations of the same system under IBM MVS, VM,
Honeywell GCOS, UNIVAC Exec, HP MPE, DEC VAX/VMS, and
Prime; all working harmoniously together. Other "PRIDE" users
experienced similar successes, particularly in Japan.

All of this drives home the point that systems are logical in nature,
and that programming is physical. If systems are designed
properly, there is no reason they shouldn't behave identically
on whatever computer platform you come up with. Better yet, it
allows us to easily migrate our systems from one configuration
to another. Uniformity and consistency in execution; and portability
to boot. Imagine that.

Productivity and the Big Project Myth

Job advertisements in newspapers and on the internet asking for IT professionals usually tout large projects as the sole reason for wanting an IT professional in the first place. A programmer, system analyst or system tester must have had experience in large corporate projects and the larger the better.

Many businesses, in Australia at least, see IT departments as a liability and a necessary evil so as little money as necessary is thrown into IT infrastructure where other areas of a business, for example the Engineering Department or the Buyers Department, get inundated with large budgets. IT Departments have to justify their existence with staff time-sheets and charging internal clients for IT solutions.

Although grandiose back-slapping projects bring in the money and look good on a resume these projects do not necessarily improve the expediency with which a company does business. In fact large corporate systems can increase the workload where more data is required to be captured by the users, call centre staff and so on.

Throughout my consultancy career my main philosophy has been to improve the user's or developer's work environment by making their job easier. As well as large projects I have developed many small applications that took anywhere between 15 minutes to an hour to create but have saved employees anywhere between hours to months of hard tedious work. The accumulation of small time-saving applications can out-perform some of the larger projects when measuring productivity especially when used over and again exponentially increasing productivity within a company.

Those employees who benefit from many of these small applications are usually confined to the IT department itself where users have direct access to an IT professional who can put together a small custom application during their spare time. Those outside of the IT department though are usually left to their own devices and this is where end users and macro recordable office suites or keyboard capturing software comes into play.

What begins as simple macro instructions within an application built by an end user eventually become large complex and business critical applications held together with chewing gum and string. As news of the application spreads throughout the department more demands are made upon the hapless user who provided the solution and ergo their stress is increased as they maintain the original solution with all its additions whilst trying to cater for a stream of new requests. When a system grows to the point of being unmanageable the department can then justify the expense of a business case which the IT department will then accept, all too often though the business case specifies an upgrade of the original system, a band-aid solution as the ultimate solution, where a total rewrite is really the only solution.

There would be more control over such a situation if IT departments provided small applications for individuals and groups, and companies realised the benefits of incorporating the IT department more into its overall infrastructure instead of annexing it to the companies structure as if it were a parasitic necessity.

Maintaining Badly Written Legacy Code

You have been handed a project or partly developed application to support. Due to prior deadlines, restricted budgets, limited developer skill, multi-developer miscommunication or just plain laziness from some previous developers you have been handed a maintenance nightmare. What steps can you take to improve this situation.

It is likely that you will not get the time to rewrite or refactor what is basically a mess, so small steps and a plan of action is needed:

  1. Do you have a prior list of complaints or help-desk calls that provide an overview of problems and priorities?
  2. Does the code have exception or error handling?
  3. How appropriately named are the variables? I have seen code with variables named aThingList and aColList.
  4. Is the code laid out in a way that makes it easy to understand the flow of instructions? I have seen code that was completely left-aligned making reading to understand it extremely difficult.
  5. Is there an infinite number of exponential loops within the code?
  6. Have you been left adequately written documentation about the application and any code and design decisions that were made.

First you need to tackle any commonly reported application problems. This often means finding the algorithmic cause of problems. Ideally you will be able to run a script over an uncompiled version of the application and replicate the error. Make a copy of any data sources the applications uses so that you can safely manipulate data without affecting the live system the users are using. If you can break into the code during an error or an exception then do so and step through the code line by line until you find the error.

If you cannot break into the code whilst the application is running then you will have to rely upon tracing code movement via a message notification, either using message boxes, writing to a file or writing the algorithm results to a makeshift debug screen. A notification at the entrance of a routine which includes the routine name and the time entered would be useful.

Once you have determined where the error is occurring you will need to determine why?

Is the data causing the problem? The best way to solve this problem is to improve data quality at the datasource. Perhaps an uploaded data file is not up to scratch. Perhaps the user is entering an unacceptable value. Even though the latter could be blamed upon the application's lack of built-in ability to check user input, decisions made during it's previous development phase could have put the responsibility upon the user to enter correctly formatted data which would make this a training issue not a data issue.

== ERROR-HANDLING ==
I have seen numerous applications' code without any kind of exception/error-handling. You need to enter exception/error-handling into routines you know have errors and extraneously long routines. Within error notification you will need to display the routine name, error number and error message. For more information upon error handling see my article Exception/Error Handling, An Integral Part of Programming.

== BADLY NAMED VARIABLES ==
Usually there is not much you can do about a situation where the variable names are less than adequately descriptive of their purpose. Search and replace functionality may help you but usually will not discriminate between variables sharing the same name, in different areas of the cod,e that are used for different purposes. In fact, the renaming of an ambiguous name to a more purposeful name may complicate the understanding of the code where other variables of the same name are affected. The best practice is to write a comment next to the variable explaining it's use for any particular routine within which it is found.

== CRUMMILY LAID OUT CODE ==
Either the code is all left-aligned or dischevelled: Reading badly laid out code is difficult in either case. If you have an editor that automatically indents code based upon language, cut and paste the code into your editor, realign the code and paste back into the application. If you do not have an editor and will be working with this code for some time, perhaps a quickly typed script to clean the code is in order. This is not as hard as it sounds. Basically all the script needs to do is count and add tab spaces whilst reading in each line of the code. If for example your script finds a While statement it adds a tab to the front of the next lines of code it reads in until it finds a Wend statement.

If an application's existing code is particularly ugly and your job is only to add functionality to the application you may consider either removing the old code to a library so you will not have to look at it or build a module as an interface to the old code. The benefit of this is that you will only have to modify your interface should you need to make changes in the future. A added bonus is that you can comment your interface and remove your reputation from the extant disaster behind your it.

== INFINITE DO, WHILE, FOR LOOPS ==
My pet hate! If the code is not inextricably entwined within looping statements then try to reduce the complexity of a routine by extracting algorithms from the loop statements and placing the functionality within separate, smaller routines.

Document your changes via comments within the code or preferably use version tracking software to capture your changes.

== PROCESS IMPROVEMENT ==
Before embarking upon a plan of gradual improvement you need to do some investigation and find out whether there are any projects underway that could replace the application you have been handed. You do not want to waste time and effort patching up an application that will soon be replaced or defunct. Perhaps there are addins to other applications that can provide the same service to the users. Your goal is to get rid of the application if you can or reduce its negative impact upon workload (due to badly written algorithms) by farming out its tasks to better written and more stable applications. Maintenance is an expensive and time-consuming process for badly written applications.

If you cannot rid yourself of the application then write down some steps of improvement, for example; introduce exception/error-handling where it is lacking. Break down seriously long routines. Rewrite extremely bad legacy code that fails to live up to expectations. Remove ugly code to a separate library and access it's functionality by a cleanly written interface. Perhaps you could introduce user input testing or format masks to force consistent data entry.

Sometimes an application produces reports with spurious results due to poorly devised calculations and inadequate testing of SQL string results. Provide users with data dumps in comma separated value (csv) files so they can build their own reports using spreadsheets and charting software (http://en.wikipedia.org/wiki/Comma-separated_values).

Do not be shy in discussing with your users the fact that you have been handed a lemon of an application, they will more than likely agree with you. Inform them on how you intend to implement a plan of process improvement and ask them for their thoughts and ideas. Remind them that it will be a gradual process and involve them in the development and testing. This is called the winning of hearts and minds! This concepts works because it is an inherently genuine and honest approach to improving the situation for your users and yourself.

Do not be disheartened by any user's cynicism towards the services and plans you plan to offer them; When an application produces bad results for any period of time, prior promises upon which the previous developer was supposed to deliver have been broken and it is the user who suffers the results of those broken promises.

Lastly! Expedient support to users' problems will be extremely appreciated even if your plan of improvement is slowed because of it.

Optimizing Your Asp.Net Pages for Faster Loading and Better Performance.

If you read the internet and all of the websites dedicated to Asp.Net you will inevitably read about the wonders of the DataGrid, DataList, and Repeater controls. While each of these has its place, if you are only displaying data there is a much faster and more efficient means to do so.

Let's say you have a page that displays articles based on a query string. Take my article pages for instance. Each article is stored in a database and displayed on the page based on the unique id of the article as stored in the database.

A normal asp page execution procedure goes something like this. The code queries the database based on the Article I.D. and then brings back that information to the page where you display it in the fashion that you would like. This is a fairly straight forward approach with asp and is done all the time.

So how do we speed up our asp.net pages?

Number 1: Use Asp.Net Caching!

This is a no-brainer, and I won't go into the brilliance or details of asp.net caching here because at the time of this writing Google has 2,780,000 articles on the topic. Basically instead of querying the database each time the page is loaded you only query the database once and load that result into the system cache. Subsequent calls to load the page retrieve the data from the cache as opposed to the database which gives you an instant and considerable performance boost. You can then set the cache for how long the cache should store the information as well as many other features. If you are not using the cache, you should be whenever possible!

Number 2: If possible, do NOT use the standard Asp.Net controls.

That's right. The standard asp.net controls are designed for rapid development and not page performance. They allow you to design pages that grab and display data very quickly but their actual performance suffers because of the extra overhead which is there for ease and speed of development time and not page execution speed.

Instead, create either a User Control or even better yet a Web Custom Control which is by far the fastest performance wise and really quite easy to create and use.

Number 3: Use an SqlDataReader or even better yet use a set based command for Sql Server data retrieval and simply execute that one command against the database.

An asp.net SqlDataReader is a fast forward only datareader that closes the connection after it reads the last set of results. Now for my article pages we are only returning 1 particular result. In this case we would opt for the set based command. If you had more than 1 result returned, in your table of contents for instance, you would use the SqlDataReader because you are returning multiple sets of results.

Set based commands are stored procedures that bring back data through parameters as opposed to a result set which then in turn needs to be looped through to obtain your data. So instead of writing your stored procedure like the following which brings back 1 result set:

Select Title, Body, Author
From Articles
Where ArtID = 215

We can write it using a set based command like this.

Create Procedure mysp_GetArticle

@Title varchar(200) Output,
@Body varchar(8000) Output,
@Author varchar(500) Output

As

Select @Title = Title, @Body = Body, @Author = Author
From Articles
Where ArtID = 215

GO

The above query will return only the three parameters called for and not a result or record set so you don't have to then walk through the returned record set that has only 1 result in it anyway. This second little process of work decreases your performance so you should avoid it whenever possible. Combine this technique with the asp.net cache.

Number 4: Use Classes and ArrayLists as opposed to returning an SqlDataReader.

Create a class and then if there are more than one set of results store those results into individual instantiations of that class. Finally store each of those classes into an ArrayList. You can then store only that ArrayList into the asp.net cache. So instead of getting the results back from a SqlDataReader when loading your page you get them from the ArrayList which is stored in the cache. Nice huh?

Finally... you want to incorporate all of these techniques into your final results which would be performed in the following manner and sequence.

On the first time the page loads, query the database and return all of your data storing it into individual classes. Then store each of those classes into an ArrayList. If you only have one single result you may store only the class into the cache. Then take your ArrayList and store it into the cache.

Next create a Web Custom Control and pass the cached ArrayList to the custom control and loop out your data using the HtmlTextWriter which is very fast. Remember each subsequent call to load the page will be called from the cache which stores your ArraList of classes or your single class.

Certainly it takes a significant amount of additional coding to do it in this fashion, especially when you take proper error handling into consideration, but if you follow this approach your pages will be screeching fast, you will immediately notice the difference, and your asp.net pages will execute in the proper sequence - Data handling in the PageLoad function and the html display in the PageRender function.

Further, you will be glad you did and so will your visitors.

Happy Programming!

10 Benefits of Using Coding Standards to Software Development Team

Having coding standards in a software development organization has the following advantages.

For the developers:

1. The source code will be more comprehensive and will become easy-to-maintain. As the programmers became more and more familiar with the coding style as they implements the coding standards on project after project.

2. The uniform approach for solving problems will be handy because the code standards documents reveal the recommended methods that were tried and tested on the earlier projects.

3. Less communication between developers and managers will be needed because the programmers will not asked anymore on the details of the specification document because the defaults are all stated in coding standards.

4. Is common to the less experience programmer to re-invent the wheel. When there are coding standards, there is a big chance that particular problem is not really a new problem, but in fact, a solution may be documented before.

For the quality assurance team:

5. Well documented coding standards will aid the creation of “Test Scripts”. Having reviewed the source code and tested an application based on compliance to coding standards, it added strong direction to ensure quality of the software product.

6. Because code standards implements traceability, the item ids can be used to describe a violation in the “Test Results” document that both developers and testers are familiar with.

For the project managers:

7. It is important for the project managers to maintain and secure source code quality on their projects. Implementing coding standards could jumpstart this goal halfway to its realization.

8. Repeated performance pitfalls could be avoided. It is a common case that a released software product could be less impressive when it comes to performance when the real data has been loaded in the new developed database application.

9. Lesser man-hour consumption as the sum of all efforts implementing coding standards.

10. It is also beneficial for the organization who are applying for ISO 9001 license because coding standards is a complement from organization’s execution plan requirements.

Databases and Sql as a Middle Tier Storage Medium

DOTNUTSHELL Technologies are an experienced database designing company, with Oracle accredicated qualification providing services both in the OpenSource and Enterprise field.

Microsoft SQL Server is a relational database management system. Its primary query language is Transact-SQL, an implementation of the ANSI/ISO standard Structured Query Language (SQL) used by both Microsoft and Sybase.

Microsoft SQL Server uses a variant of SQL called T-SQL, or Transact-SQL, an implementation of SQL-92. T-SQL mainly adds additional syntax for use in stored procedures, and affects the syntax of transaction support.

SQL Server includes support for database mirroring and clustering. A SQL server cluster is a collection of identically configured servers, which help distribute the workload among multiple servers. All the servers share an identical virtual server name, and it is resolved into the IP address of any of the identically configured machines by the clustering runtime. Automatic failover clustering is also available, in which the workload of a server is transferred to another system in the event of a system failure.SQL server also supports data partitioning for distributed databases. Database mirroring, introduced in SQL Server 2005, allows creation of mirrors (or replicas) of database contents, along with transaction logs, on another instance of SQL Server, based on certain predefined triggers.

Microsoft and other vendors provide a number of software development tools designed to allow business applications to be developed using the data stored by Microsoft SQL Server. Microsoft SQL Server 2005 now includes the common language runtime (CLR) component for Microsoft .NET. Applications developed with .NET languages such as VB.NET or C# can implement stored procedures and other functions. Older versions of Microsoft development tools typically use APIs to access Microsoft SQL Server functionality.

We can design and engineer databases based on your business model and provide tools and interfaces that can be used to mine your business data. We also have experience in database persistence and create custom persistence frameworks and algorythms which can be used to predict patterns and trends from your data.

Oracle Database is a relational database management system released by Oracle Corporation. Oracle Database has become a major feature of database computing.

An Oracle database system comprises at least one instance of the application, along with data storage. An instance comprises a set of operating-system processes and memory-structures that interact with the storage. Typical processes include PMON (the process monitor) and SMON (the system monitor).

Users of Oracle databases refer to the server-side memory-structure as the SGA (System Global Area). The SGA typically holds cache information such as data-buffers, SQL commands and user information. In addition to storage, the database consists of online redo logs (which hold transactional history). Processes can in turn archive the online redo logs into archive logs (offline redo logs), which provide the basis (if necessary) for data recovery and for some forms of data replication.

The Oracle RDBMS stores data logically in the form of tablespaces and physically in the form of data files. Tablespaces can contain various types of memory segments; for example, Data Segments, Index Segments etc. Segments in turn comprise one or more extents. Extents comprise groups of contiguous data blocks. Data blocks form the basic units of data storage. At the physical level, data-files comprise one or more data blocks, where the block size can vary between data-files.

Oracle databases can be used to create distributed database running over contiguous or disparate logistical locations. It can be used to store data and information and provides high availably and performance and is used extensively as a practial and reliable database.

We can design and engineer databases based on your business model and provide tools and interfaces that can be used to mine your business data. We also have experience in database persistence and create custom persistence frameworks and algorythms which can be used to predict patterns and trends from your data.

MySQL is a multithreaded, multi-user SQL database management system which has, according to MySQL AB, more than 10 million installations. The basic program runs as a server providing multiuser access to a number of databases.

Libraries for accessing MySQL databases are available in all major programming languages with language-specific APIs. In addition, an ODBC interface called MyODBC allows additional programming languages that support the ODBC interface to communicate with a MySQL database, such as ASP or ColdFusion. The MySQL server and official libraries are mostly implemented in ANSI C/ANSI C++.

MySQL is popular for web applications and acts as the database component of the

LAMP (Linux-Apache-MySQL-PHP/Perl/Python)

MAMP (Mac-Apache-MySQL-PHP/Perl/Python)

WAMP (Windows-Apache-MySQL-PHP/Perl/Python)

Its popularity for use with web application is closely tied to the popularity of PHP, which is often combined with MySQL. PHP and MySQL are essential components for running popular content management systems such as WordPress and Drupal blogging platforms. Wikipedia runs on MediaWiki software, which can also use PHP and a MySQL database.

MySQL is the most widely used OpenSource SQL database in the world. It provides features and services which make it ideal for small to medium enterprises to effectively manage small to reasonably large business data. It is also fulyl compliant with the SQL standard and provides support for stored procedures and object abstraction when coupled with object persistence frameworks.

We can design and engineer databases based on your business model and provide tools and interfaces that can be used to mine your business data. We also have experience in database persistence and create custom persistence frameworks and algorythms which can be used to predict patterns and trends from your data

Microsoft CRM as Time Logs for Consulting Business: Integration With Great Plains

This article is targeted to programmers, we are providing C# source code for CRM->GP integration. The code provided is not packaged product, but rather “solution”, which needs to be tailored and installed by GP eConnect C# programmers. What integration does:

1. If you log your timesheets as tasks in Microsoft CRM against contract line cases – these tasks will be integrated as GP Sales Order Processing Invoice lines with description cut to one hundred symbols – this is restriction of GP SOP line description

2. In GP sales invoices are created automatically by overnight integration when you close the case in CRM. If you close several cases for the same customer, let’s say QA, development, onsite consulting, all the cases and corresponding tasks will be combined in one invoice per customer

3. Additional possibilities in MS Dynamics CRM. If you log time against the cases, linked to contract lines, you can create very powerful consultant time tracking report and project status report.

4. Additional Comments. Microsoft Dynamics GP eConnect 10.0 SDK doesn’t have source code for Sales Invoice integration C# demo project. We worked out this project and its code is incorporated in the provided demo C# code, please look at the procedure: SerializeSalesOrderObject

Below you see the code listing:

using System;
using System.IO;
using System.Collections;
using System.Data;
using System.Diagnostics;
using System.Data.SqlClient;
using System.Xml;
using System.Text;
using System.Xml.Serialization;
using Microsoft.Dynamics.GP.eConnect;
using Microsoft.Dynamics.GP.eConnect.Serialization;
using Microsoft.Dynamics.GP.eConnect.MiscRoutines;

namespace Integration
{
sealed public class OrderApp
{
public static string outerSelectString;// = "SELECT DISTINCT SQLSERVER, DATABASENAME FROM ALBANEWTIMELOG";
public static string innerSelectString;// = "SELECT AccountNumber,BillableTime,UnitPrice,LineTotalPrice,[Description],ItemNumber,SQLSERVER,DATABASENAME, IncidentId FROM ALBANEWTIMELOG WHERE DATABASENAME=";
public static string connectionString ;//= "Integrated Security = true;Data Source = CRMSERVER; Initial Catalog = CRMCUSTOMIZATION;";
public static DataTable TableLines; // the datasource of the datagrid called DataLines.

// Error handling variables
public static string sErrMsg;
public static int lErrCode;
public static int lRetCode;

static string sDatabaseName, sServerName, sUserName, sPassword;
static string description, itemnumber, accountNumber, sCustomerPO;
static char char39=(char)39; //to immitate ' symbol
static System.Data.SqlTypes.SqlGuid incidentId;


// ****************************************************************************
// This is the application entry point
// ****************************************************************************
public static void Main()
{

string sCustomerDocument;
string sSalesOrder;
string sXsdSchema;
string sConnectionString;


string NAME="";
string CONTACT="";
string ADDRESS1="";
string ADDRESS2="";
string CITY="";
string STATE="";
string ZIP="";

string currentCustomer = "";

sConnectionString = @"data source=ALBASERVER;initial catalog=ALBA;integrated security=SSPI;persist security info=False;packet size=4096";

StreamReader re = File.OpenText("C:\_IntegrationGP\Integration\Settings.txt");
connectionString = re.ReadLine();
outerSelectString=re.ReadLine();
innerSelectString=re.ReadLine();
sUserName = re.ReadLine();
sPassword = re.ReadLine();
String crmConnectionString = re.ReadLine();
String customerSelectString = re.ReadLine();
String timeLogSelectString = re.ReadLine();
re.Close();

SqlConnection outerConnection = new SqlConnection();
outerConnection.ConnectionString = connectionString;
outerConnection.Open();

SqlCommand outerCommand = new SqlCommand();
outerCommand.CommandType = System.Data.CommandType.Text;
outerCommand.CommandText = outerSelectString;
outerCommand.Connection = outerConnection;
SqlDataReader outerReader = outerCommand.ExecuteReader();

while(outerReader.Read())
{
sServerName="";
sDatabaseName="";
//reading databases-companie and their server names in timelog
sServerName=outerReader.GetSqlString(0).ToString();
sDatabaseName=outerReader.GetSqlString(1).ToString();

sServerName=sServerName.Trim();
sDatabaseName=sDatabaseName.Trim();

SqlConnection connection = new SqlConnection();
connection.ConnectionString = connectionString;
connection.Open();

SqlCommand command = new SqlCommand();
command.CommandType = System.Data.CommandType.Text;
command.CommandText = innerSelectString+char39+sDatabaseName+char39+" order by AccountNumber";
command.Connection = connection;
SqlDataReader reader = command.ExecuteReader();

while(reader.Read())
{
decimal billableTime, unitPrice, lineTotal;
double bTime, uPrice;

description="";
itemnumber="";
accountNumber="";

sCustomerPO="";

Console.WriteLine("Record:");
//reading from timelog
accountNumber=reader.GetSqlString(0).ToString();



billableTime=reader.GetSqlDecimal(1).Value;
unitPrice=reader.GetSqlDecimal(2).Value;
lineTotal=reader.GetSqlDecimal(3).Value;
description=reader.GetSqlString(4).ToString();
itemnumber=reader.GetSqlString(5).ToString();
incidentId=reader.GetSqlGuid(8);
sCustomerPO=reader.GetSqlString(9).ToString();
//add fields

bTime=(double)billableTime;
uPrice=(double)unitPrice;

Console.WriteLine(billableTime);
Console.WriteLine(billableTime.ToString());
Console.WriteLine(unitPrice.ToString());
Console.WriteLine(lineTotal.ToString());
Console.WriteLine(description.ToString());
Console.WriteLine(itemnumber.ToString ());
Console.WriteLine(sCustomerPO.ToString ());
Console.WriteLine();

try
{
if (String.Compare(currentCustomer, accountNumber) != 0)
{
using (eConnectMethods e = new eConnectMethods())
{
//-Update-Create Customer-------------------------------------------------------
//--------------------------------------------------------------------------------
try
{
//Read Customer info from CRM

SqlConnection crmConnection = new SqlConnection();
crmConnection.ConnectionString = crmConnectionString;
crmConnection.Open();

SqlCommand commandCustomer = new SqlCommand();
commandCustomer.CommandType = System.Data.CommandType.Text;
commandCustomer.CommandText = customerSelectString + char39 + accountNumber + char39 + " order by a.AccountNumber";
commandCustomer.Connection = crmConnection;
SqlDataReader readerCustomer = commandCustomer.ExecuteReader();
if (!readerCustomer.Read()) return;
readerCustomer.GetSqlString(0).ToString();
string sName = readerCustomer.GetSqlString(1).ToString();
if (String.Compare(sName, "Null") == 0) sName = "";
NAME = sName;
string sContact = readerCustomer.GetSqlString(4).ToString();
if (String.Compare(sContact, "Null") == 0) sContact = "";
CONTACT = sContact;
string sLine1 = readerCustomer.GetSqlString(5).ToString();
if (String.Compare(sLine1, "Null") == 0) sLine1 = "";
ADDRESS1 = sLine1;
string sLine2 = readerCustomer.GetSqlString(6).ToString();
if (String.Compare(sLine2, "Null") == 0) sLine2 = "";
ADDRESS2 = sLine2;
string sCity = readerCustomer.GetSqlString(7).ToString();
if (String.Compare(sCity, "Null") == 0) sCity = "";
CITY = sCity;
string sState = readerCustomer.GetSqlString(8).ToString();
if (String.Compare(sState, "Null") == 0) sState = "";
STATE = sState;
string sZip = readerCustomer.GetSqlString(9).ToString();
ZIP = sZip;
if (String.Compare(sZip, "Null") == 0) sZip = "";
string sCountry = readerCustomer.GetSqlString(10).ToString();
if (String.Compare(sCountry, "Null") == 0) sCountry = "";

readerCustomer.Close();
commandCustomer.Dispose();
crmConnection.Close();
crmConnection.Dispose();

// Create the customer data file
SerializeCustomerObject("Customer.xml", accountNumber, sName, sContact, sLine1, sLine2, "MAIN", sCity, sState, sZip, sCountry);

// Use an XML document to create a string representation of the customer
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("Customer.xml");
sCustomerDocument = xmldoc.OuterXml;

// Create an XML Document object for the schema
XmlDocument XsdDoc = new XmlDocument();

// Create a string representing the eConnect schema
sXsdSchema = XsdDoc.OuterXml;

// Pass in xsdSchema to validate against.
e.eConnect_EntryPoint(sConnectionString, EnumTypes.ConnectionStringType.SqlClient, sCustomerDocument, EnumTypes.SchemaValidationType.None, sXsdSchema);

}
// The eConnectException class will catch eConnect business logic errors.
// display the error message on the console
catch (eConnectException exc)
{
Console.Write(exc.ToString());
}

} // end of using statement
//End Update-Create Customer
//-----------------------------------------------------------
//Sales Invoice begins-----------------------
//--------------------------------------------

using (eConnectMethods e = new eConnectMethods())
{
try
{
GetSopNumber mySopNumber = new GetSopNumber();
string SOPNUMBE = mySopNumber.GetNextSopNumber(3, "INV", sConnectionString);

eConnectType eConnect = new eConnectType();

//Read Customer info from CRM

SqlConnection crmConnection = new SqlConnection();
crmConnection.ConnectionString = crmConnectionString;
crmConnection.Open();

SqlCommand commandSalesOrder = new SqlCommand();
commandSalesOrder.CommandType = System.Data.CommandType.Text;
commandSalesOrder.CommandText = timeLogSelectString + char39 + accountNumber + char39 + " order by a.AccountNumber";
commandSalesOrder.Connection = crmConnection;
SqlDataReader readerSalesOrder = commandSalesOrder.ExecuteReader();

taSopLineIvcInsert_ItemsTaSopLineIvcInsert[] items = new taSopLineIvcInsert_ItemsTaSopLineIvcInsert[0];
decimal SUBTOTAL = 0;
int iSO = 0;
while (readerSalesOrder.Read())
{
decimal hours = readerSalesOrder.GetSqlDecimal(0).Value;
string sDescription = readerSalesOrder.GetSqlString(1).ToString();
if (String.Compare(sDescription, "Null") == 0) sDescription = "miscellaneous";
decimal rate = readerSalesOrder.GetSqlDecimal(2).Value;

taSopLineIvcInsert_ItemsTaSopLineIvcInsert item = new taSopLineIvcInsert_ItemsTaSopLineIvcInsert();

hours = Decimal.Round(hours, 2);
rate = Decimal.Round(rate, 2);
if (rate < (decimal)0.01)
rate = (decimal)0.60;

item.SOPNUMBE = SOPNUMBE;
item.SOPTYPE = 3;
item.CUSTNMBR = accountNumber;
item.DOCID = "INV";
item.QUANTITY = hours;
item.ITEMNMBR = "SERVICE";
item.ITEMDESC = sDescription;
item.UNITPRCE = rate;
item.XTNDPRCE = hours * rate;
item.DOCDATE = System.DateTime.Today.Date.ToString();
item.NONINVEN = 1;

//items[iSO] = item;
SUBTOTAL += hours * rate;
iSO++;
if (items.Length < iSO) items = (taSopLineIvcInsert_ItemsTaSopLineIvcInsert[])ExpandArray((Array)items, item);
}
readerSalesOrder.Close();
commandSalesOrder.Dispose();
crmConnection.Close();
crmConnection.Dispose();

SOPTransactionType SopOrder = new SOPTransactionType();
XmlSerializer serializer = new XmlSerializer(eConnect.GetType());

SopOrder.taSopLineIvcInsert_Items = items;

taSopHdrIvcInsert header = new taSopHdrIvcInsert();

header.SOPTYPE = 3;
header.SOPNUMBE = SOPNUMBE;
header.DOCID = "INV";
header.BACHNUMB = "ECONNECT";
header.CUSTNMBR = accountNumber;
header.CUSTNAME = NAME;
//header.ShipToName = "WAREHOUSE";
header.ADDRESS1 = ADDRESS1;
header.CNTCPRSN = CONTACT;
// header.FAXNUMBR = "13125550150";
header.CITY = CITY;
header.STATE = STATE;
header.ZIPCODE = ZIP;
// header.COUNTRY = "USA";
header.SUBTOTAL = SUBTOTAL;
header.DOCAMNT = SUBTOTAL;
// header.USINGHEADERLEVELTAXES = 0;
// header.PYMTRMID = "Net 30";
header.DOCDATE = System.DateTime.Today.Date.ToString();

SopOrder.taSopHdrIvcInsert = header;

SOPTransactionType[] mySOPOrder = { SopOrder };
eConnect.SOPTransactionType = mySOPOrder;

FileStream fs = new FileStream("SalesOrder.xml", FileMode.Create);
XmlTextWriter writer = new XmlTextWriter(fs, new UTF8Encoding());
serializer.Serialize(writer, eConnect);
writer.Close();

XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("SalesOrder.xml");
sSalesOrder = xmldoc.OuterXml;
XmlDocument XsdDoc = new XmlDocument();
sXsdSchema = XsdDoc.OuterXml;
e.eConnect_EntryPoint(sConnectionString, EnumTypes.ConnectionStringType.SqlClient, sSalesOrder, EnumTypes.SchemaValidationType.None, sXsdSchema);

}

catch (eConnectException exc)
{
Console.Write(exc.ToString());
}

}

//Sales Invoice ends-----------------------
//--------------------------------------------
}

{ //Marking case as imported
SqlConnection updateConnection = new SqlConnection();
updateConnection.ConnectionString = connectionString;
updateConnection.Open();

SqlCommand commandUpdate = new SqlCommand();
commandUpdate.CommandType = System.Data.CommandType.StoredProcedure;
commandUpdate.CommandText = "sp_UpdateImportedCase";
commandUpdate.Parameters.Add("@incidentId", SqlDbType.UniqueIdentifier);
commandUpdate.Parameters["@incidentId"].Value = incidentId;
commandUpdate.Connection = updateConnection;
commandUpdate.ExecuteNonQuery();
commandUpdate.Dispose();
updateConnection.Close();
updateConnection.Dispose();
}

}
catch { }
currentCustomer = accountNumber;
}
reader.Close();
command.Dispose();
connection.Close();
connection.Dispose();
}
}

public static void SerializeCustomerObject(string filename, string custnumbr, string name, string cntcprsn,string address1, string address2, string adrscode, string city, string state, string zip, string country)
{
try
{
// Instantiate an eConnectType schema object
eConnectType eConnect = new eConnectType();

// Instantiate a RMCustomerMasterType schema object
RMCustomerMasterType customertype = new RMCustomerMasterType();

// Instantiate a taUpdateCreateCustomerRcd XML node object
taUpdateCreateCustomerRcd customer = new taUpdateCreateCustomerRcd();

// Create an XML serializer object
XmlSerializer serializer = new XmlSerializer(eConnect.GetType());

// Populate elements of the taUpdateCreateCustomerRcd XML node object
customer.CUSTNMBR = custnumbr;
customer.CUSTNAME = name;
customer.CNTCPRSN = cntcprsn;
customer.ADDRESS1 = address1;
customer.ADDRESS2 = address2;
customer.ADRSCODE = adrscode;
customer.CITY = city;
customer.STATE = state;
customer.ZIPCODE = zip;
customer.COUNTRY = country;
customer.CUSTPRIORITY = 1;
customer.CUSTPRIORITYSpecified = true;

// Populate the RMCustomerMasterType schema with the taUpdateCreateCustomerRcd XML node
customertype.taUpdateCreateCustomerRcd = customer;
RMCustomerMasterType[] mySMCustomerMaster = { customertype };

// Populate the eConnectType object with the RMCustomerMasterType schema object
eConnect.RMCustomerMasterType = mySMCustomerMaster;

// Create objects to create file and write the customer XML to the file
FileStream fs = new FileStream(filename, FileMode.Create);
XmlTextWriter writer = new XmlTextWriter(fs, new UTF8Encoding());

// Serialize the eConnectType object to a file using the XmlTextWriter.
serializer.Serialize(writer, eConnect);
writer.Close();
}
// catch any errors that occur and display them to the console
catch (System.Exception ex)
{
Console.Write(ex.ToString());
}
}

//the following function is for demo only, not in use
public static void SerializeSalesOrderObject(string filename)
{
try
{
// Instantiate an eConnectType schema object
eConnectType eConnect = new eConnectType();

taSopLineIvcInsert_ItemsTaSopLineIvcInsert[] items = new taSopLineIvcInsert_ItemsTaSopLineIvcInsert[1];

taSopLineIvcInsert_ItemsTaSopLineIvcInsert item = new taSopLineIvcInsert_ItemsTaSopLineIvcInsert();

item.ADDRESS1 = "2345 Main St.";
item.CUSTNMBR = "CONTOSOL0001";
item.SOPNUMBE = "000001";
item.CITY = "Aurora";
item.SOPTYPE = 3;
item.DOCID = "STDINV";
item.QUANTITY = 2;
item.ITEMNMBR = "ACCS-CRD-12WH";
item.ITEMDESC = "Phone Cord - 12' White";
item.UNITPRCE = (decimal)10.95;
item.XTNDPRCE = (decimal)21.9;
item.LOCNCODE = "WAREHOUSE";
item.DOCDATE = "04/12/2017";// 'Today

items[0] = item;

SOPTransactionType SopOrder = new SOPTransactionType();
XmlSerializer serializer = new XmlSerializer(eConnect.GetType());

SopOrder.taSopLineIvcInsert_Items = items;

taSopHdrIvcInsert header = new taSopHdrIvcInsert();

header.SOPTYPE = 3;
header.SOPNUMBE = "000001";
header.DOCID = "STDINV";
header.BACHNUMB = "ECONNECT ";
header.TAXSCHID = "USASTCITY-6*";
header.FRTSCHID = "USASTCITY-6*";
header.MSCSCHID = "USASTCITY-6*";
header.LOCNCODE = "WAREHOUSE";
header.DOCDATE = "04/12/2017";
header.CUSTNMBR = "CONTOSOL0001";
header.CUSTNAME = "Contoso, Ltd.";
header.ShipToName = "WAREHOUSE";
header.ADDRESS1 = "2345 Main St.";
header.CNTCPRSN = "Joe Healy";
header.FAXNUMBR = "13125550150";
header.CITY = "Aurora";
header.STATE = "IL";
header.ZIPCODE = "65700";
header.COUNTRY = "USA";
header.SUBTOTAL = (decimal)21.9;
header.DOCAMNT = (decimal)21.9;
header.USINGHEADERLEVELTAXES = 0;
header.PYMTRMID = "Net 30";

SopOrder.taSopHdrIvcInsert = header;

// Populate the RMCustomerMasterType schema with the taUpdateCreateCustomerRcd XML node
//customertype.taUpdateCreateCustomerRcd = customer;
//RMCustomerMasterType[] mySMCustomerMaster = { customertype };

SOPTransactionType[] mySOPOrder = { SopOrder };
eConnect.SOPTransactionType = mySOPOrder;

// Populate the eConnectType object with the RMCustomerMasterType schema object
//eConnect.RMCustomerMasterType = mySMCustomerMaster;

// Create objects to create file and write the customer XML to the file
FileStream fs = new FileStream(filename, FileMode.Create);
XmlTextWriter writer = new XmlTextWriter(fs, new UTF8Encoding());

// Serialize the eConnectType object to a file using the XmlTextWriter.
serializer.Serialize(writer, eConnect);
writer.Close();

}
// catch any errors that occur and display them to the console
catch (System.Exception ex)
{
Console.Write(ex.ToString());
}
}
//this function allows us to increase Array length on the fly - we use it when we reading n=lines for Sales Invoice
public static Array ExpandArray(Array arr, object newElement)
{
int length = 1;
System.Type type = newElement.GetType();
if (arr != null)
{
length += arr.Length;
type = arr.GetType().GetElementType();
}
Array result = Array.CreateInstance(type, length);
if (arr != null)
{
arr.CopyTo(result, 0);
}
result.SetValue(newElement, result.Length - 1);
return result;
}
}
}

Advantages of Using Dream Weaver to Design Web Pages

When making a suggestion to someone to try something new, it is important to support your case with a strong evidence base. This allows your listener to make an informed decision as to whether or not they will take up your offer. A colleague or friend may suggest that you consider participating in a Dream Weaver training course. Let us consider some of the advantages of using Dream Weaver software to design web pages.

Ease and efficiency of use

This software has not only been designed with advanced level users in mind but also for beginners. Simple and complex websites can be designed using a point and click method.
The ability to view html pages during the design process

Users of Dream Weaver have the ability to select different views when creating web pages. A 'code view' shows only the html code for the page. A 'design view' gives an indication of how the html page will appear in a browser. 'A split view', as the name implies, allows you to see the code view and design view at the same time. Both views are updated automatically as changes are being made and the user can immediately see the effect of any changes.

The ability to create consistent looking web pages

This software includes templates for web pages to assist in the design process. Template files can be created by the user or alternatively, ready prepared templates are available. This feature makes it possible for beginners to design web pages as the workload is reduced. If your site is made up of twenty pages based around a particular template design, for example, it will have a consistent style and therefore be more user friendly.

Managing and updating websites effectively

Website designers can make changes to the design of a website simply by editing the Dream Weaver template files. This eliminates the need to alter each page manually because Dream Weaver can automatically update the pages created using a template. This saves much time and effort. Furthermore, the use of templates means that the code and design are separate. As a result, changes can be made to the content without the risk of making unnecessary or incorrect alterations to the code.

Easy to upload using FTP

Dream Weaver software comes with built in FTP features so it is possible to upload files directly to your website.

Customisable software

Users of Dream Weaver can customise the look of the software to match their requirements. Menus, tabs, commands, fonts and code colouring can all be adjusted to personal preference. This can effectively streamline the web design process.

Having reviewed some of the evidence for the case in favour of undertaking Dream Weaver training, it only remains for you to make the final verdict.

Sap - Performance Tuning Using Parallel Cursor

Nested Loops – This is one of the fear factors for all the ABAP developers as this consumes lot of program execution time. If the number of entries in the internal tables is huge, then the situation would be too worse. The solution for this is to use parallel cursor method whenever there is a need for Nested Loop.

Program using Normal Nested Loop:

REPORT ZNORMAL_NESTEDLOOP.

TABLES:
likp,
lips.

Data:
t_likp type table of likp,
t_lips type TABLE OF lips.

data:
W_RUNTIME1 TYPE I,
W_RUNTIME2 TYPE I.

START-OF-SELECTION.
select *
from likp
into table t_likp.

select *
from lips
into table t_lips.

get RUN TIME FIELD w_runtime1.

loop at t_likp into likp.
loop at t_lips into lips where vbeln eq likp-vbeln.
endloop.
endloop.

get RUN TIME FIELD w_runtime2.

w_runtime2 = w_runtime2 - w_runtime1.

write w_runtime2.

Nested Loop using Parallel Cursor:

REPORT zparallel_cursor2.

TABLES:
likp,
lips.

DATA:
t_likp TYPE TABLE OF likp,
t_lips TYPE TABLE OF lips.

DATA:
w_runtime1 TYPE i,
w_runtime2 TYPE i,
w_index LIKE sy-index.

START-OF-SELECTION.
SELECT *
FROM likp
INTO TABLE t_likp.

SELECT *
FROM lips
INTO TABLE t_lips.

GET RUN TIME FIELD w_runtime1.
SORT t_likp BY vbeln.
SORT t_lips BY vbeln.

LOOP AT t_likp INTO likp.

LOOP AT t_lips INTO lips FROM w_index.
IF likp-vbeln NE lips-vbeln.
w_index = sy-tabix.
EXIT.
ENDIF.
ENDLOOP.
ENDLOOP.

GET RUN TIME FIELD w_runtime2.

w_runtime2 = w_runtime2 - w_runtime1.

WRITE w_runtime2.

Analysis report: Runtime in microseconds:
Iteration 1:
Normal Nested Loop: 34,796,147
Using Parallel Cursor: 63,829

Iteration 2:
Normal Nested Loop: 38,534,583
Using Parallel Cursor: 56,894

Iteration 3:
Normal Nested Loop: 34,103,426
Using Parallel Cursor: 50,510

Rapid Application Development

Rapid application development (RAD), is a software development process developed initially by James Martin in the 1980s. The methodology involves iterative development, the construction of prototypes, and the use of Computer-aided software engineering (CASE) tools. Traditionally the rapid application development approach involves compromises in usability, features, and/or execution speed. It is described as a process through which the development cycle of an application is expedited. Rapid Application Development thus enables quality products to be developed faster, saving valuable resources.

Positive aspects of RAD:

Increased speed of development through methods including rapid prototyping, virtualization of system related routines, the use of CASE tools, and other techniques.

Decreased end-user functioality (arising from narrower design focus), hence reduced complexity

Larger emphasis on simplicity and usability of GUI design

Negative aspects of RAD:

Reduced Scalability, and reduced features when a RAD developed application starts as a prototype and evolves into a finished application

Reduced features occur due to time boxing when features are pushed to later versions in order to finish a release in a short amount of time

At DOTNUTSHELL, we understand that RAD development is applicable only when the application to be developed can call on the modular nature of the frameworks used to create it. High availability and performance software aare not usually created using RAD, and neither are mission critical sysems.