摘要: 
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() as integer 
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 
   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文件,運行結果如下圖: 
-------------------------------------------------------------------------------- 
作者:曹國宣 
-------------------------------------------------------------------------------- 
版權聲明 
凡在本網站發表的文章,作者必須保證是原創文章;如果不是原創文章,由此帶來的版權糾紛由作者自己承擔。微軟有義務對本站點發表的文章進行審核,但您需要考慮這些文章的使用風險。本站點僅提供一個用戶相互交換技術信息和學習的園地,并不對來自社區用戶的技術文章承擔任何風險。 
http://www.microsoft.com/china/community/program/originalarticles/techdoc/viewprisubtable.mspx