Publishing Microsoft Project and Team Manager on the Internet

Presented by: Sam Brooks

Sam Brooks is a Microsoft Regional Director. His company is a Solution Provider Partner offering training, development, and active web application services.

Phone: (770) 953-8637

Fax: (770) 916-1346

Email: admin@sambrooks.com

Introduction

This session provides the process and methods to publish Microsoft® Project and Team Manager data on the Internet. The examples are built around IE 3.01 as the client browser. Six individual examples show how to publish and update information using different technologies:

Demo1 illustrates how to use the Internet Data Connector (IDC) to browse Team Manager data.

Demo2 illustrates the process of updating the Team Manager database using the HTML layout control.

Demo3 illustrates the process of updating Microsoft Project database using active server pages.

Demo4 illustrates setting up a browser for Microsoft Project data using the advanced data connector (ADC).

Demo5 illustrates the process of updating Microsoft Project data using the ADC.

Demo6 illustrates how to set up Microsoft Project as an OLE server on the web.

Demo1

The first page has a button which calls step1.idc. This idc file pulls task data from the Team Manager database and populates a drop down list in the template file, step1.htx. The value behind the list box is the task ID, but the value shown is the task name. The <select> tag starts the drop down. Next the <%begindetail%> tag starts the loop for data filling. The <option> tag is for each item in the drop down. There is only one in the htx file because as each option is filled from the database. It cycles through each record and adds a new <option> tag. The taskID is inside the option tag and the taskname is outside so the user will see it. The <%enddetail%> tag and the </select> tags end the drop down list.

The second idc file takes the value from the previous drop down list (the taskID) and returns start, finish, and fixed cost information about the task. There is only one record returned and it goes into a table.

Source Code

Default.htm

<HTML>
<HEAD>
<TITLE>Browse Team Manager Data with IDC</TITLE>
</HEAD>
<BODY bgcolor="white">
<center><font color="navy" size="6">Use this form to browse Team Manager Data with the Internet Database Connector.</font></center>
<font size="4" color="navy">Step 1: Click the "View Tasks" button to see all of the tasks
<form method="post" action="step1.idc">
<input type="submit" value="View Tasks">
</form>
</BODY>
</HTML>

Step1.htx

<HTML>
<HEAD>
<TITLE>Browse Team Manager Data with IDC</TITLE>
</HEAD>
<BODY bgcolor="white">
<center><font color="navy" size="6">Use this form to browse Team Manager Data with the Internet Database Connector.</font></center>
<font size="4" color="navy">Step 1: Click the "View Tasks" button to see all of the tasks
<form method="post" action="step1.idc?">
<input type="submit" value="View Tasks">
</form>
<hr>
Step 2: Select a Task and click the "View Task Details" button to see more data
<form method="post" action="step2.idc?">
<select name="tasks" size="1">
<%begindetail%>
<option value="<%TaskID%>"><%Name%>
<%enddetail%>
</select>
<input type="submit" value="View Task Details">
</form>
</font>
</BODY>
</HTML>

Step1.idc

DataSource: Team Manager Database
Template: step1.htx
SQLStatement:
+SELECT TaskID, Name FROM Task
+ WHERE TaskID <> 0

Step2.htx

<HTML>
<HEAD>
<TITLE>Browse Team Manager Data with IDC</TITLE>
</HEAD>
<BODY bgcolor="white">
<center><font color="navy" size="6">Use this form to browse Team Manager Data with the Internet Database Connector.</font></center>
<p><font size="4" color="navy">Click the "View Tasks" button to see all of the tasks</font>
<form method="post" action="step1.idc?">
<input type="submit" value="View Tasks">
</form>
<hr>
<font size="4" color="navy">TaskID: <%TaskID%> Name: <%Name%>
</font>
<table cellpadding="1" border="1">
<tr><td><font color="navy" size="4">Start</td><td><font color="navy" size="4">Finish</td><td><font color="navy" size="4">Cost</td></font></tr>
<tr><td><font color="navy" size="4"><%UserStartDate%></td><td><font color="navy" size="4"><%UserEndDate%></td><td><font color="navy" size="4"><%FixedCost%></td></font></tr>
</table>
</form>
</font>
</BODY>
</HTML>

Step2.idc

DataSource: Team Manager Database
Template: step2.htx
SQLStatement:
+SELECT TaskID, Name, UserStartDate, UserEndDate, FixedCost FROM Task

+ WHERE TaskID=%tasks%

Demo2

This demo uses the HTML layout control. Usually, the HTML layout control's alxpath property points to an alx file, an ActiveX Layout control file. In this example, the alxpath property points to an idc. This idc, in turn points to the usual htx template to fill in the data. However, the htx file is actually an alx file that has been renamed. Use the ActiveX Control Pad to view the idcdemo1.htx file. It is a normal alx file. Click on the Script wizard button. Then click on the Layout2 object on the left and then on its OnLoad event. Click Code View at the bottom to view the code. Here is the <%begindetail%> tag. Data returned from the database is added to the list box. Count is row. The second value represents the number of columns. Five columns are added, but only one is visible to the user. In the Click event of the list box, the text boxes are filled with data from the list box and made visible.

Task name can be changed. All fields cannot be updated in this example. The 'Update this Task' button, calls another idc file. Preview the code in the same way as before. VBScript has a replace function which looks for a string within a string and replaces it with an additional string. This function is used to replace spaces with '+' signs. The idc, like a cgi, recognizes the plus sign as a space. You would see this in the URL of a search in any search engine. At this point there is a string to pass to the idc file. This idc updates the task whose ID matches the ID in the text box. It calls is the default.htm file which contains the layout control. In conclusion, the taskupdate.idc file updates the database and then opens the default.htm file. The default.htm file has the HTML layout which alxpath property is set to an idc file in order that the tasks are again selected for display. After the taskupdate.idc file updates the database, it refreshes the open htm file.

Source Code

Default.htm

<HTML>
<HEAD>
<TITLE>Task Information</TITLE>
</HEAD>
<BODY bgcolor="white">
<center><font size="6" color="navy">Update the Team Manager Database</font></center>
<OBJECT CLASSID="CLSID:812AE312-8B8E-11CF-93C8-00AA00C08FDF"
ID="Layout1_alx" STYLE="LEFT:0;TOP:0" Width="0" Height="0">
<PARAM NAME="ALXPATH" REF VALUE="idcdemo1.idc?">
</OBJECT>
</BODY>
</HTML>

Idcdemo1.htx

<SCRIPT LANGUAGE="VBScript">
<!--
Sub Layout2_OnLoad()
dim TaskArray(3,26)
Count=0
<%begindetail%>
ListBox1.Additem()
ListBox1.List(Count,0)="<%TaskID%>"
ListBox1.List(Count,1)="<%Name%>"
ListBox1.List(Count,2)="<%UserStartDate%>"
ListBox1.List(Count,3)="<%UserEndDate%>"
ListBox1.List(Count,4)="<%FixedCost%>"
Count=Count+1
<%enddetail%>
end sub
-->
</SCRIPT>
<SCRIPT LANGUAGE="VBScript">
<!--
dim Count
Sub ListBox1_Click()
btnUpdate.visible = true
Label2.visible = true
Label4.visible = true
Label5.visible = true
Label6.visible = true
Label7.visible = true
Label8.visible = true
txtTaskID.Text= ListBox1.List(Listbox1.ListIndex,0)
txtTaskID.visible = true
txtName.Text= ListBox1.List(ListBox1.ListIndex,1)
txtName.visible = true
txtCost.Text = FormatCurrency(ListBox1.List(Listbox1.ListIndex,4),2)
txtCost.visible = true
txtEndDate.Text = ListBox1.List(Listbox1.ListIndex,3)
txtEndDate.visible = true
txtStartDate.Text = ListBox1.List(Listbox1.ListIndex,2)
txtStartDate.Visible = true
end sub
-->
</SCRIPT>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub btnUpdate_Click()
NameString=txtName.Value
NewName=Replace(NameString," ","+")
Window.location.href = "taskupdate.idc?txtTaskID="&txtTaskID&"&txtName="&NewName
end sub
-->
</SCRIPT>
<DIV BACKGROUND="#ffffff" ID="Layout2" STYLE="LAYOUT:FIXED;WIDTH:473pt;HEIGHT:300pt;">
    <OBJECT ID="Label1"
     CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:25pt;LEFT:25pt;WIDTH:58pt;HEIGHT:25pt;ZINDEX:0;">
        <PARAM NAME="ForeColor" VALUE="8388608">
        <PARAM NAME="BackColor" VALUE="16777215">
        <PARAM NAME="Caption" VALUE="Tasks">
        <PARAM NAME="Size" VALUE="2046;882">
        <PARAM NAME="FontName" VALUE="Times New Roman">
        <PARAM NAME="FontEffects" VALUE="1073741825">
        <PARAM NAME="FontHeight" VALUE="360">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="FontWeight" VALUE="700">
    </OBJECT>
    <OBJECT ID="Label2"
     CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:25pt;LEFT:215pt;WIDTH:58pt;HEIGHT:25pt;DISPLAY:NONE;ZINDEX:1; ">
        <PARAM NAME="ForeColor" VALUE="8388608">
        <PARAM NAME="BackColor" VALUE="16777215">
        <PARAM NAME="Caption" VALUE="Details">
        <PARAM NAME="Size" VALUE="2046;882">
        <PARAM NAME="FontName" VALUE="Times New Roman">
        <PARAM NAME="FontEffects" VALUE="1073741825">
        <PARAM NAME="FontHeight" VALUE="360">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="FontWeight" VALUE="700">
    </OBJECT>
    <OBJECT ID="txtStartDate"
     CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:107pt;LEFT:281pt;WIDTH:83pt;HEIGHT:16pt;TABINDEX:3;DISPLAY:NO NE;ZINDEX:2;">
        <PARAM NAME="VariousPropertyBits" VALUE="746604571">
        <PARAM NAME="Size" VALUE="2928;564">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
    </OBJECT>
    <OBJECT ID="txtEndDate"
     CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:132pt;LEFT:281pt;WIDTH:83pt;HEIGHT:16pt;TABINDEX:4;DISPLAY:NO NE;ZINDEX:3;">
        <PARAM NAME="VariousPropertyBits" VALUE="746604571">
        <PARAM NAME="Size" VALUE="2928;564">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
    </OBJECT>
    <OBJECT ID="txtCost"
     CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:157pt;LEFT:281pt;WIDTH:83pt;HEIGHT:16pt;TABINDEX:5;DISPLAY:NO NE;ZINDEX:4;">
        <PARAM NAME="VariousPropertyBits" VALUE="746604571">
        <PARAM NAME="Size" VALUE="2928;564">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
    </OBJECT>
    <OBJECT ID="Label4"
     CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:107pt;LEFT:190pt;WIDTH:83pt;HEIGHT:17pt;DISPLAY:NONE;ZINDEX:5 ;">
        <PARAM NAME="ForeColor" VALUE="8388608">
        <PARAM NAME="BackColor" VALUE="16777215">
        <PARAM NAME="Caption" VALUE="Start Date">
        <PARAM NAME="Size" VALUE="2928;600">
        <PARAM NAME="FontName" VALUE="Times New Roman">
        <PARAM NAME="FontEffects" VALUE="1073741825">
        <PARAM NAME="FontHeight" VALUE="360">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="FontWeight" VALUE="700">
    </OBJECT>
    <OBJECT ID="Label5"
     CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:132pt;LEFT:190pt;WIDTH:74pt;HEIGHT:17pt;DISPLAY:NONE;ZINDEX:6 ;">
        <PARAM NAME="ForeColor" VALUE="8388608">
        <PARAM NAME="BackColor" VALUE="16777215">
        <PARAM NAME="Caption" VALUE="End Date">
        <PARAM NAME="Size" VALUE="2611;600">
        <PARAM NAME="FontName" VALUE="Times New Roman">
        <PARAM NAME="FontEffects" VALUE="1073741825">
        <PARAM NAME="FontHeight" VALUE="360">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="FontWeight" VALUE="700">
    </OBJECT>
    <OBJECT ID="Label6"
     CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:157pt;LEFT:190pt;WIDTH:58pt;HEIGHT:17pt;DISPLAY:NONE;ZINDEX:7 ;">
        <PARAM NAME="ForeColor" VALUE="8388608">
        <PARAM NAME="BackColor" VALUE="16777215">
        <PARAM NAME="Caption" VALUE="Cost">
        <PARAM NAME="Size" VALUE="2046;600">
        <PARAM NAME="FontName" VALUE="Times New Roman">
        <PARAM NAME="FontEffects" VALUE="1073741825">
        <PARAM NAME="FontHeight" VALUE="360">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="FontWeight" VALUE="700">
    </OBJECT>
    <OBJECT ID="btnUpdate"
     CLASSID="CLSID:D7053240-CE69-11CD-A777-00DD01143C57" STYLE="TOP:190pt;LEFT:281pt;WIDTH:74pt;HEIGHT:25pt;TABINDEX:9;DISPLAY:NO NE;ZINDEX:8;">
        <PARAM NAME="Caption" VALUE="Update this Task">
        <PARAM NAME="Size" VALUE="2611;882">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="ParagraphAlign" VALUE="3">
    </OBJECT>
    <OBJECT ID="Label7"
     CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:83pt;LEFT:190pt;WIDTH:83pt;HEIGHT:17pt;DISPLAY:NONE;ZINDEX:9; ">
        <PARAM NAME="ForeColor" VALUE="8388608">
        <PARAM NAME="BackColor" VALUE="16777215">
        <PARAM NAME="Caption" VALUE="Name">
        <PARAM NAME="Size" VALUE="2928;600">
        <PARAM NAME="FontName" VALUE="Times New Roman">
        <PARAM NAME="FontEffects" VALUE="1073741825">
        <PARAM NAME="FontHeight" VALUE="360">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="FontWeight" VALUE="700">
    </OBJECT>
    <OBJECT ID="txtName"
     CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:83pt;LEFT:281pt;WIDTH:173pt;HEIGHT:16pt;TABINDEX:11;DISPLAY:N ONE;ZINDEX:10;">
        <PARAM NAME="VariousPropertyBits" VALUE="746604571">
        <PARAM NAME="Size" VALUE="6103;564">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
    </OBJECT>
    <OBJECT ID="Label8"
     CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:58pt;LEFT:190pt;WIDTH:83pt;HEIGHT:17pt;DISPLAY:NONE;ZINDEX:11 ;">
        <PARAM NAME="ForeColor" VALUE="8388608">
        <PARAM NAME="BackColor" VALUE="16777215">
        <PARAM NAME="Caption" VALUE="ID">
        <PARAM NAME="Size" VALUE="2928;600">
        <PARAM NAME="FontName" VALUE="Times New Roman">
        <PARAM NAME="FontEffects" VALUE="1073741825">
        <PARAM NAME="FontHeight" VALUE="360">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="FontWeight" VALUE="700">
    </OBJECT>
    <OBJECT ID="txtTaskID"
     CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:58pt;LEFT:281pt;WIDTH:33pt;HEIGHT:16pt;TABINDEX:13;DISPLAY:NO NE;ZINDEX:12;">
        <PARAM NAME="VariousPropertyBits" VALUE="746604569">
        <PARAM NAME="Size" VALUE="1164;564">
        <PARAM NAME="FontEffects" VALUE="1073750016">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
    </OBJECT>
    <OBJECT ID="ListBox1"
     CLASSID="CLSID:8BD21D20-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:58pt;LEFT:17pt;WIDTH:155pt;HEIGHT:113pt;TABINDEX:0;ZINDEX:13; ">
        <PARAM NAME="ScrollBars" VALUE="3">
        <PARAM NAME="DisplayStyle" VALUE="2">
        <PARAM NAME="Size" VALUE="5468;3986">
        <PARAM NAME="BoundColumn" VALUE="2">
        <PARAM NAME="ColumnCount" VALUE="5">
        <PARAM NAME="cColumnInfo" VALUE="5">
        <PARAM NAME="MatchEntry" VALUE="0">
        <PARAM NAME="FontCharSet" VALUE="0">
        <PARAM NAME="FontPitchAndFamily" VALUE="2">
        <PARAM NAME="Width" VALUE="0;5469;0;0;0">
    </OBJECT>
</DIV>

Idcdemo1.idc

DataSource: Team Manager Database
Template: idcdemo1.htx
SQLStatement:
+SELECT TaskID, Name, UserStartDate, UserEndDate, FixedCost FROM Task
+ WHERE TaskID <> 0

Taskupdate.idc

DataSource: Team Manager Database
Template: default.htm
SQLStatement:
+Update Task Set Name = '%txtname%'

+ WHERE TaskID = %txttaskid%;

Demo3

This demo uses Active Data Objects. ADO is a component that is loaded when ASP is installed. There are few forms in this page. Each one refreshes this page. Only the first one will appear every time. The others check which form was called to determine if it will appear. The update Code only runs after clicking the update button, which submits the update form.

First a connection to the Multiple Microsoft Project Database is opened. This uses the ADO.Connection conn object. Next a SQL statement is created to get all tasks where ID is 0. These tasks represent the project names. The ProjectKey uniquely identifies each project in the database. A list box is filled with this data. This is almost the same way it is done with idc. This form is named "ProjectSelect." There is a hidden field (<input type="hidden" name="hname" value="projselect"> which points to the form. Again, starting with the <select> tag and next putting the <option> tag inside a loop that cycles through the data that is returned from the query. A conditional branch tests for the calling form field "ProjectKey" being equal to the recordset field ProjectKey. If so, it becomes the selected project. The last tag is another <input> tag. This tag is an image type that acts like a submit button when clicked. It submits the form.

The next form will appear only if another form has been called. It selects Microsoft Project name, start and finish data where the projectKey matches the ProjectKey in the previous list box. The start and finish times for the entire project populate the table. The remaining tasks populate a list box. Now there are two hidden text boxes. One is hname to hold the form name. The other is text box is name ProjectKey to hold the selected project.

The next form will appear only if a task is selected or updated. It receives task information for the selected/updated task and enters it in a table with editable text boxes. This form's hidden text box named hname and has the value "update" so that the update code will run if the form is submitted.

This update code receives the taskID and ProjectKey fields from the bottom form and updates all of the task information to match the values input in the text boxes. Finally, the rest of the forms are displayed to reflect updated information.

Source Code

Default.htm

<HTML>
<HEAD>
<TITLE>Update Project Database with ASP</TITLE>
<meta HTTP-EQUIV="Refresh" Content="1; URL=demo3.asp">
</HEAD>
<BODY bgcolor="white">
</BODY>
</HTML>

Demo3.asp

<%@ LANGUAGE = VBScript %>
<HTML>
<HEAD>
<TITLE>Project Information from a Database</TITLE></HEAD>
<body bgcolor="white">
<center>
<font size="6" color="navy">Manipulate Project Data from the Web using Active Server Pages and Active Data Objects</font>
<%
'This Active Server Page accesses a database created from a
'Microsoft Project File. IIS 3.0 with Active Server Pages and
'OLE DB must be installed on the server. The code is written in VBScript.
'ActiveX Data Objects are used to view and manipulate the data.
'14
'Create the connection object using ADO
Set Conn = Server.CreateObject("ADODB.Connection")
'-----Start UPDATE Code-----
'if the Update form was called, run the UPDATE SQL
if request.form("hname") = "update" then
'Update the name field from the name text box on the form
SQL = "UPDATE Tasks SET Name = '" & request.form("name") & "'"
SQL = SQL & ", Duration = '" & request.form("duration") & "'"
SQL = SQL & ", Start = #" & request.form("start") & "#"
SQL = SQL & ", Finish = #" & request.form("finish") &"#"
SQL = SQL & " WHERE TaskID = " & cint(request.form("TaskID"))
SQL = SQL & " AND ProjectKey = '" & request.form("ProjectKey") & "'"
'29
'Open the connection to the project database
Conn.open "Multiple Project Database", "", ""
'Execute the SQL to update the record
set rs = Conn.Execute(SQL)
'Close the connection
Conn.close
end if
'-----End UPDATE Code-----
'Open the connection to the project database
Conn.open "Multiple Project Database", "", ""
'Create the SQL to retrieve all project information and fill the combo box
SQL = "SELECT ProjectKey, Name, TaskID,Start, Finish FROM Tasks WHERE TaskID = 0"
'Execute the SQL and create a recordset
set rs = Conn.Execute(SQL)
'48
%>
<!-- Form with combo box for task names and button to get info -->
<form method="post" action="demo3.asp" name="ProjectSelect">
<img src="images/choosproj.gif" border="0" alt="Choose a Project Below:">
<br> 
<!-- Hidden control tells us which form was called (if any) -->
<input type="hidden" name="hname" value="ProjSelect">
<select name="ProjectKey" size="1">
<%
'61
'For each record, add an OPTION tag to the SELECT tag
Do While Not RS.EOF %>
<option value="<% =rs("ProjectKey") %>"
<%
'If we are retrieving detail information, make sure the correct
'Task is selected in the combo box (add SELECTED keyword)
if Request.form("ProjectKey") = cstr(rs("ProjectKey")) then
%>
 selected
<%
end if
%>
>
<% =rs("Name") %>
<% rs.movenext
'78	
Loop
rs.close
'Conn.close
%>
</select><br>
<input type="image" src="images/projdet.gif">
<hr>
</form>
<% if request.form("hname") <> "" then
'Conn.Open "Multiple Project Database", "", ""
SQL = "Select Name, ProjectKey, TaskID, Start, Finish FROM Tasks WHERE ProjectKey = '" & request.form("ProjectKey") & "'"
Set rs=Conn.Execute(SQL)
'93
%>
<form method="Post" Action="demo3.asp" name="TaskSelect">
<table border="1" cellpadding="5"><tr><td align="center" rowspan="2">
<font size="5" color="navy">Details for <% =rs("Name") %></font>
</td>
<input name="hname" type="hidden" value="TaskSelect">
<td align="center">
<img src="images/StartDate.gif" border="0">
</td><td align="center">
<img src="images/FinDate.gif" border="0">
</td></tr><tr><td>
<font size="5" color="navy"><% =rs("Start") %></font>
</td><td>
<font size="5" color="navy"><% =rs("Finish") %></font>
</td></tr></table>
<table border="1" cellpadding="5"><tr><td align="center">
<font size="5" color="navy">Tasks for <% =rs("Name") %></font>
<input type="hidden" name="ProjectKey" Value="<% =rs("ProjectKey") %>">
</td><td align="center">
<select name="TaskID" size="1">
<%
'For each record, add an OPTION tag to the SELECT tag
Do While Not RS.EOF
if rs("TaskID") = 0 then 
rs.movenext
end if
%>
<option value="<% =rs("TaskID") %>"
<%
'If we are retrieving detail information, make sure the correct
'Task is selected in the combo box (add SELECTED keyword)
if Request.form("TaskID") = cstr(rs("TaskID")) then
%>
 selected
<%
end if
%>
>
<% =rs("Name") %>
<% rs.movenext
	
Loop
rs.close
'Conn.close
%>
</select><br>
<input type="image" src="images/taskdet.gif">
</td></tr></table>
<hr>
</form>
<% if request.form("hname") = "TaskSelect" or request.form("hname") = "update" then
'Conn.open "Multiple Project Database", "", ""
SQL = "SELECT * FROM Tasks WHERE TaskID=" & Request.Form("TaskID")
SQL = SQL & " and ProjectKey = '" & request.form("ProjectKey") & "'"
set rs = Conn.Execute(SQL)
%>
<form method="post" action="demo3.asp">
<!-- Hidden control identifies the Update form -->
<input name="hname" type="hidden" value="update">
<input type="hidden" name="ProjectKey" value="<% =rs("ProjectKey") %>">
<table border="1" cellpadding="5"><tr><td align="center">
<img src="images/id.gif" border="0" alt="ID"</td><td align="left">
<img src="images/taskname.gif" border="0" alt="Task Name"></td><td align="center">
<img src="images/duration.gif" border="0" alt="Duration"></td><td align="center">
<img src="images/StartDate.gif" border="0" alt="Start Date"></td><td align="center">
<img src="images/FinDate.gif" border="0" alt="Finish Date"></td></tr><tr><td>
<!-- Fill the table with values from the query in text boxes -->
<input type="hidden" name="TaskID" value="<% =rs("TaskID")%>">
<font size="5" color="navy"><% =rs("TaskID") %></font>
</td><td align="center">
<input type="text" size="30" name="name" value="<% =rs("Name")%>">
</td><td align="center">
<input type="text" size="5" name="duration" value="<% =rs("Duration")%>">
</td><td align="center">
<input type="text" size="20" name="start" value="<% =rs("Start")%>">
</td><td align="center">
<input type="text" size="20" name="finish" value="<% =rs("Finish")%>">
</td></tr></table>
<br>
<%
rs.close 
'conn.close
%>
<center>
<input type="image" src="images/update.gif">
</center>
<hr>
<%
end if
end if
%>
</form>
</BODY>
</HTML>

Images (Folder)

Choosproj.gif Chootask.gif Duration.gif Findate.gif Id.gif
Projdef.gif Startdate.gif Taskdet.gif Taskname.gif Update.gif

Demo 4 & Demo 5

Demo 4

This demo uses the Advanced Data connector to browse project data. The DSN is "Single Project Database" It is the SoftDev.mpp file saved in its own database file, "Single Project.mdb" There are two ActiveX Controls on the page designated with <object> and </object> tags. The Sheridan Grid control is used to display the data. When the page is loaded, a message box comes prompts for demos only. This control’s ID is'Grid1.' There are a few parameters to investigate: AllowNew, AllowUpdate, and AllowDelete are all initialized as false. Nextr is the Advanced Data Connector, where the id=SControl. The code base attribute displays whether to download it if the control does not exist on the client. The Bindings param displays Grid1. This value places the data returned by the ADC in the grid control. There is also the connect string which contains the data source name, user id, and password. The server name is retrieved dynamically from the<%servervariables%> tag.

Preview the SUB Load event. This event sends a query to the database which returns the columns, but no rows of data. This sets up the grid with column names, but no data. Select name, duration, start and finish from Tasks where 2>1. SControl.Refresh gets the data and returns it toGrid1. The Clear button clears the search text boxes.

The Find button builds the SQL string based on the values in the textboxes. If the text box is not blank, it is added to the SQL statement. When the database is queried, the data is returned to the Grid control. If all text boxes are left blank, all tasks will be returned in the grid. The buttons below the grid have code to navigate the data.

Source Code

Default.htm

<HTML>
<HEAD>
<TITLE>Update Project Database with ASP</TITLE>
<meta HTTP-EQUIV="Refresh" Content="1; URL=demo4.asp">
</HEAD>
<BODY bgcolor="white">
</BODY>
</HTML>

Demo4.asp

<HTML>
<HEAD>
<TITLE>Browsing Project Data with ADC</TITLE>
</HEAD>
<!--
	Purpose:	Browsing Team Manager data with Advanced Data Connector
	Written By:	Brian Castor, Samuel Brooks Corporation
	Date:		January, 1997
-->
<BODY LANGUAGE="VBScript" onload="Load" bgcolor="white">
<tr>
	<td align="center" width="40%">
        <table border="2" cellpadding="7" cellspacing="7">
            <tr>
                <td width="100%"><font color="#160B5A"><font
                size="4"><strong>Project Data with the Advanced Data Connector</strong></font></font></td>
            </tr>
        </table>
        </td>
</tr>
<hr>
<h2><font color = "#160B5A">Search Parameters</h2>
<h5><font color = "#160B5A">Please enter one or more search patterns and press FIND to search.</h5>
<FONT COLOR = "#160B5A"><B>
<PRE> Name              <INPUT NAME="SName" SIZE=30> </PRE>
<PRE> Duration          <INPUT NAME="SDuration"  SIZE=30> </PRE>
<PRE> Start             <INPUT NAME="SStart" SIZE=30> </PRE>
<PRE> Finish            <INPUT NAME="SFinish" SIZE=30> </PRE>
<!-- 
	Command button options:
	-----------------------
	Find		Submit a search request to the database.
	Clear		Clear the QBE fields (labor saving function only).
-->
<INPUT TYPE=BUTTON NAME="Find" 		VALUE="Find">
<INPUT TYPE=BUTTON NAME="Clear" 	VALUE="Clear">
<hr>
<h2><font color = "#400040">Search Results</h2>
</B>
<br>
<!-- 
	This Sheridan DataGrid control (SGrid) are initialized not to
	allow changes to the data
-->
<OBJECT CLASSID="clsid:BC496AE0-9B4E-11CE-A6D5-0000C0BE9395" 
	ID=Grid1
	CODEBASE="HTTP://<%=Request.ServerVariables("SERVER_NAME")%>/MSADC/Sampl es/Sheridan.cab"  
	HEIGHT= 125
	Width = 600>
	<PARAM NAME="AllowAddNew"   VALUE="FALSE">
	<PARAM NAME="AllowDelete"   VALUE="FALSE">
	<PARAM NAME="AllowUpdate"   VALUE="FALSE">
	<PARAM NAME="DefColWidth"   VALUE="4000">
	<PARAM NAME="BackColor"     VALUE="-2147483643">
	<PARAM NAME="BackColorOdd"  VALUE="-2147483643">
	<PARAM NAME="ForeColorEven" VALUE="1">
</OBJECT>
<br>
<br>
<INPUT TYPE=BUTTON NAME="First" 	VALUE="First">
<INPUT TYPE=BUTTON NAME="Prev" 		VALUE="Previous">
<INPUT TYPE=BUTTON NAME="Next"		VALUE="Next">
<INPUT TYPE=BUTTON NAME="Last"		VALUE="Last">
<hr>
<!-- Non-visual controls - AdvancedDataControl -->
<OBJECT CLASSID="clsid:9381D8F2-0288-11d0-9501-00AA00B911A5"
	ID="SControl"
	CODEBASE="HTTP://<%=Request.ServerVariables("SERVER_NAME")%>/MSADC/msadc 10.cab"  
	WIDTH=1 HEIGHT=1>
	<PARAM NAME="BINDINGS" VALUE="Grid1;">
	<PARAM NAME="Connect" VALUE="DSN=Single Project Database;UID=;PWD=;">
	<PARAM NAME="Server" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">
</OBJECT>
<!-- VBS scripting for composing queries and retrieving search results. -->
<SCRIPT LANGUAGE="VBScript">
Dim myQuery
SUB Load
	Grid1.CAPTION = "Project Data"
	'Initialize data grid with column names only.
	SControl.SQL = "Select Name, Duration, Start, Finish from Tasks where 2 < 1"
	SControl.Refresh
END SUB
'Implement "Clear" button - clears all of the QBE fields in preparation for a new "Find."
SUB Clear_OnClick
	SName.Value=""
	SDuration.Value=""
	SStart.Value=""
	SFinish.Value=""
END SUB
'Implement "Find" button - composes a dynamic SQL query to be processed by the database and returns matching records to be bound to the SGrid object.
SUB Find_OnClick
	myQuery = "Select Name, Duration, Start, Finish from Tasks"
	'Check QBE fields and compose a dynamic SQL query.
	IF (SName.Value <> "") THEN
		myQuery = myQuery + " where Name like '" + SName.Value + "%'"
	END IF
	IF (SDuration.Value <> "") THEN
		myQuery = myQuery + " where Duration like '" + SDuration.Value + "%'"
	END IF
	IF (SStart.Value <> "") THEN
		myQuery = myQuery + " where Start like '" + SStart.Value + "%'"
	END IF
	IF (SFinish.Value <> "") THEN
		myQuery = myQuery + " where Finish like '" + SFinish.Value + "%'"
	END IF
	
	'Set the new query and then refresh the SControl so that the new results are displayed.
	SControl.SQL = myQuery
	SControl.Refresh
	
END SUB
'Navigation subroutines - based on currency changes to AdvancedDataControl (SControl).
'Move to the first record in the bound recordset.
SUB First_OnClick
  	SControl.MoveFirst
END SUB
'Move to the next record from the current position in the bound recordset.
SUB Next_OnClick
  	SControl.MoveNext
END SUB
'Move to the previous record from the current position in the bound recordset.
SUB Prev_OnClick
  	SControl.MovePrevious
END SUB
'Move to the last record in the bound recordset.
SUB Last_OnClick
  	SControl.MoveLast
END SUB
</SCRIPT>
<BR>
<font color = "#400040">This site powered by Microsoft Advanced Data Connector. </font>
</BODY>
</HTML>

Demo 5

This demo is similar to demo 4 with a significant exceptions. The data is a SQL Server database because the "for update" command is used to allow updates. There are command buttons to modify the database and cancel any pending changes. Investigate the Grid1 control properties. AllowNew, Update, and Delete are all true.

Preview the new code. SUB Update_OnClick Submit changes sends update commands to the server for each cell that has been changed in the grid since the last update or select. The database is refreshed and requeried.

SUB Cancel_OnlickCancels any changes in the grid.

Source Code

Default.htm

<HTML>
<HEAD>
<TITLE>Update Project Database with ASP</TITLE>
<meta HTTP-EQUIV="Refresh" Content="1; URL=demo5.asp">
</HEAD>
<BODY bgcolor="white">
</BODY>
</HTML>

Demo5.asp

<HTML>
<HEAD>
<TITLE>Updating Project Data with ADC</TITLE>
</HEAD>
<!--
	Purpose:	Updating Project data with Advanced Data Connector
	Written By:	Brian Castor, Samuel Brooks Corporation
	Date:		January, 1997
-->
<BODY LANGUAGE="VBScript" onload="Load" bgcolor="white">
<tr>
	<td align="center" width="40%">
        <table border="2" cellpadding="7" cellspacing="7">
            <tr>
                <td width="100%"><font color="#160B5A"><font
                size="4"><strong>Updating Project Data with the Advanced Data Connector</strong></font></font></td>
            </tr>
        </table>
        </td>
</tr>
<hr>
<h2><font color = "#160B5A">Search Parameters</h2>
<h5><font color = "#160B5A">Please enter one or more search patterns and press FIND to search.</h5>
<FONT COLOR = "#160B5A"><B>
<PRE> Name              <INPUT NAME="SName" SIZE=30> </PRE>
<PRE> Duration          <INPUT NAME="SDuration"  SIZE=30> </PRE>
<PRE> Start             <INPUT NAME="SStart" SIZE=30> </PRE>
<PRE> Finish            <INPUT NAME="SFinish" SIZE=30> </PRE>
<!-- 
	Command button options:
	-----------------------
	Find		Submit a search request to the database.
	Clear		Clear the QBE fields (labor saving function only).
	Update Tasks	Send updated "task" back to the database.
	Cancel Changes	Undo all changes since the last Update Tasks.
-->
<INPUT TYPE=BUTTON NAME="Find" 		VALUE="Find">
<INPUT TYPE=BUTTON NAME="Clear" 	VALUE="Clear">
<INPUT TYPE=BUTTON NAME="Update" 	VALUE="Update Tasks">
<INPUT TYPE=BUTTON NAME="Cancel" 	VALUE="Cancel Changes">
<hr>
<h2><font color = "#400040">Search Results</h2>
</B>
<br>
<!-- 
	This Sheridan DataGrid control (SGrid) are initialized to
	allow changes to the data - these changes will be saved
	to the database when the Update Tasks button is pressed. 
-->
<OBJECT CLASSID="clsid:BC496AE0-9B4E-11CE-A6D5-0000C0BE9395" 
	ID=Grid1
	CODEBASE="HTTP://<%=Request.ServerVariables("SERVER_NAME")%>/MSADC/Sampl es/Sheridan.cab"  
	HEIGHT= 125
	Width = 495>
	<PARAM NAME="AllowAddNew"   VALUE="TRUE">
	<PARAM NAME="AllowDelete"   VALUE="TRUE">
	<PARAM NAME="AllowUpdate"   VALUE="TRUE">
	<PARAM NAME="BackColor"     VALUE="-2147483643">
	<PARAM NAME="BackColorOdd"  VALUE="-2147483643">
	<PARAM NAME="ForeColorEven" VALUE="1">
</OBJECT>
<br>
<br>
<INPUT TYPE=BUTTON NAME="First" 	VALUE="First">
<INPUT TYPE=BUTTON NAME="Prev" 		VALUE="Previous">
<INPUT TYPE=BUTTON NAME="Next"		VALUE="Next">
<INPUT TYPE=BUTTON NAME="Last"		VALUE="Last">
<hr>
<!-- Non-visual controls - AdvancedDataControl -->
<OBJECT CLASSID="clsid:9381D8F2-0288-11d0-9501-00AA00B911A5"
	ID="SControl"
	CODEBASE="HTTP://<%=Request.ServerVariables("SERVER_NAME")%>/MSADC/msadc 10.cab"  
	WIDTH=1 HEIGHT=1>
	<PARAM NAME="BINDINGS" VALUE="Grid1;">
	<PARAM NAME="Connect" VALUE="DSN=Project;UID=sa;PWD=;">
	<PARAM NAME="Server" VALUE="http://<%=Request.ServerVariables("SERVER_NAME")%>">
</OBJECT>
<!-- VBS scripting for composing queries, updating profiles, and retrieving search results. -->
<SCRIPT LANGUAGE="VBScript">
Dim myQuery
SUB Load
	Grid1.CAPTION = "Project Data"
	'Initialize data grid with column names only.
	SControl.SQL = "Select Name, Duration, Start, Finish from Tasks where 2 < 1 for browse"
	SControl.Refresh
END SUB
'Implement "Clear" button - clears all of the QBE fields in preparation for a new "Find."
SUB Clear_OnClick
	SName.Value=""
	SDuration.Value=""
	SStart.Value=""
	SFinish.Value=""
END SUB
'Implement "Find" button - composes a dynamic SQL query to be processed by the database and returns matching records to be bound to the SGrid object.
SUB Find_OnClick
	myQuery = "Select Name, Duration, Start, Finish from Tasks"
	'Check QBE fields and compose a dynamic SQL query.
	IF (SName.Value <> "") THEN
		myQuery = myQuery + " where Name like '" + SName.Value + "%'"
	END IF
	IF (SDuration.Value <> "") THEN
		myQuery = myQuery + " where Duration like '" + SDuration.Value + "%'"
	END IF
	IF (SStart.Value <> "") THEN
		myQuery = myQuery + " where Start like '" + SStart.Value + "%'"
	END IF
	IF (SFinish.Value <> "") THEN
		myQuery = myQuery + " where Finish like '" + SFinish.Value + "%'"
	END IF
	
	myQuery = myQuery + " for browse"  'Mark recordset for editing.
	'Set the new query and then refresh the SControl so that the new results are displayed.
	SControl.SQL = myQuery
	SControl.Refresh
	
END SUB
'Navigation subroutines - based on currency changes to AdvancedDataControl (SControl).
'Move to the first record in the bound recordset.
SUB First_OnClick
  	SControl.MoveFirst
END SUB
'Move to the next record from the current position in the bound recordset.
SUB Next_OnClick
  	SControl.MoveNext
END SUB
'Move to the previous record from the current position in the bound recordset.
SUB Prev_OnClick
  	SControl.MovePrevious
END SUB
'Move to the last record in the bound recordset.
SUB Last_OnClick
  	SControl.MoveLast
END SUB
'Submits edits made and pull a clean copy of the new data.
SUB Update_OnClick
  	SControl.SubmitChanges
	SControl.Refresh
END SUB
'Cancel edits and restores original values.
SUB Cancel_OnClick
  	SControl.CancelUpdate
END SUB
</SCRIPT>
<BR>
<font color = "#400040">This site powered by Microsoft Advanced Data Connector. </font>
</BODY>
</HTML>

Demo 6

This demo uses MSProject as an OLE server. If we run this demo with Microsoft Project as an out-of-process OLE server, it will crash because it will try to create more than one instance. It would also leave a process running that cannot be stopped. An in-process dynamic link library (DLL) that calls Microsoft Project is stable. It is easier to create and close the Microsoft Project application object in a Microsoft® Visual Basic® application than it is in a web page without a constant connection to the server. In the DLL, set error handling much more intelligently and conveniently than in a Web page. So, the DLL should go in the path:C:\WINNT\System32\inetsrv/asp/cmpnts/ProjAsp.dll. The VB app,ProjAsp.vbp, is also included with its components, ProjAsp.cls andModule1.bas.

Preview the code in the asp file. The first thing is to get the project name from the default.htm list box. This is added to the hard coded path to create a string to pass to the DLL to open the project.

Another way of doing this is would be in a default.htm file, where the list box is between <select>and </select> and there are hard coded list items. As the value of each<option> tag, the full path of each project file on the server machine could be coded.

After retrieving the project path the MSProjAsp.ProjAsp object is created. This calls the ProjAsp.dll. The name of the object comes from the name of the project in Visual Basic. Open the ProjAsp.vbp project in Visual Basic. Go to the Tools/Options/Project tab for the project name "MSProjAsp" The name of the class is ProjAsp. Thus the object name MSProjAsp.ProjAsp. In the Options dialog box, look at the advanced tab. "Use OLE DLL Restrictions" is checked. This makes testing the vbp easier because it applies all restrictions for a DLL, i.e. no modal dialog boxes, etc.

A Sub Main is created as an entry point for creating the object. It is the start-up procedure, but it is empty. Otherwise, Module1.bas declares aWin32API that will be called to see if Microsoft Project is running, and declare a public variable pjApp for the Microsoft Project Application object.

In the asp page, pj is the name of the DLL object. pj.GetTaskCount is called. In the Visual Basic application, the ProjAsp.cls class is opened. Notice that there are several declarations. There are also four functions. One of these is GetTaskCount. First get an instance of Microsoft Project. The functionCheckPJInstance checks for Microsoft Project. If it is running, it opens the object, if not, it creates the application object. On that pjApp object, we run FileOpen, passing it the path in the variable 'name' from the web page. Set pjProj to the activeproject. WithpjProj, GetTaskCount = NumberOfTasks. This is the value of the function and is returned to the web page. The next line in the asp page displays this value in the form of a variable, Scount.

Next, we call GetTasks and fill an array, TaskArray. Look at the GetTasks Function in the ProjAsp class. Again, we check for and create an instance of the Microsoft Project application and open the file specified from the previous page. Dim TaskArray (1 to 7, 1 topjProj.NumberOfTasks). This means we have seven columns and a row for each task. Begin cycling through the tasks starting with number one. The If Not T is Nothing statement skips any blank tasks in the project. For each task, add the elements to the array. The last two, summary and milestone, display whether the current task is a summary or a milestone. The function is assigned the value of the array TaskArray(). This is passed back to the client to the variable in the active server page.

Now, for each row in the TaskArray, 1 to Ubound(TaskArray,2), we add the information to a table. For each new task, we add a row using the <tr>tag. I made three variables MyColor, MyFontStart, and MyFontEnd. These are for formatting the data. By default, Mycolor is black. This is for normal tasks. If the task is a Summary Task, the color is changed to blue and MyFontStart and MyFontEnd are '<b>' and '</b>' to make the text bold in HTML. If it is a Milestone, the color is green and the other variables are '<u>' and '</u>' to start and stop underlining in HTML.

Now we add the data to the table. For each column in the array from 1 to 5, add a cell in the table using the <td> tag. On value three, the duration, divide by 60 to get hours. Finally, add the value with the formatting using the variables and the </td>tag to end the cell.

At the end of each task add the </tr> tag to end the row and move to thenext task.

At the end of the project, call pj.Quit. This is another function in theVisual Basic app. This closes Microsoft Project and clears the object variable in the DLL.. Also set the pj variable = Nothing in the asp page.

After we are through, add the </table> tag to end the table.

Source Code

Default.htm

<HTML>
<HEAD>
<TITLE>Project as an OLE Server on the Web</TITLE>
</HEAD>
<BODY bgcolor="white">
<center><font size="6" color="navy">
Using Microsoft Project as an OLE Server over the Internet
<br></font></center>
<form method="post" action="aspole.asp">
Enter the name of the project file:<br>
<Select size="1" name="pjname">
<option value="Audit.mpp">Audit
<option value="Eventpln.mpp">Event Plan
<option value="mktplan.mpp">Marketing Plan
<option value="Softdev.mpp">Software Development
</select>
<br>
<input type="submit" value="Get Project Information">
</form>
</BODY>
</HTML>

Aspole.asp

<%@ LANGUAGE = VBScript %>
<HTML>
<HEAD>
<TITLE>Microsoft Project as an OLE Controller</TITLE></HEAD>
<body bgcolor="white">
<font color="navy" 
<%
'On Error Resume Next
'Get the project name from the previous form
projname=request("pjname")
'if it was blank, tell the user to go back and enter a project file
if projname = "" then
%>
Please go back and enter a project name in the "Rama Demos" Directory
<%
'otherwise, continue
else
'create an instance of the .dll to get the project data
set pj = Server.CreateObject("MSProjAsp.ProjAsp")
'Get the number of tasks in the project
Scount=pj.GetTaskCount("d:\Rama Demos\Project Files\" & projname)
%>
<font size="5" color="navy">
There are <% =Scount %> tasks in the <% =projname %> project.</font><br>
<p>
Normal tasks are in normal text.
<font color="navy"><b>Summary tasks are bold in blue.</b></font>
<font color="olive"><u>Milestones are unerlined in green.</u></font>
<font size="4">
<table width="100%" border="1" cellpadding="1">
<tr><td>TaskID</td><td>Name</td><td>Duration</td><td>Start</td><td>Finish</td>
<%
'Fill an array with all of the project data
TaskArray = pj.GetTasks("d:\Rama Demos\Project Files\" & projname)
'Loop through each element of the array
for i = 1 to ubound(TaskArray,2)
%>
<tr>
<%
'Set font properties based on the type of task
'Normal task - black normal text
MyColor = "black"
MyFontStart = ""
MyFontEnd = ""
if TaskArray(6,i) = -1 then
'Summary task = red and bold
Mycolor = "navy"
MyfontStart = "<b>"
MyFontEnd = "</b>"
end if
'Milestone = green and underlined
if TaskArray(7,i) = -1 then
MyColor = "olive"
MyFontStart = "<u>"
MyFontEnd = "</u>"
end if
for j = 1 to 5
'Convert minutes to hours and add "h" for the Duration
if j = 3 then
MyValue = TaskArray(j,i)/60 & "h"
else
MyValue = TaskArray(j,i)
end if 
%>
<td>
<font color = "<% =MyColor %>"><% =MyFontStart %><% =MyValue %><% =MyFontEnd %></font></td> 
<%
'Next element
next
%>
</tr>
<%
'Next Task
next
end if
'Call the function to close Microsoft Project.
i = pj.Quit()
'Unload the DLL
set pj = Nothing
%>
</table>
</font>
</BODY>
</HTML>

Projasp.dll (in winnt35\system32\inetsrv\asp\cmpnts)

Projasp.vbp

Class=ProjAsp; ProjAsp.cls
Module=Module1; Module1.bas
Reference=*\G{BEF6E001-A874-101A-8BBA-00AA00300CAB}#2.0#0#C:\WINNT\System32\OLEPRO32.DLL#Standard OLE Types
Reference=*\G{A7107640-94DF-1068-855E-00DD01075445}#4.0#9#D:\MSOFFICE\WINPROJ\PJ4EN32.OLB#Microsoft Project 4.1 Object Library
ProjWinSize=136,413,201,113
ProjWinShow=2
HelpFile=""
Title="ProjAsp"
ExeName32="ProjAsp.dll"
Name="MSProjAsp"
HelpContextID="0"
StartMode=1
VersionCompatible32="0"
MajorVer=1
MinorVer=0
RevisionVer=12
AutoIncrementVer=1
ServerSupportFiles=0
DllRestrictions=1
VersionCompanyName="Samuel Brooks Corporation"

Projasp.cls

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "ProjAsp"
Attribute VB_Creatable = True
Attribute VB_Exposed = True
Private Const PROJ_APP = "MSProject.Application.4_1"
Private Const PROJ_WINDOW = "JWinproj-WhimperMainClass"
Private GetProj As String
Private TaskTot As Integer
Public Function GetTaskCount(name) As String
On Error GoTo GetTaskCountEH
Dim pjProj As Project
'Get reference to MSProject
GetProj = CheckPJInstance()
'open the requested file
pjApp.FileOpen (name)
Set pjProj = pjApp.ActiveProject
'Return the number of tasks
TaskTot = pjProj.NumberOfTasks
GetTaskCount = CStr(TaskTot)
EOFunction:
    Exit Function
GetTaskCountEH:
    pjApp.Quit
    GetTaskCount = "Error in Manipulating Project"
    Exit Function
    
End Function
Public Function GetTasks(name)
On Error GoTo GetTasksEH
Dim pjProj As Project
'Get reference to MSProject
GetProj = CheckPJInstance()
'open the requested file
pjApp.FileOpen (name)
Set pjProj = pjApp.ActiveProject
'Fill an array with all of the task information
ReDim TaskArray(1 To 7, 1 To pjProj.NumberOfTasks)
Counter = 0
For Each T In pjProj.Tasks
    Counter = Counter + 1
    If Not T Is Nothing Then
        TaskArray(1, Counter) = T.ID
        TaskArray(2, Counter) = T.name
        TaskArray(3, Counter) = T.Duration
        TaskArray(4, Counter) = T.Start
        TaskArray(5, Counter) = T.Finish
        TaskArray(6, Counter) = T.Summary
        TaskArray(7, Counter) = T.Milestone
    End If
Next T
GetTasks = TaskArray()
EOFunction:
    Exit Function
GetTasksEH:
    GetTasks = "Error in Manipulating Project"
    Exit Function
    
End Function
Private Function CheckPJInstance() As String
    On Error GoTo ErrorHandler
    
    'Check to see if Microsoft Project is running.
    If FindWindow(PROJ_WINDOW, vbNullString) = 0 Then
        'if not, create the application object
        Set pjApp = CreateObject(PROJ_APP)
    Else
        'if so, get an application object
        Set pjApp = GetObject(, PROJ_APP)
    End If
    
    Exit Function
    
ErrorHandler:
    CheckPJInstance = "Error in Manipulating Project"
    Exit Function
End Function
Public Function Quit()
'Close Microsoft Project
pjApp.Quit
Set pjApp = Nothing
End Function

Module1.bas

Attribute VB_Name = "Module1"
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public pjApp As Object
Sub main()
End Sub

Conclusion

This session provides the process and methods to publish Microsoft Project and Team Manager data on the internet using six different methods. It is an excellent starting point for building internet aware project management information systems based on either Microsoft Project or Team Manager.

© 1997 Microsoft Corporation. All rights reserved.

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.

This document is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.

Microsoft and Visual Basic are registered trademarks of Microsoft Corporation.

Other product or company names mentioned herein may be the trademarks of their respective owners.