

心得/经验/绝招
Access多条件格式研究笔记
2006-08-25 09:45:45
首先是熟悉和使用了一下条件格式,并实际应用了一下,感觉还不错,添加条件格式的窗口限制使用至多三个条件格式。条件格式可以设定的格式有:粗体,斜体,禁用,下划线,字体色,背景色,条件分三种类型,参数根据条件类型需要,可以有1-2个。
二、了解条件格式的数据对象
既然想要突破三个条件格式,而微软又不允许超过三个,在条件格式的编辑窗口中被禁用了,那么我们是不是有可能自己在内存中添加更多的条件格式呢?
首先想到的是找到条件格式的对象,于是我们新建了一个窗体,在上面添加了一个带条件格式的文本框,命名为Text0,打开VBA环境,在监视窗口中添加:Application.Forms(0).Text0,所有过程,所有模块。
展开Text0的成员后,我们发现了一个成员“FormatConditions”,没错,就是他了!让我们展开这个成员,看看他的内部结构,展开后发现,好像是一个集合,既然是集合,那我们能不能用常规的集合成员添加方法Add来添加超过三个呢?同时我们注意到了FormatConditions的类型是“FormatConditions”。
于是我们按F2打开对象浏览器。在对象浏览器中找到了FormatConditions这个集合,我们赫然看到,在成员中有个名为Add的方法。让我们来看看Add的声明:
Function Add(Type As AcFormatConditionType, [Operator As AcFormatConditionOperator = acBetween], [Expression1], [Expression2]) As FormatCondition
OK!我们这就来动手试试看添加超过一下,我们新建一个模块,加入以下代码:Option Compare DatabaseOption Explicit
Public Sub TestAdd() Dim FCs As access.FormatConditions Set FCs = Application.Forms(0).Text0.FormatConditions FCs.Delete FCs.Add acFieldValue, acEqual, "=1" FCs.Add acFieldValue, acEqual, "=1" FCs.Add acFieldValue, acEqual, "=1" FCs.Add acFieldValue, acEqual, "=1"End Sub
让我们来运行一下,access报如下错误:
运行时错误'7966'您指定的格式条件号大于格式条件数
点击调试按钮,我们看到程序挂起在第四个Add方法上,看来Microsoft的程序员没偷懒,这道门也被封了。
三、强制修改窗体 看来当窗体被载入内存后,想要代码添加条件格式是不可能了,那么载入内存以前呢?是不是那个程序员也没偷懒呢?我们这就来尝试一下修改窗体。 用Access来修改显然不现实,那我们就手工改,前面的帖子中,我曾经介绍过,用户窗体可以导出为.frm文件,但是access窗体好像没这个功能,我们在工程资源窗口选择导出,结果把窗体导出成了一个.cls的类文件,里面只有窗体代码,没有窗体的设计。 这时候我们想到了access有两个未公开的函数,就是SaveAsText和LoadFromText。我们这就来试试看。 打开立即窗口,在里面输入:Application.SaveAsText acForm ,"窗体1","C:\1.frm"
打开导出的文件,哈哈,果然是.frm格式,赶快找条件格式。在Text0定义段中,我们看到了以下内容:
ConditionalFormat = Begin 0x0100000066000000010000000000000002000000000000000200000001010000 , 0xff000000c0c0c000000000000000000000000000000000000000000000000000 , 0x0000000000000000000000000000000000000000000000000000000000000000 , 0x310000000000End
我倒!怎么是二进制代码?该死的M$……没办法,分析二进制代码格式吧……
经过半个小时的苦战……终于解读出二进制数据的全部格式:0:(4Bytes) FC头4:(4Bytes) nSize8:(4Bytes) fcCount
0:(4Bytes) AcFormatConditionType 4:(4Bytes) AcFormatConditionOperator 8:(4Bytes) pOffsetExpr1 12:(4Bytes) pOffsetExpr2 16:(1Byte) bEnabled 17:(1Byte) bBold 18:(1Byte) bItalic 19:(1Byte) bUnderline 20:(4Bytes) rgbsForeColor 24:(4Bytes) rgbsBackColor Strings(n) Unicode
OK!现在让我们来自己手工写出第四个条件格式来:
ConditionalFormat = Begin 0x010000009C000000040000000000000000000000000000000200000001010101 , 0x00000000ffffff00000000000000000004000000060000000101010100000000 , 0xffffff000000000000000000080000000a0000000101010100000000ffffff00 , 0x00000000000000000b0000000d0000000101010100000000ffffff0031000000 , 0x32000000310000003200000031000000320000003100000032000000End
(下面要做的工作我们需要随时保存,因为我们正在使用未经认证的数据,很有可能会导致access崩溃)
我们通过手工写出了四个条件格式的二进制存储数据,现在把他覆盖到.frm文件对应位置去。然后我们回到立即窗口,输入以下代码:Application.LoadFromText acForm ,"窗体2","C:\1.frm"
导入成功!我们把修改过的窗体加载为了“窗体2”。然后我们在设计模式下打开窗体二,选择Text0查看条件格式。天哪!条件格式窗口的控件都错位了,根本没法正常查看,明显的数据越界错误。
罢了,惹不起,不看了。直接运行窗体…… access在数秒停顿后,终于被错误关闭了。 Mission Failed ... 4、结束语 通过各种途径的测试,我们已经可以肯定,在内存中,FormatCondition并不是一个变长的数据存储结构,仅仅通过界面来控制条件格式的数量。而是只有三条数据的存储空间,因此在一个TextBox控件中,是不可能通过设定方式来实现多个条件的。 5、后记 虽然多条件格式从设计上而言,无法从数据角度来进行扩展,但是这并不意味着没有其他变通的方法,至少我们还有VBA。在本文的下篇中,将详细讲述多条件格式的实现。