Introduction
Simple way to manage project and show progress on Gantt chart, it is on web application and there is no limitation to use it, so if some part of your project are in sites where are far from each other, you can use it and gather real data from users who are involved to same project. When you are involved in a project, you have to control affairs; otherwise we will have to pay its consequences which may be serious. I have not seen a complete package for controlling project in free. I have prepared essential parts which are needed for monitoring project resources.
Background: What is Project Management?
Project is set of activities to improve and enhance products or services. People comes together temporarily to perform tasks which have specific start and end point until they can achieve desire result. Project control is to manage resources and have best feedback; goal in this area is to reach high quality in products or services in short time with at least cost. So we have a scope which can be changed overtime based on conditions.
Project manager is responsible to ensure us that project is still in an acceptance level. He or she has to define priority in tasks and resources and specify a reasonable time interval for each task then he or she should give us feedback. In a better words project management is summarized in 7 steps as I describe follow.
Project Management:
- Specify requirements
- Plan, which task has to be done by whom in what standard?
- Gather members then motivate and encourage them
- Monitor and supervise process
- Take control changes and don`t allow to have any variance
If you want to know more about it please visit this link
For an instance I have designed a sample flowchart for trading projects which is based on my experiences, there are some tasks in this example which can be useful for task definition. They are belonging to dealer companies which are placed between providers (principals or factories) and customers.
You have two choices you can insert these tasks in your Data Base from your application directly or these are available in your MS Project file before. In second case you have to save your sheet in xml format like below picture. In this article I have selected 'PM' for file name. As you know some tasks in project are parent and another ones are set of tasks which are related to each other in the respect of their duties. For instance in trading companies inquiry and send catalog are set of sections which are related to marketing phase so I called them such as:
Group: Marketing
- Block 1: Inquiry
- Block 2: Send Catalog
Or
- Group: Transport
- Block 1: Shipment
- Block 2: Inspection Company
- Block 3: Insurance
These names are depend on project manager`s decisions. In this article I have inserted tasks to data base and then I have assigned for each project its groups and blocks for each group I have assigned a color, so we can track progress better in Gantt Chart with different colors, after that in another page I have defined blocks for each group, each blocks has specific start and end date. These points for start and end dates are something similar to predict progress and are not real, for have a real progress you can add some pages to your application and your users can log in to profile and insert exact time and cost for each blocks. Finally for get a result from it , you can go to DemoRequest.aspx and give your project name, year and season and click on show guntt chart, then you can see progress of your project. In this part I have used from eventcalendercontrol component if you want to know more about this control please visit this link: visit this link, and if you want to enhance your application with AJAX technology, please visit follow links:
DataBase
New Query
Project
CREATE TABLE [dbo].[tblProject](
[ProjID] [int] NOT NULL,
[ProjName] [nchar](90) NULL,
CONSTRAINT [PK_tblProject] PRIMARY KEY CLUSTERED
(
[ProjID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
insert into dbo.tblProject(ProjID, ProjName) values(1,'DAEWOO')
insert into dbo.tblProject(ProjID, ProjName) values(1,'DANTHERM')
Task
CREATE TABLE [dbo].[tbl_Task](
[Task_ID] [int] IDENTITY(1,1) NOT NULL,
[Task_Name] [nchar](500) NULL,
CONSTRAINT [PK_tbl_Task] PRIMARY KEY CLUSTERED
(
[Task_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Group
CREATE TABLE [dbo].[tblGroup](
[gid] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](300) NULL,
[blockcolor] [nvarchar](300) NULL,
[ProjID] [int] NOT NULL,
CONSTRAINT [PK_tblGroup] PRIMARY KEY CLUSTERED
(
[gid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Block
CREATE TABLE [dbo].[tblBlock](
[bid] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](500) NULL,
[StartDate] [nvarchar](100) NULL,
[EndDate] [nvarchar](100) NULL,
[href] [nvarchar](100) NULL,
[ProjID] [int] NOT NULL,
[gid] [int] NOT NULL,
CONSTRAINT [PK_tblBlock] PRIMARY KEY CLUSTERED
(
[bid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Stored Procedure
CREATE PROCEDURE
[dbo].[sptblTask_Insert](
@Task_Name nvarchar(500)
)
AS
INSERT INTO tbl_Task(
Task_Name
)
VALUES (
@Task_Name
)
Web Application
Task
Create a web page and name it task.aspx. Put it: upload file, repeater, 2 buttons
VB Code
Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Partial Class _Default
Inherits System.Web.UI.Page
Dim cn As New SqlClient.SqlConnection()
Dim cmd As New SqlClient.SqlCommand
Protected Sub btn_Upload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_Upload.Click
Try
Dim dirname As String = Page.MapPath("~/App_Data/")
If Directory.Exists(dirname) = False Then
Directory.CreateDirectory(dirname)
End If
Dim strfilename As String() = FileUpload1.PostedFile.FileName.Split("\")
Dim strp As String = strfilename(UBound(strfilename))
If strp = "PM.xml" Then
Dim strtotla As String = strp
FileUpload1.PostedFile.SaveAs(Request.MapPath("~/App_Data/" & "\" & strtotla))
Dim strMessage2 As String = "File was uploaded Successfully"
Dim strScript2 As String = "<script language=JavaScript>"
strScript2 += "alert(""" & strMessage2 & """);"
strScript2 += "</script>"
If (Not Page.IsStartupScriptRegistered("clientScript")) Then
Page.RegisterStartupScript("clientScript", strScript2)
End If
Else
Dim strMessage2 As String = "Please select file with sariak name and xml extension"
Dim strScript2 As String = "<script language=JavaScript>"
strScript2 += "alert(""" & strMessage2 & """);"
strScript2 += "</script>"
If (Not Page.IsStartupScriptRegistered("clientScript")) Then
Page.RegisterStartupScript("clientScript", strScript2)
End If
End If
Catch ex As Exception
End Try
End Sub
Protected Sub btn_Show_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_Show.Click
Dim Tasks As New DataSet
Tasks.ReadXml(Server.MapPath("~/App_Data/PM.xml"))
Dim results As DataRow()
results = Tasks.Tables("Task").Select()
Dim tb As DataTable
tb = results(0).Table.Clone()
Dim dr As DataRow
For Each dr In results
tb.ImportRow(dr)
Next
Me.Repeater1.DataSource = tb
Me.Repeater1.DataBind()
End Sub
Protected Sub btnInsert_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnInsert.Click
Dim strCon As String = "Data Source=. ;Initial Catalog=MyDB ;Integrated Security=True"
cn.ConnectionString = strCon
Dim Tasks As New DataSet
Tasks.ReadXml(Server.MapPath("~/App_Data/PM.xml"))
Dim results As DataRow()
results = Tasks.Tables("Task").Select()
Dim tb As DataTable
tb = results(0).Table.Clone()
Dim dr As DataRow
For Each dr In results
tb.ImportRow(dr)
Next
cn.Open()
cmd.Connection = cn
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "sptblTask_Insert"
Dim Task_Name As New SqlParameter("@Task_Name ", SqlDbType.NVarChar, 3000)
cmd.Parameters.Add(Task_Name)
Task_Name.Direction = ParameterDirection.Input
Dim i2 As Integer = CInt(tb.Rows.Count.ToString())
Dim I As Integer
Try
For I = 0 To i2 - 1
Task_Name.Value = Tasks.Tables("Task").Rows(I).ItemArray(2).ToString()
cmd.ExecuteNonQuery()
Next
Dim strMessage2 As String = "Tasks have been saved successfully"
Dim strScript2 As String = "<script language=JavaScript>"
strScript2 += "alert(""" & strMessage2 & """);"
strScript2 += "</script>"
If (Not Page.IsStartupScriptRegistered("clientScript")) Then
Page.RegisterStartupScript("clientScript", strScript2)
End If
Catch ex As Exception
End Try
End Sub
End Class
C# Code
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
public partial class Task : System.Web.UI.Page
{
SqlConnection cn = new SqlConnection();
SqlCommand cmd = new SqlCommand();
protected void btnInsert_Click(object sender, EventArgs e)
{
DataSet Tasks =new DataSet();
Tasks.ReadXml(Server.MapPath("~/App_Data/PM.xml"));
string strCon = "Data Source=. ;Initial Catalog=MyDB ;Integrated Security=True";
cn.ConnectionString = strCon;
cmd.Connection = cn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sptblTask_Insert";
SqlParameter Task_Name=new SqlParameter("@Task_Name ", SqlDbType.NVarChar, 3000);
cmd.Parameters.Add(Task_Name);
Task_Name.Direction = ParameterDirection.Input;
int i2 = Int32.Parse(Tasks.Tables["Task"].Rows.Count.ToString());
try
{
cn.Open();
for(int i = 0; i<=i2 - 1;i++)
{
Task_Name.Value = Tasks.Tables["Task"].Rows[i].ItemArray[2].ToString();
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{}
finally
{
cn.Close();
}
}
protected void btn_Show_Click(object sender, EventArgs e)
{
DataSet Tasks =new DataSet();
Tasks.ReadXml(Server.MapPath("~/App_Data/PM.xml"));
DataTable tb;
tb = Tasks.Tables["Task"];
this.Repeater1.DataSource = tb;
this.Repeater1.DataBind();
}
protected void btn_Upload_Click(object sender, EventArgs e)
{
try
{
if( ( FileUpload1.PostedFile != null ) && ( FileUpload1.PostedFile.ContentLength > 0 ) )
{
string fn = System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName);
string SaveLocation = Server.MapPath("~/App_Data/") + "\\" + fn;
try
{
FileUpload1.PostedFile.SaveAs(SaveLocation);
Response.Write("The file has been uploaded.");
}
catch ( Exception ex )
{
Response.Write("Error: " + ex.Message);
}
}
else
{
Response.Write("Please select a file to upload.");
}
}
catch{}
}
}
Group
Create a web page and name it Group.aspx. Put it like picture:
VB Code
Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Partial Class Group
Inherits System.Web.UI.Page
Dim cn As New SqlClient.SqlConnection()
Dim cmd As New SqlClient.SqlCommand
Protected Sub btn_Save_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_Save.Click
Dim strCon As String = "Data Source=. ;Initial Catalog=MyDB ;Integrated Security=True"
cn.ConnectionString = strCon
Dim strsql As String
Try
strsql += "insert into tblGroup(name,blockcolor,ProjID) values('"
strsql += Me.txtGroup.Text + "',N'" + Me.drp_Color.Text + "'," + Me.drp_ProjName.SelectedValue.ToString() + ") "
Dim objcommand As New SqlClient.SqlCommand(strsql, cn)
cn.Open()
objcommand.ExecuteNonQuery()
Catch ex As Exception
Finally
cn.Close()
End Try
End Sub
End Class
C# Code
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
public partial class Group : System.Web.UI.Page
{
protected void btn_Save_Click(object sender, EventArgs e)
{
SqlConnection cn=new SqlConnection();
SqlCommand cmd = new SqlCommand();
string strCon="Data Source=. ;Initial Catalog=MyDB ;Integrated Security=True";
cn.ConnectionString = strCon;
string strsql="";
try
{
strsql += "insert into tblGroup(name,blockcolor,ProjID) values('" ;
strsql += this.txtGroup.Text + "',N'" + this.drp_Color.Text + "'," + this.drp_ProjName.SelectedValue.ToString() + ") ";
SqlCommand objcommand=new SqlCommand(strsql, cn);
cn.Open();
objcommand.ExecuteNonQuery();
}
catch
{
}
finally
{
cn.Close();
}
}
}
Block:
Create a web page and name it Block.aspx. Put it like picture:
VB Code
Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Partial Class Block
Inherits System.Web.UI.Page
Dim cn As New SqlClient.SqlConnection()
Dim cmd As New SqlClient.SqlCommand
Protected Sub btn_Save_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_Save.Click
Dim strCon As String = "Data Source=.;Initial Catalog=MyDB ;Integrated Security=True"
cn.ConnectionString = strCon
Dim strsql As String
Dim strHref As String = "DemoDetails.aspx?ActID=" + Me.txtBlock.Text
Try
strsql += "insert into tblBlock(name,StartDate,EndDate,href,ProjID,gid) "
strsql += " values('" + Me.txtBlock.Text + "','" + Me.txtStartDate.Text + "','" + Me.txtEndDate.Text + "','" + strHref + "',"
strsql += Me.ddListProject.SelectedValue.ToString + "," + Me.ddListGroup.SelectedValue.ToString + ")"
Dim objcommand As New SqlClient.SqlCommand(strsql, cn)
cn.Open()
objcommand.ExecuteNonQuery()
Catch ex As Exception
Finally
cn.Close()
End Try
End Sub
End Class
C# Code
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
public partial class Block : System.Web.UI.Page
{
protected void btn_Save_Click(object sender, EventArgs e)
{
SqlConnection cn=new SqlConnection();
SqlCommand cmd = new SqlCommand();
string strCon= "Data Source=.;Initial Catalog=MyDB ;Integrated Security=True";
cn.ConnectionString = strCon;
string strsql="";
string strHref= "DemoDetails.aspx?ActID=" + this.txtBlock.Text;
string strGroup=this.ddListGroup.SelectedValue.ToString() ;
string strProject = this.ddListProject.SelectedValue.ToString();
try
{
strsql += "insert into tblBlock(name,StartDate,EndDate,href,ProjID,gid) values('";
strsql += this.txtBlock.Text + "','" + this.txtStartDate.Text + "','" + this.txtEndDate.Text + "','";
strsql += strHref + "'," + strProject + "," + strGroup + ")";
SqlCommand objcommand = new SqlCommand(strsql, cn);
cn.Open();
objcommand.ExecuteNonQuery();
}
catch
{
}
finally
{
cn.Close();
}
}
}
DemoRequest
Create a web page and name it DemoRequest.aspx. Put it like picture:
VB Code
Partial Class DemoRequest
Inherits System.Web.UI.Page
Protected Sub btnGo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGo.Click
Dim strProj As String = Me.drpProject.SelectedValue.ToString()
Dim strQrt As String = Me.drpQ.SelectedValue.ToString()
Response.Redirect("DemoReport.aspx" & "?Project=" + strProj & "?" + strQrt & "?" + Me.txtYear.Text)
End Sub
End Class
C# Code
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class DemoRequest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnGo_Click(object sender, EventArgs e)
{
string proj = this.drpProject.SelectedValue.ToString();
Response.Redirect("DemoReport.aspx" + "?Project=" + proj + "?" + this.drpQ.SelectedValue.ToString() + "?" + this.txtYear.Text);
}
}
DemoReport:
Create a web page and name it DemoReport.aspx. Put it like picture:
VB Code
Imports System.Data
Imports System.Xml
Imports System.Xml.Schema
Imports System.Data.SqlClient
Partial Class DemoReport
Inherits System.Web.UI.Page
Dim strDemoAnticipate As String
Dim strProj As String
Dim strQrt As String
Dim strYear As String
Dim cn As New SqlClient.SqlConnection()
Dim cmd As New SqlClient.SqlCommand
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strCon As String = "Data Source=. ;Initial Catalog=MyDB ;Integrated Security=True"
cn.ConnectionString = strCon
If Not IsNothing(Request.QueryString("Project")) Then
strDemoAnticipate = Request.QueryString("Project")
End If
Dim strArr As String() = strDemoAnticipate.Split("?")
strProj = strArr(0).ToString()
strQrt = strArr(1).ToString()
strYear = strArr(2).ToString()
Dim custDA As SqlDataAdapter = New SqlDataAdapter("select gid,name,blockcolor from tblGroup where ProjID=" + strProj, cn)
Dim orderDA As SqlDataAdapter = New SqlDataAdapter("SELECT gid,href,StartDate,EndDate,name FROM tblBlock where ProjID=" + strProj, cn)
cn.Open()
Dim custDS As DataSet = New DataSet("NewDataSet")
custDA.Fill(custDS, "group")
orderDA.Fill(custDS, "block")
cn.Close()
Try
Dim custOrderRel As DataRelation = custDS.Relations.Add("CustOrders", custDS.Tables("group").Columns("gid"), custDS.Tables("block").Columns("gid"))
custOrderRel.Nested = True
Catch ex As Exception
End Try
Dim MyXml As String = custDS.GetXml()
EventCalendarControl1.XMLData = MyXml
EventCalendarControl1.BlankGifPath = "trans.gif"
EventCalendarControl1.Year = strYear
EventCalendarControl1.Quarter = strQrt
EventCalendarControl1.BlockColor = ""
EventCalendarControl1.ToggleColor = "#dcdcdc"
EventCalendarControl1.CellHeight = 10
EventCalendarControl1.CellWidth = 10
End Sub
End Class
C# Code
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Xml;
using System.Xml.Schema;
using System.Data.SqlClient;
public partial class DemoReport : System.Web.UI.Page
{
string strDemoAnticipate;
protected void Page_Load(object sender, EventArgs e)
{
string strProj;
string strQrt;
string strYear;
SqlConnection cn =new SqlConnection();
SqlCommand cmd =new SqlCommand();
string strCon = "Data Source=. ;Initial Catalog=MyDB ;Integrated Security=True";
cn.ConnectionString = strCon;
if (Request.QueryString["Project"] != null)
{
strDemoAnticipate = Request.QueryString["Project"];
}
string[] strArr= strDemoAnticipate.Split('?');
strProj = strArr[0].ToString();
strQrt = strArr[1].ToString();
strYear = strArr[2].ToString();
SqlDataAdapter custDA=new SqlDataAdapter("select gid,name,blockcolor from tblGroup where ProjID=" + strProj, cn);
SqlDataAdapter orderDA =new SqlDataAdapter("SELECT gid,href,StartDate,EndDate,name FROM tblBlock where ProjID=" + strProj, cn);
cn.Open();
DataSet custDS=new DataSet("NewDataSet");
custDA.Fill(custDS, "group");
orderDA.Fill(custDS, "block");
cn.Close();
try
{
DataRelation custOrderRel = custDS.Relations.Add("CustOrders", custDS.Tables["group"].Columns["gid"], custDS.Tables["block"].Columns["gid"]);
custOrderRel.Nested = true;
}
catch
{
}
string MyXml = custDS.GetXml();
EventCalendarControl1.XMLData = MyXml;
EventCalendarControl1.BlankGifPath = "trans.gif";
EventCalendarControl1.Year = Int32.Parse(strYear);
EventCalendarControl1.Quarter = Int32.Parse(strQrt);
EventCalendarControl1.BlockColor = "";
EventCalendarControl1.ToggleColor = "#dcdcdc";
EventCalendarControl1.CellHeight = 10;
EventCalendarControl1.CellWidth = 10;
}
}
In Design
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="DemoReport.aspx.vb" Inherits="DemoReport" %>
<%@ Register Assembly="EventCalendarControl" Namespace="EventCalendar" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server" >
<div>
<cc1:EventCalendarControl ID="EventCalendarControl1" runat="server" />
</div>
</form>
</body>
</html>
Try Step by Step
- If you want to know more about event calender DLL please go to this site , and click these links for autocomplete or cascading dropdownlist, they are essential.
- Download event calender DLL from this article, and put it on your bin folder, and solution->Right Click->Add References->Browse->Bin->event calenderDLL->ok
- Refresh and Rebuild your solution: Build Menu > click Rebuild.
- Create database and tables like above, and add some rows which are your tasks or activities.
- Create Web Forms like something that I have described above.
- It is up to you if your tasks are in MS Project or you want to add them directly.
- you have to define your group and block as I mentioned above.
- You can add user profile and keep track time and cost for each group and block.
- Finally you can calculate variance in your project between your prediction and something which have happende in real.
History
Version 1 , 1th April 2012
Version 2, 22th April 2012, I have added C# code
Feedback
Feel free to leave any feedback on this article; it is a pleasure to see your offer and vote about this code. If you have any questions, please do not hesitate to ask me here.
I have been working with different technologies and data more than 10 years.
I`d like to challenge with complex problem, then make it easy for using everyone. This is the best joy.
ICT Master in Norway 2013
Doctorandin at Technische Universität Berlin in Data Scientist ( currently )
-------------------------------------------------------------
Diamond is nothing except the pieces of the coal which have continued their activities finally they have become Diamond.
http://www.repocomp.com/