PB中动态增加数据库字段

sky8184911 2007-12-24 11:29:10
举例:
表1 表2
工资款项代码 工资款项名称 员工号码 姓名
01 基本工资 001 张三
02 津贴 002 李四
03 奖金 003 王五
.. ..
. .

如何才能在输入数据时产生如下样式(当款项增加时,款项字段自动增加)

用户输入员工工资数据时显示样式
员工号码 姓名 基本工资 津贴 奖金 ...
001 张三 1250 300 50
002 李四 1200 250 50
003
...全文
1174 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
blood_hound 2011-07-06
  • 打赏
  • 举报
回复
动态修改数据源,确实需要学习一下。
jirmeny 2008-06-21
  • 打赏
  • 举报
回复
好贴,收藏先
'回复内容太短了!'
  • 打赏
  • 举报
回复
不会,学习一下
UltraBejing 2008-05-01
  • 打赏
  • 举报
回复
关注 接分
meiZiNick 2008-05-01
  • 打赏
  • 举报
回复
不会,帮顶
jianache 2008-04-16
  • 打赏
  • 举报
回复
太谢谢了
liangyuan198412 2008-01-04
  • 打赏
  • 举报
回复
可以1!!顶以下
f_mei520 2008-01-03
  • 打赏
  • 举报
回复
學習
wuyuchang 2007-12-29
  • 打赏
  • 举报
回复
总结的不错
wuyuchang 2007-12-27
  • 打赏
  • 举报
回复
不错
ckc 2007-12-26
  • 打赏
  • 举报
回复
crosstab不可以用于输入吧
我以前做过这样的应用,事先定义了N多的字段,比如10个,假定你的工资项目不会超过10种
现在只有6种的时候就用代码把后面4种消隐,不显示,tab位清0,这样处理就可以了
lllyyymmm 2007-12-26
  • 打赏
  • 举报
回复
总结的不错
dawugui 2007-12-26
  • 打赏
  • 举报
回复
  第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图标即告完成。

dawugui 2007-12-26
  • 打赏
  • 举报
回复
动态创建数据窗口

  在实际应用中,经常需要根据用户需求来动态创建数据窗,一般方法是这样的。
  在一个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_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.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()

dawugui 2007-12-26
  • 打赏
  • 举报
回复
举例:
表1 表2
工资款项代码 工资款项名称 员工号码 姓名
01 基本工资 001 张三
02 津贴 002 李四
03 奖金 003 王五
.. ..
. .

如何才能在输入数据时产生如下样式(当款项增加时,款项字段自动增加)

用户输入员工工资数据时显示样式
员工号码 姓名 基本工资 津贴 奖金 ...
001 张三 1250 300 50
002 李四 1200 250 50
003
使用动态创建数据窗口.
其中连接两个表的语句为:

--你的表2应该缺少金额一项,表2缺少工资款项代码一项
select 表2.员工号码 , 表2.姓名 ,
sum(case 表1.工资款项名称 when '基本工资' then 金额 else 0 end) '基本工资',
sum(case 表1.工资款项名称 when '津贴' then 金额 else 0 end) '津贴',
sum(case 表1.工资款项名称 when '奖金' then 金额 else 0 end) '奖金'
from 表2,表1
where 表2.工资款项代码 = 表1.工资款项代码
group by 表2.员工号码 , 表2.姓名
wangxg_1980 2007-12-26
  • 打赏
  • 举报
回复
你用的什么库,在数据窗口中加列,数据库中你保存到什么地方都要考虑到,要实现数据窗口中加入列可以在data source中加入 如:
select emp_id //员工号码 已有列
name //姓名 已有列
    '' as pay1 // 基本工资
'' as pay2 //津贴
'' as pay3 //奖金
...
from 表2
就可以了,不过你要在数据窗口update时只能保存员工号码和姓名,因为表2中没有pay1、pay2、pay3等列,这些就要在数据窗口事件中判断并在其它表中保存了。不知道我说明白没有
wangxg_1980 2007-12-26
  • 打赏
  • 举报
回复
从数据库的角度来说,你的设计存在问题,你要把基本工资、奖金等存到什么地方?
我想你可以在不改变现有表结构的基础上,新建一个表用于保存本工资、奖金等这类东西,只要三列就可以了,一个是员工号,一个是工资款项代码,和金额
这样一关联就可以得出你要的结果了
AFIC 2007-12-25
  • 打赏
  • 举报
回复
crosstab样式的dw就可以

1,108

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 相关问题讨论
社区管理员
  • 基础类社区
  • WorldMobile
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧