经常被用户抱怨,我想要这个这个筛选,这个这个也要。最好是都可以。我说是不是像excel一样,人家点头了。晕死。一句话:微软害死人。去年实现了一个,可是加载速度实在是慢,后来在我的一位研究生学长的改进下给了我很大的启发,最后在这方面真的接近了excel。在此跟大家分享,欢迎提出意见。
vb里有个mshflexgrid控件,可以用来查看数据。我想基本上每个可视化编程工具都有类似的吧。我在它的基础上搭配combbox下拉列表框来实现。
在数据从数据库读取出来填充表格控件的时候,加载相同列数的下拉列表框。并动态定位,让他们刚好定位在第一行的对应的列。下拉列表框里填充什么数据呢,用select distinct读取出来然后填充对应的下拉列表框吗,不是的,否则数据量大的时候会让你崩溃的,慢了5-6倍。这时候除了填充列名之外什么都不填充的,用户每点击一次填充一次,填充完成后再弹出下拉列表框。
到这一步,并不意味着工作就结束了。还有一个很严重的问题。
首先介绍下我的一个名词:级联查询。在excel里用户一般是这里点一个条件,那里点一个条件。显示出来的数据是这些查询的综合。也就是说我们的where语句中不是一个条件就可以的,是动态变化的,用户选了几个我们就得有几个。
如果作为一个控件的话,是不能预先知道要显示的数据对应数据库里面的哪些字段的,可是我们的查询里面得知道每个字段。这个的解决请参考我前面的一片关于描述表的文章。现在假设我们知道每个字段。
我们用一个同表格列数相同的数组来保存用户的每一个选择,每选择一次保存一个条件,如:name='xxx',数组里面都是这些东西。没有选择的话肯定都是空的字符串了。
每一次用户点击下拉列表框要做什么呢(下拉列表框要填充什么呢):
cmbCol(index).Clear '第index个下拉列表框 cmbCol(index).AddItem "(全部)" cmbCol(index).AddItem "(自定义)" '弄清查询条件 For i = 0 To DisplayCols 'DisplayCols 显示的列数 If TempText(i) <> "" And i <> index Then ConditionStr = ConditionStr & TempText(i) & " and " '查询条件 End If Next i sql = "select distinct " & FieldEname(index) & " from " & tablename '组成正确的sql语句 If ConditionStr <> "" Then ConditionStr = Mid(ConditionStr, 1, Len(ConditionStr) - 4) sql = sql & " where " & ConditionStr End If TetRec.Open sql, G_UserCon, adOpenDynamic, adLockOptimistic, adCmdText Do While Not TetRec.EOF cmbCol(index).AddItem Trim(TetRec.Fields(mFieldInfo(index).FieldEname).Value) & "" TetRec.MoveNext Loop TetRec.Close
应该能看清吧。
用户做出选择了,怎么填充数据呢?
For i = 0 To DisplayCols If TempText(i) <> "" Then ConditionStr = ConditionStr & TempText(i) & " and " End If Next i sql = "select " & Colstring & " from " & tableename If ConditionStr <> "" Then ConditionStr = Mid(ConditionStr, 1, Len(ConditionStr) - 4) sql = sql & " where " & ConditionStr End If If OrderStr <> "" Then sql = sql & OrderStr TetRec.Open sql, G_UserCon, adOpenDynamic, adLockPessimistic, adCmdText Set mGrid.DataSource = TetRec TetRec.Close
大体就这样了。