我觉得在动态生成数据库表单窗口时最适合使用动态加载控件
因为使用SQL语句不知道有多少字段。所以窗体动态加载控件最适合数据库操作
只写一个窗体就能包含所有表单窗体。减少了代码量
现在说说我的动态加载控件的思路
1.窗体接口定义:
  a.数据查询的字段名和值
  b.当前窗体的查询索引
  c.定义控件数组 dim my_ctrl() as object
     object的好处是可以包含任何控件
     关于动态控件的事件问题后面在做说明
  d.窗口的按钮不是动态的,需要写按钮的点击事件过程
2.全局用户类型类型定义
  用户定义数据类型
  a.查询语句(查询值可以使用{fieldname}表示,使用replace替换)
  b.窗体控件名(可以使用与字段名相同的字符串ctrlname=“fieldname1,fieldname2,...”)
    以后可以使用instr(1,ctrlname,"fieldname")>0来查找
  c.窗体控件类型名与b相对应(ctrltype="TextBox,CheckBox,TextBox,ComboBox,...")
  d.控件可编辑字段(editstr="fieldname1,fieldname3,...")
  e.可更新(0|1)
  f.可插入(0|1)
  g.可编辑的权限名
  h.更新语句(值的替换同查询语句)
  i.插入新行语句(值的替换同查询语句;有可能有多个表插入使用";"分割多个插入语句)
  
用户定义数据类型定义完成
public 窗口参数数组(表单窗口种类) as 用户定义数据类型
定义一个过程对窗口参数数组进行付值3.定义全局字段规则检查函数。比如:public function FieldCheck(FieldName as string,FieldValue as string) as boolen
   这里是进行数据库所有字段的规则检查
   select case FieldName]
      case "fieldname1"
'对FieldValue进行检查
      ...
  end select窗体load控件过程(注:这里标签控件名等于字段名 & "lab“;其他控件名=对应的字段名)
分割窗体控件名
分割控件类型名
redim my_ctrl(分割窗体控件名的数量*2-1)
根据分割窗体控件名的数量循环执行
{
Set my_ctrl(i * 2) = Controls.Add("VB.Label", 分割窗体控件名(i) & "lab")
Select Case 分割控件类型名(i)
     case "TextBox"
Set my_ctrl(i * 2 + 1) = Controls.Add("VB.TextBox", 分割窗体控件名(i))
Set my_ctrl(i * 2 + 1)属性付值(包含位置自动排列算法)
设置my_ctrl(i * 2 + 1)为非编辑状态
     case "ComboBox"
...
end select
}窗体enable控件过程
分割窗体控件名
分割控件类型名
为了方便这里用 a= 窗口参数数组(当前窗体的查询索引).控件可编辑字段
根据分割窗体控件名的数量循环执行
{
Select Case 分割控件类型名(i)
     case "TextBox"
if instr(1,a,typename(my_ctrl(i * 2 + 1)))>0 then
my_ctrl(i * 2 + 1).locked=false
else
my_ctrl(i * 2 + 1).locked=true
end if
     case "ComboBox"
if instr(1,a,typename(my_ctrl(i * 2 + 1)))>0 then
my_ctrl(i * 2 + 1).enabled=false
else
my_ctrl(i * 2 + 1).enabled=true
end if
     case 
}窗体disable控件过程
与窗体enable控件过程类似,全部禁止编辑刷新数据库过程
query=根据数据查询的字段名和值替换窗口参数数组(当前窗体的查询索引).查询语句
查询数据库
循环对对应字段的控件付值
状态检查
状态检查过程
根据可编辑的权限名设置相应的按钮是否可见
根据当前状态设置相应的按钮有效其他就是按钮的点击事件过程
遍历每个控件  调用字段规则检查函数

这里就不多说了再说说动态控件的事件问题
在设计上因为表单的字段不确定,所以不能预先定义控件变量,而且控件数组也不支持事件
如果表单编辑的时候需要事件的支持
可以使用Implements多态接口
使用WinAPI函数getwindowlong,setwindowlong  
截获需要事件的控件,再利用Implements多态接口就能写出相应的事件

解决方案 »

  1.   

    太复杂了!
    其实很容易实现,需要用到控件数组而已。1、定义三个常用的控件数组,如txt(0),lbl(0),cb(0).
    2、数据库中存放字段名、字段类型、字段来源(方便取数)、在窗体中的绝对坐标、需要的事件等等。这样在txt_click(index)中你的需要的代码就可以定义得很好了。
    3、从数据库中取出你所需的字段,按字段类型决定load的是那个类型的控件了。如是单据编号:需要输入load(txt(1))就行了。控件的位置也可以从数据库取出啊!所以表单估计很难看是不会的了。
    4、事件的处理有点小难度,不过难过数据库也可以解决。现在我做的项目都是通过这种方式处理的,应该说效果还是很不错的。特别是维护量小了很多,还真的不怕客户要增加或减少字段了。
      

  2.   

    我改好了,控件数组确实也很方便
    在窗体级上定义
    dim dim my_ctrl() as object
    在textbox控件数组定义了2个数组,一种是单行,一种是多行
    所有字段名我放在对应控件的.tag属性里面
    在load控件后使用set语句。比如:
    load text1(text1.count)
    set my_ctrl(i)=text1(text1.count-1)
    在遍历所有字段控件就简单了
    for i=0 to ubound(my_ctrl)
       控件遍历处理
       my_ctrl(i).tag为字段名
       typename(my_ctrl(i))为控件类型
    next i
    哈哈,这样所有控件都有事件了