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.
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:
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
Or
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:
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')
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]
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]
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]
CREATE PROCEDURE [dbo].[sptblTask_Insert]( @Task_Name nvarchar(500) ) AS INSERT INTO tbl_Task( Task_Name ) VALUES ( @Task_Name )
Create a web page and name it task.aspx. Put it: upload file, repeater, 2 buttons
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)) 'Message 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 'Message 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() ' we need to add the rows to a table , because we can't use the arry of rows as a datasource Dim dr As DataRow For Each dr In results tb.ImportRow(dr) Next 'here you can assign the tb to any data presentaion control ,\ 'you can use GridView because of its auto genrate columns , its simple 'for ListView , you need to build the Layout and the ItemTemplate , i did a one for you which has a bad look :) 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() ' we need to add the rows to a table , because we can't use the arry of rows as a datasource 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" '=====START INTERDUSE PARAMETERS========== 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>" 'Show Message If (Not Page.IsStartupScriptRegistered("clientScript")) Then Page.RegisterStartupScript("clientScript", strScript2) End If Catch ex As Exception End Try End Sub End Class
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")); //' we need to add the rows to a table , because we can't use the arry of rows as a datasource string strCon = "Data Source=. ;Initial Catalog=MyDB ;Integrated Security=True"; cn.ConnectionString = strCon; cmd.Connection = cn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "sptblTask_Insert"; //'=====START INTERDUSE PARAMETERS========== 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"]; //'here you can assign the tb to any data presentaion control ,\ //'you can use GridView because of its auto genrate columns , its simple //'for ListView , you need to build the Layout and the ItemTemplate , i did a one for you which has a bad look :) 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); //Note: Exception.Message returns a detailed message that describes the current exception. //For security reasons, we do not recommend that you return Exception.Message to end users in //production environments. It would be better to put a generic error message. } } else { Response.Write("Please select a file to upload."); } } catch{} } }
Create a web page and name it Group.aspx. Put it like picture:
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
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(); } } }
Create a web page and name it Block.aspx. Put it like picture:
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
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(); } } }
Create a web page and name it DemoRequest.aspx. Put it like picture:
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
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); } }
Create a web page and name it DemoReport.aspx. Put it like picture:
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 '==============NESTED================= 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() 'It is very IMPORTANT that you do not allow to change the fields in group and block tables 'Because these names are in the eventcalender DLL and just read xml data which are includde these names. 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
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; //'==============NESTED================= 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; } }
<%@ 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>
Version 1 , 1th April 2012
Version 2, 22th April 2012, I have added C# code
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.