进销存管理系统

来源:互联网 发布:守望先锋 网络初始化 编辑:程序博客网 时间:2024/05/12 05:11
一、数据库设计
实例系统数据表及其用途
数据表名称        数据表用途
用户清单          保存系统使用者的信息
权限清单          保存系统使用者的权限信息,可以指定到菜单级权限
商品清单          保存企业经营商品的资料信息
供货商清单        保存企业供货商的资料信息
客户清单          保存企业客户的资料信息
仓库清单          保存企业库房的分类信息,可以用于数据辞典
业务员清单        保存企业的业务员信息,可以用于数据辞典
进货单            进货单主表
进货单明细        进货单从表
进货单历史        保存进货单历史
进货单明细历史    保存进货单明细历史
销售单            销售单主表
销售单明细        销售单从表
销售单历史        保存销售单历史
销售单明细历史    保存销售单明细历史
库存库            保存企业商品库存的数量、金额等信息
应付款、应收款    保存企业应付款明细、应收款明细
 
********************************************************************
1.创建数据库(SQL SERVER 2000)
数据表SQL脚本如下:
 
CREATE DATABASE jxc
********************************************************************
2.创建表
 2.1 创建“商品清单”数据表
数据表SQL脚本如下:
create table [dbo].[商品清单](
[货号]        [char]    (14)  NOT NULL PRIMARY KEY,
[条码]        [char]    (14)  NULL ,
[拼音编码]    [char]    (40)  NULL ,
[品名]        [varchar] (80)  NULL ,
[规格]        [varchar] (40)  NULL ,
[单位]        [char]    (6)   NOT NULL ,
[产地]        [varchar] (50)  NULL ,
[类别]        [char]    (20)  NULL ,
[进货价]      [decimal] (28,6)  NULL default(0) ,
[销售价1]     [decimal] (28,6)  NULL default(0) ,
[销售价2]     [decimal] (28,6)  NULL default(0) ,
[最低销价]    [decimal] (28,6)  NULL default(0)
)
GO
********************************************************************
 2.2 创建“供货商清单”数据表
数据表SQL脚本如下:
create table [dbo].[供货商清单] (
[供货商号]        [char]    (10)  NOT NULL PRIMARY KEY,
[拼音编码]        [char]    (40)  NOT NULL ,
[简称]            [varchar] (80)  NULL ,
[名称]            [varchar] (80)  NULL ,
[地址]            [varchar] (80)  NULL ,
[邮编]            [char]    (6)   NULL ,
[区号]            [char]    (6)   NULL ,
[地区]            [varchar] (12)  NULL ,
[类型]            [char]    (10)  NULL ,
[电话]            [varchar] (20)  NULL ,
[传真]            [varchar] (20)  NULL ,
[电报]            [varchar] (20)  NULL ,
[开户行]          [varchar] (40)  NULL ,
[开户行邮编]      [char]    (6)   NULL ,
[银行账号]        [varchar] (20)  NULL ,
[税号]            [varchar] (20)  NULL ,
[库房地址]        [varchar] (40)  NULL ,
[库房电话]        [varchar] (20)  NULL ,
[业务员]          [char]    (10)  NULL ,
[业务部门]        [varchar] (20)  NULL
)
go
********************************************************************
 2.3 创建“客户清单”数据表
数据表SQL脚本如下:
create table [dbo].[客户清单] (
[客户编号]        [char]    (10)  NOT NULL PRIMARY KEY,
[拼音编号]        [char]    (20)  NOT NULL ,
[简称]            [varchar] (80)  NULL ,
[名称]            [varchar] (80)  NULL ,
[联系人]          [varchar] (30)  NULL ,
[地址]            [varchar] (80)   NULL ,
[邮编]            [char]    (6)   NULL ,
[区号]            [char]    (6)   NULL ,
[地区]            [varchar] (12)  NULL ,
[电话]            [varchar] (20)  NULL ,
[传真]            [varchar] (20)  NULL ,
[电报]            [varchar] (20)  NULL ,
[开户行]          [varchar] (40)  NULL ,
[开户行邮编]      [char]    (6)   NULL ,
[银行账号]        [varchar] (20)  NULL ,
[税号]            [varchar] (20)  NULL ,
[性质]            [varchar] (10)  NULL ,
[业务员]          [char]    (10)  NULL ,
[业务部门]        [varchar] (20)  NULL ,
[授信额度]        [decimal] (28,6)  NULL
)
GO
********************************************************************
 2.4 创建“进货单和进货单明细”数据表
数据表SQL脚本如下:
CREATE TABLE [dbo].[进货单] (
[编号]        [char] (14)   Not NULL Primary key,
[供货商号]    [char] (10)   NOT NULL ,
[进货日期]    [datetime]    NULL,
[业务员]      [char] (10)   NULL ,
[制单人]      [char] (10)   NULL ,
[验收员]      [char] (10)   NULL ,
[保管员]      [char] (10)   NULL ,
[税价合计]    [decimal]  (28,6) NULL ,
[不含税价]    [decimal]  (28,6) NULL ,
[税额]        [decimal]  (28,6) NULL,
[订单号]      [char] (14)    NULL
)
GO
CREATE TABLE [dbo].[进货单明细] (
[编号]       [char] (14) Not NULL Primary key,
[进货单号]   [char] (14) Not NULL ,
[货号]       [char] (14) NOT NULL ,
[进货数量]   [decimal] (28,6) NOT NULL ,
[进价]       [decimal] (28,6) NULL ,
[税价合计]   [decimal] (28,6) NULL ,
[扣率]       [decimal] (28,6) NULL ,
[税率]       [decimal] (28,6) NULL ,
[不含税价]   [decimal] (28,6) NULL ,
[税额]       [decimal] (28,6) NULL ,
[仓库]       [char] (20) NULL ,
[货物质量]   [varchar] (50) NULL
)
GO
********************************************************************
 2.5 创建“销售单和销售单明细”数据表
数据表SQL脚本如下:
create table [dbo].[销售单] (
[编号]            [char]    (14)  NOT NULL PRIMARY KEY,
[客户编号]        [char]    (10)  NOT NULL,
[销售日期]        [datetime]      NULL ,
[业务员]          [char]    (10)  NULL ,
[制单人]          [char]    (10)  NULL ,
[保管员]          [char]    (10)  NULL ,
[税价合计]        [decimal] (28,6)  NULL,
[不含税价]        [decimal] (28,6)  NULL,
[税额]            [decimal] (28,6)  NULL,
[订单号]          [char]    (14)  NOT NULL ,
)
GO
create table [dbo].[销售单明细] (
[编号]            [char]    (14)  NOT NULL PRIMARY KEY,
[销售单号]        [char]    (14)  NOT NULL,
[货号]            [char]    (14)  NOT NULL,
[销售数量]        [decimal] (28,6)  NULL,
[销售价]          [decimal] (28,6)  NULL,
[税价合计]        [decimal] (28,6)  NULL,
[扣率]            [decimal] (28,6)  NULL,
[税率]            [decimal] (28,6)  NULL,
[不含税价]        [decimal] (28,6)  NULL,
[税额]            [decimal] (28,6)  NULL,
[仓库]            [char]    (20)  NULL ,
)
GO
********************************************************************
 2.6 创建“库存表与权限清单”数据表
数据表SQL脚本如下:
create table [dbo].[库存表] (
[货号]            [char]    (14)  NOT NULL ,
[仓库]            [varchar] (20)  NOT NULL ,
[库存数量]        [decimal] (28,6)  NOT NULL,
[库存金额]        [decimal] (28,6)  NOT NULL,
[库存单价]        [decimal] (28,6)  NOT NULL,
[最新进价]        [decimal] (28,6)  NULL
)
GO
create table [dbo].[权限清单] (
[权限序号]        [int]  identity (1,1)  NOT NULL ,
[用户编号]        [char]    (6)  NULL,
[部门]            [char]    (20) NULL,
[权限名称]        [char]    (6)  NOT NULL
)
GO
**************************************************************************************************
 3 创建外部关键字
数据表SQL脚本如下:
 
-- 外部关联字段
alter table [dbo].[进货单] add
constraint [进货单_ 供货商_FK] FOREIGN KEY([供货商号])
REFERENCES [dbo].[供货商清单]([供货商号])
GO
alter table [dbo].[进货单明细] add
constraint [FK_进货单明细_进货单] FOREIGN KEY([进货单号])REFERENCES [dbo].[进货单]([编号]),
constraint [进货单明细_ 货号_FK] FOREIGN KEY([货号])REFERENCES [dbo].[商品清单]([货号])
GO
 
alter table [dbo].[销售单] add
constraint [销售单_ 客户编号_FK] FOREIGN KEY([客户编号])
REFERENCES [dbo].[客户清单]([客户编号])
GO
alter table [dbo].[销售单明细] add
constraint [FK_销售单明细_销售单] FOREIGN KEY([销售单号])REFERENCES [dbo].[销售单]([编号]),
constraint [销售单明细_ 货号_FK] FOREIGN KEY([货号])REFERENCES [dbo].[商品清单]([货号])
GO
**************************************************************************************************
4. 创建存储过程
系统使用了两个存储过程,分别实现进货时增加库存、产生应付款和销售时减少库存、产生13:57 12/29/2009应收款的功能。
建库脚本如下:

-- 存储过程
CREATE PROCEDURE sf_进货单 @记帐人 char(10) = NULL
AS
begin transaction
-- 库存库中没有,增加记录
           
     INSERT INTO 库存库(货号,仓库,库存数量,库存金额,库存单价)
            SELECT DISTINCT j.货号, j.仓库, 0,0,0
            FROM 进货单明细 AS J left join 库存库 as k on (j.仓库=k.仓库 and j.货号=k.货号)
            where k.货号 is null
-- 修改库存信息
     UPDATE 库存库 SET 库存单价=case when 库存数量<=0 or (库存数量+数量ALL)<=0 then 进价
            else (库存金额+税价合计ALL)/(库存数量+数量ALL) end ,
            库存数量=库存数量+数量ALL,
            库存金额=case when 库存数量<=0 or (库存数量+数量ALL)<=0
            then 进价*(库存数量+数量ALL) else (库存金额+税价合计ALL) end ,
            最新进价=进价
            FROM
           (SELECT 仓库,货号,'数量ALL'=sum(进货数量), '进价' = sum(税价合计)/sum(进货数量),
           '税价合计ALL'=sum(税价合计) FROM 进货单明细 GROUP BY 仓库,货号) AS LSJ
           WHERE  库存库.仓库=LSj.仓库 AND 库存库.货号=LSj.货号
-- 加入应付款
    INSERT INTO 应付款(编号, 进货单号, 货号, 供货商号, 数量, 进货单价, 金额, 进货日期, 状态)
           SELECT '付'+a.编号,b.编号,a.货号,b.供货商号,进货数量,进价,a.税价合计,进货日期,'应付'
           FROM 进货单明细 as a, 进货单 as b
           where a.进货单号=b.编号
-- 加入历史
    insert into 进货单历史 select * from 进货单
    insert into 进货单明细历史 select * from 进货单明细
-- 清除进货单
    delete from 进货单明细
    delete from 进货单
commit
go
CREATE PROCEDURE sf_销售单 @记帐人 char(10) = NULL
AS
begin transaction
-- 修改库存信息
    UPDATE 库存库 SET 库存数量=库存数量-数量ALL, 库存金额=库存单价*(库存数量-数量ALL)
       FROM (SELECT 仓库,货号,'数量ALL'=sum(销售数量) FROM 销售单明细
       GROUP BY 仓库,货号) AS LSJ
       WHERE  库存库.仓库=LSj.仓库 AND 库存库.货号=LSj.货号
-- 加入应收款
    INSERT INTO 应收款(编号, 销售单号, 货号, 客户编号, 数量, 销售价, 金额, 销售日期, 状态)
    SELECT '收'+a.编号,b.编号,a.货号,b.客户编号,销售数量,销售价,a.税价合计,销售日期,'应收'
    FROM 销售单明细 as a, 销售单 as b
    where a.销售单号=b.编号
-- 加入历史
    insert into 销售单历史 select * from 销售单
    insert into 销售单明细历史 select * from 销售单明细
-- 清除销售单
    delete from 销售单明细
    delete from 销售单
commit
**************************************************************************************************
二、程序开发
2.1.1创建工程
   建立一个JXC.PBW的工程,并且包含一个JXC的PBL文件
   定义全局变量
   string gs_profile ="jxc.ini"    //定义数据配置文件
   string gs_user,gs_username
  jxc.ini 的文本文件的代码如下:
  
  [DataBase]
  SQLCA.DBMS= "MSS Microsoft SQL Server"  //为数据库关系系统的类型
  SQLCA.DataBase= "jxc"                   //为数据库名称
  SQLCA.ServerName= jxc                   //为数据库所在的服务器名称
  SQLCA.LogId= sa                         //登录数据库用户名称
  SQLCA.LogPass=********                  //登录数据库密码
//------------------------------------------------------------------------------------------------
  在jxc.pbl的OPEN事件中输入以下功能代码
 
  string rtn
  integer li_rc
  uo_toolbarfont luo_toolbarfont
  setpointer(hourglass!)                  //设置鼠标为漏斗状
  openwithparm(w_splash,"show")           //打开FALSH窗口
//从INI文件读取连接数据库的参数
  SQLCA.DBMS       = profilestring (gs_profile, "DataBase" ,"SQLCA DBMS", "" )
  SQLCA.DataBase   = profilestring (gs_profile, "DataBase" ,"SQLCA.DataBase", "" )
  SQLCA.ServerName = profilestring (gs_profile, "DataBase" ,"SQLCA.ServerName", "" )
  SQLCA.LogId      = profilestring (gs_profile, "DataBase" ,"SQLCA.LogId", "e" )
  SQLCA.LogPass    = profilestring (gs_profile, "DataBase" ,"SQLCA.LogPass", "" )
  SQLCA.AutoCommit =False
  SQLCA.DBParm = ""
 
  connect using SQLCA;                    //连接数据库
  if SQLCA.sqlcode <> 0 then
           close(w_splash)
  messagebox ("提示信息","连接数据库失败!")
//数据库连接错误,打开设置数据库参数窗口
  open (w_db)
  rtn = message.stringparm
  if rtn ="cancel" or rtn ="" then
       halt close
       return
     end if
  end if
  close (w_splash)                        //关闭FLASH 窗口
  open (w_login)                          //打开登录窗口
  rtn = message.stringparm                //取得登录窗口返回的参数
  if rtn = "login" then
     microhelpdefault = "进销存开发实例"  //设置状态栏标题
     open (w_main)                        //打开主窗口
  end if
  setpointer(ARROW!)                      //设置鼠标为肩头状
//------------------------------------------------------------------------------------------------
  在jxc.pbl的close事件中输入以下功能代码
  disconnect using sqlca;                 //断开数据连接
//------------------------------------------------------------------------------------------------
  2.1.2 创建主窗体
  建立WINDOWS对象
  命名为w_main
  对象控件             属性            取值
  w_main               Name            W_main
  w_main               Title           进销存管理系统
  w_main               MenuName        m_main
  w_main               window type     Main!
 
  创建主菜单
  命名为m_main
  对象控件             属性            取值
  m_main               Name            W_main
  m_zlgl               text            字典维护
  m_spzl               text            商品资料维护
  m_gyszl              text            供货商资料维护
  m_khzl               text            客户资料维护
  m_cggl               text            采购管理
  m_jhd                text            进货单
  m_xsgl               text            销售管理
  m_xsd                text            销售单
  m_kcgl               text            库存管理
  m_kccx               text            库存查询
  m_xtgl               text            系统管理
  m_qxgl               text            权限管理
  在菜单m_spzl中加入如下代码,打开[商品资料维护]窗口
    opensheet (w_sp_gl,w_main,1,layered!)
  其它菜单打开代码如和m_spzl一样
//------------------------------------------------------------------------------------------------
 2.1.3 连接数据库
   选择tools | database profile 菜单命令配置数据库连接信息
//------------------------------------------------------------------------------------------------
 2.1.4 完善主窗体功能
   在窗口w_main中定义一个窗体函数“wf_setmenu”.参数为string型的"as_user",返回值为 integer。
   打开主窗体时,根据用户设置来配置菜单能否使用,“wf_setmenu” 
   功能代码如下:
    datastore lds_user                            //定义数据存储
    integer i,j
    string ls_menuitem,ls_ss
    im_main = menuid                              //获得菜单
    lds_user =create datastore                    //建立数据存储
    lds_user.dataobject ="d_qx_yh"
    lds_user.settransobject(sqlca)
    lds_user.retrieve()
    lds_user.setfilter("用户编号=' "+ gs_user +" '  ")
    lds_user.filter()                             //过滤出as_user用户的权限
    for i =1 to upperbound(im_main.item)
        for j = 1 to upperbound(im_main.item[i].item)
          if im_main.item[i].item[j].visible =true then
             ls_menuitem = im_main.item[i].item[j].text
             if lds_user.find("权限名称=' "+ ls_menuitem +" ' ",1,lds_user.rowcount()) >0 then
                                                  //如果用户有该权限,则菜单可用
            im_main.item[i].item[j].enabled = true
                else
                                                 //如果用户没有该权限,则菜单可用
             im_main.item[i].item[j].enabled = false
             end if
          end if
         next
        next
     destroy lds_user                             //破坏数据存储
   return 1
//------------------------------------------------------------------------------------------------
   在w_main的OPEN事件中的代码
                                                 //设置菜单
   wf_setmenu("gs_user")
//------------------------------------------------------------------------------------------------
   创建FLASH窗口(连接数据库时可以显示给用户看,这样用户觉得不单调)
  
   1> 创建一个窗口,保存名称为“w_splash”
   2> 设置窗口Window type 属性为popup
   3> 在窗口上放置一个图片控件,将控件名称改为p_splash
   4> 设置图形控件p_splash 的Picture NAME属性为cibas.bmp,即引用程序目录下的图片文件“cibas.bmp”
//------------------------------------------------------------------------------------------------
   创建登录窗口
   创建一个窗体,保存名称为"w_logon"
   设置窗体window type 属性为response!
  
   控件类型                对象名                     属性                     取值(说明)
    window                w_login                    title                     登录系统
    window                w_login                    window type               response!
   statictext             st_1                       text                      用户编号:
   statictext             st_2                       text                      用户名:
   statictext             st_3                       text                      密码:
   statictext             st_4                       text                      请输入用户名和密码,登录系统....默认用户编号“1” 默认密码“sys”
   picture                p_1                        picture                   kp2003_2m.bmp
   singlelineedit         sle_no      
   singlelineedit         sle_user                   displayone                true
   singlelineedit         sle_pass                   password                  true
   commandbutton          cb_ok                      text                      确定
   commandbutton          cb_cancel                  text                      取消
//------------------------------------------------------------------------------------------------
   如果编号不存在,则sle_no的内容为空,并且焦点聚集到sle_no上。
   在文本框sle_no的MODIFIED事件中加入以下代码:
   string ls_no,ls_user
   ls_no = trim(this.text)
   select 用户清单.姓名
   into   :ls_user
   from   用户清单
   where  用户清单.用户编号 =:ls_no ;
 if sqlca.salcode <> 0 or ls_user ="" or isnull(ls_user) then
    sle_no.text =""
    sle_user.text =""
    sle_pass.text =""
    sle_no.setfocus()
    return
  end if
    gs_user = ls_no                  //复制全局变量gs_user
    gs_username = ls_name            //复制全局变量gs_username
    sle_user.text = ls_user
    sle_pass.setfocus()
//------------------------------------------------------------------------------------------------
   在按钮cb_ok的CLICKED事件中加入以下代码,判斷用户名与密码是否正确。
   string ls_user,ls_pass,ls_passdata
   integer li_count
   ls_user = trim(sle_user.text)
   ls_pass = trim(sle_pass.text)
   if isnull(ls_pass) then ls_pass =""
   select count(*) into :li_count from 用户清单 where 姓名 =:ls_user;
   if li_count < 1 then
      messagebox("提示信息","请输入正确的用户名!")
      sle_user.setfocus()
      return
   end if
   //查询密码
   select 密码 into: ls_passdata from 用户清单 where 姓名 = :ls_user;
   if isnull(ls_passdata) then ls_passdata =""
   if ls_pass <> trim(ls_passdata) then
      messagebox("提示信息","请输入正确的密码!")
      sle_pass.setfocus()
    return
    end if
   closewithreturn(parent,"login")
//------------------------------------------------------------------------------------------------
   在按钮cb_cancel的clicked事件中写的代码
   closewithreturn(parent,"cancel")
//------------------------------------------------------------------------------------------------
  2.1.5 商品资料维护
   2.1.5.1 创建字典查询的祖先窗口
      1> 新建一个PBL,命名为“Dictionary.pbl”
      2> 创建一个窗体,保存名称为“w_zd”
      3> 设置窗体WINDOW TYPE 的属性为MAIN!
      4> 添加控件
  
   控件类型                    对象名称                   属性                     取值
   window                      w_zd                      window type              main!
   datawindow                dw_1                     
   commandbutton               cb_query                  text                     检索
   commandbutton               cb_add                    text                     增加
   commandbutton               cb_modify                 text                     修改
   commandbutton               cb_close                  text                     取消
      5> 在窗口w_zd中定义实例变量is_sql,用它来存储数据窗dw_1 的初始语法(因为以后对dw_1数据检索时会用到dw_1 的语法,所以行定义得到)。
         代码:string is_sql
      6> w_zd 的OPEN 代码 dw_1与数据库连接起来,并得到数据窗dw_1的初始语法。
         代码: dw_1.settransobject(sqlsa)
                is_sql=dw_1.getsqlselect()
      7> cb_close的CLICKED事件代码
         代码:  close(parent)
//------------------------------------------------------------------------------------------------------------------------------------
   2.1.5.2 创建商品资料维护主窗口(此窗口是创建好的祖窗口w_zd继承下来的)
      1> 选择FILE|INHERIT菜单命令,找出祖先窗口w_zd来继承一个新的窗口
      2> 得到的新窗口与祖先窗口w_zd相同
      3> 保存为"w_sp_gl"
      4> 创建一个数据窗口对象"d_sp_gl",其风格为Grid,  Data Source为SQL Select,选择表“商品清单”中的所有字段
      5> 设置数据窗口DW_1的Dataobject属性为 d_sp_gl 数据窗对象。
      6> 窗口w_sp_gl中控件的属性与祖先窗口一样
      7> 在按钮cb_query中添加代码如
         dw_1.retrieve()
      8> 定义一个实例变量LONG il_row,用来记录当前数据窗选中的行数。
      9> 在数据窗dw_1的CLICKED事件中写入如下代码,选种鼠标单击的行数。
         if row < 1 then return
         il_row = row
         this.selectrow(0,false)
         this.selectrow(row,true)
     10> 在按钮cb_modify的CLICKED事件中加入如下代码,打开商品字典编辑窗口
         string ls_hh
         if il_row < 1 then return
         ls_hh = dw_1.getitemstring(il_row,"货号")
         openwithparm(w_sp_add,ls_hh)
//---------------------------------------------------------------------------------------------------------------------------------- 
    
  
      1> 创建一个窗体,保存名称为"w_sp_add"
      2> 设置窗体Window type属性为 response!
      3> 添加控件如下:
     
   控件类型                    对象名称             属性              取值
   window                      w_sp_add             title             商品资料编辑
   window                w_sp_add             window type       response!     
   window                      w_sp_add             icon              library5!
   datawindow                  dw_1                 dataobject        d_sp_add
   picture control             P_1                  picture name      edit.bmp
   picture control             P_1                  border            true
   line                        ln_1                 line thickness    4
   commandbutton               cb_1                 text              确定
   commandbutton               cb_2                 text              取消
    
      4> 创建一个数据窗口对象"d_sp_add",其风格为Free form, Data Source 为SQL select,选择表“商品清单”中的所有字段.
      5> 在窗口w_sp_add 的OPEN事件中加入代码如下,根据“w_sp_gl”过来的参数判断是对商品资料的新建还是编辑。
         string ls_parm
      6> 在按钮cb_1的CLICKED事件中,加入代码:判断一些字典的字段是否输入,为新输入的商品取得编号,并保存数据。
        
       string ls_pm,ls_dw,ls_pym,ls_hh,ls_hhdata
       long   ll_hh
        
      //拼音编码不能为空
         lp_pym=dw_1.getitemstring(1,"拼音编码")
         if trim(ls_pym) = "" or isnull(is_pym) then
         messagebox("提示信息","请输入拼音码!")
         dw_1.setcolumn("拼音编码")                //焦点聚在拼音编码上
         dw_1.setfocus()
         end if
     
     //品名不能为空
         ls_pm=dw_1.getitemstring(1,"品名")
         if ls_pm = "" or isnull(ls_pm) then
         messagebox("提示信息","请输入品名!")
         dw_1.setcolumn("品名")                    //焦点聚在拼音编码上
         dw_1.setfocus()
         end if
    
     //单位不能为空
         ls_dw=dw_1.getitemstring(1,"单位")
         if ls_dw = "" or isnull(ls_dw) then
         messagebox("提示信息","请输入单位!")
         dw_1.setcolumn("品名")                    //焦点聚在拼音编码上
         dw_1.setfocus()
         end if
        
     //得到货号
         ls_hh=dw_1.getitemstring(1,"货号")
     //货号为空,则取得最大货号加1
         if ls_hh="" or isnull(ls_hh) then
            select max(货号) into:ls_hhdata from 商品清单;
            if sqlca.sqlcode <> 0 then
            messagebox("提示信息","取得商品清单信息失败")
            return
         end if
     //货号取6位
         if isnull(trim(ls_hhdata)) then
            ls_hh = "000001"
         else
         ll_hh = long(ls_hhdata) + 1
         ls_hh = string(ll_hh,"000000")
         end if
     //赋值货号
         dw_1.setitem(1,"货号",ls_hh)
        end if
     //保存数据
         if dw_1.update() = 1 then
            commit;                                   //提交数据
            messagebox("提示信息","保存成功!")
            w_sp_gl.dw_1.retrieve()
            close(parent)
         else
      //回滚数据
         rollback;
         messagebox("提示信息","提交数据失败!")
        end if
    7> 在按钮cb_2的CLICKED事件中,加入代码:关闭窗口
       close(parent)                                    //关闭窗口
//-------------------------------------------------------------------------------------------------------------------
    2.1.6 销售单管理
       2.1.6.1 创建销售单管理窗口
    (1)通过祖先窗口"w_zd"生成窗口"w_xsd_gl"
    (2)因为按钮cb_modify在这里不用,visible属性设置为false,使按钮隐藏起来。
    (3)创建一个数据窗对象"d_xsd_bt",显示风格为grid,data source为SQL select,选择表"销售单历史",
       中的所有字段,和"客户清单",的拼音编码,简称和名称字段.
    (4)创建一个数据窗对象"d_xsd_mx",显示风格为grid,data source为SQL select,选择表"销售单明细历史",
       中的所有字段,和"商品清单",的拼音编码,简称和名称字段.
    (5)为数据窗对象"d_xsd_mx"定义检索参数 as_bh,并在where条件中设置"销售单明细历史","编号" =:as_bh.
   控件类型                    对象名称             属性                    取值
   window                      w_xsd_gl             window type             main!
   datawindow                d_xsd_bt             dataobject              D_xsd_bt     
   datawindow                  d_xsd_mx             dataobject              D_xsd_mx
   commandbutton               cb_query             text                    检索
   commandbutton               cb_add               text                    增加
   commandbutton               cb_modify            text                    修改
   commandbutton               cb_modify            visible                 false
   commandbutton               cb_close             text                    取消
    
    (6)在窗口w_xsd_gl中定义实例变量long il_row  用来标志数据窗dw_1中选择的当前行。
    (7)在数据窗dw_1的CLICKED事件中加入如下代码。得到当前销售单历史的编号,并且检索出销售单的历史明细。
   
       string ls_bh
       if row < 1 then return
       il_row = row
       this.selectrow(0,false)
       this.selectrow(row,true)
       ls_bh = dw_1.getitemstring(row,"编号")
       dw_2.retrieve(ls_bh)
    (8)在按钮cb_query的CLICKED事件中加入代码,用来打开检索窗口,并从检索窗口得到检索的WHERE条件
       然后结合数据窗dw_1的原始语法生成新的SQL语句赋值为数据窗在进行检索。
    
       string ls_query,ls_select
       open(w_xsd_query)                                             //打开检索窗口
       ls_query = messagebox.stringparm                              //得到检索窗口的参数                         
       if upper(ls_query) = "cancel" or ls_query = " " then return 
       ls_select = is_sqlselect + " and  " + ls_query                //得到检索语句
       dw_1.setsqlselect(ls_select)                                  //赋值语句
       dw_1.retrieve()                                               //检索数据
    (9)在按钮cb_add的CLICKED事件中加入代码,用来打开销售单增加窗口
       opensheetwithparm(w_xsd_add,"add",w_main,2,layered!)
       cb_close 使用祖先窗口的代码。
 //----------------------------------------------------------------------------------------------------------------------------------------   
     2.1.6.2 创建销售单查询窗口
    (1)创建一个窗口,保存名称为"w_query"
    (2)设置窗口的属性为response!
    (3)通过祖先窗口"w_query1"生成窗口w_xsd_query
    (4)根据系统的需要,设置检索条件。
    (5)窗口各个控件的属性如下表
   控件类型                    对象名称             属性                    取值
   window                      w_xsd_query          tetle                   销售单查询条件
   window                      w_xsd_query          window type             response!
   window                      w_xsd_query          icon                    library5!
   groupbox                gb_1                 text                    时间     
   picture control             p_1                  picture name            edit.bmp
   picture control             p_1                  border                  true
   line                        ln_1                 line thickness          4
   static text                 st_6                 text                    起始时间
   static text                 st_7                 text                    终止时间
   static text                 st_1                 text                    编号
   static text                 st_2                 text                    客户
   static text                 st_3                 text                    业务员
   static text                 st_4                 text                    制单员
   static text                 st_5                 text                    保管员
   editmask                    em_begin             maskdatatype            datemask!
   editmask                    em_begin             mask                    yyyy-mm-dd
   editmask                    em_end               maskdatatype            datemask!
   editmask                    em_end               mask                    yyyy-mm-dd
   singlelineedit              sle_bh               text
   singlelineedit              sle_kh               text
   singlelineedit              sle_ywy              text
   singlelineedit              sle_zdy              text
   singlelineedit              sle_bgy              text
   commandbutton               cb_query             test                    确定
   commandbutton               cb_cancel            test                    取消
   (6)在窗口的w_xsd_query的open事件代码:
      em_begin.text = string(year(today())) + "-01-01"   //当年头一天
      em_end.text = string(today(),"yyyy-mm-dd")         //当天
      这样系统默认的检索时间为当年的第一天到当天,默认为查询当前年的销售单历史情况。
   (7)在窗口的cb_query的clicked事件代码
      string ls_reselect
      string ls_begin,ls_end
      datetime ld_begin,ld_end
      string ls_bh,ls_khh,ls_khmc,ls_ywy,ls_zdy,ls_bgy
      //得到检索的条件
      ls_begin = em_begin.text
      ls_end = em_end.text
      ls_bh = trim(sle_bh.text)
      ls_khmc = trim(sle_kh.text)
      ls_ywy = trim(sle_ywy.text)
      ls_zdy = trim(sle_zdy.text)
      ls_bgy = trim(sle_bgy.text)
      ls_begin = datetime(ls_begin)
      ls_end = edatetime(ls_end)
      ls_reselect = "(convert(char(10),销售单历史,销售日期,120) >= '" +ls_begin +"'
                    and convert(char(10),销售单历史,销售日期,120) <= '" +ls_end +"' )"
      //编号
      if ls_bh <> "" then
         ls_reselect = ls_reselect + " and 销售单历史.编号 like '% " + ls_bh +" %' "
      end if
      //客户号
      if ls_bh <> "" then
         ls_reselect = ls_reselect + " and 销售单历史.客户号 like '% " + ls_khmc +" %' "
      end if
      //业务员
      if ls_bh <> "" then
         ls_reselect = ls_reselect + " and 销售单历史.业务员 like '% " + ls_ywy +" %' "
      end if
      //制单员
      if ls_bh <> "" then
         ls_reselect = ls_reselect + " and 销售单历史.制单员 like '% " + ls_zdy +" %' "
      end if
      //保管员
      if ls_bh <> "" then
         ls_reselect = ls_reselect + " and 销售单历史.保管员 like '% " + ls_bgy +" %' "
      end if
     closewithreturn(parent,ls_reselect)
//---------------------------------------------------------------------------------------------------------------------------------------------------------
    2.1.6.3 创建销售单编辑窗口
    (1)创建一个窗口,保存名称为"w_xsd_add"
    (2)设置窗口的属性为main!
    (3)窗口各个控件的属性如下表
   控件类型                    对象名称             属性                    取值
   window                      w_xsd_add            window type             main!
   datawindow                  dw_bt                dataobject              d_jhd_bt_add
   datawindow                  dw_2                 dataobject              d_jhd_mx_edit
   datawindow                  dw_1                 dataobject              d_jhd_mx_add
   datawindow                  dw_3                 visible                 false
   datawindow                  dw_3                 dataobject              dd_sp_list
   datawindow                  dw_4                 visible                 false
   datawindow                  dw_4                 dataobject              dd_ckkc
   datawindow                  dw_print             visible                 false
   datawindow                  dw_print             dataobject              d_jhd_print
   groupbox                gb_3                 text                    销售单
   groupbox                gb_1                 text                    销售单明细编辑
   groupbox                gb_2                 text                    销售单明细
   statictext                  st_1                 text                    拼音编辑
   singlelineedit              sle_1                text
   commandbutton               cb_insert            test                    插入
   commandbutton               cb_update            test                    更新
   commandbutton               cb_delete            test                    删除
   commandbutton               cb_ok                test                    保存
   commandbutton               cb_exit              test                    退出
   commandbutton               cb_print             test                    打印
   commandbutton               cb_confirm           test                    确认
   注意:销售单由两个表组成,分成销售单和销售单明细,并且销售单和销售单明细是一对多的关系。
    (4)创建一个数据窗对象"d_xs_bt",其风格为free form,data source为sql select 选择销售单的所有字锻(供货商使用下拉方式来表现)
    (5)创建一个数据窗对象"d_xsd_mx_edit",其风格为free form,data source为sql select 选择"销售单明细"的所有字段
       ,表“仓库清单”的仓库名字段,表“商品清单”的条码,品名,拼音码,规格,单位,产地,类别字段
    (6)创建一个数据窗对象"d_xsd_mx_add",其风格为free form,data source为sql select 选择"销售单明细"的所有字段
       ,表“仓库清单”的仓库名字段,表“商品清单”的条码,品名,拼音码,规格,单位,产地,类别字段
    (7)通过拼音码的检索出商品的方法(隐藏数据窗中放置所有商品的资料) 
    (8)创建一个数据窗对象"dd_sp_list",其风格为free form,data source为sql select 选择“商品清单”所有字段 
    (9)在窗口"w_xsd_add"定义实例变量
      integer ii_oldrow,ii_currow,ii_delrow,ii_selrow
      long il_bh
      string is_bh
   
    (10)在文本框sle_1的MODIFIED事件加入代码。
      string msqltj
      //输入值为空时
      if isnull(lower(this.text)) or len(lower(this.text)) = 0 then
         return
      end if
      //生成filter语句
      msqltj = "(拼音编码 like ' %" +trim(lower(this.text)) + "%')"
      //过滤数据
      dw_3.setfilter(msqltj)
      dw_3.filter()
      //没有检索到数据
      if dw_3.rowcount() = 0 then
         dw_3.setfilter("")
         dw_3.filter()
         messagebox("操作提示","没有你所选择的品种...",question!)
         this.text=''
         return
      else
      //有数据时
         dw_3.visible=true  
         dw_3.setfocus()
         dw_3.selectrow(1,true)
         ii_oldrow = 1
         this.text=''
      end if
    (11)在文本框dw_3的CLICKED事件加入代码。
    
       //赋值实例变量
       ii_currow =row
       if ii_currow < 1 then return
       //选择单击的行
       if isselected(ii_currow) then
          this.selectrow(ii_currow,false)
       else
          this.selectrow(0,false)
          this.selectrow(ii_currow,ture)
       end if
    (12)在数据窗dw_3的doubleclicked事件加入代码,双击时将商品资料相关的有用信息赋值给数据窗dw_2,并将数据窗dw_3隐藏。
       if ii_currow = 0 then return
       //给dw_2赋值
       dw_2.setitem(1,"货号",this.getitemstring(ii_currow,"货号"))
       dw_2.setitem(1,"品名",this.getitemstring(ii_currow,"品名"))
       dw_2.setitem(1,"规格",this.getitemstring(ii_currow,"规格"))
       dw_2.setitem(1,"单位",this.getitemstring(ii_currow,"单位"))
       dw_2.setitem(1,"税率",0.170000)
       //隐藏数据窗dw_3
       this.visible = flase
       dw_2.setcolumn("仓库")
       dw_2.setfocus()
    (13)在数据窗dw_3的KEY_ENTER事件中加入代码如下:响应键盘的上下方向键和回车键(用户自定义事件KEY_ENTER,选择系统event ID为“pbm_dwnkey”)。
       long mm,row
       mm = this.rowcount()
       //向上箭头
       if keydown(keyuparrow!) then
          if this.getselectedrow(0) = 1 then
             this.setrow(mm)
             this.selectrow(1,false)
             this.selectrow(mm,ture)
          else
             row=this.getselectedrow(0)
             this.setrow(row - 1)
             this.selectrow(row,false)
             this.selectrow(row - 1,true)
          end if
       end if
 
      //向下箭头
      if keydown(keydownarrow!) then
          if this.getselectedrow(0) = mm then
             this.setrow(1)
             this.selectrow(mm,false)
             this.selectrow(1,ture)
          else
             row=this.getselectedrow(0)
             this.setrow(row + 1)
             this.selectrow(row,false)
             this.selectrow(row + 1,true)
          end if
       end if
     
       //回车键
       if keydown(keyenter!) then
       row = this.getselectedrow(0)
       ii_currow = row
     
       //响应数据窗的双击事件
       this.postevent(doubleclicked!)
       end if
(14)在数据窗cb_insert的CLICKED事件中加入代码如下:将数据窗dw_2的记录赋值给dw_1判断货号,数量,进价仓库等信息是否输入,
    并查看dw_1是否有记录存在,有则不能插入。
    string ls_hh,ls_sl,ls_find,ls_ck
    decimal ld_xssl,ld_xsj,ld_shl
    long ll_row
    dw_2.accepttext() //接收到数据
    //得到dw_2中输入的值
    ls_hh = dw_2.getitemstring(1,"货号")
    ld_xssl = dw_2.getitemstring(1,"销售数量")
    ld_xsj = dw_2.getitemstring(1,"销售价")
    ld_shl = dw_2.getitemstring(1,"税率")
    ls_ck = dw_2.getitemstring(1,"仓库")
    //货号不能为空
    if isnull(ls_hh) or trim(ls_hh) = " " then
       messagebox("提示信息","请先选择货号!")
       sle_1.setfocus()
       return
    end if
    //销售数据不能为空
    if ld_xssl <= 0.00 or trim(ld_xssl) = " " then
       messagebox("提示信息","请先输入销售数量!")
       dw_2.setfocus()
       dw_2.setcolumn("销售数量")
       return
    end if
    //仓库不能为空
    if trim(ls_ck) = " " or isnull(ls_xssl) then
       messagebox("提示信息","请先选择仓库!")
       dw_2.setfocus()
       dw_2.setcolumn("仓库")
       return
    end if
    //销售单价不能为空
    if ld_xsj <= 0.00 or isnull(ld_xsj) then
       messagebox("提示信息","请先输入销售价!")
       dw_2.setfocus()
       dw_2.setcolumn("销售价")
       return
    end if
    //税率不能为空
    if isnull(ld_shl) then
       messagebox("提示信息","请先输入税率!")
       dw_2.setfocus()
       dw_2.setcolumn("税率")
       return
    end if
    //判断是否有重复的增加
    if dw_1.rowcount() > 0 then
       ls_find ="货号='" + ls_hh +"' "
       if dw_1.find(ls_find,1,dw_1.rowcount()) <> 0 then
       messagebox("提示信息","该品种已存在,请不要重复添加!")
       cb_cancel.triggerevent(clicked);
       return
     //没有重复则在dw_1中加入数据
     else
       ll_row = dw_1.insertrow(0)
       dw_1.scrolltorow(ll_row)
       dw_1.setitem(ll_row,"货号",ls_hh)
       dw_1.setitem(ll_row,"销售数量",ld_xssl)
       dw_1.setitem(ll_row,"品名",dw_2.getitemstring(1,"品名"))
       dw_1.setitem(ll_row,"单位",dw_2.getitemstring(1,"单位"))
       dw_1.setitem(ll_row,"销售价",dw_2.getitemdecimal(1,"销售价"))
       dw_1.setitem(ll_row,"税价合计",dw_2.getitemdecimal(1,"税价合计"))
       dw_1.setitem(ll_row,"扣率",dw_2.getitemdecimal(1,"扣率"))
       dw_1.setitem(ll_row,"不含税价",dw_2.getitemdecimal(1,"不含税价"))
       dw_1.setitem(ll_row,"税额",dw_2.getitemdecimal(1,"税额"))
       dw_1.setitem(ll_row,"仓库",dw_2.getitemstring(1,"仓库"))
       dw_1.setitem(ll_row,"税率",dw_2.getitemdecimal(1,"税率"))
    end if
    //dw_1小于0插入行
    else
        ll_row = dw_1.insertrow(0)
        dw_1.scrolltorow(ll_row)
    //赋值数据
       dw_1.setitem(ll_row,"货号",ls_hh)
       dw_1.setitem(ll_row,"销售数量",ld_xssl)
       dw_1.setitem(ll_row,"品名",dw_2.getitemstring(1,"品名"))
       dw_1.setitem(ll_row,"单位",dw_2.getitemstring(1,"单位"))
       dw_1.setitem(ll_row,"销售价",dw_2.getitemdecimal(1,"销售价"))
       dw_1.setitem(ll_row,"税价合计",dw_2.getitemdecimal(1,"税价合计"))
       dw_1.setitem(ll_row,"扣率",dw_2.getitemdecimal(1,"扣率"))
       dw_1.setitem(ll_row,"不含税价",dw_2.getitemdecimal(1,"不含税价"))
       dw_1.setitem(ll_row,"税额",dw_2.getitemdecimal(1,"税额"))
       dw_1.setitem(ll_row,"仓库",dw_2.getitemstring(1,"仓库"))
       dw_1.setitem(ll_row,"税率",dw_2.getitemdecimal(1,"税率"))
    end if
    //调用cancel按钮事件
    cb_cancel.triggerevent(clicked!)
    
    (15)在数据窗dw_1的CLICKED事件中加入代码如下:
        ii_delrow = row
        if row < 1 then return
      if dw_2.rowcount() < 1 then dw_2.insertrow(0)
      //给dw_2赋值
       dw_2.setitem(1,"货号",dw_2.getitemstring(ii_delrow,"货号"))
       dw_2.setitem(1,"品名",dw_2.getitemstring(ii_delrow,"品名"))
       dw_2.setitem(1,"单位",dw_2.getitemstring(ii_delrow,"单位"))
       dw_2.setitem(1,"销售数量",getitemdecimal(ii_delrow,"销售数量"))
       dw_2.setitem(1,"销售价",dw_2.getitemdecimal(ii_delrow,"销售价"))
       dw_2.setitem(1,"税价合计",dw_2.getitemdecimal(ii_delrow,"税价合计"))
       dw_2.setitem(1,"扣率",dw_2.getitemdecimal(ii_delrow,"扣率"))
       dw_2.setitem(1,"不含税价",dw_2.getitemdecimal(ii_delrow,"不含税价"))
       dw_2.setitem(1,"税额",dw_2.getitemdecimal(ii_delrow,"税额"))
       dw_2.setitem(1,"仓库",dw_2.getitemstring(ii_delrow,"仓库"))
       dw_2.setitem(1,"税率",dw_2.getitemdecimal(ii_delrow,"税率"))
       //设置按钮状态
       cb_ok.enableed = false
       cb_exit.enableed = false
       cb_update.enableed = true
       cb_delete.enableed = true
       cb_cancel.enableed = true
       cb_insert.enableed = false
       //聚焦 dw_2
       dw_w.setfocus()
    
     (16)在数据窗cb_update的CLICKED事件与cb_insert大同小异,就是将数据窗dw_2修改的记录赋值给dw_1中
   
     (17)在数据窗cb_delete的CLICKED事件加入如下代码,删除数据窗dw_1中选中的记录.
        integer msg
       //询问是否删除
       msg=messagebox("提示信息","你确定要删除此条记录吗?",question!,yesno!,2)  
       if msg=2 then return
       //删除
       dw_1.deleterow(ii_delrow)
       cb_cancel.triggerevent(clicked!)
    
     (18)在数据窗cb_cancel的CLICKED事件加入如下代码,消除数据窗dw_2中的记录,以便继续添加.
       dw_2.reset()
       dw_2.insertrow(0)
       dw_2.scrolltorow(1)
       cb_ok.enableed = true
       cb_exit.enableed = true
       cb_update.enableed = false
       cb_delete.enableed = false
       cb_insert.enableed = true
       this.enableed = false
       //sle_1 聚焦
       sle_1.text=""
       sle_1.setfocus()
   
     (19)在数据窗cb_ok的CLICKED事件加入如下代码,判断是新增还是修改.
        long msg,lsh,nf,i,mm,msl,mnf
        string pp,mspbm,mph,mckbm
        real mcgzje
        datetime msxq
        decimal ld_she,ld_sjhj,ld_bhsj
        string ls_xhbh,ls_lsbh
        long ll_xhbh,ll_lsbh
        if dw_1.rowcount() = 0 then
        messagebox("提示信息","销售单没有任何数据,不能保存!")    
        return
        end if
        //msg=messagebox("提示信息","你确定现在要保存销售单数据吗?",question!,yesno!,2)  
        //if msg=2 then return
        if is_bh = "add" then
        //得到历史销售编号
        //ls_lsbh
        select max(convert(decimal(8,0),销售单号)) into :ll_lsbh from 销售单明细历史;
        if sqlca.sqlcode <> 0 then
        messagebox("提示信息","获得销售单编号失败!")
        return
        end if
        //得到销售编号
        select max(convert(decimal(8,0),销售单号)) into :ll_bh from 销售单明细;
        if sqlca.sqlcode <> 0 then
        messagebox("提示信息","获得销售单编号失败!")
        return
        end if
        //得到最大销售编号
        if ll_lsbh > il_bh or isnull(il_bh) or il_bh =0 then
           il_bh = ll_lsbh
        end if
        if isnull(il_bh) or il_bh = 0 then
           is_bh="00000001"
        else
           is_bh =string(il_bh + 1,'00000000')
        end if
        //赋值编号
        dw_bt.setitem(1,"编号",is_bh)
        dw_bt.setitem(1,"订单号",is_bh)
        end if
        //得到最大销售明细历史编号
        select max(convert(decimal(8,0),编号)) into :ll_lsbh from 销售单明细历史;
 %
原创粉丝点击