答:建立一个计算列,expression为 getrow() - first(getrow() for group 1)+1
33、如何实现在datawindow中只有新增的行,才可以编辑?
答:在所有的column的protect属性表达式中写入以下表达式:
if(isrownew(),'0','1')
34、保存datawindow数据到excel中
// ... Init docname // ... GetFileOpenName or any other method
if dw_1.SaveAs(docname, HTMLTable!, True) = -1 then MessageBox("Warning", "Unable to export data. Error writing to file!", Exclamation!) return end if
// Convert HTML file to Excel native format OLEObject excel excel = CREATE OLEObject if excel.ConnectToObject(docname) = 0 then excel.application.DisplayAlerts = FALSE excel.application.workbooks(1).Parent.Windows(excel.application.workbooks(1).Name).Visible = True excel.application.workbooks(1).saveas(docname, 39) excel.application.workbooks(1).close() end if
DESTROY excel // done
35、除了循环以外,有没有更好的方法统计数据窗口中处于选中状态的行数?
一般习惯于使用循环来统计数据窗口中处于选中状态的行数,有没有更好的方法?
其实此问题在应用上用处不大,讨论一下,活跃一下思维还是有好处的。
方法一: long ll_Selected
ll_Selected = long(dw_1.describe("evaluate('sum( if(IsSelected(), 1, 0) for all)',1)"))
方法二: long ll_Selected
ll_Selected = long(dw_1.describe("evaluate('count(IsSelected() for all)',1)"))
(2)、转到WORD $PBExportHeader$f_outputtoword_new.srf global type f_outputtoword_new from function_ O B J E C T end type
forward prototypes global function integer f_outputtoword_new (datawindow adw) end prototypes
global function integer f_outputtoword_new (datawindow adw); //函数名:f_outputtoword_new //输入: adw - datawindow,指定的数据窗口 //返回值: Integer constant integer ppLayoutBlank = 12 OLEObject ole_ O B J E C T ole_ O B J E C T = CREATE OLEObject
integer li_ret
li_ret = ole_ O B J E C T.ConnectToObject("","word.application") IF li_ret <> 0 THEN //如果Word还没有打开,则新建。 li_ret = ole_ O B J E C T.ConnectToNewObject("word.application") if li_ret <> 0 then MessageBox('OLE错误','OLE无法连接!错误号:' + string(li_ret)) return 0 end if ole_ O B J E C T.Visible = True END IF
long ll_colnum,ll_rownum constant long wdWord9TableBehavior = 1 constant long wdAutoFitFixed = 0 constant long wdCell = 12 string ls_value pointer oldpointer
oldpointer = SetPointer(HourGlass!)
string ls_ O B J E C Ts,ls_obj,ls_objs[],ls_objtag[] long ll_pos,ll_len,ll_num = 0
ls_ O B J E C Ts = trim(adw.Describe('datawindow.Objects'))
do while (pos(ls_ O B J E C Ts,"~t") > 0) ll_pos = pos(ls_ O B J E C Ts,"~t") ll_len = ll_pos - 1 ls_obj = left(ls_ O B J E C Ts,ll_len) if (adw.Describe(ls_obj + '.type') = 'column' or & adw.Describe(ls_obj + '.type') = 'compute') and & (adw.Describe(ls_obj + '.band') = 'detail') and (ls_obj <> "asd") then ll_num += 1 ls_objs[ll_num] = ls_obj ls_objtag[ll_num] = adw.Describe(ls_obj + '.tag') end if ls_ O B J E C Ts = right(ls_ O B J E C Ts,len(ls_ O B J E C Ts) - ll_pos) loop
ole_ O B J E C T.Documents.Add() ole_ O B J E C T.ActiveDocument.Tables.Add(ole_ O B J E C T.Selection.Range, ll_rownum, ll_colnum)
string ls_colname integer i,j,k
for i = 1 to ll_colnum //得到标题头的名字 ls_value = ls_objtag[i] ole_ O B J E C T.Selection.TypeText(ls_value) for k = 1 to f_cncharnum(ls_value) ole_ O B J E C T.Selection.TypeBackspace() next ole_ O B J E C T.Selection.MoveRight(wdCell) next
adw.setredraw(false) ole_ O B J E C T.Selection.MoveLeft(wdCell) string column_name for i = 2 to ll_rownum for j = 1 to ll_colnum column_name = ls_objs[j] if adw.Describe(column_name + '.type') = 'column' then ls_value = adw.Describe("Evaluate('LookupDisplay("+column_name+")',"+string(i - 1)+")") end if if adw.Describe(column_name + '.type') = 'compute' then ls_value = adw.Describe("Evaluate('" + adw.Describe(column_name + '.expression') + "',"+string(i - 1)+")") end if ole_ O B J E C T.Selection.MoveRight(wdCell) ole_ O B J E C T.Selection.TypeText(ls_value) //for k = 1 to f_cncharnum(ls_value) //ole_ O B J E C T.Selection.TypeBackspace() //next next next adw.setredraw(true)
constant long wdFormatDocument = 0
SetPointer(oldpointer) //保存新建的文档 if messagebox("保存","文档已经成功完成,是否保存?",Question!,YesNo!) = 1 then string docname, named integer value
value = GetFileSaveName("选择文件",docname, named, "DOC","Doc Files (*.DOC), *.DOC")
IF value = 1 THEN ole_ O B J E C T.ActiveDocument.SaveAs(docname, 0,False,"",True,"",False,False,False, False,False) end if
end if //断开OLE连接 Ole_Object.DisConnectObject() Destroy Ole_Object
uf_set_text(datawindow adw_content,string as_columns,boolean,ab_ignoreblank) /************************************************************* describe: 在数据窗口adw_content中,在as_columns中包含的列中插入空格 args: as_columns 要操作的多个列,列间用逗号隔开 *************************************************************/ if (not isvalid(adw_content)) or isnull(as_columns) or len(as_columns)<1 or isnull(ab_ignoreblank) then return -1
n_cst_string lnv_string string ls_column[] , ls_width ,as_source,as_replaced ,ls_temp int li_upperbound , li_width , li_column , li_fontWidth, li_counter long ll_rowcount , ll_row , ll_totalstep int li_yield
lnv_string.of_parsetoarray(as_columns,',',ls_column) li_upperbound = upperbound(ls_column) ll_rowcount = adw_content.rowcount() if li_upperbound<1 or ll_rowcount<1 then return -1
openwithparm(w_waiting,this) ib_cancel = false iw_frame.enabled = false ll_totalstep = ll_rowcount * li_upperbound w_waiting.uf_register(ll_totalstep) for li_column = 1 to li_upperbound ls_width = adw_content.describe(ls_column[li_column]+".width") li_width = integer(ls_width) if ls_width='!' or ls_width='?' or li_width=0 then continue end if //ls_temp = adw_content.describe(ls_column[li_column]+".Font.property { = 'width' }") //messagebox(ls_column[li_column]+".Font.property { = 'width' }",ls_temp) //return 1 li_fontwidth = 27 li_counter = li_width / li_fontWidth
for ll_row=1 to ll_rowcount if ib_cancel then iw_frame.enabled = true return 0 //pressed cancel button end if as_source = adw_content.getitemstring(ll_row,ls_column[li_column]) as_replaced = uf_insertstring(as_source,li_counter,' ',false) if as_replaced<>as_source then adw_content.setitem(ll_row,ls_column[li_column],as_replaced) end if w_waiting.uf_stepit() next next close(w_waiting) iw_frame.enabled = true
在一个window中加入一个数据窗控件,如dw_new,但是该数据窗没有data O B J E C T,(空白的) 就可以用以下语法来创建: dw_new.create(ls_syntax,ls_error) // 创建语法,错误信息 ls_syntax可以用以下三种方法来形成:
一、动态由sql语法创建:
// 连接到pb的example数据库 string ls_sql,ls_syntax,ls_error ls_syntax = '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.settrans O B J E C T(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.settrans O B J E C T(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!)
// 以下是pb5的代码 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
global type f_createextenddw from function_ O B J E C T end type
forward prototypes global function string f_createextenddw (ref datawindow dw, string cols[]) end prototypes
global function string f_createextenddw (ref datawindow dw, string cols[]);string sql_dw_general, sql_dw_columns_type, sql_dw_headers_conf, sql_dw_columns_conf, ls_errors int i long ll_colcount string ls_colnametype string ls_colname,ls_coltype long ll_pos
答://==================================================================== // [PUBLIC] Function wf_settitle_length 在 w_search_report inherited from window //-------------------------------------------------------------------- // 说明:设置表头长度 //-------------------------------------------------------------------- // 参数1:[reference] datawindow adw_1 // 说明:报表DW //-------------------------------------------------------------------- // 返回: (INTEGER) 成功返回1,不成功返回0 //-------------------------------------------------------------------- // 作者: cwl 日期: 2001.12.15 //==================================================================== Long Row String List string token[] String tag_1 Integer StartPos = 1, EndPos, Top, i = 1 , index = 0 //取出DW中所有的对象存入token[]中 list = adw_1.Describe("datawindow. O B J E C Ts") EndPos = pos(list, '~t', StartPos) Do while ( EndPos > 0 ) token[i] = Mid(list, StartPos, EndPos - StartPos) i ++ StartPos = EndPos + 1 EndPos = pos(list, '~t', StartPos) LOOP token[i] = Mid(list, StartPos) Top = UpperBound(token[])
//找出最后一列 string ls_lastcol int li_lastpos=0,li_thispos For i = 1 to Top CHOOSE CASE UPPER(adw_1.Describe(token[i] + '.type')) CASE 'COLUMN', 'COMPUTE' li_thispos = integer(adw_1.Describe(token[i] + '.X')) if li_thispos>=li_lastpos then //这是目前最后一列 li_lastpos=li_thispos ls_lastcol=token[i] end if end choose NEXT //设置表头长度 string ls_change ls_change="800~tlong(describe('"+ls_lastcol+".x')) + long(describe('"+ls_lastcol +".width')) + 10" //messagebox('',ls_change) adw_1.modify('title.width="'+ls_change+'"')
long ll_firstrowonpage=long(dw_1.describe("datawindow.firstrowonpage"))
dw_1.scrolltorow(ll_firstrowonpage)
dw_1.setrow(ll_firstrowonpage)
45. Grid的窗口如何使第一列固定不动?
①选上data OBJECT的HSplitScroll属性 ②在constructor事件中: dw_1.Object.DataWindow.HorizontalScrollSplit=integer(dw_1.describe("#1.width")) //第一列的宽度 ③在scrollhorizontal事件中: int i
if pane = 1 then
i = integer(this.OBJECT.datawindow.horizontalscrollposition2)
string str_ O B J E C Tname, str_curcol, str_addpic integer int_pic_x
str_ O B J E C Tname =string (dwo.name) //对象名称 if row = 0 and this.describe(str_ O B J E C Tname+".band") = "header" and this.describe(str_ O B J E C Tname+".text") <> "!" then //是否点击列对象 str_curcol = left(str_ O B J E C Tname,len(str_ O B J E C Tname) - 2) //当前列对象名称 if str_curcol <> i_str_oldcol then //点击的是不同列对象 this.modify("destroy p_sort") //不管有没有位图对象都删除 i_str_oldcol = str_curcol //保存上次点击的列对象 //画图 int_pic_x = integer(this.describe(str_ O B J E C Tname+".x")) + (integer(this.describe(str_ O B J E C Tname+".width")) - 70) str_addpic = 'create bitmap(band = foreground filename= "..\pic\up.bmp" x= "'+string(int_pic_x)+'" y= "24" height= "48" width= "48" border= "0" name= p_sort visible= "1")' this.modify(str_addpic) //动态画个图 this.setsort(str_curcol + " A") //头一次点击当然是升序了 this.sort() else //当前列已经点过了 if this.describe("p_sort.filename") = "..\pic\up.bmp" then //上次是升序 this.modify("p_sort.filename = '..\pic\down.bmp'") this.setsort(str_curcol + " D") //这次是降序 else this.modify("p_sort.filename = '..\pic\up.bmp'") this.setsort(str_curcol + " A") end if this.sort() end if end if
------ 1.pb9应用xp风格 将PB9升级到7119后,编译时有一个 New Visual Style Controls 选项,选中后,编译出来的文件在XP下就可以应用XP风格了 2.Yield()函数的作用 Yield()是一个不常用到的PowerBuilder函数。可是,在一个大的循环过程中,如果用户想在执行到一半时通过单击按钮或菜单来退出的话,就一定要用到Yield()函数了,否则程序只会在执行完成整个循环后才会响应按钮或菜单的Click事件。将Yield()函数放在循环体的中间。那么在循环执行的过程中发现有新的事件消息在消息队列中就回立即去响应。
Yield() 功能将控制权转移给其它图形对象,包括非PowerBuilder对象。该函数检测消息队列,如果有消息,就把消息取出。利用该函数可以在执行耗时较长的操作时把控制权转让给其它应用。 语法Yield() 返回值Boolean。如果在消息队列中提取到了消息,那么函数返回TRUE,否则返回FALSE。用法正常情况下,PowerBuilder应用程序在执行一段代码(比如函数或事件处理程序)的过程中不响应用户的操作。对耗时短暂的代码段来说,这种处理方式没有什么不妥的地方,但是,如果某个代码段的执行耗时较长,应用程序又希望为用户提供更多的控制权,那么需要在这段代码中插入Yield()函数,让用户能够进行其它操作,特别在循环执行的代码中更应该如此。应用程序执行Yield()函数后,如果发现消息队列中存在消息,它将允许对象处理这些消息,处理之后,继续Yield()函数后面代码的执行。因此,代码中插入Yield()函数将降低应用程序的运行效率。 3.sqlca.SQLCode 与update() 在利用Embedded SQL 的时候,每运行一次SQL指令就应该检查一次交易对象中的属性SQLCode,而不是等到 所有的SQL指令运行完毕后再去运行检查交易对象中的SQLCode属性.当我们使用数据窗口所提供的函数时, 要记住不要检查SQLCode来判断是否运行成功.而是要依照每一个函数运行后所返回的值来判断是否运行 成功. update tab_test set col1 = 'test' if sqlca.sqlCode = -1 then rollback using sqlca; if sqlca.sqlCode = -1 then messageBox('错误','连接失败!') end if messageBox('错误','连接失败!') else commit using sqlca; end if //确保数据保存的成功 if dw_1.update() = -1 then RollBack Using SQLCA; MessageBox("警告!","数据保存失败!") else Commit Using SQLCA; End if
7.屏蔽窗口的ALT+F4键 //方法一: 1.在窗口的systemkey事件中增加以下代码: IF KeyDown(KeyF4!) THEN Message.Processed = TRUE END IF 2.在窗口的closequery事件中增加如下代码: Long ll_ret IF KeyDown(keyF4!) THEN ll_ret = 1 END IF return ll_ret //方法二: 建一实例变量,在你的关闭程序上赋一个True然后在closequery中判断该值, 如为False则Return 1
send(handle(this),256,9,long(0,0)) return 1 //This statement scrolls the window w_emp up one page: Send(Handle(w_emp), 277, 2, 0) //Both of the following statements click the CommandButton cb_OK: Send(Handle(Parent), 273, 0, Handle(cb_OK)) cb_OK.TriggerEvent(Clicked!) //minimizes the DataWindow: Send(Handle(dw_1), 274, 61472, 0) //maximizes the DataWindow: Send(Handle(dw_1), 274, 61488, 0) //returns the DataWindow to its normal, defined size: Send(Handle(dw_1), 274, 61728, 0)
13.如何使PB窗口总在最上层(Always On Top) 通过SetWindowPos函数把窗口的显示层次修改为HWND—TOPMOST,就可使指定窗口永远不会被其它窗口覆 盖,该函数声明为: Function Long SetWindowPos(Long hwnd,Long ord,Long x,Long y,Long dx,Long dy,Long uflag) Library ″user32″ 参数1为要顶层显示的窗口句柄,参数2指定显示的层次,参数7为附加选项,其余参数指定窗口位置和 大小,均可忽略。在窗口的Open或Activate事件中加入如下函数调用: SetWindowPos(Handle(This),-1,0,0,0,0,3) 参数2取-1表示在最顶层显示窗口,取1表示在最底层显示;最后一个参数若取1,表示窗口大小保持不 变,取2表示保持位置不变,因此,取3(=1+2)表示大小和位置均保持不变,取0表示将窗口的大小和 位置改变为指定值。
14.在PB中如何获得光盘盘符 通过GetDriveType函数可以获取驱动器(如:软驱、硬盘、光驱、网络映射驱动器等)的信息,该函数 声明为: Function Uint GetDriveTypeA(String drive) Library ″kernel32.dll″ 参数为一个盘符(如"C:"),返回值:1表示未知,2表示软驱,3表示本地硬盘,4表示网络驱动器, 5表示光驱。因此如下代码可以获得光盘的盘符: For i=Asc(′D′) to Asc(′Z′) //列举所有可能的CDROM驱动器 If GetDriveTypeA(Char(i)+″:″)=5 Then //若找到CDROM MessageBox(″CDROM″,Char(i)+″:″) //显示光盘盘符 Exit //退出列举 End If Next
---- 按计算列字段分组,并一定将check box-->New Page On Group Break选中。
---- 第三步:将此计算列设为不可视。
---- 另外,如果需要最后一页不足补空行。也很简单,如下:
long ll_pagerow = 6 //每页打印行数 long ll_count, ll_row ll_count = dw_report.retrieve(...) //取得现有报表的总行数 ll_count = ll_pagerow - mod(ll_count, ll_pagerow) If ll_count < ll_pagerow Then for ll_row = 1 to ll_count dw_print.insertrow(0) //补足空行 next end If