Programmer to Programmer (TM)
www.asptoday.com
keyword search

ADSI/CDO (13)
ASP Tricks (78)
BackOffice (27)
Components (58)
Data Access (100)
Miscellaneous (25)
Non-MS ASP (6)
Scripting (68)
Security/Admin (36)
Site Design (27)
Site server (10)
XML (34)
free email updates

ASPTODAY Diary
S M T W T F S
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
Links
Author Page
About ASPToday
Aug 25, 1999 
By Gardiner B. Jones
By Gardiner B. Jones
ASP Tricks
Data Access
 
enter the discussion

Using Active Server Pages to Build Microsoft Word Documents 

Background

BuildDoc.asp is an Active Server Page (ASP) that reads the output of a Web page form, and creates as output a Microsoft Word document containing a table of changed data within the form. Forms are no longer limited to containing static information. With database connectivity, the increasing use of Dynamic HTML (DHTML), and the growing interest in XML, it has become common practice in business Web pages for the data contained in them to be dynamic. That is, what is shown in the form may change based on user interaction (see the sample input form below).

The business need filled by BuildDoc is to enable sales associates to create form letters from the changed records of a Web page table. Only the data modified by the sales person is sent to Word, where it is formatted into a table. Obviously, all samples here are fictitious.

BuildDoc will read all of the information on the form, identifying which rows have been changed, and then creates the Microsoft Word document using only the information contained within the changed rows (see the sample output document below). BuildDoc uses a template file (buildDoc.dot) that contains the address header, and some preformatted text. It then writes a table into the document that has a row for each modified row from the Web page form.

How To Do It

We start by reading all of the Web page form fields into hidden form fields on the receiving Web page. In the source code below, note the " onLoad " call in the body tag. It calls the buildDoc VBScript subroutine, passing three parameters to it: the contents of the page's form (all the hidden fields), the location of the Word template file, and the number of rows received from the input form. The input form fields are all read and then, when the page loads, it calls the buildDoc subroutine. For the sake of brevity, we will assume that all variables have been first declared before use.

The code for the loading of the input form fields into buildDoc.asp is thus: -

<!DOCTYPE HTML PUBLIC "-//W3C/DTD HTML 3.2 Final//EN">
<HEAD>
	<TITLE>Build Document</TITLE>
	<META HTTP-EQUIV="Refresh" CONTENT="30;URL='orderForm.asp'">
</HEAD>
<%
	dotLocation="'\\servername\directory\theTemplate.dot'"
	intRowCount = Request.Form("rowCount")   'initialize a row counter
%>
<BODY Language="VBScript" onLoad="buildDoc document.theForm, 
<%=dotLocation%>,intRowCount>
<FORM NAME="theForm">
<%
	itemCount = 0                            'set field counter to zero
	For Each Item in Request.Form            'count up the form fields
	itemCount = itemCount + 1             'using For..Next loop
%>
	<INPUT TYPE="hidden" NAME="<%=Item%>" VALUE="<%=Request(Item)%>">
<% Next %>
	<INPUT TYPE="hidden" NAME="numbRows"   VALUE="<%=intRowCount%>">
	<INPUT TYPE="hidden" NAME="fieldCount" VALUE="<%=itemCount%>">
</FORM>
</BODY>
</HTML>

We create an instance of the Word Document object, using the sample code immediately below. Note that in Internet Explorer 4+ this will fail unless the browser security is set to Low, or Custom with the appropriate setting to run programs.

<%
Set objWordDoc = CreateObject("Word.Document")
ObjWordDoc.Application.Documents.Add theTemplate, False
ObjWordDoc.Application.Visible=True
%>

We re-dimension our array so that it is the same size as the number of rows that are contained in the Web page's form. In this case, we set the Y-axis to a constant value of four because that is the number of columns we need in the output document. The X-axis contains the number of received rows from the form.

<%
Redim Preserve theArray(4,intTableRows)
%>

Now we are ready to examine all of the form rows. We do this by looping through all the input Web page form fields to collect each form field name and corresponding value. We test each to determine which array element to put it into, and then we put it there. The SELECT CASE statement in the code sample below is important. It is where we determine in which column the form field belongs. We used hard coded CASE options here for expediency.

<%
For intCount = 0 to frmData.fieldCount.value
   strOkay = "Y"
   strSearch = frmData.elements(intCount).name   'load the field name
   strValue = frmData.elements(intCount).value   'load the field value
   strPosition = Instr(1,strSearch,"_")          'get pos val of "_"
   intStringLen=strPosition-1
   If intStrLen > 0 Then
      strLeft = Left(strSearch,intStringLen)
      strRight = Right(strSearch,(Len(strSearch)-Len(strLeft)-1))
      Select Case strLeft
         Case "SKU"                          intArrayY=0
         Case "description"                  intArrayY=1
         Case "price"                        intArrayY=2
         Case "quantity"                     intArrayY=3
      End Select
      IntArrayX = strRight
      If strOkay <> "N" Then
         TheArray(intArrayY, intArrayX) = strValue
      End If
   End If
Next
%>

Now we are ready to begin creating the document. We start by setting the Microsoft Word Document object RANGE using our variable, rngCurrent , to the active document (just in case the user has a different document also open). Then we specify the table size by specifying its location ( rngCurrent ) and the number of rows and columns it needs.

<%
	Set rngCurrent = objWordDoc.Application.ActiveDocument.Content
	Set tabCurrent =  ObjWordDoc.Application.ActiveDocument.Tables.Add
	rngCurrent,intNumrows,4)
%>

Having created the document with the table, we now begin populating the table with data. First we point to the first row ( tabRow=1 ), then begin a loop that will run through each row. We insert a line feed [ Chr(10) ] at the end of each row to put some white space between rows. Finally, we increment our row counter, output the dollar values with "FormatCurrency" to ensure use of dollar signs, commas and decimal places. Right justification of dollar amounts is handled by setting the column in question to " ParagraphAlignment=2 ". I won't tell you how much of a pain it was to discover how to do that! Suffice it to say that it is easier and better documented in VBA, which is not at all like what is required in VBScript.

<%
For j = 1 to intTableRows
	
ObjWordDoc.Application.ActiveDocument.Tables(1).Rows(tabRow).Borders.Enable=False
	
objWordDoc.Application.ActiveDocument.Tables(1).Rows(tabRow).Cells(1).Range.InsertAfter theArray(1,j)
	
objWordDoc.Application.ActiveDocument.Tables(1).Rows(tabRow).Cells(2).Range.InsertAfter theArray(2,j)
	
objWordDoc.Application.ActiveDocument.Tables(1).Rows(tabRow).Cells(3).Range.InsertAfter  FormatCurrency(theArray(3,j))
	
objWordDoc.Application.ActiveDocument.Tables(1).Rows(tabRow).Cells(4).Range.InsertAfter theArray(4,j)
	
objWordDoc.Application.ActiveDocument.Tables(1).Rows(tabRow).Cells(4).Range.InsertAfter Chr(10)
	
objWordDoc.Applicatoin.ActiveDocument.Tables(1).Rows(tabRow).Cells(3).Range.ParagraphFormat.alignment=2
	
tabRow = tabRow + 1
	
Next
%>

Finally, we finish up our document with some closing text and specifying the template's location, and then our subroutine.

<%
objWordDoc.Application.ActiveDocument.Paragraph.Add.Range.InsertAfter("Thank you for shopping at Acme Co., and please come again!")
objWordDoc.Application.ActiveDocument.Paragraph.Add.Range.InsertAfter(" ")
objWordDoc.Application.ActiveDocument.Paragraph.Add.Range.InsertAfter(" ")
objWordDoc.Application.ActiveDocument.Paragraph.Add.Range.InsertAfter("Regards,")
objWordDoc.Application.ActiveDocument.Paragraph.Add.Range.InsertAfter(" ")
objWordDoc.Application.ActiveDocument.Paragraph.Add.Range.InsertAfter("Daryl B. Morticum")
objWordDoc.Application.ActiveDocument.Paragraph.Add.Range.InsertAfter("Sales Associate")
End Sub
%>

Hopefully this will get your gears spinning for ways you can do something similar. We are sure that we aren't the only people who have had a need to create a document from a Web page's form. This is how we did it. If you have a better way, or an improvement on or method, we would love to hear from you.

This article was written as a joint collaboration between the following co-employees of the Education Networks of America: -

Gardiner Jones, MCP+I, MCSE+I, MCT (principal author)

Cal Evans (the right alignment genius)

Sandie Mountz (input form author)

Click here to download this articles support material.


RATE THIS ARTICLE

Overall
Poor Excellent
User Level
Beginner Expert
Useful
No! Very
enter the discussion
 

Related Articles on ASPToday

What’s in your ASP toolkit?
Advanced ASP Charting Using ASPdb2000
Exporting ASP Reports to Excel Format

Related Links

Office Development - Sample Scenarios and Solutions
Using the Microsoft Office Assistants to Create Web Content
Web Word Wizard™ from Document Automation
Book: Word 2000 VBA Programmers Reference


If you would like to contribute to ASPToday, then please get in touch with us by clicking here.

ASPToday is a subsidiary website of WROX Press Ltd. Please visit their website. This article is copyright ©2000 Wrox Press Ltd. All rights reserved.