摘要:
DataSet是數據集在內存中的表示方法,數據集可以有主從關系的數據表,在Access中這種關系表現的很直觀,本文討論在同一網頁上直觀地顯示有主從關系的相應數據的程序設計和程序。
--------------------------------------------------------------------------------
目錄
方法
Tables和ImageButtons的ID的命名規則
網頁上Table的字段長度的估計
主要程序
事件過程
應用實例
--------------------------------------------------------------------------------
方法 :
對DataSet中的每一張表,如果有子表,將這張表的字段名行和每一紀錄行在網頁上都顯示為只有一行的Table,並在記錄行Table的第一列置上一個ImageButton,以便程序控制展開或關閉相應的子表的紀錄行所形成的Table或Tables。對於每一紀錄行,子表有相應的記錄行,若子表還有子表,則對子表重復上述過程,即將子表的字段名行與相應的記錄行在網頁上都顯示為只有一行的Table,並在記錄行Table的第二列置上一個ImageButton,反之將子表的字段名行與相應的紀錄行在網頁上顯示為一個Table。利用Table的Visible屬性,可以控制子表相應記錄行的顯示。顯然可以使用遞歸調用實現這一過程。
--------------------------------------------------------------------------------
Tables和ImageButtons的ID的命名規則:
用對ImageButton的點擊,程序控制網頁上的相應的Tables的顯示與隱藏,這些ImageButton.id和Table.id的命名就需要一定的規則。
對DataSet中的第一張主表:
由字段行生成的網頁Table的id命名為t0
由記錄行生成的網頁Tables的id分別為t1,t2,...tn ,與這些Tables相對應的ImageButton.id命名為 e1,e2,...en, 這裡 n:主表的記錄行數
對DataSet中的子表:
子表中的記錄行都是隸屬於主表中的某一記錄行,因此這些記錄行生成的網頁Tables也隸屬於主表某一記錄行所生成網頁的Table,如隸屬於t2的Tables命名為t2-0,t2-1,t2-3...,其中t2-0為子表的字段名行在網頁上生成的Table.id名,其余以此類推,若子表沒有子表了,即最後一個子表,則t2-0是包含子表的字段名行和相應的子表記錄行在網頁上生成的Table.id名。
與這些table.id相對應的ImageButton.id分別命名為e2-1,e2-2,...。
--------------------------------------------------------------------------------
網頁上Table的字段長度的估計:
DataSet中的每一張表都會在網頁上生成一些Table,這些Tables的外在形式應該是相同的。即Tables的相同的Cell應有同樣的長度。函數子程序SetCellSize計算DataTable的每一字段平均字符數,和字段名的字符數,並取其大者,若字段的某一紀錄或字段名都是ASCII字符,則其字符數減半。用此數據便可估計網頁上的Table的相應字段的顯示長度。
下面是SetCellSize的程序,容易理解。
Function SetCellSize(myTable as DataTable)
dim myRow as DataRow
dim i,j,k,m as integer
dim aa() as integer
dim myBool as Boolean
m=myTable.columns.count-1
redim aa(m)
for i=0 to m
aa(i)=0
next
for each myRow in myTable.rows '計算每一字段的平均字符長度
for i=0 to myTable.columns.count-1
dim mystr as string
mystr=myRow(myTable.columns(i)).tostring
j=len(mystr)
if j>0 then
myBool=true
for k=1 to j '判斷dataTable中的每一項是否包括漢字
dim str1 as char=mid(mystr,k,1)
if ascw(str1)>255 then '有非ASCII字符
myBool=false
exit for
end if
next
if myBool then j=(j/2+0.5) '都是ASCII字符,字符串長度減半
aa(i)+=j
end if
next
next myRow
k=myTable.rows.count
for i=0 to m
aa(i)=aa(i)/k 'DataTable的每一列的平均長度
next
for i=0 to myTable.columns.count-1 '對每一字段名
dim str2 as string=myTable.columns(i).columnname
j=len(str2)
if j>0 then
myBool=true
for k=1 to j '判斷字段名中是否包括漢字
dim str1 as char=mid(str2,k,1)
if ascw(str1)>255 then '有非ASCII字符
myBool=false
exit for
end if
next
if myBool then j=(j/2+0.5) 'ASCII字符,字符串長度減半
if j>aa(i) then aa(i)=j
end if
next
SetCellSize=aa
end Function
--------------------------------------------------------------------------------
主要程序:
子程序ShowTables設置一些初始值,然後調用子程序ShowChildRows。
子程序ShowChildRows的參數說明:
Rows:是一個DataRow數組,第一次調用ShowChildRows時,是DataTable的所有的記錄行。以後遞歸調用ShowChildRows時,是與父表某一記錄行相關的子表的一些記錄行。
myTable:Rows所屬的DataTable,程序將使用它的Columns,即字段名行。
aa:函數子程序SetCellSize返回的一維整型數組。
spaces:整型參數,用於在網頁顯示Tables時,這些Tables左側應設置幾個空單元格,以顯示Table的隸屬關系。
signal:字符串參數,ImageButton的id值,用於生成相關的Tables和ImageButtons的id。
因為要在網頁中添加Table控件,所以在網頁中應有一個id為form1的Form控件。
動態地創建一個Table有三個步驟,首先,創建 TableCell 對象,即行中的單元格,添加單元格的內容有兩種方法:設置 Text 屬性,或者向 TableCell 的 Control.Controls 集合添加控件,程序中對某些單元格添加ImageButton控件;接下來,創建 TableRow 以表示表中的行,將此前創建的 TableCell 對象添加到 TableRow 的 Cells 集合中。最後,將 TableRow 添加到 Table 控件的 Rows 集合中。
以下是程序:
Sub ShowTables(mySet as DataSet)
dim spaces as integer=0
dim aa() asinteger
dim i,d as integer
dim signal as string=""
dim myTable as dataTable=mySet.tables(0)
dim rows() as DataRow
d=myTable.rows.count-1
redim rows(d)
for i=0 to myTable.rows.count-1
rows(i)=myTable.rows(i)
next
aa=SetCellSize(myTable)
Call ShowChildRows(rows,aa,myTable,spaces,signal)
End Sub
Sub ShowChildRows(rows() as DataRow,aa() as integer,myTable as DataTable,spaces as integer,signal as string)
dim i,j,k,m,leng as integer
dim fontsize as integer=10
dim myRow as DataRow
dim myCol as DataColumn
dim testTable as Table
dim Cell as TableCell
dim Row as TableRow
dim myBool as Boolean
dim myimage as ImageButton
dim ChildRows() as DataRow
dim ChildTable as DataTable
dim myRel as DataRelation
dim bb() as integer
dim CellStyle as new TableItemStyle
cellStyle.borderwidth=unit.pixel(1)
cellStyle.borderstyle=Borderstyle.solid
cellStyle.wrap=false
if myTable.ChildRelations.count=1 then '有從表
myRel=myTable.ChildRelations(0)
ChildTable =myRel.ChildTable
m=ChildTable.Columns.count-1
redim bb(m)
myBool=True
bb=SetCellSize(ChildTable)
end if
testTable=New Table
testTable.borderwidth=unit.pixel(1)
testTable.cellspacing=0
testtable.cellPadding=0
testTable.font.name="宋體"
testTable.font.size=fontunit.point(fontsize)
testTable.visible=true
if signal<>"" then '遞歸調用時,字段名行形成的Table.id的賦值
leng=len(signal)
testTable.id="t" & mid(signal,2,leng-1) & "-0"
testtable.visible=false
else
testTable.id="t" & "0" '初始時,字段名行形成的Table.id
testTable.visible=true
end if
form1.controls.add(testtable)
'********** 以下程序為生成表的字段名稱行的Table ********************
Row=New tableRow
Row.borderwidth=unit.pixel(1)
m=rows.length
if spaces>0 then
for i=1 to spaces
cell=new Tablecell
cell.applyStyle(CellStyle)
cell.width=unit.pixel(13)
if not myBool then cell.rowspan=m+1
row.cells.add(cell)
next
end if
if myBool then
cell=new Tablecell
cell.applystyle(CellStyle)
cell.backcolor=color.lightgray
cell.bordercolor=color.black
cell.width=unit.pixel(13) > row.cells.add(cell)
end if
m=myTable.Columns.count-1
for i=0 to m
Cell=new tableCell
dim str2 as string
cell.applystyle(cellstyle)
cell.backcolor=color.lightgray
cell.bordercolor=color.black
cell.text= myTable.columns(i).columnName
cell.HorizontalAlign=HorizontalAlign.Center
k=(fontsize+6)*aa(i)
cell.width=unit.pixel(k)
row.Cells.add(cell)
next
testtable.Rows.add(row)
'************* 以下程序為生成表的各行紀錄的Tables *********************
for i=0 to rows.length-1
if myBool then
testTable=New table
testTable.borderwidth=unit.pixel(1)
testTable.cellspacing=0
testtable.cellPadding=0
testTable.font.name="宋體"
testTable.font.size=fontunit.point(fontsize)
testTable.visible=true
if signal<>"" then
testTable.id="t" & mid(signal,2,leng-1) & "-" & (i+1).tostring
testtable.visible=false
else
testTable.id="t" & (i+1).tostring
testTable.visible=true
end if
form1.controls.add(testtable)
end if
myRow=rows(i)
Row=New tableRow
if myBool then
if spaces>0 then
for k=1 to spaces
cell=new Tablecell
cell.applystyle(cellstyle)
cell.width=unit.pixel(13)
row.cells.add(cell)
next
end if
Cell=New tableCell
cell.width=unit.pixel(13)
cell.applystyle(CellStyle)
myimage=New imagebutton
myimage.imageurl="close.gif"
if signal<>"" then
myimage.id=signal & "-" & (i+1).tostring
else
myimage.id="e" & (i+1).tostring
end if
AddHandler myimage.Command, AddressOf ImageButton_Command
myimage.imagealign=ImageAlign.absmiddle
cell.controls.add(myimage)
row.cells.add(cell)
end if
m=myTable.columns.count-1
for j=0 to m
cell=new tablecell
cell.ApplyStyle(CellStyle)
cell.text=myRow(myTable.columns(j)).tostring
k=(fontsize+6)*aa(j)
cell.width=unit.pixel(k)
row.cells.add(cell)
next
testtable.rows.add(row)
if myBool then '若有從表,遞歸調用
dim spaces2 as integer
spaces2=spaces+1
ChildRows=myRow.GetChildRows(myRel)
call ShowChildRows(ChildRows,bb,ChildTable,spaces2,myimage.id)
end if
next
End Sub
--------------------------------------------------------------------------------
事件過程:
在“Tables和ImageButtons的ID的命名規則”一節中給出了命名的規則,這裡舉例說明:
如果點擊了id為e1的ImageButton,它所對應的網頁上的Table的id為t1,與t1相關的子表上的相應的記錄行在網頁上形成id為t1-1,t1-2,...t1-n的Tables,這裡 n為子表上的相應的記錄行數,而t1-0為子表的字段名行在網頁上形成的Table。如果e1的ImageUrl為“”close.gif,則將其設置為“”open.gif,並將t1-0,t1-1,...t1-n的Visible屬性設置為True。反之,除了要將e1的ImageUrl改為close.gif和將t1-0,t1-1,...t1-n的Visible屬性改為False外,如果t1-1,t1-2,...t1-n有對應id為e1-1,e1-2,...e1-n的ImageButton的,而這些ImageButtons中的某些ImageUrl為open.gif,即子表的子表的某些記錄行生成的Tables是打開的,則這些ImageUrl設置為close.gif。
文章標題:Using Web Services Enhancements to Send SOAP Messages with Attachments
程序如下:
Sub ImageButton_Command(Sender as object,e as CommandEventArgs)
dim myControl as Control
dim str1 as string
dim leng as integer
str1=sender.id
leng=len(str1)
str1="t" & mid(str1,2,leng-1) & "-"
if Sender.ImageUrl="close.gif" then
Sender.ImageUrl="open.gif"
for each myControl in form1.controls
dim pos1 as integer=instr(leng+2,myControl.id,"-")
if left(myControl.id,leng+1)=str1 and pos1=0 then myControl.visible=true
next
else
Sender.ImageUrl="close.gif"
for each myControl in form1.controls
dim str0 as string=myControl.id
if left(myControl.id,leng+1)=str1 then
dim dTable as table
dtable=ctype(myControl,table)
if dtable.controls.count>0 then
dim rowControl as control
for each rowControl in dtable.controls
dim drow as tablerow
drow=ctype(rowControl,tablerow)
if drow.controls.count>0 then
dim cellControl as control
for each cellControl in drow.controls
dim dcell as tablecell
dcell=ctype(cellControl,TableCell)
if dcell.controls.count>0 then
dim imageControl as control
for each imageControl in dcell.controls
dim dimage as imageButton
dimage=ctype(imageControl,imageButton)
dimage.ImageUrl="close.gif"
next
end if
next
end if
next
end if
&nb sp; myControl.visible=false
end if
next
end if
End Sub
--------------------------------------------------------------------------------
應用實例:
以羅斯文數據庫為例,該數據庫有客戶、訂單和訂單明細三個表文件,客戶和訂單兩張表在字段名“客戶ID”有一對多的關系,訂單和訂單明細在字段名“訂單ID”有一對多的關系。下述程序連接數據庫,形成DataSet後,調用子程序ShowTables。
<%@Import Namespace=System.Data.oledb%>
<%@Import Namespace=System.Data%>
<%@Import Namespace=System.drawing%>
<Html>
<head><script language="VB" runat="server">
sub Page_Load(Sender as Object, e as EventArgs)
dim dsDataSet as DataSet=new DataSet()
dim Constr,Conn as string
dsdataSet=cache("mySet")
if dsDataSet is Nothing
Constr =server.mappath("northwind.mdb")
Conn="provider=microsoft.jet.oledb.4.0; data source=" & Constr
dsDataSet=new DataSet()
dim odA as oledbDataAdapter=new oledbDataAdapter("select * from 客戶",Conn)
odA.fill(dsDataSet,"Customers")
odA.SelectCommand.CommandText="select * from 訂單"
odA.fill(dsDataSet,"Orders")
odA.SelectCommand.CommandText="select * from 訂單明細"
odA.fill(dsDataSet,"Order_details")
dsDataSet.Relations.Add("M",dsDataSet.Tables(0).Columns("客戶ID"),dsDataSet.Tables(1).Columns("客戶ID"))
dsDataSet.Relations.Add("N",dsDataSet.Tables(1).Columns("訂單ID"),dsDataSet.Tables(2).Columns("訂單ID"))
Cache("mySet")=dsdataSet
end if
call ShowTables(dsDataSet)
end sub
'子程序ShowTables添加處
'子程序SetCellSize添加處
'子程序ShowChildRows添加處
'子程序ImageButton_Command添加處
</script>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</Html>
將上述程序copy到記事本中,並將前面的程序copy到相應的子程序添加處,注意:在上述過程中可能會出現文本的斷行錯誤,在加以修改後,命名為.ASPx文件,運行結果如下圖: