Foxtable数据库应用开发宝典
人民邮电出版社
北京
图书在版编目(CIP)数据
Foxtable数据库应用开发宝典/贺辉,周菁编著.--北京:人民邮电出版社,2019.1
ISBN 978-7-115-49789-5
Ⅰ.①F… Ⅱ.①贺…②周… Ⅲ.①关系数据库系统—程序设计 Ⅳ.①TP311.138
中国版本图书馆CIP数据核字(2018)第240551号
◆编著 贺辉 周菁
责任编辑 李永涛
责任印制 马振武
◆人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
三河市君旺印务有限公司印刷
◆开本:787×1092 1/16
印张:37.5
字数:886千字 2019年1月第1版
印数:1-3000册 2019年1月河北第1次印刷
定价:99.00元
读者服务热线:(010)81055410 印装质量热线:(010)81055316
反盗版热线:(010)81055315
广告经营许可证:京东工商广登字20170147号
Foxtable是一款国产软件,它与Excel非常类似,不同的是,Foxtable既是办公软件,也是二次开发平台。从应用角度来说,无论是数据录入、查询、统计还是报表生成,Foxtable都比Excel更加强大和易用;从开发角度来说,Foxtable又是一个高效的.net平台开发工具,用户在开发过程中只需关注商业逻辑,无需纠缠于具体功能的实现。
全书共分3篇9章,详细介绍了Foxtable在日常数据应用、桌面程序开发、B/S及手机端程序开发上所必须掌握的一些基本知识、操作技巧及开发思路,非常适合职场数据管理人员、高等院校信息管理专业师生及程序开发爱好者阅读。
如果有人告诉你,有这样一款软件,不管你有没有基础,只需一周左右的时间就能让你成为一个数据管理高手,而且其数据录入之快捷、统计查询之强大、报表输出之多样,目前市面上的软件无出其右;同时只要你愿意,它可以立即变身为一个开发平台,而且从PC到手机、从C/S到B/S、从客户端到服务端、从单机到局域网再到互联网、从常规的数据管理到文档管理、从单业务管理系统到企业整套ERP,包括企业IM,它都能胜任开发,并且可以编译成独立的可执行文件。它不仅简单,而且高效,高效到一人可抵一个小团队;它能让一个完全没有接触过编程的职场菜鸟,在3个月甚至更短的时间内蜕变为一个管理软件开发的全栈工程师。
你可能不会相信,真的有这样的软件吗?有,它就是Foxtable!
简单和强大永远是矛盾的,但Foxtable却在二者中取得了很好的均衡,使得二者不再是完全对立的两面,下面通过一些常用的功能看看Foxtable如何将看似强大的功能做到极致的简单。
1.轻松输入
用Excel实现下拉列表输入相当复杂,但是在Foxtable中却异常简单,以下图的“学历”列为例,只需在列属性设置中将其下拉列表框设置为“博士”“硕士”“本科”“大专”“高中”“初中”“小学”,即可用下拉列表形式输入学历。
如果在设置列表项目的同时需要将扩展列类型设置为“多值字段”,就可以从下拉列表框中选择多个值输入,如下图的“负责人”列。
对于日期列和数值列,如果在列属性设置中将“使用内置输入器”设置为True,则可以使用下拉日历或计算器输入数据,如下图的“入职日期”列。
更令人拍案叫绝的是,Foxtable可以使用目录树作为下拉列表。例如,下图的“大类”列就设置了目录树列表,单击目录树中的某个节点,能够同时输入“大类”“二类”“三类”这3列的数据。
下拉列表还可以是一个表,如下图所示。
要完成这些看似复杂的功能,并不需要编写任何代码,只需进行一些简单的设置即可。
Foxtable内置了图片和备注编辑窗口,可以很方便地编辑长文本和管理图片,如下图所示。
图片的管理是通过扩展列类型实现的,在一个单元格中可以插入多个图片,此外,也可以将列扩展为文件列,这样就可以管理任何类型的文档,如下图所示。
2.轻松统计
有下图所示的一个订单表。
假定你需要得到下图所示的统计分析结果。
要在Excel中完成这样的统计,相信对于绝大多数的用户来说,都是一件不可能完成的任务。而在Foxtable中,不用编写任何代码,只需简单地单击几次鼠标,在菜单中执行分组统计命令,然后按下图所示进行设置,最后单击【确定】按钮即可。
如果要编写代码完成上述统计,即使对资深程序员也是一件颇费时间的任务,代码至少百行以上,而在Foxtable中则只需寥寥几行:
Dim g As New Group Table Builder("统计表1", Data Tables("订单"))
g.Groups.Add Def("日期", Date Group Enum.Year, "年")
g.Groups.Add Def("日期", "月")
g.Totals.Add Def("数量")
g.Totals.Add Def("金额")
g.Same Period Growth = True ‘开启同比分析
g.Circle Growth = True ‘开启环比分析
g.Build()
Main Table = Tables("统计表1")
上述代码只有9行,而且无任何复杂的逻辑,普通用户经过简单的基础学习就能掌握。实际上,我们并不需要自己编写代码,因为单击设置窗口的【生成代码】按钮,即可根据现有设置自动生成上述代码。
再例如,假定要得到下图所示的每年各产品的销量、占比及各产品的总销量和总占比。
同样只需单击几次鼠标或使用不到10行的代码即可完成。
Dim g As New Cross Table Builder("统计表1", Data Tables("订单"))
g.HGroups.Add Def("产品")
g.VGroups.Add Def("日期", Date Group Enum.Year, "{0}年_数量")
g.Totals.Add Def("数量", "数量")
g.Horizontal Total = True
g.Vertical Total = True
g.Vertical Proportion = True
g.Build()
Main Table = Tables("统计表1")
以上只是Foxtable统计功能的牛刀小试,Foxtable内置合计模式、汇总模式、分组统计、交叉统计等多个统计工具,以前需要数小时甚至数天才能完成的统计,现在可以随时信手拈来。
3.轻松报表
以Excel为代表的电子表格制表功能强大,可以设计出非常复杂的报表,但在数据输入、查询和统计分析方面,远不如数据库软件强大便利,而Foxtable则结合了二者的优势,可以直接利用Excel设计报表模板,然后根据此模板批量生成报表,如下图所示。
Foxtable还可以利用Word设计报表模板,如下图所示。
4.轻松查询
和统计功能一样,Foxtable查询功能之强大、智能和方便,可以说到了令人难以置信的程度,以日期查询为例,假定日期列中某个单元格的值为“2018-9-18”,右击此单元格,弹出的筛选菜单如下图所示。
由图可见,可以通过菜单筛选出等于、早于或晚于此日期的行,也可以筛选出和此日期同年、同月、同日、同季度或同星期的行,还可以直接筛选出指定季度或月份的行。例如,单击上图菜单的【范围之内】命令,可以弹出下图所示的对话框用于筛选指定日期范围内的行。
不仅是日期列,字符列和数值列同样有类似的智能筛选功能。包括智能筛选在内,Foxtable合计提供了10种筛选功能,其中最为方便的是筛选树。可以根据数据表的任意列生成一个目录树,然后单击相应的节点,即可筛选出对应的行。例如,下图筛选出了2009年1月产品为“PD03”的销售记录。
5.界面设计
Foxtable的初始界面虽然类似于电子表格,看起来就是一个普通的应用软件,但实际上Foxtable还是一个真正的开发平台,提供了非常强大的菜单和窗口设计功能,以下两图就是基于Foxtable设计的两个窗口,前者为主界面,后者为数据输入对话框。
与普通的管理软件二次开发平台不同,Foxtable具备编译功能,能将设计好的系统编译成可执行文件,成为独立的软件,脱离Foxtable运行,所以完全可以基于Foxtable开发商业软件,实际上有相当多的软件公司和咨询公司正在使用Foxtable进行开发。
6.B/S和手机开发
Foxtable内建Web服务及手机网页生成功能,普通用户即使完全不懂网页设计,也能基于Foxtable快速开发出手机端的管理系统。下面就来演示Foxtable在这方面到底有多简单。
首先在项目的After Open Project事件中输入以下代码:
Http Server.Prefixes.Add("http://*/")
Http Server.Web Path ="d:\web"
Http Server.Start()
上面用3行代码就完成了一个Web服务器的搭建工作,这应该是目前最简单的Web服务器搭建方法。
然后将Http Request事件代码设置如下:
Dim wb As New We UI
wb.Add Form("","form1","addnew.htm")
With wb.Add Input Group("form1","ipg1","新增订单")
.Add Select("cp","产品","PD01|PD02|PD03|PD04|PD05")
.Add Input("gy","雇员","text")
.Add Input("kh","客户","text")
.Add Input("dj","单价","number")
.Add Input("zk","折扣","number")
.Add Input("sl","数量","number")
.Add Input("rq","日期","date")
End With
With wb.Add Button Group("form1","btg1",True)
.Add("btnok","确定")
End With
e.Write String(wb.Build)
以上代码用于生成网页,现在在本机打开浏览器,输入地址“http://127001/”,即可看到下图所示的网页。
我们只用18行代码就完成了Web服务端的架设及客户端网页的生成。因为代码编写全部在Foxtable中完成,不需要借助其他平台,所以也不需要额外学习,只需掌握Foxtable即可。如果按常规方式自行编码,不仅代码量10倍于此,而且涉及的知识面非常多,需要很长的学习周期,一般用户很难掌握,这也是为什么手机端管理软件的开发往往只有少数专业人士掌握的原因。
7.企业IM
Foxtbale内置即时通信功能,可以用不到30行的代码,快速搭建一个企业内部的IM系统。下图所示为内置的企业IM聊天窗口。
值得一提的是,这个内置的IM系统可以和基于Foxtable开发的管理系统紧密结合起来,实现消息、数据和文档的自动收发,还可以直接和微信进行通信。
8.大数据管理
企业的数据量通常以百万行甚至千万行计算,对于这种级别的数据量,采用Excel管理是不可能的,但Foxtable却能轻松应对。Foxtable能连接局域网或互联网数据库,包括Access、SQL Server和Oracle等主流数据库,将外部数据库中的表添加到Foxtable中时,可以选择初始不加载数据或只加载少量数据(这一点很重要),然后通过代码或菜单设置加载树,如可以按下图所示的订单表设置加载树。
可以勾选“自动显示加载树”复选框,这样打开项目时就能自动生成加载树;或者在After Open Project事件中加上以下代码:
Tables("订单").Open Load Tree("日期 YM|产品",150,50)
表示根据日期(按年月)和产品生成加载树,加载树的宽度为150个像素,每页加载50行数据。下图所示为生成的加载树。
加载树和前面介绍的筛选树有些类似,但是筛选树是筛选已经加载的数据,而加载树是从后台加载符合条件的数据,而且可以分页加载。例如,在上图单击2010年1月的节点,即可加载该月的订单,该月的订单不止50行,可以通过目录树下方的按钮加载不同页面的数据,而且Foxtable的筛选和统计都可以直接针对后台所有数据,所以分页加载并不会对日常使用带来任何影响。有了加载树功能,Foxtable可以让一个普通用户,在几分钟内就能搭建完成一个基于互联网的大数据管理系统,而且不用编写任何代码。
9.无需留恋VBA
如果你是Excel或Word的资深用户,一定会留恋VBA,实际上你的VBA知识在Foxtable中一样有用。将原来的VBA代码稍作修改,就可用于Foxtable中。这样,除了Foxtable本身提供的Excel或Word报表功能外,还可使用VBA无所拘束地操控它们。
例如,在Foxtable中运行以下代码,将自动创建一个新的Excel工作簿文件:第1个工作表的名称为“测试表”,同时在A1单元格写入内容“我是用来测试的单元格”,保存的文件名为“d:\testxls”:
Dim App As New MSExcel.Application
Dim Wb As MSExcel.Workbook = App.Work Books.Add
Wb.Work Sheets(1).name ="测试表"
Wb.Work Sheets(1).range("A1").Value ="我是用来测试的单元格"
Wb.Save As("d:\test.xls")
App.Quit
由此可见,Foxtable已经针对国人的数据使用习惯及各种不同的应用场景,在Excel的基础上做了大量的功能优化、提炼及扩展。从某种程度上说,超越Excel已为事实。例如,在Excel中处理海量数据是很不方便的,尽管后来推出了Power Query与Power Pivot两个插件,但在职场环境中能熟练使用它们的仍然寥寥无几。而Foxtable的“数据展示面”虽然还是Excel(包括快速移动光标、快速复制单元格等操作方法甚至和Excel一模一样),但它的“芯”已经变为数据库,加上扩展的各种模块化功能,这样做起商业智能分析(BI)来才会更加顺畅、便捷、简单。
这里仅仅是让大家对Foxtable的定位和特点有个初步的了解,以坚定读者继续学习的决心。事实上,随着学习的深入,你会发现Foxtable所提供的功能远远不止于此。本书由Foxtable软件作者贺辉及资深用户周菁合作完成,尽管期间已数易其稿,但疏漏及错误之处仍在所难免,恳请广大读者批评指正。
作者
2018年7月
Foxtable是一款完全国产化的软件,在其官网首页上有很醒目的软件下载按钮,单击该按钮即可下载试用版以体验Foxtable的各种功能。安装、使用过程中如遇到任何问题,可随时到官方论坛发帖提问。
Foxtable正常运行时的界面参见下图。
很显然,整个Foxtable的工作区是由三大部分组成的:最上面的部分为菜单区;中间为数据区;最下面为状态栏。是不是和Excel长得非常像?Excel初始打开时默认有“Sheet1”“Sheet2”“Sheet3”这3个表,Foxtable也有3个表;Excel拖曳单元格区域可以自动计算,Foxtable也一样可以。
当然,这还仅仅只是表面上的“形似”,数据处理起来就会发现有太多本质上的不同。
Foxtable中绝大多数的操作都可以通过菜单来完成,现在先来看一下Foxtable的菜单构成。
由下图可见,Foxtable的菜单界面和Office 2007之后的版本非常相似,都是采用的Ribbon风格。
Foxtable的菜单和传统菜单有所不同,它包含以下几个部分。
❶功能区
系统菜单默认包括【日常工作】【数据表】【管理项目】【打印输出】【杂项】这5个功能区;而每一个功能区又是由功能组构成的。例如,【日常工作】功能区,包含剪贴板、数据、排序与筛选、数据统计、编辑、窗口等功能组;通过功能区和功能组可以将各种按钮按照功能分类,有序地组合起来。
当用户仅需将Foxtable作为办公软件使用时,仅【日常工作】一个功能区即可完成平时90%的工作任务。
❷快速访问工具栏、配置栏和文件菜单
快速访问工具栏位于窗口的左上角,配置栏位于窗口的右上角,如下图所示。
单击【文件】按钮,将出现与文件和打印相关的命令。
菜单功能区中的每个功能组都包括很多操作按钮,这些按钮可分为以下3种类型。
❶标准按钮
绝大部分按钮都是标准按钮,单击标准按钮即可执行某一项操作,如【复制】【剪切】【粘贴】等。
❷下拉按钮
单击下拉按钮将出现下拉菜单,用以选择具体的操作,如【数据】功能组中的【其他】按钮。
❸组合按钮
组合按钮其实就是标准按钮和下拉按钮的组合。组合按钮分为两部分,单击上半部分会立即执行某项操作;而单击下半部分将出现一个下拉菜单,用以选择执行更多的相关操作。
例如,【数据】功能组中的【增加行】按钮就是一个组合按钮。单击该按钮的上半部分,将直接增加一行;单击该按钮的下半部分,将出现一个下拉菜单,用以选择增加一行还是增加多行,如下图所示。
虽然Foxtable在外观上和Excel非常相似,但本质上是完全不同的:Excel是电子表格,而Foxtable则使用数据库。
以数值“2018年12月1日”为例,由于Excel并没有严格的数据类型限制,在表格中可能输入“20181201”,也可能输入“2018121”“12/01/2018”或者“18121”,甚至直接是英文或汉字,这就会给后期的数据处理带来很大的麻烦。为提升数据输入的准确率,Excel数据管理员一般会通过设置公式等方法来限定数据的有效性(Excel 2013以后的版本称为“数据验证”)。尽管如此,往往还是会出现“百密一疏”的情况,到最后出统计报表时仍然避免不了再走一遍“数据规范化”的流程。
而Foxtable采用的数据库管理方式,其最大特点就是规范化。比如,日期列就只能输入日期格式的数据,数值列只能输入数值,字符列只能输入字符串……,既然如此,当使用Foxtable来管理数据时,首先就应该创建数据表结构,并给相应的列指定数据类型。
现以Excel下图所示数据表为例,看看它们在Foxtable中是怎样进行管理的。
要在Foxtable中创建一个新的表结构是很简单的,常用以下4种方法。
❶在新建项目时创建或修改表结构
单击【文件】中的【新建】命令按钮,可在“创建项目”对话框中创建表,如下图所示。
其中,“表A”“表B”“表C”是Foxtable自动生成的3个数据表,每个表的列数默认为10。在这个对话框中,既可以通过单击【增加表】【删除表】或【重命名】按钮对表进行管理(比如仅保留“表A”并将其重命名为“订单”),也可以单击【上移行】或【下移行】按钮调整选定表的列顺序,单击【删除行】按钮将不需要的列删除。如果要设置的列数量大于10,可以将光标定位在最后一行的尾部,按“Enter”键或按“↓”键即可自动增加一列;如要修改指定行上的“列名”“长度”或“标题”,只需在相应单元格上双击,列类型的可选择项则有10个。
请注意,这里的“列名”不能以数字开头,更不能全是数字,也不能包括空格和各种符号(但可以使用下划线);“列标题”则没有任何限制,只要你觉得能准确地表达出语义就好。而且,“列标题”是可选的,当标题省略时,将自动以列名称作为标题在表格中显示。
由于Foxtable兼有办公软件和开发平台两种功能,当需要使用Foxtable开发自己的管理系统时,建议将“列名”设置为具有一定语义的英文单词或是简洁的中文。即便使用中文作为列名,也要注意简洁,因为这样更便于后期编写程序代码。
例如,有个用于保存客户名称的列,可以将列名设为拼音的简称“kh”,也可以设置为英文“custom”,而列标题可设为“客户”,这样在后期的程序编码中将直接使用“kh”或“custom”,但用户看到的列标题仍然是很容易理解的“客户”。当然,为了后期项目维护的方便,尽量还是不要使用太过简洁的列名,如“kh”之类的。事实上,对于习惯于Office办公软件的用户来说,直接使用简洁的中文名称也是不错的选择。
当后期需要修改标题时,比如觉得用“客户名称”可能更为合适,那么只需将列标题改为“客户名称”即可,原来编写的程序代码无需作任何修改,因为列名并没有发生变化,标题的修改不会对系统的正常运行产生任何影响。
❷在当前项目中创建表结构
如果用户希望直接在当前打开的项目中创建新表,可通过【数据表】功能区的【表相关】功能组进行操作,如下图所示。
很显然,所有涉及当前项目数据表的增加、删除、重命名、复制、移动等操作,都集中在这个功能区中。单击【增加表】按钮,系统将弹出下图所示的增加表对话框。
默认情况下,Foxtable在增加表时会自动生成10个列字段,可以根据需要对其进行修改。具体操作方法与新建项目时的修改表结构相同。
表结构设置完毕,单击【确定】按钮,还将弹出表名及表标题的设置对话框,如下图所示。
关于表名和表标题的输入规则与“列名”“列标题”完全相同。
在新表创建之后,如果不再需要系统自动生成的“表A”“表B”和“表C”,可分别选中它们,然后单击【删除表】按钮予以删除。删除表时一定要慎重,因为这种操作是不可逆的,如下图所示。
选择表时,既可使用鼠标单击表标题的方法,也可单击表标题所在位置右侧的下拉箭头,在弹出的下拉列表框中进行选择(这在项目中存在很多表时会非常方便)。
❸在当前项目中以修改表结构的方式创建表
如果不喜欢上述两种创建表的方式,也可以在Foxtable默认生成的3个表的基础上直接修改,当表数量不够时再单击【增加表】按钮添加。
假如希望修改“表A”的结构,可先选中该表,然后单击【数据表】功能区的【表相关】功能组中的【其他】按钮,如下图所示。
这是下拉菜单按钮,执行【查看表结构】命令。如要修改第一列,只需在相应的行上双击,即可弹出“更改列-第一列”对话框,这样就可以修改“第一列”的相关设置。如下图所示。
假如将“表A”修改为处理订单数据的表结构,那么还应该给该表重新设置一个更具语义的表名。单击菜单【数据表】→【表相关】中的【重命名】命令按钮,在打开的对话框中进行设置,如下图所示。
关于表名和表标题的重命名规则与“列名”“列标题”完全相同。
❹在当前项目中以复制方式创建表
如果要创建的表结构和现有的表大同小异,可以采用“复制表”的方式创建新表。【复制表】按钮在功能区【数据表】→【表相关】的【其他】下拉菜单中,如下图所示。
假如要在“订单”表的基础上创建一个结构基本雷同的新表,可以先选中“订单”表,然后单击【复制表】按钮,如下图所示。
如果选中“仅复制结构”单选钮,那么将自动创建一个结构完全相同的空表,后续再对该复制后的表稍作修改即可。复制表时,也可以选择连同表中的数据一起复制。关于复制条件方面的知识,可参考14节。
在Foxtable中,数据表的列类型共有四大类、10小类,如下表所示。
由上表可以看出,数值型列共有6种,除了整数和小数的差别外,主要是范围和精度的差别:范围越大,精度(有效数字)越高,那么占据的存储空间就越大,处理速度也就越慢。特别是高精度小数,除非确有需要;否则不要选用。那么究竟怎么选择呢?有个简单的方法:没有小数的列选择整数型,有小数的列选择双精度小数型,这会符合绝大多数场合的需要。唯一需要注意的是,整数的范围并不大,在−2147483648~2147483647之间,如超出此范围,可用双精度小数代替。
小数的有效数字是指从左边第一个不是0的数字算起,直到最后一个数字,就是一个数值的有效数字。例如,1324的有效数字是4位(1、3、2、4),13240的有效数字是5位(1、3、2、4、0),而0024的有效数字是两位(2、4)。明白了有效数字的概念,有助于选择合理的小数类型。例如,对于订单表中的折扣列,范围在0~1之间,精度通常不会超过3个有效数字,那么选用单精度类型完全符合要求。
现以订单表为例,假如采用之前所介绍的第二种方法来创建表,应当把“产品ID”“客户ID”设置为字符型,长度为3;“单价”和“折扣”设置为单精度小数,“数量”设置为短整数,“日期”设置为日期时间型,如下图所示。
由于“订单”表只有6列,而Foxtable默认生成的表有10列,后面多余的4列可以单击【删除行】按钮予以删除。修改后的“订单”表结构如下图所示。
同理,根据Excel中另外两个数据表“产品”“客户”的数据内容,再分别添加两个表,即“产品”和“客户”表,如下图所示。
在数据表全部创建完成后,如果需要调整它们的位置,可在【数据表】功能区的【表相关】功能组中单击【左移表】按钮,将当前选中的数据表向左移动,单击【右移表】按钮可向右移动。除了菜单方式外,也可以通过拖动的方式来移动表。例如,要将“订单”表移动到“客户”表的后面,可以用鼠标选择“订单”表后按住鼠标左键不放,然后向右拖动到合适位置释放鼠标即可。
在实际工作中,如果仅仅只是对指定表的某个列进行处理,可直接单击【数据表】功能区的【列相关】功能组中的相关命令按钮进行快速操作,如下图所示。
例如,单击【增加列】按钮将在当前表的最后位置添加一列,单击【插入列】按钮将在当前光标所在列的前面插入一列,单击【更改列】按钮可重新设置当前光标所在列的表名、表标题及数据类型和长度,单击【删除列】按钮可删除当前光标所在列,单击【左移列】和【右移列】按钮可将当前光标所在列进行左移和右移。
至于列相关的其他操作,如【表达式】【重置列】【列属性】等,后面还将有专门讲解。
❶不要忘记设置主键
对于数据管理来说,主键是一个非常重要的概念。
我们每个人都有一个身份证号码,每个身份证号码都是唯一的,在正常情况下,不会再有其他人的身份证号码与你相同,这个号码就是我们的“身份标识”,是社会生活能有序进行的基础。
同样,数据表中的每一行记录都应该有一个主键值,这个主键值都是唯一的。不同的行其主键值绝对不会相同,所以行的主键值类似人的身份证号码,是行的“身份标识”,是数据管理能有序进行的基础。因此,在创建表时应该指定一列用于存储行的主键值,这一列就是主键列。
可能有的读者会问,之前在创建数据表时并没有设置主键的选项啊,那怎么处理?事实上,凡是通过Foxtable创建的数据表,都会自动生成一个名为“_Identify”的列,这就是主键列,每增加一行,该列的值就会自动在上一行的基础上加1,所以对于每一行来说,“_Identify”列的值都不会相同,是有效的“身份标识”。
出于安全考虑,凡是命名为“_Identify”的列,在修改表结构时都会被自动隐藏,以免用户误操作;由于该列仅用于数据行标识,日常操作中很少会用到,因而在显示的数据表中同样会被隐藏。
❷列名称最好使用有意义的英文单词或简洁的汉字,一旦设置就不要随便修改
列名、列标题的设置规则与表名、表标题完全一致。
如果担心这样的列名在数据展示时不够直观,可以在创建表时给每个列设置列标题。列标题是列名更具描述性的表示,没有任何书写规则上的限制。
❸对于复杂层次关系的列可使用多层表头
要实现多层表头的效果,只需在列名称或者列标题中包含下划线“_”即可。当然,最好是在列标题中使用下划线,如下图所示。
其中,东部用east中的e表示,西部用west中的w表示,季度用q表示,列标题用下划线进行分层。显示效果如下图所示。
❹谨慎使用标志列
Foxtable有两个专门的标志列名称:一个是“_Locked”,这是一个逻辑类型的列,用于标识数据行的锁定状态;另一个是“_Sort Key”,这是一个高精度的小数列,用于标识数据行在表中的显示位置,以实现数据插入功能。这两个标志列和主键“_Identify”列一样,在修改表结构或显示数据表时都是自动隐藏的。
● 锁定标志列:_Locked
正常情况下,对任何一个数据表的数据行,随时都可锁定,锁定后的数据行不能再修改。如果这个表在创建时没有添加“_Locked”列,则在项目退出后重新进入时,那些锁定的行会自动解锁,仍然可以编辑。这是因为数据表没有办法记录当时的锁定状态。
如要永久记录数据行的锁定状态,只需在对应的数据表结构上增加一个列“_Locked”。
● 插入标志列:_Sort Key
由于数据库本身并不存在记录插入这样的说法,每一条新增加的记录都是按顺序添加到数据表的最后一行。但在实际工作中,有时又会用到这样的功能:比如,公司已经输入了全部的人员名单,这个名单是按照职务高低顺序输入的;后来公司新来一位领导,按职位属于公司第二把手,这就需要输入到第二个人的前面,此时插入功能就派上用场了。
为实现这样的插入功能,就必须在对应的数据表结构上增加一个列“_Sort Key”。说白了,这种插入也是变通方法实现的,它在数据库中仍然排在最后一行,只不过在显示数据时按“_Sort Key”排序罢了。
很明显,为了实现上述两个功能,数据表上都要单独增加相应的标志列。如果数据量非常大,可能就会占用比较多的资源。因此,除非非常有必要;否则就不要使用这样的标志列。
默认情况下,凡通过Foxtable创建的数据表都会自动增加上述两个标志列。如果想在数据表中取消这样的功能,可单击【数据表】→【表相关】→【设置标志列】命令按钮,然后根据需要选择需要开启的功能,如下图所示。
上图中取消了“客户”表的“插入行标志列”的勾选,单击【确定】按钮后,该表中的“_Sort Key”列将被删除,那么以后在“客户”表中编辑数据时就不能再使用“插入行”的功能;同样地,如果将“产品”表的“锁定行标志列”取消勾选,那么该表的“_Locked”列也会被删除,日常操作时即使在该表中锁定了某个数据行,但在项目文件重启后仍然会失效。
取消后当然也可以再加上。例如,再次勾选“客户”表的“插入行标志列”复选框,单击【确定】按钮后就会在该表中重新加上“_Sort Key”列,插入行功能生效。添加“_Locked”列的方法同理。
尽管标志列的设定看起来非常方便,但在使用时仍然要慎重。一旦设置就不要再轻易修改,尤其是在有大量数据时。
❺自动隐藏列
综上所述,Foxtable提供了3个专用的列名,即_Identify、_Locked、_Sort Key,这3个列名默认情况下都是隐藏的,对普通用户是不可见的。
在创建数据表时,如果将列名以“sys_”开头,则该列同样会被自动隐藏,如sys_标记。
需要注意的是,这种隐藏仅仅是针对非开发者而言的。对于开发者来说,以字符“sys_”开头的系统列,和普通列无异,仍然可以显示,也可以对其进行更改(初次打开Foxtable时默认都是使用开发者身份。至于开发者和非开发者的区别第3章将有讲述)。
之前的所有操作仅仅是建立了数据表结构。表结构建立起来之后,就可以在其中添加数据了。
和Excel一样,可以直接在Foxtable的数据表中输入数据。
不同的是,由于Foxtable在数据表中事先定义了每列的数据类型,在相应的列中只能输入指定类型的数据。
例如,在订单表中,如果想在单价、折扣或数量列输入字符(包括汉字)是输入不进去的;同理,如果在日期列输入非日期格式的内容也是不会被接受的。这样就很好地避免了Excel中“群类乱舞”现象的发生。
❶单元格选择与快速移动操作
当需要在数据表中进行编辑、修改、复制、粘贴或删除时,首先要做的就是选择要操作的对象。在Foxtable中,选定数据或单元格的方法如下表所示。
和Excel类似,在Foxtable的数据表中也可使用以下方法快速移动光标。
按“Ctrl +↑”组合键移到同一列的第一个单元格。
按“Ctrl +↓”组合键移到同一列的最后一个单元格。
按“Home”键或按“Ctrl +←”组合键移到同一行的第一个单元格。
按“End”键或按“Ctrl +→”组合键移到同一行的最后一个单元格。
按上、下、左、右箭头键可以分别向上、向下、向左、向右移动单元格。
❷数据编辑操作
● 常规输入操作
选择要输入数据的单元格,直接输入数据即可。输入完成后按“Enter”键或“Tab”键将自动移动到右边的单元格;当移动到数据行的最后一个单元格时,按“Enter”键或“Tab”键将自动移动到下一行的第一个单元格。
当需要在单元格中换行时,可同时按“Ctrl+Enter”组合键,换行输入内容。当然,我们并不建议这样做,关于长文本的处理,本书第2章将给出完美的解决办法。
如果要修改数据,可在选择要修改的单元格后,按空格键或“F2”键进入修改状态,也可双击单元格进入编辑状态,并会将光标置于双击位置。
复制数据时,可以先选择要复制的单元格或单元格区域,按“Ctrl+C”组合键复制到剪贴板;然后单击要粘贴到的单元格,按“Ctrl+V”组合键。也可使用鼠标右键菜单或者【日常工作】功能区的【剪贴板】功能组中的按钮。当直接按“Ctrl+D”组合键时,可以将上一行相同位置单元格的内容复制到当前单元格,这是一种快速复制方法。
编辑修改数据时,如果在按“Enter”键或“Tab”键之前想撤销正在输入的内容,可按“Esc”键;也可单击快速访问栏中的【撤销】按钮。如果要撤销多步输入操作,反复单击【撤销】按钮即可,如下图所示。
在上图所示的椭圆形区域中,左侧的按钮为【撤销】,右侧的按钮为【重做】。
● 编辑功能组
在【日常工作】功能区的【编辑】功能组中,还有一系列常用的编辑功能,如下图所示。
○ 查找与替换
这是很多编辑类软件都有的功能,Foxtable中的用法也大同小异,如下图所示。
这里的查找位置可以选择要查找的列,匹配方式有以下4种。
完全匹配:单元格内容必须和查找内容完全相同,才算符合条件。
开始位置:单元格内容以查找内容开头即可。例如,若查找“abc”,那么“abcde”也是符合条件的。
结束位置:单元格内容以查找内容结尾即可。例如,若查找“abc”,那么“xyzabc”也是符合条件的。
任意位置:只要单元格内容包含查找内容即可。例如,若查找“abc”,那么“abcde”“xyzabc”“xabcy”等都是符合条件的。
如果单击【替换】按钮,则此查找窗口自动增加“替换”的内容,如下图所示。
替换方式有两种,分别是:全部内容和匹配内容。
全部内容:原内容将完全被替换。例如,匹配方式为任意位置,查找内容为“PTD”,替换内容为“UTC”,那么查找到的“HAPTD”都会被替换为“UTC”。
匹配内容:原内容中只有和查找内容匹配的部分才会被替换。例如,匹配方式为任意位置,查找内容为“PTD”,替换内容为“UTC”,查找到的“HAPTD”会被替换为“HAUTC”。
○ 插入符号
单击该按钮,出现插入符号窗口。双击其中的任一符号,即可将该符号插入到所选定的单元格中,如下图所示。
请注意,这些符号都保存在Foxtable安装目录下的文件SYMBOLTXT中,可通过修改这个文件,加入自己的常用符号、删除不常用的符号。如果单击“更多符号”按钮,还将弹出字符映射表,以方便查找自己需要的其他字符。
○ 标记与还原
当单击【标记】按钮时,所有在表中被修改过的单元格都会被标记出来,如下图所示,有4个单元格的内容被修改过。
如果需要撤销对某指定单元格的修改,可以先选定此单元格,然后单击【还原】按钮。很显然,这种处理方法要比标准的撤销按钮方便得多。因为撤销按钮只能逐步撤销上一步的操作,而无法单独跨步直接撤销对某个单元格的修改。
如果选定某个区域后,再单击【还原】按钮,将撤销该区域内的所有修改。
○ 序列填充、重复填充与快速清零
这3种编辑处理方法都在【日常工作】功能区的【编辑】功能组的【其他】下拉菜单中,如下图所示。
这里的【序列填充】和【重复填充】都是垂直方向的,也就是只能在某一列中向下填充。
序列填充:在填充区域的前两个单元格中,输入序列中的头两个值,如“001”“002”(也可以包括前缀,如“A01”“A02”);然后选定整个要填充的区域,单击【序列填充】命令即可在所选定的区域自动按相应的序列顺序填充内容。
重复填充:在填充区域的第一个单元格输入要填充的值,然后选定整个要填充的区域,单击【重复填充】命令或按“Ctrl+D”组合键即可。
例如,在“客户ID”列先输入C01和C03,然后选择10行要填充的区域,如下图所示。
执行【序列填充】命令后的效果如下图所示。
由于“C01”和“C03”的序列间隔为2,因此,后面的填充内容会顺序加2;如果执行【重复填充】命令,则所有的填充区域都会填入“C01”。
快速清零:将选定区域内数值内容为0的单元格内容全部清除,原来为0的单元格将变成空值。
❸数据行操作
默认情况下,Foxtable新建的数据表中只有10条记录,当需要增加记录时,可通过【日常工作】功能区的【数据】功能组中的按钮进行操作,如下图所示。
也可在任意的行号或单元格上,通过选择右键菜单进行处理,如下图所示。
需要注意的是,这里的【插入行】【上移行】【下移行】命令需要在表结构中设置了“插入行标志列”才能有效,【锁定行】【解锁行】命令需要设置“锁定行标志列”才能永久保存。
以下是Foxtable在处理数据行时的两个特别功能。
● 行号颜色
默认情况下,数据表的左边会显示每条记录的行号。行号的颜色是有特殊意义的,不同的颜色表示不同的行状态。
其中,灰色表示该行被锁定,既无法编辑也无法删除;橙色表示该行内容被修改了;红色表示这是新增行;蓝色表示这是保存在数据库中的原始行。
在上图中,第2~3行的行号为橙色,表示这是被修改过的行;第5行是灰色,表示该行被锁定;第6行是红色,表示新增加的行;第1行和第4行为已经保存到数据库中的原始数据,既未被修改,也没被锁定。
数据编辑完成后,一旦按“Ctrl+S”组合键或者单击窗口左上方的【保存】按钮,除了锁定行的行号继续为灰色外,其他所有行的行号都将变为蓝色,表示全部数据已同步保存到数据库中(被锁定的行如果在锁定前发生了更改,更改后的数据仍然会保存且继续保持锁定)。
请注意,锁定行在被解锁之后,即使没有对该行作任何手工修改,其行号颜色也会变为橙色。这是因为,从锁定到解锁,其状态已经发生了改变,数据库中的“_Locked”值由True变成了False。同样,对新增行锁定时,行号也只是在原来的红色基础上加灰,只有保存后才会完全变为灰色。
● 整行突出显示
在编辑和查看数据时,如果表很宽,左右滚动表格时,很容易将相邻行的数据误作本行的数据。为避免此情况,可使用【整行】命令以突出显示。
单击【日常工作】功能区的【编辑】功能组中的【整行】按钮,如下图所示。
那么当前表中的光标所在行就会突出显示(整行都有一种淡红色的背景),如下图所示。
如果已经有了现成的数据,可以不用再重复输入,将现有数据导入到Foxtable中即可。
例如,在Excel中已经有了现成的3个数据表,而且之前的数据表都是按照这3个表的结构来创建的,则可采用以下方法将数据导入到Foxtable中。
❶复制粘贴法
在Excel中选择要复制的内容区域(注意不要选择标题行,因为Foxtable的表结构中已经有独立的标题行了),按“Ctrl+C”组合键复制到剪贴板;然后在Foxtable相应数据表中选择目标区域的第一个单元格,按“Ctrl+V”组合键即可将剪贴板上的内容复制过来,如下图所示。
使用此方法时需要注意以下两点。
第一,要复制的表结构必须和Foxtable中的数据表结构完全一致,且列顺序相同;否则复制过来后将会出现错位现象。
第二,Foxtable数据表默认只有10行记录。当要复制的数据行大于10时,应在Foxtable中先行给数据表增加行数。如本例,Excel的订单表数据共有864行,要把这些内容全部复制过来,必须给Foxtable中的订单表增加854行。增加多行的方法:单击【日常工作】功能区的【数据】功能组中的【增加行】按钮,选择【增加多行】命令,如下图所示。
由于Foxtable每次最多只能增加300行,因此当需要增加854行的数据记录时就要执行多次【增加多行】命令。
❷导入法与合并法
如果现有数据量非常大,采用复制粘贴法就会非常不方便。如上例,虽然数据只有800多行,在Foxtable里就要至少先执行3次的【增加多行】命令,如果数据量上十万甚至更多,那岂不要把人搞死?因此,复制粘贴法仅适用于很少量的数据,大批量的数据要使用导入法或合并法。
这两种方法都在【杂项】功能区中,如下图所示。
其中,【高速导入】按钮用于导入最常见的4种类型文件,包括Excel中的xls和xlsx格式文件、Access中的mdb和accdb格式文件、d Base中的dbf文件以及文本txt格式文件。为方便操作,还有专门的【文本文件】【XML文件】及【其他类型】导入按钮。
“合并”与“导入”的命令按钮完全相同,仅仅是将导入改为合并而已。那么,“合并”与“导入”的区别在哪儿呢?
“导入”是将外部数据表的结构和数据一同添加到Foxtable中,导入完成后将自动在Foxtable项目中创建一个新表来保存数据;而“合并”仅仅是将外部数据添加到Foxtable已经存在的数据表中。
仍以之前的Excel文件为例,如果单击【高速导入】按钮,将首先弹出【打开】对话框用来选择文件,如下图所示。
这里选择“测试数据xls”文件。单击【打开】按钮,将列出该文件中包含的所有工作表,如下图所示。
需注意,Excel文件所列出的工作表中可能会有多个同名表,它们的区别仅仅在于是否有“$”后缀,一般选择带“$”后缀的数据表即可。如本例就选择导入“订单$”而不是“订单”。选择要导入的工作表后,还将列出该表所包含的全部列。如果不需导入某些列的数据,可将其勾选取消。一旦单击【确定】按钮,将弹出【增加表】设置对话框,如下图所示。
设置好表名,单击【确定】按钮将自动把Excel文件中的订单表数据以指定的表名称导入到Foxtable项目中。该表导入完成后,将弹出“是否继续导入其他表”的提示对话框,如此反复就能将所需要的全部数据表都导入进来。下图就是导入后的“订单”表数据,全部共864行。
如果不希望在Foxtable中新建数据表,而是仅仅将数据合并到现有的数据表中,可以使用“合并”功能。例如,将外部数据合并到Foxtable现有的“订单”表中,可以先在Foxtable中选择该表,然后单击【高速合并】按钮,在弹出的对话框中选择文件“测试数据xls”和工作表“订单$”,如下图所示。
合并数据时会自动比较列名,只有在Foxtable的数据表中存在同名列时才会合并。如上图所示,由于Excel文件中的列名和Foxtable中的订单表列名完全匹配,因而这些同名列的数据会全部合并过来;如果选择合并Excel中的“产品$”表,如下图所示。
由于该表只有一列“产品ID”和Foxtable中的“订单”表相匹配,因而只有该列数据会被合并进来,其他列全部为空。合并后的效果如下图所示。
其中,行号为红色的数据记录是新合并进来的数据。很显然,合并数据时不会对数据表中的原有记录产生影响,仅仅是在当前表中增加记录而已。
至于合并时的主键选择项,这些功能留待第3章再来讲解。这主要因为以上示例所合并的仅仅是Excel格式的文件,而Excel并不是严格意义上的数据库,它不存在主键之说,因而这些主键选择项对于Excel来说没有任何意义。
之前在创建或修改数据表结构时,用到的都是普通数据列,这些列都可直接输入数据,所输入的全部内容也都将物理保存在项目文件中。
所谓的表达式列,其内容是由一个表达式计算得出的。这些内容并不会进行物理保存,仅在运行时动态生成。这和Excel中的公式计算是一样的道理。
以Excel的订单表为例,假如希望通过单价、折扣和数量得到金额的值,可以先在G2单元格设置计算公式,然后按住G2单元格右下角的加号(填充柄)向下拖曳即可得到结果(或者双击填充柄),如下图所示。
拖曳或双击后得到的金额数值如下图所示。
此时,如果单击金额列的任意一个单元格,其上方的编辑栏显示的都是计算公式而不是具体的值,这就表明该列数据并不是物理存在的,而是根据其他列的内容动态生成的。
Foxtable的表达式列也是同样的道理。
例如,在订单表中增加一个表达式列:单击【数据表】功能区的【表相关】功能组中的【其他】命令按钮,选择下拉菜单中的【查看表结构】命令,或者直接单击【数据表】功能区的【列相关】功能组中的【增加列】按钮,选择下拉菜单中的【表达式列】命令,如下图所示。
弹出对话框如下图所示,先设置列名和数据类型。
然后单击“表达式”输入框右侧的【…】按钮,打开【表达式生成器】对话框,如下图所示。
其中,表达式编辑框下方的一排按钮为常用运算符,单击即可添加到编辑框中;下方左侧列表框列出的为常用函数,中间列表框列出的为当前数据表已经存在的数据列,双击均可添加到编辑框中;下方右侧列表框列出的为在线帮助,双击相应选项可查看具体的帮助内容。
需注意,字段名称列表中的“_Identify”和“_Locked”是隐藏列,其作用在之前的“创建数据表结构”一节中有过详细讲解。
表达式编辑完成后,单击【确定】按钮,将生成一个表达式列,如下图所示。
上图中,“金额”列的值就是根据其他列的值动态生成的。只要相关列的数据发生变化,该列数据也会自动即时更新。当需要修改表达式列的列名、标题或数据类型时,可以单击菜单上的【更改列】命令按钮;当需要修改表达式时,可单击【fx表达式】命令按钮。
注意:当表达式列没有设置计算公式时,虽然可以输入数据,但这些数据并不会被保存;已经设置了计算公式的表达式列,虽然手工可以修改列中的数据,但按“Tab”键或“Enter”键确认时仍然会自动还原为公式计算。
表达式不仅可以用于生成表达式列,还可用于条件设置等其他场合。例如,复制“订单”表时,可同时设置要复制的数据条件,如下图所示。
需注意,这里设置的条件只能使用数据列,不能使用表达式列。如上图所示,假如将条件改为:
[金额] > 500
单击【确定】按钮将不会有任何结果,这是因为“金额”列是表达式列!而且,在复制完成的数据表中表达式列不会被复制。
表达式由运算符、列名称及函数组成。首先说明一点,这些都是不区分大小写的。例如,运算符“In”可写成“in”,列名“产品ID”可写成“产品id”,函数“Len”可写成“len”等。
❶运算符
如同前面的“表达式生成器”对话框所示,常用的运算符有20个,实际数量比20个还要多。具体可分为以下几类。
● 算术运算符
此类运算符共有5个,分别为+(加)、-(减)、*(乘)、/(除)、%(取余数)。
其中,前4个都很好理解,第5个表示取余数:当使用%计算的结果为0时,表明前一个数可以被后一个数整除。例如,5 % 2的结果为1,表示5除以2的余数是1。
需要注意的是,使用%时,前后两个数字必须是整数,如51%2就会提示错误。
再如,将订单表中的“金额”列表达式改为:
[折扣] % [单价]
同样也会出错。这是因为折扣和单价列并不完全是整数。
● 比较运算符
此类运算符共有8个,一般需要配合表达式函数来使用。具体包括=(等于)、<(小于)、>(大于)、<=(小于等于)、>=(大于等于)、<>(不等于)、In(包含)、Like(匹配)。
其中,前6个运算符同样很好理解,例如:
[数量] < 100
现重点学习后面两个运算符。
○ In:用来判断某一个值是否为指定的多个值中的任何一个
例如,以下3个表达式就分别使用了字符、数值和日期3种数据类型进行判断,以表示指定列的值是否在所列举的范围之中:
[产品ID] In ('P01','P02','P03')
[数量] In (170,500,820)
[日期] In ('7/2/2012', #7/12/2012#, #2012-8-10#)
很显然,当使用In时,如果指定值为字符,要用单引号括起来;如果为日期,可用单引号或#号,日期值可以是“年-月-日”,也可以是“月/日/年”;其他类型数值可直接写。当判断的内容中有英文字母时,是不区分大小写的。例如,上面的第一行代码,当“产品ID”为p01、p02或p03时,也是符合判断条件的。
当指定的字符本身就带有单引号时,编写表达式时要用两个单引号代替。例如,以下代码表示判断标题名称是否为“你在用foxtable吗”:
[标题名称] In ('你在用''foxtable''吗')
由于这里只有一个判断值,因此也可以写成:
[标题名称] =‘你在用''foxtable''吗'
如果在In运算符之前加上Not关键词,表示不在指定的数值中。例如:
[产品ID] Not In ('p01','p02','p03')
○ Like:使用“*”或“%”通配符比较字符串
在这种比较中,“*”和“%”是可以互换的,表示任意个数的字符,且只能用在开头或者结尾。例如,判断以“P”开头的“产品ID”:
[产品ID] Like 'P%'
再如,判断是否以单引号结尾:
[产品ID] Like '*'''
需注意,在字符串的中间是不允许使用通配符的。如果要将通配符作为比较内容的一部分,必须使用中括号括起来,这样就会将“*”和“%”还原为普通的字符。例如,判断“产品ID”是否以“A*”开头:
[产品ID] Like 'A[*]%'
和In一样,Like运算符的前面也可以加上Not关键词,表示不类似的意思。例如:
[产品ID] Not Like '*A*'
● 连接运算符
在之前所举的表达式示例中,已经多次用到这种连接运算符。例如,[]用于连接列名称或者将“*”“%”还原为普通字符,单引号“‘”用于连接字符串,“#”用于连接日期。此外,还有以下几种常用的连接运算符。
():用于组合表达式或者强制改变优先级。例如,之前用于计算金额列的表达式为:
[数量] * [单价] * (1 - [折扣])
And:前后连接的表达式必须同时满足。例如,“产品ID”以P开头、同时数量小于500:
[产品ID] Like 'P%' And [数量] < 500
Or:前后连接的表达式只需满足一个即可。例如,“产品ID”以P开头或者数量小于500:
[产品ID] Like 'P%' Or [数量] < 500
计算表达式值时And优先于Or,可使用括号来强制改变这种优先级。例如:
([产品ID] ='P01' Or [产品ID] ='P02') And [数量] < 500
❷列名称
当在表达式中需要用到列名时,列名称最好用方括号括起来,尽管这并不是必需的。
但是,当列名称中含有一些特殊字符时,列名则必须用中括号括起来。关于这一点将在第3章中再作详细说明。
❸表达式函数
在“表达式生成器”对话框中,下方左侧的列表框就是一些常用的表达式函数。具体可分为以下几种。
● 聚合函数
此类函数一般用于数据统计,共有7个,即Sum(求和)、Avg(平均)、Min(最小值)、Max(最大值)、Count(计数)、Var(方差)、St Dev(标准偏差)。
其中,最后两个函数是用于测量数值型数据离散程度的重要指标,一般用于专业性较强的数理统计,日常工作中很少用到,基本可以忽略。
需要说明的是,表达式中的聚合函数很少在单独的数据表中使用,它一般用于关联表的统计。关于这方面的知识将在“表间关联”一节中学习。
● IIF函数
该函数使用频率很高,如果表达式的计算结果为True,则返回一个指定值;否则将返回另一个指定值。例如,将“金额”列的表达式修改为:
IIF([单价] = 0, Null ,[单价] * (1 - [折扣]) * [数量])
该表达式的意思是,如果“折扣”列的值为0,那么“金额”就设置为Null;否则就以单价、折扣、数量三列的乘积生成“金额”值。
在列表达式中,Null用于表示空值,也就是什么都没有。
● Is Null函数
该函数用于判定一个指定表达式的值是否为空值。如果不为空,则返回表达式的值;否则返回一个替代值。例如,将下图所示的第3行和第5行“折扣”为0的值按“Delete”键删除,它们就变成了空值。
然后将"金额"列的表达式修改为:
[单价] * (1 - [折扣]) * [数量]。
执行后发现,第3行和第5行“金额”列的值仍然是空。此种情况表明,只要表达式中存在空值,那么它的计算结果肯定也为空。如果希望将空值列正常参与运算,有以下两种处理方法。
第一种,使用IIF函数:
[单价] * (1 - IIF([折扣] Is Null, 0,[折扣])) * [数量]
该表达式的重点在于加粗的部分:如果“折扣”为空值,就以0替代;否则仍然取原来的折扣值。如果判断不为空,可使用Is Not Null。
第二种,使用Is Null函数:
[单价] * (1 - Is Null([折扣],0)) * [数量]
这里Is Null函数的意思是:如果“折扣”为空,那么就以0替代;否则仍然用原来的折扣值。
很显然,使用Is Null语句返回的是一个逻辑值;而使用Is Null函数则直接返回具体的数值。虽然仅有一个空格之差,但意义却完全不同!
以上两种方式的处理结果都是一样的,如下图所示。
● 字符处理函数
这方面的表达式函数有3个,即Trim(移除字符串的前后空格)、Substring(从字符串中的指定位置开始返回指定长度的子字符串)、Len(返回字符串的长度)。
例如,再增加一个临时的字符型表达式列,如下图所示。
这里表达式的意思是,取“产品ID”列和“客户ID”列的前两个字符并进行拼接(Substring的起始位置是从1开始的)。生成的表达式列效果如下图所示。
● Convert转换函数
该函数可以将表达式转换为指定的数据类型。其语法格式为:
Convert(expression,type)
其中,参数expression为要转换的表达式;type为转换成的数据类型。可转换的数据类型包括以下几种。
System String:字符型
System Date Time:日期时间型
System Boolean:逻辑型
System Byte:微整数
System Int16:短整数
System Int32:整数
System Int64:长整数
System Single:单精度小数
System Double:双精度小数
System Decimal:高精度小数
其中,只有“System Int64”和Foxtable数据表中的列类型不存在对应关系。该类型表示长整数,其值介于-9 223 372 036 854 775 808~+9 223 372 036 854 775 807之间。在Foxtable数据表中,此范围的整数一般是用双精度小数代替。
Convert函数除了可以转换数据类型外,还可变相实现一些其他功能。例如,列表达式并没有提供专门的四舍五入函数,只能用Convert函数来间接实现。假如将金额列保留两位小数,表达式可修改为:
Convert([单价] * (1 - Is Null([折扣],0)) * [数量] * 100, 'System.Int64')/100
该表达式的意思是,先将得到的计算结果乘以100,再转换为长整数;然后再以这个长整数除以100,得到的数据肯定最多只有两位小数。同理,如果要保留3位小数,将表达式中的100改为1000即可,其余类推。
再比如,利用数据表中隐藏的自动编号列“_Identify”,可以生成指定格式的编号列。假如希望编号列能够按照下面的格式显示:
MP0001
MP0002
┇
MP0011
MP0012
┇
MP0123
MP0124
┇
MP9998
MP9999
这种编码的规则是:前面是两个字母“MP”,后接4个数字,当数字的长度没有达到4位时要自动补充0。实现此目的的重点在于如何根据“_Identify”的值来确定补充多少个0:当“_Identify”的值是一位数时,要加3个0;是两位数时,加2个0;是3位数时加1个0。由此可见,需要补充的0的数量为:用4减去“_Identify”值的长度。用代码表示为:
4 - Len(Convert([_Identify],’System.String’))。
把这个长度用到Substring函数中,就表示要从字符串“0000”中截取的长度,也就是需补充多少个0:
Substring(‘0000’, 1, 4 - Len(Convert([_Identify],’System.String’)))
然后再在其前面加上字符串“MP”、在尾部加上“_Identify”列的值即可:
'MP'+ Substring('0000', 1, 4 - Len(Convert([_Identify],'System.String'))) + Convert([_Identify], 'System.String')
运行效果如下图所示。
如果要将编码的数字固定为6位,可将上述表达式中的“0000”改为“000000”,将4改为6。因而这种自动编号的表达式是可以通用的。
需要注意的是,当在列表达式中使用Convert函数进行数据类型转换时,日期型的数据只能与字符串进行转换,逻辑型数据只能与字符串及整数类型(Byte、Int16、Int32、Int64)进行转换。
单击【数据表】功能区的【列相关】功能组中的【其他】按钮,将弹出表达式列与数据列相互转换的下拉菜单,如下图所示。
❶ 当数据列转换为表达式列时,该数据列中的原有内容将全部消失,因为表达式列只能通过设置的表达式来动态生成数据。
❷ 同理,当表达式列转换为数据列时,由于该列的表达式已经被删除,因此数据一样会消失。既然已经转换为数据列,就只能自行编辑输入数据。
不论是数据列转换为表达式列,还是表达式列转换为数据列,一旦确定转换,Foxtable都会自动重新打开当前项目。
顾名思义,表间关联就是在多个表之间建立一种联系。
例如,在之前所创建的“产品”“客户”“订单”这3个表中,“订单”表中的每一个订单都分别在“产品”表和“客户”表中有对应的行。也就是说,每一个订单都会对应一个产品和一个客户。同样,“产品”表或者“客户”表中的每一行会在“订单”表中有若干条的对应记录(也就是订单)。如果能够在“产品”表与“订单”表、“客户”表与“订单”表之间建立关联,这些表就可以相互引用数据或者快速查阅关联数据。
在【数据表】功能区的【表相关】功能组中,单击【关联】按钮。弹出“表间关联”对话框后,再单击【增加】按钮即可设置表间关联,如下图所示。
关于设置关联的一些重要概念说明。
❶父表与子表
在“编辑关联”对话框中,左侧用于设置父表及关联列,右侧用于设置子表及关联列。那么,如何选择父表和子表呢?
仍以“产品”表和“订单”表为例。“订单”表中的每一条记录只能对应“产品”表中的一个产品(记录),而每一个产品在“订单”表中可能对应多个记录(订单),就像一个父亲可以有多个儿子,而一个儿子只能有一个父亲一样,这种一对多的关系就称为父子关系。很明显,在“产品”表和“订单”表之间建立关联时,“产品”表是父表,“订单”表是子表,它们通过“产品ID”列就可建立关联。
在Foxtable中,这种父子关系的约束其实并不是很严格的。也就是说,子表中的一条记录,也可以在父表中对应有多条记录。例如,一个作者可以写多本书,而一本书也可以有多个作者,不过实际应用时这种情况并不多见。
在上图中,父表和子表是通过“产品ID”列进行关联的。两个表的关联列名称未必完全相同,仅仅是本例中“产品”和“订单”表恰好都使用了相同的列名称而已:假如将父表的“产品ID”列改为“产品编号”,那么就可以设置父表的“产品编号”列和子表的“产品ID”列进行关联。尽管父表和子表的关联列名称可以不同,但其数据类型必须相同,且不能把表达式列作为关联列使用。
关联列数量不限,可根据需要随意增加。一般建议关联列的数量不要超过两个。
❷关联选项
关联设置对话框有两个选项,分别是【同步更新关联列内容】和【同步删除关联行】。
● 同步更新关联列内容。
如果选中此复选框,在父表修改某行关联列内容后,子表中对应行的关联列内容会同步更新,使得两个表之间的关联行始终保持联系。例如,“产品”表和“订单”表通过“产品ID”建立了关联,如果修改“产品”表中的“产品ID”,那么“订单”表中相对应的“产品ID”也会自动作出修改。
● 同步删除关联行。
如果选中此复选框,在父表中删除某行,在子表中对应的关联行会同步删除。例如,“产品”表和“订单”表通过“产品ID”建立了关联,如果在“产品”表中删除某产品,那么“订单”表中此产品的全部订单也会被自动删除。
❸设置关联名称
由于这是一个新创建的表间关联,单击【确定】按钮后,系统将提示输入一个关联名称,以方便后期的使用和管理。这个名称是自定义的,其命名规则和表名、列名完全一致,只要自己能够准确地理解其语义即可。例如,产品的英文是“product”,订单是“order”,可以简单地将它们之间的关联命名为“po”。表间关联创建之后,系统会自动生成一个关联表,如下图所示。
其中,显示在父表下方的“产品订单”就是系统自动生成的关联表,这个关联表的名称为父表标题和子表标题的两者相连,因此显示为“产品订单”。此时,在“产品”表中单击不同的记录行时,关联表会同步显示与当前“产品ID”相关联的订单记录。如上图所示,由于父表中的“产品ID”为“P02”,因而关联表就会从子表中调取与“P02”相关联的全部订单记录并给予显示。
❹不同的关联选项对管理表数据的影响
如果在创建关联时,没有选中【同步更新关联列内容】复选框,那么在父表上对关联列的任何修改都不会影响到子表。例如,将父表中的“P02”改为“A02”,这样修改之后,由于子表没有对应的“产品ID”为“A02”的记录,因而关联表不会有任何记录显示,如下图所示。
如果在创建关联时,选中【同步更新关联列内容】复选框,那么在父表修改关联列内容后,子表中相对应的关联内容也会同步更新。例如,在父表中将“P02”改为“A02”,子表中的“P02”也将被同步更改为“A02”,这样就可以使两个表之间的关联行始终保持联系,如下图所示。
需要注意的是,父表中的关联列内容可以修改,但不能将其内容删除,而且也无法删除,子表则没有此限制。例如,想将上图父表中的“A02”单元格内容进行删除是做不到的,只能进行修改,也就是内容不得为空。如果一定要删除,只能删除“A02”的所在行。
同样地,在删除父表中的数据行时,关联表数据会受到【同步删除关联行】选项的影响。其原理与“同步更新关联列内容”相同。
这里还要补充说明一点,由于关联表数据是基于其他表的,在关联表中对所做的任何修改都会同步体现到相对应的数据表中。例如,上图关联表中的“P02”都被改成了“A02”,而这个关联表是基于“订单”生成的,因而“订单”表中的“P02”也都改成了“A02”,如下图所示。
再如,在关联表中增加行时,关联列的内容会自动输入,这个增加的行同样会体现在其对应的数据表中。而且,这种自动输入并不会受到是否选中【同步更新关联列内容】复选框的影响。
如下图所示,由于父表中的关联列内容为“B02”,那么当在关联表中新增数据行时,与其相关联的“产品ID”列会自动填上“B02”;如果设置的关联列有多个,则多个关联列都会自动完成输入。
假如父表和子表都有“产品ID”和“产品名称”列,同时希望在关联表新增行时,这两列都能自动输入,那么在建立父子关联时,仍然只需选择能唯一区分每一行的列(如“产品ID”),无需同时选择“产品ID”和“产品名称”列。如要实现“产品名称”的自动输入,可采用表达式列实现。
在关联设置窗口中,还可以设置关联模式,如下图所示。
关联表有3种生成模式,分别为“单向”“双向”“无”。现仍以“产品”表和“订单”表的关联为例。
❶“单向”模式
此为默认模式。在单向生成模式下,“产品”表的底端会出现一个关联表,标题为“产品订单”;但“订单”表的底端并不会出现关联表。
如果希望在“订单”表中单击某个数据行,同样可以查看该订单所对应的产品资料时,可使用双向模式。
❷“双向”模式
在双向生成模式下,无论是父表还是子表,其下方都会出现一个关联表。其中,父表下方的关联表显示的是子表数据,子表下方的关联表显示的是父表数据。
如下图所示,当在“订单”中单击“产品ID”为“P05”的数据行时,关联表会显示与之对应的父表记录。
关联表的标题名称变为“订单产品”,它是通过子表标题与父表标题拼接而成的。
为了更清楚地看到双向模式下的关联表生成情况,再将“客户”表和“订单”表建立双向关联,并将其关联名称命名为“co”(c表示客户“customer”,o表示订单“order”),如下图所示。
确定后就会发现,每个数据表的下方都会出现两个关联表,如下图所示。
在上图中,当在上方的“客户”表中单击不同的数据行时,下方的“客户订单”将显示与之相关联的订单数据,这是因为“客户”表与“订单”表是父子关系,它们通过“客户ID”列建立了关联;当在下方的“客户订单”表中单击不同数据行时,下方的“产品”表又会显示与之相关联的产品数据,这是因为关联表“客户订单”是基于订单表生成的,而“订单”表与“产品”表又通过“产品ID”列建立了双向关联,如下图所示。
由于“客户订单”表中所单击的数据行“产品ID”的值为“P05”,因而这里的“产品”表显示的就是与之相对应的数据记录。
如果不喜欢这种关联表的显示方式(同样的位置只能独立显示一个关联表,查看其他关联表时需单击下面的表名称切换),也可以在关联表中单击鼠标右键,选择快捷菜单【停靠位置】→【独立停靠】命令,这样会更直观一些(关于窗口停靠方面的知识将在下一章学习),如下图所示。
由此可见,双向生成模式可以为使用带来很多便利,使得无论选择哪一个表,所有相关的数据都可以信手拈来。再如,在“产品”表中,单击任意一个产品,可看到与产品相关的所有订单;单击“订单”中的任意一个订单,又能立刻显示与该订单相关的客户资料,如下图所示。
同理,在“订单”表中,单击任意一个订单,即可马上看到与该订单相关联的产品和客户信息,如下图所示。
很显然,如果将双向改为单向,那么就只会在“产品”和“客户”的下面生成两个关联表,“订单”不会生成关联表,也就无法做到双向生成那样的环环相扣、数据信手拈来。但是,双向模式下,随着关联的增加,表的数量也会按平方数增长;若项目中产生太多表,就可能会影响到运行效率。
如上例,分别在“产品”表和“订单”表之间、“客户”表和“订单”表之间建立两个关联,那么在双向生成模式下,系统会产生2×3=6个关联表,加上原来的3个数据表,合计就有9个表;而单向生成模式下只会产生两个关联表,加上原来的3个数据表,合计5个表,远远低于双向生成的表数据量。假如以后再把数据表增加到5个、建立4个关联,而这4个关联都选择了双向生成,那么就将产生4×5=20个关联表,加上原有的5个数据表,合计就有25个表,多么可怕!
当然,实际使用时是否开启双向生成完全根据自身的硬件性能及需求而定,只要不去滥用双向生成就好。
❸“无”模式
如果生成模式选择“无”,那么不管是“产品”表和还是“订单”表,底端都不会出现关联表,这样既不能在选择某产品时查看订购此产品的订单,也不能在选择某订单时查看其对应产品的资料。
你也许会感到奇怪,既然如此,那还建立关联干什么?
其实建立关联,有时并不仅仅是为了方便查看关联数据,更重要的是在关联表之间相互进行数据的引用和计算。如果建立关联的目的仅仅只是为了引用或统计数据,那么就直接将生成模式选择为“无”吧!
❶多级关联
如果“表A”和“表B”建立了关联,“表B”和“表C”建立了关联,也就是A是B的父表,B又是C的父表,三者的关系类似于“父(表A) →子(表B) →孙(表C)”这样的关系。
在双向生成模式下,将生成6个关联表,分别如下。
“表A”生成两个关联表:“表A表B”、“表A表B表C”。
“表B”生成两个关联表:“表B表A”、“表B表C”。
“表C”生成两个关联表:“表C表B”、“表C表B表A”。
在单向生成模式下,将生成3个关联表,分别如下。
“表A”生成两个关联表:“表A表B”、“表A表B表C”。
“表B”生成一个关联表:“表B表C”。
“表C”不生成任何关联表。
由此可见,单向生成并非每个关联只生成一个关联表,而是按照“父 → 子 → 孙”这样的路径逐级生成;而双向生成除了这条路径外,还多了反向的“孙 → 子 → 父”的路径,所以生成的关联表数量至少要翻倍。
❷同表关联
表间关联一般是将两个不同的表通过关联列联系起来。在实际建立关联时,父表和子表也可以是同一个表,这就是“同表关联”。使用同表关联时需要注意以下几点。
第一,双向生成对于同表关联无效,即使选择双向生成,Foxtable还是会按照单向生成模式生成关联表。
第二,建立同表关联时父表和子表的关联列必须不同。
例如,有一个“员工表”,其中有一列名为“上级”,用于输入此员工的直接上司的姓名;另有一列为“姓名”列,用于输入全部员工的姓名(包括所有的上级)。
现在新建一个关联,父表为“员工表”,关联列为“姓名”;子表同样是“员工表”,关联列为“上级”,这样在单击某个员工时会自动列出此员工的所有直接下属,如下图所示。
但是,如果在父表中单击除姓名为“王兵”以外的其他行时,关联表内容都为空。这是因为,其他员工姓名没有出现在“上级”列中。
同表关联在实际工作中极少用到,了解即可。
仍以之前的“产品”“客户”和“订单”表为例。假如已经创建了两个关联:一个是“产品”与“订单”通过“产品ID”列建立的关联,关联名称为“po”;另一个是“客户”与“订单”通过“客户ID”列建立的关联,关联名称为“co”。由于这里的关联仅仅用于不同表之间的数据引用和统计,因此在建立以上两个关联时,生成关联表的模式选择为“无”。
❶引用父表数据
在“po”和“co”两个关联中,“订单”表都是作为子表出现的。在这个表中,不论是“产品ID”还是“客户ID”,都只能显示具体的ID号。如果要在此表中同时显示具体的产品名称或客户名称,就可以通过引用父表数据的方法实现。
首先,在“订单”表中添加一个表达式列,列名为“产品名称”,然后编辑列表达式,如下图所示。
在该生成器对话框中,可选择的表有3个:一个是“订单”,也就是当前表;另外两个分别是“Parent(po)”和“Parent(co)”,也就是与当前表存在关联关系的两个父表。其中,“Parent(po)”表示产品表(关联名称为po),“Parent(co)”表示客户表(关联名称为co)。
由于要引用“产品”表中的数据,因而这里就选择“Parent(po)”。选择该父表后,列表框将显示该表中的所有列名称,如下图所示。
如果要引用该表中的“产品名称”数据,只需双击“Parent(po)产品名称”即可。
表达式设置完成后单击【确定】按钮,“订单”表将自动增加一个表达式列“产品名称”,该列的内容就取自产品表中的“产品名称”。同理,再增加一个表达式列“客户名称”,其内容取自客户表的“客户名称”列,如下图所示。
如此一来,“订单”表不仅能显示“产品ID”“客户ID”,也能同时显示它们对应的“产品名称”和“客户名称”了。
在引用父表数据时,如果当前表只有一个父表,列表达式可以简写为“Parent产品名称”或“Parent客户名称”。由于本例的订单表存在两个父表,因此“po”或“co”是不能省略的,必须通过关联名称来指定从哪个父表中引用数据。
此外,对于这种父表与子表之间的数据引用,父子之间必须是严格的一对多关系。理由很明显,如果不是一对多的关系,而是多对多的关系,那么子表在引用数据时,就不知道该引用父表中哪一条记录的数据了,从而导致错误。
❷统计子表数据
假如想在父表中统计相关联的子表数据,也是一样的处理方法。例如,现在想在“产品”表中统计不同产品的销售数量,可以在“产品”表中增加一个名称为“数量”的表达式列,如下图所示。
需注意,这里的表达式使用了聚合函数Sum,表示对指定的列求和:Sum(Child(po)数量)。这里的Child表示的是子表。
由于“产品”表只有一个子表,因此,该表达式也可以简写为“Sum(Child数量)”。
用同样的方法,也可以再增加一个“金额”表达式列,对子表中的“金额”进行统计。统计结果如下图所示。
列表达式可用的其他聚合函数还有Avg(平均)、Min(最小值)、Max(最大值)、Count (计数)、St Dev(标准偏差)、Var(方差),如在“客户”表中再增加下图所示的列表达式。
上图中所有的表达式列都是新增的,列表达式在右侧。执行后的效果如下图所示。
必须说明的是,通过聚合函数统计子表数据,只能是无条件的。但在实际工作中,有条件的统计非常普遍,怎样才能实现条件统计呢?这就需要采取一种变通的方法。
比如,“订单”表中有个用于记录“是否付款”的逻辑列,已付款的为True,未付款的为False。如果想在“产品”表中统计“已付款”和“未付款”的订单金额,就可以先在“订单”表中增加一个表达式列“已付款金额”,此列可作为统计过渡列使用。其表达式为:
IIF([是否付款] = True,[金额],Null)
也可简写为:
IIF([是否付款],[金额],Null)
执行后的效果如下图所示(如觉得此过渡列在“订单”表中显得多余,可将其隐藏)。
然后再在“产品”表中增加两个表达式列对此过渡列进行统计。这两个表达式列一个是“已付款金额”,一个是“未付款金额”。它们的表达式分别为:
Sum(Child(po).已付款金额)
Sum(Child(po).金额) - Sum(Child(po).已付款金额)
执行效果如下图所示。
是不是觉得有点麻烦且不太方便?确实如此,毕竟表达式所支持的函数有限,而且限制比较多,对于一些较为复杂的统计要求,有时会显得无能为力。
其实,Foxtable有两种方式来实现计算和统计:一种是利用刚才的表达式;另一种就是利用代码。表达式使用简单,计算速度快,即使10万行的计算也可以瞬间完成,而且不占据存储空间,仅仅在运行时生成计算结果;而用代码计算具备无比的灵活性,可以随心所欲,只要代码写得合理,运行速度一样快捷,但这就需要用到编程知识了。
关于编程,这是Foxtable作为开发平台使用时才用到的知识,本书第2篇将专门学习。
在本章“向数据表添加数据”一节中,我们知道了不同行号颜色所代表的意义,如红色为新增行、橘黄色为发生修改的行等。这些都属于样式的范畴,如果你愿意,可以自行在“表样式”中修改这些默认设置。
“表样式”在【数据表】功能区的【样式】功能组中,如下图所示。
需注意,此功能组中的【字体】设置对当前表中的全部数据有效,【靠左】【居中】【靠右】对选中的当前列有效,【表样式】则主要用于控制当前表中不同组成部分的外观,如行号、网格线、标题区等。
单击【表样式】按钮,将弹出设置对话框。在该对话框中包括“样式设置”和“配色方案”两个选项卡,可以控制表格外观的方方面面,如下图所示。
由于当前打开的数据表为“产品”,因而弹出的设置对话框在修改后仅对“产品”表有效。
❶样式设置
“样式设置”选项卡中的每项属性都是自我描述性的,很容易理解。例如,要更改新增行的行号颜色,只需在“行号颜色”这组属性中选择“新增行”选项,然后修改其颜色即可。
如果对某个属性的具体意义不是很清楚,可以更改该属性的值,然后单击【应用】按钮,即可看出更改该属性所带来的变化。
默认情况下,数据表是显示行号的。在显示行号时,数据行是否被锁定就通过行号的颜色来表示;如果想通过标记来表示数据行是否被锁定,就必须将“显示行号”设置为False。如下图所示,被锁定的行以勾号做标记,其他行为空白。很显然,通过行号颜色来表示行状态更直观。
除了锁定行可以显示标记外,当锁定列、锁定表、排序数据时也可以显示标记。关于这方面的应用稍后讲解。
❷配色方案
在“配色方案”选项卡中提供了涉及数据表12大类区域的背景及字体颜色的配色方案。通过这些方案可以控制表中所有区域的背景颜色和字体颜色。单击【应用】按钮即可看到设置效果,可随心所欲地去设置,单击【还原为默认值】按钮,就能回到初始状态(同时将“样式设置”及“配色方案”两个选项卡中的所有属性都还原为默认值),如下图所示。
配色方案的12大类区域具体包括以下内容。
● 数据区:表数据区。
● 选定区:表格内的选择区域。
● 标题区:表格标题区,包括列标题和行标题(行号列)。
● 选定标题区。包括选定行、选定列及选定区域时所对应的列标题和行标题。
● 交替行:交替显示的数据行。
● 冻结区:数据表中的冻结列。关于冻结列方面的知识稍后将学到。
● 焦点单元格:光标所在的单元格。
● 已修改单元格:发生修改的单元格。此样式效果只有在启用【标记】状态按钮时才有效,具体可参考“向数据表添加数据”一节。
● 当前行:光标所在的数据行。此样式只有在启用【整行】突出显示时才有效,具体可参考“向数据表添加数据”一节。
● 总计行:在数据表进入“合计模式”或“汇总模式”时自动增加的总计行。至于“合计模式”或“汇总模式”将在下一章讲解。
● 小计行:在数据表进入“汇总模式”时所自动增加的小计行,可设置最多达6级汇总下的小计行样式,分别为小计0~5。
● 空白区:表格数据没有覆盖到的其他空白区域。
例如,默认情况下,表格空白区都是灰色背景,如下图所示。
如果修改空白区的配色方案,将其背景颜色设置为浅黄色,如下图所示。
那么,数据表外围的空白区域就会显示为浅黄色,如下图所示。
事实上,在实际应用中,需要更改默认配色方案的时候并不多,只有以下两种配色方案较常用:
第一,交替行。
默认的交替行背景颜色和数据区是一样的,因而无法体现出交替行效果。如要使用交替行,只需将其背景或字体设置成与数据区不一样的颜色即可,如下图所示。
第二,当前行。
每当单击到其他数据行时,这个数据行就变成了当前行,这个数据行也就会以指定的样式显示。由于默认的当前行背景颜色比较浅,可以将其适当加深,如下图所示。
此外,上述12类配色方案中的选定区、标题区和选定标题区,在默认情况下设置是无效的,因为这涉及数据表的界面风格问题。
在【数据表】功能区的【表相关】功能组中单击【表属性】按钮,即可对当前数据表进行属性设置。下图所示为对“产品”表所进行的设置。
❶操作属性
● 允许编辑:如设置为False,当前表将不能修改,也就是锁定表。由于此功能很常用,因而菜单及配置栏都提供了相关的功能按钮,如下图所示。
需要说明的是,菜单中的【锁定表】命令,主要用于临时锁定,重新打开项目时仍然会回到非锁定状态;而表属性中一旦将“允许编辑”设置为False就会永久锁定。
单击菜单中的【锁定表】按钮和配置栏中的【查阅模式】按钮都可锁定表,再单击一次取消锁定。它们的不同之处在于:【锁定表】仅锁定当前数据表,而【查阅模式】是锁定所有表。数据表被锁定后,左上角将出现一个锁形标记。如不希望出现此标记,可在表样式中设置取消。
● 允许增加行:设置为False时将不能增加数据行。
● 自动增加行:设置为True时,当光标移动到最后一行的最后一个单元格时,按“Enter”键可自动增加一行数据记录,以提高数据输入效率。
● 允许删除行:设置为False时将不允许删除当前表中的数据记录。
● 允许锁定行:设置为False时将不允许锁定当前表中的数据记录。
● 允许解锁行:设置为False时将不允许对锁定的记录解锁。
● 允许复制粘贴:设置为False时将不允许复制粘贴表中的数据,防止重要数据被复制。
● 允许初始化:设置为False时将不允许对此表进行初始化,也就是清空表中的全部记录。关于初始化方面的知识可参考第3章。
● 允许重定向:关于重定向方面的知识,可参考第3章。
● 删除行需要确认:设置为False时将在删除数据行时不给任何提示,直接删除。
● 按“Enter”键向下移动:默认情况下,在表中按“Enter”键,光标向右移动;如将此属性设置为True,将向下移动。
● 按“Tab”键向下移动:“Tab”键在默认情况下的移动方向与“Enter”键相同。如将此属性设置为True,将向下移动。
● 分页后台筛选:设置为True时将允许用户通过菜单直接筛选后台数据。关于后台数据方面的知识可参考第3章。
❷鼠标属性
关于鼠标方面的属性设置共有5个,分别如下。
● 是否允许通过鼠标拖动列标题来调整列位置。
● 是否允许通过鼠标拖动调整冻结的列数。
● 是否允许通过鼠标拖动来调整列宽。
● 是否允许通过鼠标拖动来调整行高。
● 是否允许通过鼠标拖动来分别调整每一行的高度。
关于列方面的操作稍后将专门学习,这里重点看一下如何调整行高。默认情况下,调整行高是对表中的全部数据行进行统一处理的(标题行的高度单独设置,不会与数据行混在一起)。当需要调整表格中的数据行高度时,可将鼠标指针移到行号列的行分界线处,此时鼠标指针形状变为上下箭头样式,拖动鼠标至所需行高即可,如下图所示。
但这样拖动所改变的行高将对所有的数据行有效。如果仅需调整其中某一行的行高,可将“允许分别调整行高”设置为True,调整后的效果如下图所示。
需注意,以上光标属性的设置仅仅与鼠标操作有关。例如,将“允许调整行高”属性设置为False,这仅仅只是限制了使用鼠标拖动来调整行高而已,但【日常工作】功能区的【数据】功能组中的行高设置功能仍然可以使用,如下图所示。
在行号上单击右键,选择快捷菜单中的【设置行高】命令也是执行的相同行高设置功能,如下图所示。
其中,“指定行高”用于精确地设置行高,默认为21像素;“自动调整行高”用于根据指定的列内容来调整高度,这里可以选择根据哪些列的内容来自动调整行高。自动调整之后,所有行的高度都会等于最高的那一行,如果希望各行分别调整行高,可以取消勾选“相等行高”复选框。
例如,把“产品名称”列的宽度缩窄,然后选中“自动调整行高”单选钮,如下图所示。
自动调整后的行高显示效果如下图所示。
由于没有勾选“相等行高”复选框,因此只有第三行的高度变大以适应内容,其他行的高度仍然正常显示。
❸杂项属性
这方面的属性有4个。
● 使用界面风格。该属性默认为True,数据表的界面风格如上图所示。由于此界面风格下的表格标题及选择区域样式都是固定的,因此,表样式配色方案中的选定区、标题区和选定标题区设置无效。假如需要修改标题的配色样式,就必须将此属性设置为False。下图所示为重新设定标题及选择区配色方案后的应用效果。
在上图中,选择区域的背景颜色改成了粉红色,标题背景改成了红色,选定标题区则被改为红底黑字。
● 启用多层表头。多层表头是通过在列名称或列标题中包含下划线“_”来实现的,如将此属性设置为False,则列名称或列标题中所包含的下划线将被作为普通字符处理,这样也就关闭了多层表头的显示效果。关于多层表头方面的知识可参考“创建数据表结构”一节。
● 自定义图标。默认情况下,表标题前面是不显示图标的。如要显示图标,需先在【管理项目】功能区的【项目属性】的界面属性组中将“显示图标”改为True,然后再在表属性中设置“自定义图标”(关于项目属性方面的知识将在第3章中学习),如下图所示。
需要特别说明的是,在上述设置窗口中,单击右侧的【…】按钮可选择要使用的图标文件。这些文件不管它们原来的位置在哪里,一旦为Foxtable所用,都会被自动复制到Foxtable项目文件所在目录相应的子文件夹下。以后Foxtable项目再运行时,将仅使用这些新复制的文件,和原来的文件不再有任何联系。这样做的好处就是,可以很方便地将自己制作的Foxtable项目移植到任何电脑的任何目录(只要将整个项目文件目录打包即可),而无需再考虑项目所引用的第三方文件来自哪里。
以这里所选择的文件为例,由于是图片性质的第三方文件,因而会自动复制到项目所在目录的Images子目录下。应用后的效果如下图所示。
由于仅在“产品”表的表属性中自定义图标(图标大小建议为16×16),因而,另外两个表都会自动使用默认图标。
● 责任设计者。此属性仅在将Foxtable作为开发平台使用,且为多人协同开发时才会用到。
之前所学习的关于数据列方面的操作,还仅仅局限于数据表结构方面,如设置列名、列标题、列数据类型、列表达式、添加列、删除列、更改列等。由于数据表结构并不是需要经常改动的,因而之前学习的这些列操作功能都集中在【数据表】功能区的【列相关】功能组中。而现在开始学习的列操作,都是日常工作中经常要用到的,因而都放到了【日常工作】功能区的【数据】功能组中,如下图所示。
❶调整列宽
和行高的调整方式一样,将光标放到要调整列的右边界,光标形状将变为左右箭头形式,然后开始拖动,直到达到所需列宽后松开鼠标即可,如下图所示。
如果希望列宽自动匹配列内容的宽度,可在出现左右箭头时双击,列宽将会自适应内容的宽度。
如果希望同时调整连续多列的宽度,可按住其中一列的标题向左或向右拖动。选择好多列后,在其中任何一个列的右边界处拖动改变列宽,则所选中的列都会调整为一样的列宽;双击则全部自适应列宽,如下图所示。
需要注意的是,如果当前表已经在“表属性”中将鼠标的“允许调整列宽”设置为False,那么这里将无法使用鼠标方式来改变列宽(不会出现左右方向的箭头),只能通过菜单【日常工作】功能区的【数据】功能组中的【其他】按钮或列右键菜单中的【列宽】命令进行调整,如下图所示。
在这里可以设置具体的宽度,也可以单击【最佳列宽】按钮让列宽度自动适应内容。
❷调整列位置
先单击要调整列的列标题,然后再次单击并按住鼠标左键即可进行左右拖动,拖动过程中会动态显示目标位置,到达目标位置后松开鼠标即可。
需注意,调整列位置时,在列标题上执行的是两次单击;如果第一次单击后就直接按住鼠标右键拖动,只能是选中多列。
如果要同时调整连续多列的列位置,可以先选定多列,然后再单击其中任意列的列标题按住鼠标左键拖动即可。
和“调整列宽”一样,如果在“表属性”中将鼠标的“允许拖动列”设为False,那么这里将无法使用鼠标的方式来调整列位置,只能通过【数据表】功能区的【列相关】功能组或列右键菜单中的相应命令来调整,如下图所示。
❸冻结列
对于一个有很多列的表,可以冻结左边的部分列。这样在左右滚动表时,被冻结的列不会随其他列滚动,而是一直显示在表的最左边。
冻结列只能从最左边的第一列开始:将鼠标光标移到行号列的右边界,此时鼠标光标将变为锁形状,按住鼠标左键向右拖动,到达要冻结的最后一列松开鼠标即可,如下图所示。
被冻结的列将以与其他数据区相区别的背景颜色显示。如果对Foxtable默认提供的背景颜色不满意,也可通过“表样式”的配色方案重新设置,以改变冻结区的背景颜色和字体颜色。
当需要调整冻结列的范围时,可将鼠标光标移到冻结区和非冻结区的分界区,此时鼠标光标将变为锁形状,按住鼠标左键左右拖动即可调整冻结区的列数,如下图所示。
如要取消冻结,只需在鼠标光标变为锁形状态时,按住鼠标左键向左拖动,到达行号列后松开鼠标即可取消全部的冻结列。
和“调整列宽”“调整列位置”一样,如果在“表属性”中将鼠标的“允许冻结列”设为False,那么这里将无法使用鼠标的方式来冻结列,只能通过菜单【日常工作】功能区的【数据】功能组的【其他】按钮或选择列右键菜单中的【冻结列】和【取消冻结列】命令进行设置。
❹锁定列
数据表可以锁定,数据行可以锁定,列同样可以锁定。
单击菜单【日常工作】功能区的【数据】功能组中的按钮或者选择列右键菜单中的【锁定列】命令,即可将光标所在的当前列锁定,被锁定的列将无法进行编辑修改,如下图所示。
被锁定的列在列标题处会有一个锁形标记。如果不希望出现此标记,可以在“表样式”设置中将“显示锁定列标记”设置为False。
如要取消锁定,只需再次单击菜单中的【锁定列】按钮(如果使用列右键菜单,可选择【解锁列】命令)。
❺隐藏列
对于数据表中不需要显示的一些列,可以将其隐藏。例如,之前在学习关联表的按条件统计汇总时,为了在“产品表”中得到已付款金额和未付款金额,就在“订单表”中增加了一个名称为“已付款金额”的表达式列。此列仅作统计时的过渡列使用,无需展示给用户,完全可以将其隐藏。
要隐藏该列也很简单,只要先将其选中,然后在菜单【日常工作】功能区的【数据】功能组的【其他】按钮或选择列右键菜单中的【隐藏列】命令即可。
需注意,【隐藏列】仅仅是将该列置于不可见状态,但该列数据仍然是存在的,不会影响数据统计等操作。如果要将其再次显示,可以单击【取消隐藏】按钮,如下图所示。
显而易见,“取消隐藏列”对话框还同时兼有“隐藏列”和“调整列位置”的功能。如果要隐藏多列,而且是非连续的,使用“取消隐藏列”对话框更方便。
【列日常操作】小结
以上就是关于“列”方面最常用的5种操作。为方便使用,在列标题上单击鼠标右键可列出与上述5种操作相关的全部命令,如下图所示。
如果在表格的任意单元格上单击鼠标右键,则这里的“列相关”命令下还会同时列出与调整表结构相关的常用子命令,如增加列、删除列、更改列等。
因此,在Foxtable中,善用、多用右键菜单,不仅有助于更快地熟悉软件操作,更能大大提高工作效率。