PB datawindows 動態創建數據窗口


  在實際應用中,經常需要根據用戶需求來動態創建數據窗,一般方法是這樣的。
  在一個window中加入一個數據窗控件,如dw_new,但是該數據窗沒有data object,(空白的)就可以用以下語法來創建:
  dw_new.create(ls_syntax,ls_error) // 創建語法,錯誤信息
  ls_syntax可以用以下三種方法來形成:

  一、動態由sql語法創建:
  // 連接到pb的example數據庫
  string ls_sql,ls_syntax,ls_error
  ls_sql= 'select * from department'
  ls_syntax = sqlca.SyntaxFromSQL(ls_sql,'style(type=grid)',ls_error)
  if len(ls_error) >0 then
   messagebox('Error','SyntaxFromSQL Error:~r'+ls_error)
  else
   dw_new.create(ls_syntax,ls_error)
   if len(ls_error) >0 then
    MessageBox("Error", "Create have these errors: ~r" + ls_error)
   else
    dw_new.settransobject(sqlca)
    dw_new.retrieve()
   end if
  end if

  二、由另一個數據窗的syntax來創建
  string ls_syntax,ls_error
  ls_syntax = dw_test.describe('datawindow.syntax')
  dw_new.create(ls_syntax,ls_error)
  if ls_error <> '' then
   messagebox('Create Error',ls_error)
  else
   dw_new.settransobject(sqlca)
   dw_new.retrieve()
  end if

  三、讀取psr文件來創建
  string ls_syntax,ls_error,ls_ret
  ls_ret = char(13)+char(10) //回車鍵
  int li_fileNum
  long li_length
  li_FileNum = FileOpen("efef.psr",Streammode!, read!, shared!, Replace!)

  if li_filenum >0 then
   FileSeek(li_FileNum, 158, FromBeginning!)
   li_length = fileRead(li_filenum,ls_syntax)
  end if
  fileclose(li_filenum)
  if li_length = 0 then return
  ls_syntax = "release 5;"+ls_ret+ls_syntax

  //截掉ls_syntax中的數據部分,5.0以"sparse(names="dept_name?) "作爲參考位置
  //6.0以html(作爲參考位置
  long pos1,pos2
  pos1 = pos(ls_syntax,'sparse(names="',1)
  pos2 = pos(ls_syntax,'"',pos1 +16)
  ls_syntax = left(ls_syntax,pos1) + mid(ls_syntax,pos1 +1,pos2 - pos1 +1)
  dw_New.create(ls_syntax,ls_error)
  if ls_error <> '' then
   messagebox('Create Error',ls_error)
  else
   dw_new.settransobject(sqlca)
   dw_new.retrieve()
  end if
  //pb6,pb7的代碼可以參照pb5自己寫,只是文件頭和數據窗結束標記不同而已。

  PowerBuilder用Create()函數創建動態數據窗口,其語法格式爲:dw.Create(Syntax[,ErrString])
  其中:dw爲需創建的動態數據窗口名;Syntax爲創建動態數據窗口的語法字符串;ErrString爲可選參數,用來存放發生錯誤時的錯誤信息,若忽
略,發生錯誤時系統自動顯示消息框,一般不符我們需要,所以需定義該參數。

  顯然重點在Syntax, PowerBuilder提供LibraryExport()與SyntaxFromSQL()二個函數來達到這個目的:

  一、 LibraryExport()函數
  功能:從PowerBuilder庫中輸出一個對象,返回該對象的語法。
  語法格式:LibraryExport(LibName,ObjName,ObjType)
  其中:LibName 爲帶路徑的PowerBuilder庫名,若未指定路徑,則按系統標準搜索路徑搜索;ObjName爲導出對象名,現爲LibName中的數據窗口
對象名;ObjType爲該對象的類型,現爲數據窗口,值爲ExportDataWindow!。示例如下:
  String ls_DwSyntax,ls_Error
  ls_DwSyntax=LibraryExport("C:\PBExam\dy_dw.pbl","d_tbl1", ExportDataWindow!)
  //數據窗口dw_1的產生下面將詳細討論,現暫略
  dw_1.Create(ls_DwSyntax,ls_Error)
  //以下語句與下面示例中的相同,故此處略。
  LibraryExport()函數是利用已有的數據窗口對象創建動態數據窗口,有一定的使用價值,但不多見。

  二、 SyntaxFromSQL()函數
  功能:基於SQL的SELECT 語句產生創建數據窗口的語法。
  語法格式:Transaction.SyntaxFromSQL(SqlString,StyleString,ErrorString)
  其中:Transaction.爲已連接的事務對象,一般即爲SQLCA;SqlString爲SQL--SELECT 語句;Stylestring爲數據窗口的顯示風格字符串,比較復
雜,一般常用"Style(Type=Grid)";ErrorString用來存放發生錯誤時的錯誤信息。
  一般來說,SyntaxFromSQL()函數靈活性高、功能強,因此創建動態數據窗口大都使用該函數,下面的示例也是使用該函數。

  三、創建動態數據窗口的一般步驟
  創建動態數據窗口的一般步驟如下:
  1、在某窗口(如w_main)上用鼠標點建一個數據窗口控件(如dw_1),其DataObject爲空。
  2、構造SyntaxFromSQL()函數的語法字符串。這是PowerBuilder動態數據窗口的關鍵,稍爲複雜一些,具體做法請見下面實例。
  3、用Create()函數創建動態數據窗口dw_1,並用SetTransObject()函數爲其分配事務對象,具體做法請見下面實例。
  這種方法的主要缺點是必須在設計階段先建數據窗口控件,運行時無法增減,這對於一些較爲特殊的應用(如設計階段尚不知需幾個數據窗口)
就不太適合了。那如何解決這個問題呢?經過一番摸索並查閱了一些資料,終於找到了二種解決方法,現分別介紹如下:   1、創建一個標準可視數據窗口用戶對象u_d_sample
  PowerBuilder6.0/6.5中步驟爲:點擊工具欄上的UserObject圖標,在彈出的Select User Object窗口中點擊New按鈕,出現New User Object窗口,雙擊其中Visual下的Standard圖標, 在彈出的Select Standard Visual Type窗口中雙擊datawindow選項,即出現User Object(Untitled)窗口,點擊工具欄上的Save圖標,彈出的Save User Object窗口,在User Objects: 中輸入u_d_sample回車即進入User Object---u_d_sample窗口,關閉該窗口,標準可視數據窗口用戶對象u_d_sample即告建成。

  PowerBuilder7.0中步驟爲:點擊工具欄上的New圖標,在彈出的New窗口中選擇Object頁面,雙擊其中的Standard Visual圖標, 在彈出的Select Standard Visual Type窗口中雙擊datawindow選項,出現User Object(Untitled)inherited from datawindow窗口,將其右邊的Title欄中的none刪除,再點擊左邊空白區,然後點擊工具欄上的Save圖標,以後的操作步驟與PowerBuilder6.0/6.5大致相同。至於PowerBuilder8.0則與PowerBuilder7.0大體相同,不再贅述。

  2、直接定義DataWindow型變量dw_1如下:
  DataWindow dw_1
  dw_1=Create DataWindow
  其實第1種方法還須定義dw_1,形式如下:
  u_d_sample dw_1
  dw_1=Create u_d_ sample //此句可省略
  這二種方法的關鍵都是使用OpenUserObject()函數,其功能即爲打開一個用戶對象,語法格式:w_name.OpenUserObject(ObjName[,x,y]) 其中ObjName爲需打開的用戶對象名;x、y爲用戶對象的打開位置,省略時值均爲0。
  下面請見具體實例, 該實例在Win98、PowerBuilder8.0/PowerBuilder7.0/PowerBuilder6.5下通過,ODBC數據源已配置,爲FoxPro25(可根據需要使用其他數據庫),數據表爲bb.dbf。請先建窗口w_main,在其Open事件中寫入以下代碼:(注意:PowerBuilder8.0中先須創建WorkSpace(*.pbw),其他操作基本同PowerBuilder7.0)

  //動態數據窗口dw_1創建實例
  string lserr,lsSQLstr,lsDWsyntax,lserrC
  SQLCA.DBMS="ODBC"
  SQLCA.DBParm="ConnectString='DSN=FoxPro25'" //本例使用FoxPro25數據庫,可根據需要用其他數據庫
  Connect;
  //下面3條語句即爲關鍵,若dw_1爲鼠標點建請刪除這3條語句,否則會出錯。
  DataWindow dw_1 //若採用數據窗口用戶對象u_d_sample,則可改爲:u_d_sample dw_1
  dw_1=Create DataWindow //若採用數據窗口用戶對象u_d_sample,此句應去除。
  OpenUserObject(dw_1)
  //Select…As…的As可將列標題顯示爲As之後的字符,較爲靈活方便。
  //可根據實際情況設計生成Select語句及Where子句的可視化界面
  lsSQLstr="Select A12 As 主管部門,A01 As 法人代碼,mc As 企業名稱,A06 From bb Where A12 <'1'"
  lsDwsyntax=SQLCA.SyntaxFromSQL(lsSQLstr,"style(type=Grid)",lserr) //構造SyntaxFromSQL()函數
  If Len(lserr)>0 Then
   //如果構造SyntaxFromSQL()函數失敗,則顯示錯誤信息並退出
   messagebox("錯誤信息!",lserr)
   Return
  end if
  dw_1.Create(lsDwsyntax,lserrC) //創建動態數據窗口dw_1
  If Len(lserrC)>0 Then
   //如果創建動態數據窗口dw_1失敗,則顯示錯誤信息並退出
   messagebox("錯誤信息!",lserrC)
   Return
  end if
  //以下設置dw_1的一些屬性,可根據實際需要設置。
  dw_1.X=5
  dw_1.Y=5
  dw_1.width=1500
  dw_1.height=650
  dw_1.Visible=True
  dw_1.Enabled=True
  dw_1.HScrollBar=True
  dw_1.VScrollBar=True
  //爲dw_1分配事務對象SQLCA
  dw_1.SetTransObject(SQLCA)
  //提取數據
  dw_1.Retrieve()

  第2種方法的優點大家一看即知,不必費勁去創建一個標準可視數據窗口用戶對象,但存在不足之處:不能在窗口w_main的其他事件或控件中引用dw_1。解決方法很簡單:將dw_1定義爲實例變量(Instance Variable)。PowerBuilder6.0/6.5中:在窗口畫筆(w_main)的菜單上點擊Declareà Instance Variables…,在彈出窗口Declare Instance Variables中輸入datawindow dw_1, 點擊Ok按鈕即告完成。PowerBuilder7.0/8.0中:打開窗口畫筆,在其下半部的窗口Declare Instance Variables中輸入datawindow dw_1, 點擊工具欄上的Save圖標即告完成。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章