大鸟的学习乐园
路漫漫其修远兮,吾将上下而求索
posts - 26,comments - 27,trackbacks - 0
Mysql 的rank 函数如何实现

表特征:
mysql> select * from test;
+------+------+
| a    | b    |
+------+------+
|    1 |   20 |
|    1 |   21 |
|    1 |   24 |
|    2 |   20 |
|    2 |   32 |
|    2 |   14 |
+------+------+
6 rows in set (0.00 sec)

现在,我们以a分组,查询b列最大的2个值。 这条sql要怎么写了?



1.创建表
Create Table: CREATE TABLE `sam` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8

2.插入模拟数据
INSERT INTO `sam` VALUES (1,10),(1,15),(1,20),(1,25),(2,20),(2,22),(2,33),(2,45);
+------+------+
| a    | b    |
+------+------+
|    1 |   10 |
|    1 |   15 |
|    1 |   20 |
|    1 |   25 |
|    2 |   20 |
|    2 |   22 |
|    2 |   33 |
|    2 |   45 |
+------+------+

3.SQL实现
select a,b,rownum,rank from
    (select ff.a,ff.b,@rownum:=@rownum+1 rownum,if(@pa=ff.a,@rank:=@rank+1,@rank:=1) as rank,@pa:=ff.a
    FROM
       (select a,b from sam group by a,b order by a asc,b desc) ff,(select @rank:=0,@rownum:=0,@pa=null) tt) result
    having rank <=2;

4.结果:
+------+------+--------+------+
| a    | b    | rownum | rank |
+------+------+--------+------+
|    1 |   25 |      1 |    1 |
|    1 |   20 |      2 |    2 |
|    2 |   45 |      5 |    1 |
|    2 |   33 |      6 |    2 |
+------+------+--------+------+
4 rows in set (0.00 sec)
posted @ 2011-01-28 13:28 大鸟 阅读(4035) | 评论 (2)编辑 收藏
记得刚参加工作时(那是97年),中国的IT刚刚兴起,那时,作为一个IT人士是一件很光荣的事,而那时的我正在做电气和电子相关的工作。99年第一次跳槽,进入了IT行业做软件开发。至今,中国的IT已经走过了十多年。但昔日的“光荣一员”却成为了现在的“IT农民工”,这究竟是怎么了?是中国的IT发展已经很好了所造成的吗?不是!在我看来中国的IT还比较的原始,还有很大的提升空间。我认为造成这一切的都是我们自己,是人!是我们的意识和方法问题。还记得刚从事软件行业时,当时有一句话很流行,这句话现在应当还能听到,那就是:做IT是吃青春饭。说实现在的,一直以来我对于这句话一点都不认同,但最近慢慢的觉得有道理。这种意识的转变不是因为自己在职业生崖上出现了什么问题,而是观察身边的人发现这句话还真有道理。由于不注意方法和不转变意识,我们当中的不少人过着“有工作没有生活”的日子,被工作压得失去了激情。接下来,让我说说我能想到或是看到的一些问题。

    1)我们从学校毕业以后,觉得学习到此结束,应当是享受人生的时候了。其实,学习和享受生活是“正交”的,我们完全可以即学好又生活好。毫无疑问我们是生活在竞争的环境中的,那竞争的依据是什么呢?就是我们的能力。大家参加工作后应当知道,我们学校所学的东西在现实工作中不足以成为我们的核心竟争力。要打造自己的核心竟争力,必须学习,而且是在自己的业余时间学习。当然,工作也是一种学习方式,只是这种学习方式不容易创造很大的能力区分度。此外,学习是保持激情的有效方法。我工作近12年了,在软件行业干了大约10年,但是至今我还保持着非常好的工作激情,这是我很多同事对于我的评价,这一点我想与我保持学习很是相关。学习是我从学校毕业开始一直没有放弃去做的事!学得多了,自然会想去改变些什么,进而使得我们有激情。我在面试别人的时候,我一定会问题的一个问题是:你平时看书吗?看些什么书?一个不看书的人,其能力不可能很高,看问题的深度也不会深到哪儿去。通过看书,能让我们更快的积累知识和经验。有些弯路我们不是需要自己去走、有些错误我们不是非得犯了才知道、有些好方法和想法也不是一定要我们自己去想,看书能让我们站得更高、看得更远。当然,学习过了的东西应当转化为我们自己的东西(参见第14、15点)。

    2)认为自己的能力与工作的年份是成正比的一条直线。在有些行业可能是,但在IT行业,这种想法是不对的。如果你了解三极管,我想我们的能力与工作年份的关系更像是一条伏安特性曲线。在开始的一段时间是线性的(因为我们刚毕业什么都不会),但之后从某一点开始永远是一个饱和区,到了饱和区后,能力的变化就非常的小了。这里要指出来的是,这条曲线的出现是因为我们从参加工作以来,都是采用同一种原始的方法去对待我们的工作的。如果我们善于改变自己的工作和学习方法,那么就不会得到一条伏安特性曲线,而有可能是一条接近直线的线。一个工作了七、八年左右的人,如果没有形成自己的一些思想(比如,设计思想),那么我认为很是有问题,自己得多去想想为什么。我们真正学习的黄金时间就是前面的七、八年左右。

    3)不明白练“内功”的重要性。这里的内功是指系统性的分析和看待问题,或是其它的一些能力(比如软件设计的能力)。有些人今天学这个、明天学那个,总喜欢学“新”技术,但忘记了将所学的东西串起来从而系统性的去掌握这些技术背后的东西。其实,一旦学精了一样,很多东西是相通的,如此一来,我们很容易快速的去掌握新的东西。再说说软件开发,其实学习编程语言是简单的,是基本功而且不是软件开发的全部,软件开发要学习的是如何设计好一个软件,这一点要掌握一定原则和方法,比如我在《一个好的设计应当具备哪些要素》中提到到的“四性”就可以作为我们设计时的一些原则。软件设计能力是本质,而编语言只是一种表达设计的工具。当我们“内功”好了以后,学什么都快、做得也好、看得也深,这与练功夫是一样的道理。

    4)害怕变化。拥抱变化往往能带给我们提高的机会。我们都有自己的舒适圈,我们害怕变化打破我们的舒适圈,但舒适圈的打破不是使得我们没有了舒适圈,相反意味着我们的舒适圈越来越大。我敢说,现在还有人在用Visual C++ 6.0做开发,而现在最新的是Visual Studio 2008(2010马上也要上市了),这不是因为Visual C++ 6.0比Visual Studio 2008好用,而是我们不想改变,还找个借口说“Visual C++太经典了”。而事实是,Visual Studio 2008能帮助我们更快的找出问题,不信试试看!我认为,一个勇于拥抱变化的人,他(她)的能力往往更容易提高。

    5)过于埋头苦干。有的人一接到任务那可就埋头苦干起来了,有时应当停下来想一想:我这样做的方法是不是很有效率?能不能通过学一点别的工具或是方法来使我的工作更高效?我能从中学到新的东西呢?还是只是一种重复性的体力劳动?还存在一种人,这种人的确很能干,因此领导什么事都让他(她)出马,这样一来再苦再累都扛下来。这个人,从上司的角度来看,很好,但从个人的发展来看不一定是一件好事。你想,这个团队没有你就不行了?我想可能性很小。那如果是这样为什么什么事都要你干呢?有的工作其实干过了一遍就没有什么可学的,只是上司因为放心你才将事情交给你,在这种情况下,花再多的时间去干对于自己来讲可能是在浪费时间。如果不干,省出来的时间我们可以去学其它的东西。可能有人会想,我如果不答应上司(参见第12点),那会不会对我的绩效不大好呢?其实,这种想法大可不必了,加上有时绩效并不是真正的公平(其实世上不存在完全的公平)。今年绩效好是一个短期利益,如果多学一点提高自己则是一种长期的利益。再说,我们不干的话还可以给别人创造一些锻炼的机会。真的是双赢!

    6)不善于思考。对于工作有时就是一个应声虫,别人怎么说,我们就怎么做。有时更为可怕的是:为什么那么做?合不合理?这种做法与我想到的做法有什么不同?这些问题全都不去想。一个没有自己思想的人,不可能在工作中比别人出色,能力自然也不会太高。

    7)不明白高效的完成工作对于我们自己意味着什么。高效意味着我们可以花节约下来的时间去学习、生活,毕竟工作不是我们人生的全部。我们时刻应当警觉自己是不是在做无效率的工作,如果是,想尽办法找出自己无效率的原因并改善它。有时我们会找借口,说现在太忙了,没有时间去改善,但真相不是这样的。我们完全可以通过一段时间的努力找到一种好的解决方法,将自己解放出来。的确,在忙的时候,如果为了解决无效率问题而花时间去学习其它的东西,那会让我们更加的忙。但这种更加的忙(短期的)是有回报的,而且往往回报很不错(长期的),不要总是想“等我有时间时再来改善”,“乱中求冶”永远是王道!

    8)见难就退,而不是迎难而上。容易意味着我们所学到的东西很少,或是根本就没有。做一百件容易的事,不如做一件难的事所学到的东西多。难的事多做一件,信心也会更强一点。

    9)不善于表达我们对问题的不同看法。有些人在工作中不敢去表达自己与别人相左的想法。我想,如果存在相左的意见,说明当中有可能会是别人有些东西没有想到,或是我们自己有些东西没有想到,而通过交流我们有可能相互提高。拥有一个开放的态度面对相左的意见!

    10)缺乏创新。一说到创新,比较容易让我们想到那种改变全世界的大举,其实不然,任何一种能改善我们生活的行为都可以认为是一种创新。创新也是一种思考和行动,是一种勇于改变现状的思考和行动。有的人在做一项工作时,其中有很多的重复(动作),即使烦,他(她)也不会想想是否可以写一个脚本去改变、或是采用什么方式解放自己。这一点或许与害怕变化(参见第4点)有关!

    11)不善于记笔记和总结。对于我们IT人士,笔记不一定要写在本子上,可以写成一个Word文档,或是其它的什么文件。在笔记中将自己碰到的问题写下来,这便于我们需要用的时候马上能找到。有了笔记我们能更高效的工作以及更高兴的工作。好处很明显,干吗不记笔记呢?通过笔记我们也能很好的总结自己,发现一些有待于提高的部分。

    12)不善于与上司沟通。通过沟通,一是可以从上司那得知他(她)对于我们的期望是什么,从而,我们可以得知自己的工作方式、方法是否与上司的期望是一致。如果不一致要想想,是不是自己可以改善,或是反过来改变上司原来的想法。第二就是要告诉上司你所期望的。比如,你想升级(职),那可以与上司说一说,当然,前提是你觉得自己的确能胜任。可能这一次上司并不会答应我们的要求,那也正常,因为他(她)有自己的考虑,此时上司可能会与你说原因。我们不能报着不同意就离职的态度来提要求。一次不同意,那我下次再提。在这种情况下,上司如果有一个名额,那很有可能就考虑到你了。沟通即简单也不简单,你所想的、做的不一定就是上司所想要的,如果这样的话结果自然也不会令自己满意。

    13)少了一点追求完美的执着。人是不完美的,所以我们要去追求完美。追求完美的人更容易出色、更具责任心,做事往往也显得更专业。

    14)不明白模仿的重要性。人天生就是模仿者,模仿多了,我们就会形成一定的思考和行事习惯,慢慢的也就转化成了自己的能力。我想很多人看过《设计模式》,可能在看时也有一种同感:其实,不少模式我们平时都在用。我做设计时,从来不去套《设计模式》中的模式,我能凭自己的直觉找到一种好的设计,当然,有时我得进行多次的反复。但是不是每一个人都有很好的直觉,这种直觉其实是一种能力,是长期的学习、思考和模仿所积累的能力。在我看来模仿是将所学东西转换为自己的能力的很好的一种方法。

    15)只求知其然,不求知其所以然。学习不能只是表面化的“学过了”,还要从深层次去想其背后的思想和原理是什么,这往往使得我们更加容易的去分析和解决问题。想得多了,自己的层次才有可能提高,如果只是停留在被动的接受,那很难有所提高。

    16)少了那么一点坚持。我们有可能在学习过程中少了那么一点坚持,本来已经做(学)到了90%,再坚持一下我们就能上一个台阶,能力也会有一个质的飞跃。但是很可惜,就是因为不多坚持那么一点,最后很有可能前功尽弃,最为可怕的是会打击我们的自信心 — 下次就不学了!人与人能力的区别或许可以说是能否坚持的区别!

    17)不热爱自己的职业。这一点可能是一些综合性的因素造成的,或是在工作中没有找到成就感、或是自己不适合这个行业,等等。有时好好的想想,问问自己是什么原因造成的这种状况。如果是因为自己的一些方式或方法不对,那么看看是否能改变。如果的确是因为自己对行业没有兴趣,那我想长痛不如短痛,还是应当转行去做自己有兴趣的工作。快乐的工作着是重要的!

    此外,除了注意个人的提高,我想我们还要注意“金字塔原理”。无论我们能力多高,但我们还是处于金字塔中的一层,也就是说能力强的人的数量总是相对的少,我们不可能人人都在顶上。即然这样的话,我们是不是就不应当去提高了呢?我想不是的,毕竟提高能改善我们的生活,而生活,是自己的。

    看了上面的这些,是不是觉得有些道理呢?千万别看过就完了,而是要有所行动!拥抱变化!

本文出自 “李云” 博客,请务必保留此出处http://yunli.blog.51cto.com/831344/169937

posted @ 2010-02-06 08:35 大鸟 阅读(157) | 评论 (0)编辑 收藏

 

下面是我所掌握的使用ADO对数据库操作的一些常用方法,主要是提供给初学者作为参考,有不对的地方请指正。如有补充不胜荣幸

准备工作

========

Dim conn As New ADODB.Connection '创建一个 Connection 实例,在这里使用New等于将Dim和Set合并为一段代码执行

Dim rs As ADODB.Recordset '创建一个 Recordset 实例,不使用New 是因为,经常需要重复使用Set,因此没必要在这里使用

Dim CnStr As String, Sql As String '创建两个字符串变量分别存放两个集合的SQL语句代码段

1、装载数据库(不属于Recordset集合)

=============

Dim FileNamw$, DbIp$, DbName$, DbUser$, DbPw$

'以上5个字符串变量分别表示文件路径和文件名、数据库地址、数据库名、数据操作员用户名、操作员密码

FileName = App.Path & "\'数据库名'"

DbIp = "数据库地址"

DbName = "数据库名"

DbUser = "数据操作员用户名"

DbPw = "操作员密码"

'以上变量根据数据库类型的不同而不同,有可能只需要1至两个变量

'1)连接Access数据库:

'-------------------

CnStr = "PROVIDER=microsoft.jet.oledb.3.51;persist security info =false;data source=" & FileName & ";Jet OLEDB:Database Password=" & DbPw

'2)连接Oracle数据库:

'-------------------

CnStr = "PROVIDER=MSDAORA.1;Password=" & DbPw & ";User ID=" & DbUser & ";Data Source=" & FileName & ";Persist Security Info=True"

'其中:

'PASSword: 密码

'User ID: 用户号

'Data Source: 数据库名

'Persist Security Info:

'Provider:

'3)连接VF的DBF库:

'----------------

CnStr = "PROVIDER=MSDASQL.1;Persist Security Info=False;Driver={Microsoft Visual FoXPro Driver};UID=" & DbUser & ";SourceDB=" & FileName &


";SourceType=DBF;Exclusive=No;BackgroundFetch=Yes;Collate=Machine;"

'4)连接SQL的数据库

'------------------

CnStr = "PROVIDER=MSDataShape;Data PROVIDER=MSDASQL;uid=" & DbUser & ";pwd=" & DbPw & ";DRIVER=SQL Server;DATABASE=" & DbName & ";WSID=GQSOFT;SERVER=" &

DbIP

'也可以使用这段简易代码 CnStr = "Provider=SQLOLEDB;Data Source=" & DbIp & ";DATABASE=" & DbName & ";UID=" & DbUser & ";pwd=" & DbPw

Conn.Open cnstr '使用 Connection 集合的 Open 方法 与数据库建立连接

2、Recordset集合的常用方法

==========================

'1)打开一个表

'------------

Sql = "select * from 表名" 'SQL查询语句

Set rs = New ADODB.Recordset '新建一个实例

rs.Open SQL, conn '使用 Open 方法打开数据库中的一个表

'注意,这种打开方式只能使用 rs.MoveNext (即,向后移动行坐标)而不能像其他方向,并且不能修改数据内容

'

'rs.Open SQL, conn,1 '虽然只加了个“1”,但这种方法可以向任何方向移动行坐标。

'

'以下参数代表了这个可选值的含义

'0 = adOpenForwardOnly (默认值)打开仅向前类型游标。

'1 = adOpenKeyset 打开键集类型游标。

'2 = adOpenDynamic 打开动态类型游标。

'3 = adOpenStatic 打开静态类型游标。

'

'虽然使用以上方法可以可以实现行坐标(游标)的任意移动,但是仍然无法写入数据。因此需要进一步的对Open 方法进行完善

'rs.Open SQL, conn, 1, 3 '后面的3是确定读写权限的

'以下参数代表了这个可选值的含义

'1 = adLockReadOnly (默认值)只读 — 不能改变数据。

'2 = adLockPessimistic 保守式锁定(逐个) — 在编辑时立即锁定数据源的记录。

'3 = adLockOptimistic 开放式锁定(逐个) — 只在调用 Update 方法时才锁定记录

'4 = adLockBatchOptimistic 开放式批更新 — 用于批更新模式(与立即更新模式相对)。

'

'2)读写数据

'----------

'增加一行记录并对新记录的内容进行修改并保存可以如下写法

rs.AddNew '增加一行记录

rs("...")="..." '数据读写操作

...

rs.UpDate '保存写入资料,如果使用只读权限,则不能使用这个方法

rs.Close '这个方法用来关闭你所代开的表,如果不使用这个方法也可以,但是数据库仍然认为你在对标进行锁定,可造成数据库负担过重

2、对数据进行筛选和排序

=======================

Sql = "select * from 表名" 'SQL查询语句

'以上为打开一个表的所有内容

Sql = "select top 50 * from 表名" 'SQL查询语句

'以上为只打开前50行的记录

Sql = "select top 50 列名1,列名2,列名5 from 表名" 'SQL查询语句

'以上为只打开前50行的记录,并且只打开第1、2、5列数据

Sql = "select * from 表名 where 列名1='" & 字段 & "'" 'SQL查询语句

'以上为一个简单的筛选,表示打开的内容必须符合[列名1='" & 字段 & "'"]的内容

'需要注意的是,数据库列的类型必须匹配,比如字符串类型需要以单引号括起

'而数字类型则不能用单引号括起

'另外SQL语句还支持通配符,例如 列名1 like '%" & 字段 & "%'" 表示包含[字段]

'在表达式中的匹配

'? _(下划线) 任何单一字符

'* or % 零个或多个字符

'# 任何单一数字(0 — 9)

'[charlist] 任何在字符表中的单一字符

'[!charlist] 任何不在字符表中的单一字符

'注:根据数据库的不同?、_和*、%的应用有所差别,比如SQL只使用% 和 _ 分别代表多个字符和单一字符

SQL = "select * from 表名 where 列名1='" & 字段 & "' ORDER BY 字段1 ASC" '对查询结果进行升序排列

SQL = "select * from 表名 where 列名1='" & 字段 & "' ORDER BY 字段1 DESC" '对查询结果进行降序排列

SQL = "select * from 表名 where 列名1='" & 字段 & "' ORDER BY 字段1 DESC, ORDER BY 字段2 DESC" '对查询结果进行多维降序排列(速度奇慢,不推荐使用)


3、Recordset集合的常用属性方法

==============================

rs.BOF '是否游标在最上边

rs.EOF '是否游标在最下边

rs.RecordCount '记录集的行数(如果使用像前类型的游标,可能返回不准确)

rs.AddNew '新建一行记录

rs.Update '保存当前行被修改的记录

rs.Delete '删除当前行

rs.Close '关闭记录集

4、Fields集合的一些属性的解释

=============================

'以下为简写,正常情况需要rs.Fileds.。。。但是Fields属于Recordset的一个默认集合,因此可以省略

rs() '括号内可以是列名也可以是列的序号例如:rs("姓名")、rs(3) 都是是可以的

rs(3).Name '返回列名

rs(3).Type '返回列的类型

rs(3).Value '返回当前行的值

rs.Fields.Count '返回列数

posted @ 2008-11-26 07:30 大鸟 阅读(298) | 评论 (0)编辑 收藏

VB应用程序的打包

 

    使用VB开发软件的最后一项工作就是打包应用程序生成安装包,利用VB本身提供的打包程序可以实现打包,但是如果软件中包含了其他非VB的文件,打包程序不能将这些文件也添加进来。根据个人的使用经验,特总结了以下两种打包的方法:

    方法一、VB打包程序+Winrar

    1首先利用VB的“打包和展开向导”进行打包:

    在VB的“外接程序”菜单里选择“外接程序管理器”命令,在“外接程序管理器”对话框中选择“打包和展开向导”:选中“加载行为”中的“加载/卸载”选项,点击“确定”关闭“外接程序管理器”对话框。

    再在VB的“外接程序”菜单里选择“打包和展开向导”,在“向导”对话框中选择“打包”功能:在接下来的对话框中选择“编译”功能,生成.exe文件;“选择包类型”为“标准安装包”;指定包的存储位置;其他选项根据自己的需要进行设定即可。                            打包结束,并闭VB。

    2、利WinRar制作安装包:

    将生成的包文件夹和软件中所需的所有文件放在一个文件夹中,并用Winrar对该文件夹进行压缩:选择建立“自解压文件”;在高级选项里,设定解压的目标文件夹(如C:)和解压完成后自动执行包文件中的setup.exe文件;完成压缩。

    经过以上两步生成的压缩包,在解压后会自动进行安装,实现软件的安装。

    方法二、VB打包程序+setup factory

    1首先利用VB的“打包和展开向导”进行打包,方法同上。

    2启动setup factory将包文件中“Support”文件夹的文件全部添加进行,并添加软件中所要包含的所有文件,按照向导的要求可以非常方便地完成安装包的制作。

     比较以上两种方法,方法一在没有专门的安装包制作软件的情况下也可以实现安装包的制作,但是对不同操作系统的支持性较差,在Windows2000下可用,在WindowsXP下可能会出现“路径错误”;方法二制作的安装包却更加专业,更加美观,支持各种操作系统,而且简单易用。

    此外,在应用程序当中在访问文件时要使用相对路径,否则可能会导致文件访问错误。

posted @ 2008-11-26 07:26 大鸟 阅读(8553) | 评论 (1)编辑 收藏

使用ADO控件可以方便的在VB6中访问ODBC数据库,但是通过直接放置ADODS控件来获得ADO的数据连接比较麻烦,我们可以在VB工程中创建一个公共数据模块,将ADO控件的初始化、建立连接、关闭连接等操作都写到函数中,这样就可以在工程的其他模块中共享调用这个ADO连接。
一次完整的ADO调用操作分为如下几个步骤:
1.打开ADO到数据库的连接,初始化ADO RECORDSET集。
2.通过写入SQL语句执行查询并返回查询结果RECORDSET集;或者可以通过写入SQL语句执行相应数据库操作。
3.释放RECORDSET集,关闭数据库连接。
需要注意的是,每个动态创建的ADO同时只能被一个过程调用,如果需要进行多表并行操作,可能需要在公共数据模块中建立多个动态ADO。
下面是相关的代码:

'-----------------------------------------------------------------
'如下代码保存在名为my.bas的工程模块中
Public CONN As Adodb.Connection        '定义ADO CONNECTION对象
Public RS As Adodb.Recordset           '定义ADO RECORDSET对象
'****************************
'打开数据库连接
'****************************
Function ConnOpen()                   
  Dim ASTR As String
  Set CONN = New Adodb.Connection
  ASTR = GetDatabasePath  'MDB文件数据库路径
  CONN.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ASTR & ";Persist Security Info=False"
  '本例的ODBC连接为JET4.0的直接到MDB文件的连接,如果使用ODBC数据源可以使用如下CONNECTION串:
  'Provider=MSDASQL.1;Password="";Persist Security Info=True;Data Source=数据源名称;Initial Catalog=数据表库名称
  CONN.Open
  Set RS = New Adodb.Recordset
  With RS Do
    ActiveConnection = CONN
    CursorType = adOpenDynamic
    LockType = adLockOptimistic
  End With
End Function
'****************************
'关闭数据库
'****************************
Function ConnClose()                       
   Set RS = Nothing
   CONN.Close
   Set CONN = Nothing
End Function

'**********************************************************
       获得数据库路径
本例数据库保存在程序目录下的DBS子目录中,名为db1.mdb
'**********************************************************
Public Function GetDatabasePath() As String
    Dim sPath As String
    If Right$(App.Path, 1) = "\" Then
        sPath = App.Path + "dbs\"
    Else
        sPath = App.Path + "\dbs\"
    End If
   
    GetDatabasePath = sPath + "db1.mdb"
End Function
'End of my.bas
'-----------------------------------------------------------------

如下示例代码为my.bas的使用方法:
'-----------------------------------------------------------------
'使用RS对象执行SELECT语句
'TableName和FieldName分别为表名和字段名
'查询结果保存在数组s中
Private Sub RunSelectCommand()
    Dim s(99) as String
    Dim i as Integer
    i=0
    Call my.ConnOpen
        my.RS.Open "SELECT * FROM TableName"
        While Not RS.EOF
            i=i+1
            If Not isNull(my.RS!FieldName) Then s(i)=Cstr(my.RS!FieldName)
            RS.MoveNext
        Wend
    Call my.ConnClose
End Sub
'使用CONN对象执行UPDATE/DELETE/INSERT语句
'SQL语句放在变量sSQL中
Private Sub RunSqlCommand()
    Dim sSQL as String
    Call my.ConnOpen
        my.CONN.Execute sSQL
    Call my.ConnClose
End sub
'对于DATAGRID和DATAREPORT这些需要DATASOURCE的控件可以做如下操作
'使用SELECT语句打开RS的数据集
Set OBJ.Datasource=my.RS
'---------------------------------------------------------------------
这个方法对于开发简单小型的MIS系统很实用,也可以在报表和数据表中使用,缺点是在多表操作和函数嵌套调用时,一个动态ADO对象不能同时执行两个工作,后一个写入的SQL语句会覆盖先写入的SQL语句,当在回到前一个过程时,会因为字段找不到而出错。因此如果可能需要进行多表操作,可以尝试多定义几个CONN 和RS对象。

posted @ 2008-11-26 07:24 大鸟 阅读(355) | 评论 (0)编辑 收藏

>> 将文本赋值给MsFlexGrid的单元格
MsFlexGrid.TextMatrix(3,1)=”Hello”

>> 在MsFlexGrid控件单元格中插入背景图形
Set MsFlexGrid.CellPicture=LoadPicture(“C:\temp\1.bmp”)

>>选中某个单元
MsFlexGrid.Row=1
MsFlexGrid.Col=1

>>用粗体格式化当前选中单元
MsFlexGrid.CellFontBold=True

>> 添加新的一行
使用AddItem方法,用Tab字符分开不同单元格的内容

dim row as string
row=”AAA”&vbtab&”bbb”
MsFlexFrid1.addItem row


>>怎样来实现MSFlexGrid控件单数行背景为白色,双数的行背景为蓝色?
    Dim i As Integer
    With MSFlexGrid1
         .AllowBigSelection = True    ’ 设置网格样式
         .FillStyle = flexFillRepeat
         For i = 0 To .Rows - 1
             .Row = i: .Col = .FixedCols
             .ColSel = .Cols() - .FixedCols - 1
             If i Mod 2 = 0 Then
                .CellBackColor = &HC0C0C0    ’ 浅灰
             Else
                .CellBackColor = vbBlue ’ 兰色
             End If
         Next i
     End With

>> MSFlexGrid控件如何移到最后一行
MSFlexGrid1.TopRow = MSFlexGrid1.Rows – 1

>>如何判断msflexgrid有无滚动条
Declare Function GetScrollRange Lib "user32" (ByVal hWnd As Long, ByVal nBar As Long, lpMinPos As Long, lpMaxPos As Long) As Long

Public Const SB_HORZ = &H0
Public Const SB_VERT = &H1

Public Function VsScroll(MshGrid As MSHFlexGrid) As Boolean           ’判断水平滚动条的可见性
Dim i As Long
VsScroll = False
i = GetScrollRange(MshGrid.hWnd, SB_HORZ, lpMinPos, lpMaxPos)
If lpMaxPos <> lpMinPos Then VsScroll = True
End Function

Public Function HeScroll(MshGrid As MSHFlexGrid) As Boolean           ’判断垂直滚动条的可见性
Dim i As Long
HeScroll = False
i = GetScrollRange(MshGrid.hWnd, SB_VERT, lpMinPos, lpMaxPos)
If lpMaxPos <> lpMinPos Then HeScroll = True
End Function

>>程序运行时,想动态增加MSFlexgrid的列数
在第2列后插入一列:

Private Sub Form_Load()
Me.MSHFlexGrid1.Cols = 5
MSHFlexGrid1.Rows = 2
For i = 0 To Me.MSHFlexGrid1.Cols - 1
Me.MSHFlexGrid1.TextMatrix(0, i) = i
Me.MSHFlexGrid1.TextMatrix(1, i) = i
Next
End Sub

Private Sub Command1_Click()
Me.MSHFlexGrid1.Cols = Me.MSHFlexGrid1.Cols + 1
Me.MSHFlexGrid1.ColPosition(5) = 3
End Sub

>> MSFlexGrid中的对齐功能的使用
设置MSFlexGrid1.ColAlignment(index)=n


>>得到MSFlexGrid控件中当前选中的一行
msflexgrid1.rowsel就是当前选中行

>> 如何通过代码调节列宽度
msflexgrid1.colwidth(i)=4000
增加 MsFlexGrid 的编辑功能

概述
MsFlexGrid 控件没有提供文本编辑的功能,下面的例子演示了如何利用一个TextBox 实现编辑当前网格的功能。

在按下一个键后, 就把TextBox 移动到当前的位置, 并激活。 在键入回车或移动到其他网格时, 就把TextBox 中的内容放到网格中。

实现步骤
1 打开 VB5, 开启一个新的工程。

2 在菜单“工程” 中选择 “部件”, 在列表中选中 “Microsoft FlexGrid Control ..”

3 放一个 MsFlexGrid 控件和一个TextBox 控件(Text1)到 Form1。 修改MsFlexGrid 控件的名称为 Grid1, 设置Grid1 的行,列 为 4, 固定行,列为 0。 设置 Text1 的 Visiable 为 False, BorderStyle 为 None(0)。

4 在Form1 的代码中增加声明:

Const ASC_ENTER = 13 '回车
Dim gRow As Integer
Dim gCol As Integer

5 增加代码到 Grid_KeyPress 过程:

Private Sub Grid1_KeyPress(KeyAscii As Integer)
' Move the text box to the current grid cell:
Text1.Top = Grid1.CellTop + Grid1.Top
Text1.Left = Grid1.CellLeft + Grid1.Left
' Save the position of the grids Row and Col for later:
gRow = Grid1.Row
gCol = Grid1.Col
' Make text box same size as current grid cell:
Text1.Width = Grid1.CellWidth - 2 * Screen.TwipsPerPixelX
Text1.Height = Grid1.CellHeight - 2 * Screen.TwipsPerPixelY
' Transfer the grid cell text:
Text1.Text = Grid1.Text
' Show the text box:
Text1.Visible = True
Text1.ZOrder 0 ' 把 Text1 放到最前面!
Text1.SetFocus
' Redirect this KeyPress event to the text box:
If KeyAscii <> ASC_ENTER Then
SendKeys Chr$(KeyAscii)
End If
End Sub

6 增加代码到 Text1_KeyPress 过程:

Private Sub Text1_KeyPress(KeyAscii As Integer)
If KeyAscii = ASC_ENTER Then
Grid1.SetFocus ' Set focus back to grid, see Text_LostFocus.
KeyAscii = 0 ' Ignore this KeyPress.
End If
End Sub

7 增加代码到 Text1_LostFocus 过程:

Private Sub Text1_LostFocus()
Dim tmpRow As Integer
Dim tmpCol As Integer
' Save current settings of Grid Row and col. This is needed only if
' the focus is set somewhere else in the Grid.
tmpRow = Grid1.Row
tmpCol = Grid1.Col
' Set Row and Col back to what they were before Text1_LostFocus:
Grid1.Row = gRow
Grid1.Col = gCol
Grid1.Text = Text1.Text ' Transfer text back to grid.
Text1.SelStart = 0 ' Return caret to beginning.
Text1.Visible = False ' Disable text box.
' Return row and Col contents:
Grid1.Row = tmpRow
Grid1.Col = tmpCol
End Sub

posted @ 2008-11-26 07:23 大鸟 阅读(2143) | 评论 (1)编辑 收藏
VB利用ADO控件连接access数据库


    今天告诉大家VB利用ADO控件连接access数据库的两种方法:

    一种是在 adodc1的属性里设置数据库文件的路径,这种方法的优点是简单易操作,缺点是,当源文件换了地方后,要重新设置数据库的路径,否则连接不上数据库了。

    一种是用代码设置数据库的路径,这种方法的优点就是只要源文件和数据库在同一文件夹下,无论移动到哪里都能连接上。

    如果没有建立好数据库的话,先建立一个数据库,然后建立一个表比如我们建的表名为message,然后把里面的字段名称和数据类型都按自己的需要设置好.然后保存就可以了.
    打开Microsoft Visual Basic6.0 我用的是VB6.0,在需要调用数据库的窗体上加入一个adodc控件,默认名称为:Adodc1。默认的情况下工具栏里是没有这个控件的,可以打开工程---部件(快捷键CTRL+T),去掉只显示选定项的勾,然后勾上Microsoft ADO Data Control(OLEDB),然后确定,工具栏就会多了一个adodc的控件。

第一种方法:设置adodc1的属以连接数据库.在adodc1控件上右键--Adodc属性--使用连接字符串--生成--Microsoft Jet 4.0 OLE DB Provider--下一步--选择或输入数据库名称---找到要连接的数据库后,确定.然后记录源设置属性. 如果要把内容提交到数据库一般使用adCmdTable. 表选择要连接的表。
设置完毕后就可以了.
如果我们想把内容提交到数据库.举个例子..
在窗体建立一个文本框,设置属性中的DataSource为adodc1   DataField为要连接的数据库的字段名。如果数据库中有字段,会让你选择。
设置好后在窗体加一个添加记录和一个提交的按钮,设置代码:
Private Sub Command1_Click()
Adodc1.Recordset.Update   '保存
Adodc1.Refresh '刷新
End Sub
添加按钮代码:
Private Sub Command2_Click()
Adodc1.Recordset.AddNew '添加新纪录
Adodc1.Recordset("姓名").Value = Text1.Text
End Sub

第二种方法:
在窗体添加Adodc控件一个text控件 一个添加记录按钮一个提交按钮
在窗体设置代码:
Private Sub Form_Load()
Adodc1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + App.Path + "\db1.mdb;Persist Security Info=False" '设置数据库路径
Adodc1.CommandType = adCmdText '设置记录源
Adodc1.RecordSource = "select * from message" '连接数据库的message表文件
Set Text1.DataSource = Adodc1
text1.DataField = "姓名"
End Sub
添加记录按钮代码:
Private Sub Command1_Click()
Adodc1.Recordset.AddNew '添加新纪录
End Sub

提交代码:
Private Sub Command2_Click()
Adodc1.Recordset.Update   '保存
Adodc1.Refresh '刷新
End Sub
    好了连接方法讲完了,我都在机子上测试过了,因该没有什么问题的。如果有问题请多看几遍,或看些别人写的程序代码,会有很大进步的,我的VB也不好,因为不是计算机专业的,老师也没有教很多,高手莫笑。好了我再给大家几个查询数据库常用的代码:
首记录按钮的代码:
Private Sub sjl_Click()
Adodc1.Recordset.MoveFirst
End Sub
上一条记录按钮代码:
Private Sub up_Click()
Adodc1.Recordset.MovePrevious
If Adodc1.Recordset.BOF Then
Adodc1.Recordset.MoveFirst
End If
End Sub
下一条记录代码:
Private Sub down_Click()
Adodc1.Recordset.MoveNext
If Adodc1.Recordset.EOF Then
Adodc1.Recordset.MoveLast
End If
End Sub
末记录代码:
Private Sub mjl_Click()
Adodc1.Recordset.MoveLast
End Sub
删除记录代码:
Private Sub Command3_Click()
Adodc1.Recordset.Delete
Adodc1.Recordset.MoveNext
If (Adodc1.Recordset.BOF Or Adodc1.Recordset.EOF) Then
MsgBox "已经无记录", , "提示"
End If
End Sub

如果有什么不对的地方,请大家指正。

posted @ 2008-11-26 07:19 大鸟 阅读(2318) | 评论 (0)编辑 收藏

DataGrid 控件是一种类似于电子数据表的绑定控件,可以显示一系列行和列来表示 Recordset 对象的记录和字段。可以使用 DataGrid 来创建一个允许最终用户阅读和写入到绝大多数数据库的应用程序。DataGrid 控件可以在设计时快速进行配置,只需少量代码或无需代码。当在设计时设置了DataGrid 控件的 DataSource 属性后,就会用数据源的记录集来自动填充该控件,以及自动设置该控件的列标头。然后您就可以编辑该网格的列;删除、重新安排、添加列标头、或者调整任意一列的宽度。
    在运行时,可以在程序中切换 DataSource 来察看不同的表,或者可以修改当前数据库的查询,以返回一个不同的记录集合。
    注意 DataGrid 控件与 Visual Basic 5.0中的 DBGrid 是代码兼容的,除了一个例外:DataGrid 控件不支持 DBGrid 的“解除绑定模式”概念。DBGrid 控件包括在 Visual Basic 的 Tools 目录中。
    可能的用法
    查看和编辑在远程或本地数据库中的数据。
    与另一个数据绑定的控件(诸如 DataList 控件)联合使用,使用 DataGrid控件来显示一个表的记录,这个表通过一个公共字段链接到由第二个数据绑定控件所显示的表。
    使用 DataGrid 控件的设计时特性
    可以不编写任何代码,只通过使用 DataGrid 控件的设计时特性来创建一个数据库应用程序。下面的说明概要地说明了在实现 DataGrid 控件的典型应用时的一般步骤。完整的循序渐进的指示,请参阅主题“DataGrid 方案1: 使用 DataGrid 控件创建一个简单数据库应用程序”。
要在设计时实现一个 DataGrid 控件
    1. 为要访问的数据库创建一个 Microsoft 数据链接 (.MDL) 文件。请参阅“创建 Northwind OLE DB 数据链接”主题,以获得一个示例。
    2. 在窗体上放置一个 ADO Data 控件,并将其 ConnectionString 属性设置为在第 1 步中所创建的OLE DB 数据源。
    3. 在这个 Ado Data 控件的 RecordSource 属性中输入一条将返回一个记
录集的 SQL 语句。例如,Select * From MyTableName Where CustID = 12
    4. 在窗体上放置一个 DataGrid 控件,并将其 DataSource 属性设置为这个 ADO Data 控件。
    5. 右键单击该 DataGrid 控件,然后单击“检索字段”。
    6. 右键单击该 DataGrid 控件,然后单击“编辑”。
    7. 重新设置该网格的大小、删除或添加网格的列。
    8. 右键单击该 DataGrid 控件,然后单击“属性”。
    9. 使用“属性页”对话框来设置该控件的适当的属性,将该网格配置为所需的外观和行为。
    在运行时更改显示的数据
    在创建了一个使用设计时特性的网格后,也可以在运行时动态地更改该网格的数据源。下面介绍实现这一功能的通常方法。
    更改 DataSource 的RecordSource
    更改所显示的数据的最通常方法是改变该 DataSource 的查询。例如,如果DataGrid 控件使用一个ADO Data控件作为其 DataSource,则重写RecordSource和刷新该ADO Data 控件都将改变所显示的数据。
    ' ADO Data 控件连接的是 Northwind 数据库的' Products 表。新查询查找所有
    ' SupplierID = 12 的记录。
    Dim strQuery As String
    strQuery = "SELECT * FROM Suppliers WHERE SupplierID = 12"
    Adodc1.RecordSource = strQuery
    Adodc1.Refresh
    更改 DataSource
    在运行时,可以将 DataSource 属性重新设置为一个不同的数据源。例如,您可能具有若干个 ADO Data 控件,每个控件连接不同的数据库,或设置为不同的 RecordSource 属性。可以简单地将 DataSource 从一个 ADO Data控件重新设置为另一个 ADO Data 控件:
    ' 将 DataSource 重新设置为一个连接到 Pubs 数据库的、
    ' 使用 Authors 表的 ADO Data 控件。
    Set DataGrid1.DataSource = adoPubsAuthors
    重新绑定 DataSource
    当将 DataGrid 控件用于一个远程数据库,诸如 SQLServer 时,可以改变表的结构。例如,可以给这个表添加一个字段。在这种情形下,可以调用Rebind 方法根据新的结构来重新创建该网格。注意,如果已经在设计时改变了这个列的布局,DataGrid 控件将会试图重新创建当前的布局,包括任何空的列。不过,通过首先调用 ClearFields 方法,可以强制该网格重新设置所有的列。
    从 DataGrid 返回值
    在 DataGrid 被连接到一个数据库后,可能想要监视用户单击了哪一个单元。可以使用 RowColChange 事件——而不是 Click 事件。如下所示:
    Private Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)
       ' 显示用户所单击的单元的文字、行和列的信息。
       Debug.Print DataGrid1.Text; DataGrid1.Row; DataGrid1.Col
    End Sub
    使用 CellText 和 CellValue 方法
    当一个列使用 NumberFormat 属性设置格式后,CellText 和 CellValue 属性是很有用的。NumberFormat 属性不必更改实际的数据格式就可以更改任何包含数字的列的格式。例如,给定一个网格,其中包含一个名为 ProductID的、包含整数的列。下面的代码将使 DataGrid 以"P-0000" 的格式来显示数据。换句话说,尽管在 ProductID 字段中所包含的实际数值为 "3",但该网格所显示的值将是 "P-0003"。
      Private Sub Form_Load()
        DataGrid1.Columns("ProductID").NumberFormat = "P-0000"
      End Sub
    要返回数据库中所包含的实际值,应使用 CellValue 方法,如下所示:
      Private Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)
        Debug.Print _
        DataGrid1.Columns("ProductID").CellValue(DataGrid1.Bookmark)
      End Sub
    注意 上面所用的 CellValue 和下面所用的 CellText 值,都需要将Bookmark 属性作为一个参数,功能才正确。
    相反地,如果要返回该字段的格式化的值,应使用 CellText 方法:
      Private Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)
        Debug.Print _
        DataGrid1.Columns("ProductID").CellText(DataGrid1.Bookmark)
      End Sub
    注意 上面的 CellText 方法等价于使用 DataGrid 控件的 Text 属性。
    下一步
    要阅读关于使用该控件创建简单的应用程序的一个循序渐进的过程,请参阅“使用 DataGrid 控件创建简单的数据库应用程序”,或“创建一个连接DataList 控件的 DataGrid”。
    要了解关于 Split 对象以及如何对其编程的详细信息,请参阅“操作DataGrid 视图”。
    创建 Northwind 的OLE DB 数据链接
    访问数据的一个重要步骤是为想要访问的每个数据库都创建一个 OLE DB数据源。下面的步骤为 Visual Basic 所提供的Nwind.mdb (Northwind) 数据库创建这样一个对象。这个数据源被用于 Visual Basic 文档所提供的一些示例过程。在一个计算机上只需要创建一次OLE DB数据源。
    要创建 Northwind 的OLE DB 数据源
    1. 打开 Windows Explorer或 Windows NT Explorer。
    2. 打开您想要创建 OLE DB 数据源的目录。在该示例中,打开 ProgramFiles、Microsoft Visual Studio和VB98。
    3. 右键单击 Explorer 的右边窗格,然后单击上下文菜单上的“新建”。从文件类型列表中单击“Microsoft 数据链接”。
    4. 重命名新文件 Northwind.MDL。
    5. 右键单击文件并单击上下文菜单上的“属性”,以显示“Northwind.MDLProperties”对话框。
    6. 单击“连接”选项卡。
    7. 单击“提供方”框并选择“Microsoft Jet 3.51 OLE DB Provider”。
    8. 在Data Source 框中输入nwind.mdb文件的路径。
    9. 单击“测试连接”,检测连接。
    10. 如果连接通过,单击“确定”。
    注意 也可以通过在“控制面板”中单击“数据链接”图标创建一个 OLE DB数据源。在“管理数据链接文件”对话框中,单击“新建”创建一个新的数据源。
    使用 DataGrid 和 ADO Data控件创建一个简单的数据库应用程序
    只使用一个 DataGrid 和一个 ADO Data 控件,可以创建一个允许最终用户阅读和写入记录集的数据库应用程序。
    要使用 ADO 数据控件来创建一个简单的数据库应用程序
    1. 为 Northwind 数据库创建一个OLE DB 数据源。如果还没有创建数据源,请按照“创建 Northwind 的OLE DB Data Link”中的步骤操作。
    2. 在Visual Basic 中创建一个新的标准的 EXE 工程。如果 DataGrid 控件不在“工具箱”中,则用右键单击“工具箱”,然后使用“部件”对话框来添加控件。同时也载入 ADO 控件。
    3. 在空窗体上各放置控件的一个实例。
    4. 将 ADO 控件的ConnectionString 属性设置为 Northwind 的数据源。单击并选定该 ADO Data 控件,并按 F4 键出现“属性”窗口。单击“ConnectionString”,然后单击 OLE DB File。单击 Northwind 的数据源。
    5. 设置 ADO 控件的 RecordSource 属性。在“属性”窗口中,单击“记录源”并输入一条 SQL 语句来填充 DataGrid
控件。在本例中,输入“Select * From Products”。
    6. 将 DataGrid 控件的 DataSource 属性设置为这个 ADO Data 控件。单击并选定该 DataGrid 控件。在其“属性”窗口中,单击“数据源”将出现一个包含所有数据控件的下拉列表——在本例中只有 ADO Data 控件。单击这个控件。
    7. 按 F5 键运行这个工程。
    创建一个连接 DataList 控件的 DataGridData
    Grid 的通常用法是显示数据库的一个表所提供的“详细内容”。例如,Northwind (Nwind.mdb) 数据库包括两个表,一个名为 "Suppliers",另一个名为 "Products"。在本例中,我们使用 DataList 控件来显示 "Suppliers" 表中的供应商的公司名称。当用户单击任意一个公司名称时,这个 DataList 控件将提供该公司的 SupplierID。使用这个标识符,就可以构造一个查询,在 "Products" 表中检索具有相匹配的 SupplierID 的所有记录。换句话说,当用户单击一个公司时(在 DataList 控件中),该公司生产的所有产品将出现在 DataGrid 控件中。
要使用一个指定供应商的产品填充一个 DataGrid 控件
    1. 确认在机器上已为 Northwind 数据库建立了一个OLE DB 数据源;如果还没有创建这样的一个数据源,请按照“创建 Northwind 的OLE DBData连接”的步骤操作。
    2. 在Visual Basic 中创建一个新的标准的 EXE 工程。
    如果 DataGrid、DataList 和 ADO Data 控件不在“工具箱”中,则右键单击“工具箱”,然后单击“部件”。在“部件”对话框中双击“MicrosoftDataGrid Control”、“Microsoft DataList Controls”以及“Microsoft ADOControl”。
    3. 在一个空窗体中各放置一个 DataGrid 和 DataList 控件的实例。将 DataList 控件放置在该窗体的左上角,然后将 DataGrid 控件放在它的下面的某处。
    4. 在窗体放置两个 ADO Data 控件实例。选择第一个 ADO Data 控件,并按 F4 键来显示其“属性页”。将该控件的 Name 属性设置为 adoSuppliers。选择第二个 ADO Data 控件并将其 Name 属性设置为 adoProducts。将第一个控件直接放在 DataList 控件的下面,把第二个控件直接放在 DataGrid 控件的下面。
    5. 将这两个 ADO Data 控件的 ConnectionString 属性设置为 Northwind的OLE DB 数据源。选择名为 adoSuppliers 的控件,然后将其ConnectionString 属性设置为Northwind 的OLE DB data source (Northwind.mdl)。选择名为 adoProducts的控件,并重复该操作。
    6. 设置这两个 ADO Data 控件的 RecordSource 属性。选择 adoSuppliers 并在其“属性页”上单击“RecordSoure”。输入 Select* From Suppliers。这个查询将指示该 ADO Data 控件返回 Suppliers 表中的所有记录。选择 adoProducts,单击“RecordSoure”,并输入 Select *From Products。这个查询将返回在 Products 表中的所有记录。
    7. 将 DataList 控件的 RowSource 属性设置为 adoSuppliers。
     RowSource 属性决定由哪一个数据源为 ListField 属性供应数据。
    8. 将 DataList 控件的 ListField 属性设置为 CompanyName。
     ListField 属性被设置成名为 Suppliers 的表中的字段名称。在运行时,DataList 控件显示在这个属性中所指定的字段的值。在本例中,该属性将显示在 Suppliers 表中找到的一个公司名称。
    9. 将 DataList 控件的 BoundColumn 属性设置为 SupplierID。
     BoundColumn 属性被设为 Suppliers 表中的第二个字段。在本例中,这个属性就被设为 SupplierID 字段。当单击 DataList 控件时,BoundText属性返回与在 DataList 控件中所显示的公司相关联的 SupplierID 字段的值。这个值将用于对 Products 表的查询,该查询为 DataGrid 控件提供数据。
    10. 将 DataGrid 控件的 DataSource 属性设置为 adoProducts。
     DataSource 属性为该控件指定数据源。在本例中,该属性被设置为名为adoProducts 的 ADO Data 控件,这将返回 Products 表中的所有记录。
    11. 在窗体的代码模块中,添加下述内容:
      Private Sub Datalist1_Click()
      ' 声明一个用来包含新查询的字符串变量。这个新的
      ' 查询使用 DataList 控件的BoundText属性
      ' 来提供一个 SupplierID 值。新查询查找所有
      ' 具有相同的 SupplierID 的产品。这个查询被
      ' 指定给名为 adoProducts 的 ADO Data 控件
      ' 的 RecordSource 属性。在刷新控件后,DataGrid
      ' 将使用包含由同一个公司供应的所有产品的新
      ' 记录集来更新。
      Dim strQuery As String
      strQuery = "Select * FROM Products WHERE SupplierID = " & _
      Datalist1.BoundText
      With adoProducts
        .RecordSource = strQuery
        .Refresh
      End With
      With DataGrid1
        .ClearFields
        .ReBind
      End With
      End Sub
    12. 运行该工程。
    单击 DataList 控件中的任意公司名称,将自动用该公司所供应的产品更新 DataGrid 控件。

使用列
    通过更改 DataSource 属性,可以动态地更改在 DataGrid 控件中显示的数据。例如,可以显示同一个数据库的不同表。如果这样做,则 DataGrid 控件将只根据默认的属性显示数据。
    添加、删除或隐藏列
    通过使用 Columns 集合和 Column 对象的属性和方法,可以在程序中添加、删除或隐藏列。
    添加和删除一列
    要在运行时添加一列,可以使用 Add 方法。如果首先声明一个变量,并将新对象赋给该变量,就可以用简明的代码设置各种属性。
    Private Sub AddColumn()
      ' 在最右边的位置添加一列。然后设置其 Visible、Width、
      ' Caption以及 Alignment 属性。DataField 属性则指定
      ' 该列将绑定到哪一个字段。
      Dim c As Column
      Set c = DataGrid1.Columns.Add(DataGrid1.Columns.Count)
      With c
       .Visible = True
       .Width = 1000
       .Caption = "我的新列"
       .DataField = Adodc1.Recordset.Fields("ProductName").Name
       .Alignment = dbgRight
      End With
    End Sub
    可以使用方法来删除任意一列。请确保使用 ColIndex 参数来指定要删除的列。下面的代码将删除被单击的列。
    Private Sub DataGrid1_HeadClick(ByVal ColIndex As Integer)
       DataGrid1.Columns.Remove ColIndex
    End Sub
    隐藏一列
    通过将 Visible 属性设置为 False,可以隐藏任意一列。当想要限制用户可以查看或编辑的列时这一功能特别有用。下面的示例在 Columns 集合中循环,隐藏除少数列之外的所有列。
    Private Sub HideColumns()
      ' 使用 DataField 属性来判别正在测试的是哪一列。
      ' 只显示三列:ProductName、UnitPrice以及
      ' UnitsInStock。
      Dim c As Column
      For Each c In DataGrid1.Columns
         Select Case c.DataField
         Case "ProductName"
           c.Visible = True
         Case "UnitPrice"
           c.Visible = True
         Case "UnitsInStock"
           c.Visible = True
           c.Caption = "In Stock"    ' 更改这个列的标头。
         Case Else             ' 隐藏其它所有的列。
           c.Visible = False
         End Select
      Next c
    End Sub
    操作 DataGrid 视图
    一个“拆分”的网格使最终用户对相同的数据可以拥有多个视图。例如,假设有一个由十个字段组成的大表。在这种情况下,在控件中察看的记录集将有十列宽,除非窗体非常宽,否则用户将无法同时看见所有列的内容。,而且,假设用户只对第一列和最后一列感兴趣(例如,第一列是名字,最后一列是电话号码)。为了能同时看到在两端的列(不重新安排列的顺序),可以对网格进行拆分。
    创建一个 Split 对象
    在设计时,可以创建一个拆分,具体步骤是:右键单击网格,单击“编辑”,再单击右键,然后单击“拆分”。通过右键单击该控件,并单击“属性”来显示“属性页”对话框,可以编辑这个拆分。可以使用“拆分”选项卡来自定义拆分。要删除一个拆分,右键单击该拆分,并单击“删除”。
    在运行时,最终用户也可以通过单击位于这个网格控件的左下边的右边的选项卡,以手工方式来拆分该网格(除非不允许这个操作),如下图所示:
 
默认情况下,DataGrid 控件包含一个 Split 对象。防止最终用户添加拆分的代码为:
    DataGrid1.Splits(0).AllowSizing = False
    在程序中添加和删除拆分
    DataGrid 控件包含一个 Split 对象的集合。要在程序中添加拆分,可以使用 Add 方法,如下所示:
    DataGrid1.Splits.Add 1
    注意 Add 方法需要新的拆分索引作为其参数。要添加一个拆分,应将这个索引参数设置为 Splits 集合的 Count 属性值。
    使用 Split 集合的 Add 方法,可以在程序中按照实际需要添加拆分。由于添加多于两个以上的拆分将使网格很难使用,可以使用该集合的 Count 属性来限制拆分的数目。
    If DataGrid1.Splits.Count < 3 Then ' 添加一个拆分。
       DataGrid1.Splits.Add DataGrid1.Splits.Count
    End If
    使拆分同步
    当拆分多于一个时,可能希望控制这些拆分如何滚动。例如,在一个具有三个拆分的网格中,可以决定只让第一个和第三个拆分同步,而让中间的拆分独立地滚动。要同步任何两个(或多个)拆分,只需将每个 Split 对象的 ScrollGroup 属性设置为同一个值。
    ' 使第一个和第三个 Split 对象同步。
    With DataGrid1
      .Splits(0)
    .ScrollGroup = 1
    .Splits(1).ScrollGroup = 2
    .Splits(2).ScrollGroup = 1
    End With
    通过设置 Scrollbars 属性,使同步的拆分组只显示一个滚卷条,从而进一步自定义拆分的外观。
    控制 Tab 键和箭头键的行为
    使用 WrapCellPointer、TabAcrossSplits以及 TabAction 属性,可以决定当最终用户按下 tab 键或箭头键时网格的行为。
    在这三个属性中,TabAction 属性级别最高,它决定 WrapCellPointer 和TabAcrossSplits 这两个属性是否能生效。TabAction 有三个设置值: ControlNavigation、Column Navigation 和 Grid Navigation。当该属性设置为 ControlNavigation 时,按 Tab 键根据 TabIndex 将焦点切换到下一个控件。这一设置优先于 WrapCellPointer 和 TabAcrossSplits。
    WrapCellPointer 属性决定在任何单个的拆分中 tab 键和箭头键的行为。如果该属性设置为 True,且当前单元位于最后一列,这时最终用户按 tab 键则使第一列的下一行变成当前的单元。不过,如果当前单元位于最后一行的最后一列时,这时就没有地方可以“换行”。
    TabAcrossSplits 属性决定当网格中存在两个或多个拆分时 tab 和箭头键的行为。如果该属性设置为 True,且当前单元位于任何一个拆分的最后一列,则按Tab或箭头键将使当前单元“跳” 到下一个拆分的第一列。当前单元仍保持相同的行位置。
    注意 如果 WrapCellPointer 和 TabAcrossSplits 属性都设置为 True,则只有当前单元位于最后一个拆分的最后一列时才会换行。这时当前单元将换到第一个拆分的第一列中的下一行。
    自定义列集合
    每一个 Split 对象都有一个 Columns 属性,允许用户来操作一个 Column对象的集合。通过这样做,可以更改每个 Split 对象的外观。例如,可以用一个拆分包含显示姓氏字段和名字字段的两个列,而第二个拆分则显示电话字段和地址字段。要实现这一目标,需要将其它的每一列的 Visible 属性设置为 False,如下所示:
    ' 枚举 Columns 集合,对每一个 Column 对象的 DataField 属性
    ' 进行测试。如果测试失败,则隐藏这一列。
    Dim i As Integer
    ' 隐藏除 ProductName 列之外的所有列。
    For i = 0 To DataGrid1.Splits(0).Columns.Count - 1
      If DataGrid1.Splits(0).Columns(i).DataField <> "ProductName" Then
         DataGrid1.Splits(0).Columns(i).Visible = False
      End If
    Next i
    ' 隐藏除 UnitPrice 列之外的所有列。
    For i = 0 To DataGrid1.Splits(0).Columns.Count - 1
      If DataGrid1.Splits(1).Columns(i).DataField <> "UnitPrice" Then
         DataGrid1.Splits(1).Columns(i).Visible = False
      End If
    Next I
   使用 Bookmarks 和 SelBookmarks 跟踪记录
    Bookmarks 和 SelBookmarks 提供了标记记录的一种手段。当编写应用程序中的特定功能(诸如允许最终用户手工地选择多个不相邻的记录,进行所选记录的大批更新)时,这就很有必要。在这些情形中,需要标记哪些记录已被选择,因此可以使用 SelBookmarks 集合及其属性。
    有两个函数,分别是 CellText 和 CellValue 方法,需要标记才能正确执行。
    标记用户的选择
    SelBookmarks 集合包含所有选定的记录的书签。当最终用户手工选择记录时(即在单击时按住 CTRL 键),每一个选定的记录的书签都会加入到该集合中。使用标准的循环,用户可以知道已经选定了什么,也可以保存书签(因为可能需要恢复某个值),以及执行操作:
    Dim i as Integer ' 计数器
    Dim intCount As Integer
    intCount = DataGrid1.SelBookmarks.Count - 1
    ReDim arrSelBK(intCount) ' 声明用于保存书签的数组。
    For i = 0 To intCount
      ArrSelBK(i) = DataGrid1.SelBookmarks(i)
      ' 在此处执行操作。如果该操作必须被
      ' 取消,则退出该循环,然后使用该数
      ' 组来取消这些更改。
    Next i
    通过在程序中添加到 SelBookmarks 集合来选择记录
    通过将记录添加到这个集合,也可以在程序中选定记录。例如,可能有一个显示指定的客户所有订货的网格。如果要高亮显示该客户花费超过 $100的所有记录,则对记录进行过滤,并将结果书签添加到 SelBookmarks 集合。
    Dim rs As Recordset
    Set rs = Adodc1.Recordset
    While Not rs.EOF
      If rs!SupplierID = 12 Then
        DataGrid1.SelBookmarks.Add rs.Bookmark
      End If
      rs.MoveNext
    Wend
    显示计算结果字段
    假设在表中有一个名为 "Price" 的字段,并且想使用本地税率来计算表中每一项的税费。这就是一个计算结果字段,可以通过修改 DataSource 的查询来计算这个值,并把这个值返回给 DataGrid 控件。
    要在 DataGrid 控件中创建一个计算结果字段
    1. 确认在机器上已为 Northwind 数据库建立了一个OLE DB 数据源;如果还没有创建这样的一个数据源,请按照“创建 Northwind 的OLE DBData 连接”的步骤操作。
    2. 在窗体上放置一个 ADO Data 控件和一个 DataGrid 控件。
    3. 将 ADO Data 控件的ConnectionString 属性设置为 Northwind 的数据源。
    4. 设置 ADO Data 控件的 RecordSource 属性。在“属性”窗口中,单击“记录源”并输入 Select ProductName, UnitPrice,(UnitPrice * .082) As Tax From Products。
    5. 将 DataGrid 控件的 DataSource 属性设置为这个 ADO Data 控件。
    6. 运行该工程。
    与类模块一起使用 DataGrid 控件
    如果想要访问以自定义格式或以 ODBC 驱动程序不直接支持的格式存放的数据,可以创建一个类来封装该数据。然后可以编写该类的自定义函数来检索这些数据。这样该类就变成了一种数据源,可以被任何数据使用者(如DataGrid 控件)使用。
    在这个类模块的Initialize 事件中,首先通过声明一个作为 New ADODB.Recordset的变量,来创建一个 ADODB recordset 对象。在创建了这个 recordset 对象后,再添加字段,每个数据源中的每个字段都要加入。然后使用合适的数据填充这个记录集。
    注意 也可以使用 OLEDB 示例提供者来创建一个数据源。关于 OLEDB示例提供者的详细信息,请参阅“创建带有数据提供方的部件”。
    类模块有一个 GetDataMember 事件,只要当数据使用者(诸如 DataGrid 控件)需要数据时就产生该事件。在这个事件中,Data 参数被设置为在Initialize 事件中所创建的 recordset 对象。
    如果要使用这个类模块,应创建一个具有一个 DataGrid 控件的窗体。在该窗体的 Load 事件的代码中,将该控件的 DataSource 属性设置为这个类。
    注意 数据类模块在设计时是不可用的。例如,如果使用 DataGrid 控件,则当用户在“属性”窗口中单击“数据源”时,所有可用的数据源都会出现在一个下拉列表中。但其中不会有这个数据类模块,它只能在代码中设置。
    使用类模块创建一个数据源
    下面的示例使用一个类模块来创建一个简单数据源。然后通过 DataSource属性将 DataGrid 控件绑定到该模块。
要创建一个用于DataGrid 的类
    1. 创建一个新的标准 Exe 工程。
    2. 给窗体添加一个 DataGrid 控件。如果DataGrid控件不在“工具箱”中,则在“工程”菜单中单击“部件”,
再单击“Microsoft DataGrid Control”,然后单击“确定”。
    3. 在“工程”菜单中,单击“引用”。在“引用”对话框中,单击“MicrosoftActiveX Data Objects 2.0 Library”。
    4. 在“工程”菜单中,单击“添加类模块”来给工程添加一个数据类模块。
    5. 在“工程资源管理器”窗口中,单击并选定“类”图标,并按 F4 键显示“属性”窗口。
    6. 在“属性”窗口中,将类的名称更改为NamesData。
    7. 在“属性”窗口中,单击“DataSourceBehavior”并将该属性更改为vbDataSource。
    8. 在该类模块的 Declarations 部分,创建一个 ADODB Recordset变量,如下所示:
    Option Explicit
    Private WithEvents rsNames As ADODB.RecordSet
    使用 WithEvents 关键词来声明该变量,使用户可以对 RecordSet 对象的事件编程。
    9. 在该类的 Initialize 事件中,添加下述代码:
    Private Sub Class_Initialize()
      ' 将新的数据成员的名称添加到 DataMember 集合
      ' 这使其它对象可以看见这些可用的
      DataMembersDataMembers.Add "Names"
      Set rsNames = New ADODB.RecordSet    ' 设置对象变量。
      ' 创建一个具有两个字段的 recordset,并打开该 recordset。
      ' 第一个记录具有一个整数的数据类型,第二个记录是一个最大可
      ' 达 256 个字符的字符串。CursorType 被设置为 OpenStatic
      ' —— 一个可更新的对一组记录的快照。LockType 被设置为
      ' LockOptimistic,以允许对该 recordset 进行更新。
      With rsNames
        .Fields.Append "ID", adInteger
        .Fields.Append "Name", adBSTR, 255
        .CursorType = adOpenStatic
        .LockType = adLockOptimistic
        .Open
      End With
      Dim i As Integer
      For i = 1 to 10   ' 添加十条记录。
        rsNames.AddNew
        rsNames!ID = i
        rsNames!Name = "Name " & i
        rsNames.Update
      Next i
      rsNames.MoveFirst ' 移到该记录集的开始。
    End Sub
    这部分代码首先创建 recordset 对象,然后给该对象添加两个字段。代码接着给 recordset 添加十条记录。
    10. 在该类的 GetDataMember 事件中,添加下述代码 :
    Private Sub Class_GetDataMember(ByVal DataMember As String, _
    Data As Object)
       Set Data = rsNames
    End Sub
    只要发生该事件——即当该类对象被绑定到一个数据使用者,如 DataGrid控件时,代码将返回该 recordset 对象。
    11. 在 Form 对象的代码模块中,声明一个数据类的对象变量:
    Option Explicit
    Private datNames As NamesData ' 类变量
    12. 在 Form 对象的 Load 事件的代码中,将 DataGrid 控件的 DataSource设置为该类对象。
     Private Sub Form_Load()
       ' 创建一个新的 NamesData 对象
       Set datNames = New NamesData
       ' 将这个 DataGrid 绑定到新的数据源 datNames
       Set DataGrid1.DataSource = datNames
     End Sub
    13. 按 F5 键运行该工程。
    RecordSet事件的编程
    也可以对这个 Recordset 对象的事件进行编程。在该类模块中,单击“对象”框(在位于左上角),然后单击“rsNames”。在“过程/事件”框(在右上角)中,下拉列表将显示这个 Recordset 对象的所有事件。
    给类添加一个属性
    类模块也可以进行修改,来响应事件或函数调用。下面的代码演示了如何先给类添加属性。当从其它对象调用该对象时,这一属性将返回该类的RecordCount。
    Public Property Get RecordCount() As Long
       RecordCount = rsNames.RecordCount
    End Sub
    使用 DataMember 属性
    GetDataMember 事件也包括 DataMember 参数。使用这个参数,可以在类模块中包括多个记录集,并使用带 DataMember 参数的 Select Case 语句来返回相应的记录集:
    Private Sub Class_GetDataMember(ByVal DataMember As String, Data As _
    Object)
       Select Case DataMember
       Case "Names"
         Set Data = rsNames
       Case "Dates"
         Set Data = rsDates
       Case Else
         ' 设置一个默认的数据成员
         Set Data = rsYears
       End Select
    End Sub
    如果要指定所需的 DataMember,请将数据使用者的 DataMember 属性设置为适当的字符串,然后如平常一样设置 DataSource。对于 DataGrid 控件,可以采用如下方法:
    Private Sub Form_Load()
       ' 创建一个新的 NamesData 对象
       Set datNames = New NamesData
       ' 指定所需的 DataMember,然后设置 DataSource。
       DataGrid1.DataMember = "Names"
       Set DataGrid1.DataSource = datNames
    End Sub

posted @ 2008-11-26 07:19 大鸟 阅读(304) | 评论 (0)编辑 收藏

引言

  作为微软旗下一款优秀的RAD工具,VB在数据库应用开发方面的能力十分强大。微软设计了多种数据库访问方法,下面通过对VB访问数据库的多种技术进行深入剖析,并总结出实际开发中的几点经验。希望能够对那VB的初学者有所帮助。(注意,文中所有的描述均在Windows 2000 professional和Visual Basic 6.0的环境下进行的)

一. DAO、RDO、ODBC和ADO

  在VB的开发环境中,可以使用三种数据库访问方式,它们分别是:数据访问对象(DAO)、远程数据对象(RDO)和ADO对象模型。

  DAO:

  数据访问对象是用来显露了Microsoft Jet数据库引擎(最早是给Microsoft Access 所使用,现在已经支持其它数据库),并允许开发者通过ODBC直接连接到其他数据库一样,直接连接到 Access 表。DAO 最适用于单系统应用程序或在小范围本地分布使用。其内部已经对Jet数据库的访问进行了加速优化,而且其使用起来也是很方便的。所以如果数据库是Access数据库且是本地使用的话,建议使用这种访问方式。

  VB已经把DAO模型封装成了Data控件,分别设置相应的DatabaseName属性和RecordSource属性就可以将Data控件与数据库中的记录源连接起来了。以后就可以使用Data控件来对数据库进行操作。

  RDO

  RDO(Remote Data Objects)远程数据对象是一个到ODBC的、面向对象的数据访问接口,它同易于使用的DAO style组合在一起,提供了一个接口,形式上展示出所有ODBC的底层功能和灵活性。尽管RDO在很好地访问Jet或ISAM数据库方面受到限制,而且它只能通过现存的ODBC驱动程序来访问关系数据库。但是,RDO已被证明是许多SQL Server、Oracle 以及其他大型关系数据库开发者经常选用的最佳接口。RDO提供了用来访问存储过程和复杂结果集的更多和更复杂的对象、属性,以及方法。

  和DAO一样,在VB中也把其封装为RDO控件了,其使用方法与DAO控件的使用方法完全一样。

  ODBC

  ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,它建立了一组规范,并提供了一组对数据库访问的标准API(应用程序编程接口)。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。

  一个基于ODBC的应用程序对数据库的操作不依赖任何DBMS,不直接与DBMS打交道,所有的数据库操作由对应的DBMS的ODBC驱动程序完成。也就是说,不论是FoxPro、Access还是Oracle数据库,均可用ODBC API进行访问。由此可见,ODBC的最大优点是能以统一的方式处理所有的数据库。

  一个完整的ODBC由下列几个部件组成:
   
  1. 应用程序(Application)

  ODBC管理器(Administrator)。该程序位于Windows 95控制面板(Control Panel)的32位ODBC内,其主要任务是管理安装的ODBC驱动程序和管理数据源。

  驱动程序管理器(Driver Manager)。驱动程序管理器包含在ODBC32.DLL中,对用户是透明的。其任务是管理ODBC驱动程序,是ODBC中最重要的部件。

  2. ODBC API

  ODBC 驱动程序。是一些DLL,提供了ODBC和数据库之间的接口。

  数据源。数据源包含了数据库位置和数据库类型等信息,实际上是一种数据连接的抽象。

  ODBC连接目前仅仅限于关系型数据库,对于其他数据源比如EXCEL、文本文件都不能进行访问,而且有很多DBMS(数据库管理系统)都不能充分的支持其所有的功能。相比之下,OLEDB可以存取任何形式的数据,所以其功能是相当的强大,它也指导了目前技术发展的方向。

  ADO

  ADO(ActiveX Data Object)是DAO/RDO的后继产物。ADO 2.0在功能上与RDO更相似,而且一般来说,在这两种模型之间有一种相似的映射关系。ADO"扩展"了DAO和 RDO 所使用的对象模型,这意味着它包含较少的对象、更多的属性、方法(和参数),以及事件。

  作为最新的数据库访问模式,ADO的使用也是简单易用,所以微软已经明确表示今后把重点放在ADO上,对DAO/RDO不再作升级,所以ADO已经成为了当前数据库开发的主流。

  ADO涉及的数据存储有DSN(数据源名称)、ODBC(开放式数据连接)以及OLE DB三种方式。后面的例程将详细讲解这三种方式的具体访问实现。

  要使用ADO,必须清楚ADO的对象层次结构,其大体上分为以下7个对象层次:

  1、 Command 对象:包含关于某个命令,例如查询字符串、参数定义等的信息。Command 对象在功能上和 RDO的rdoQuery 对象相似。

  2、 Connection 对象:包含关于某个数据提供程序的信息。Connection 对象在功能上和 RDO 的 rdoConnection 对象是相似的,并且包含了关于结构描述的信息。它还包含某些 RDOEnvironment 对象的功能,例如transaction 控件。

  3、 Error对象:包含数据提供程序出错时的扩展信息。Error 对象在功能上和 RDO 的rdoError 对象相似。

  4、 Field 对象:包含记录集中数据的某单个列的信息。Field 对象在功能上和 RDO的rdoColumn 对象相似。

  5、 Parameter 对象:包含参数化的Command对象的某单个参数的信息。该 Command对象有一个包含其所有Parameter 对象的 Parameters 集合。Parameter 对象在功能上和 RDO 的 rdoParameter 对象相似。

  6、 Property对象:包含某个 ADO 对象的提供程序定义的特征。没有任何等同于该对象的RDO,但DAO有一个相似的对象。

  7、Recordset对象:用来存储数据操作返回的记录集。此对象和Connection对象是所有对象最重要的两个对象。

  当然,对于初级用户来说,我们只需要掌握其中的Connection对象和RecordSet对象就可以实现基本的数据库操作,在后面的经验介绍里面我将给出详细的介绍。

二. 开发经验小结:

  前面总体上介绍了一下当前在VB平台下的数据库访问技术,这些技术也是当前数据库技术的主流。下面笔者结合近几年的开发经验,给出一些开发经验和小技巧,以供参考:

  经验一:如果数据量不大,而且要求开发周期短的情况,建议使用DAO+Access虽然DAO功能并不强大,但是其对Jet引擎进行了加速优化处理,所以这种搭配应该是比较好的选择。

  经验二:RDO当前已经用的很少了,一般用ADO来替代。

  经验三:(本经验很重要)使用ADO开发时,连接数据库的方式有三种(前面已经叙述了),其中DSN需要用户首先使用要将所要操纵的数据库设置为数据库源并给其命名。方法是在控制面板->管理工具->数据源(ODBC)下面进行配置。比如设置的数据源名称为data,那么可以通过下面几行代码来连接数据库:

Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
注释:连接数据库
conn.Open "dsn=data"
注释:打开数据源(即选定操作的数据对象)
rs.Open SQL语句, conn  

  但是如果是使用ODBC和OLEDB的方式进行连接,那么大家一定知道在连接字符串上那一长串的代码,不要说对于初学者,就是对于那些经验丰富的程序员来说,也很难记住这一串代码。那么如何可以记住这一串代码呢?其实,方法很简单,只要添加一个ADO Data控件,然后在其属性框中使用向导进行设置后,那么最后向导就会自动生成一段ConnectionString,只需要将这一行代码拷贝下来然后放到conn.open之后的连接字符串参数的位置上就可以了。这条经验希望读者能够记住,实际开发中很实用。

  经验四:前面讲到手动设置ODBC数据源,这里可以通过程序来进行动态设置。首先要清楚的是ODBC的详细信息全部存放在注册表的下述键值内:"HKEY_LOCAL_MACHINE\SOFTWARE\ODBC",通过调用Win32函数WriteProfileString来对相应的键值进行修改即可达到目的。

  经验五:通常将数据库的连接代码和资源释放代码放入各自特定的函数里面,因为一般大一点的程序里需要经常对这两个功能模块进行调用,这样做就可以提高效率,当然很多时候都需要写成连接池的形式。

  经验六:使用VB在SQL中处理含单引号的字符串时,对字符串数据都用单引号引起来,如:


Select * from MyTable Where ID=注释:FirstID注释:

  若其中的FirstID为First注释:ID,即中间多出一个单引号,则上述写法将导致错误,解决的办法是将字符串中的每一个单引号用两双引号替换,下面的函数StrToSQL完成该功能,并用单引号将处理后的字符串引起来:


 Private Function StrToSQL(ByVal strValue As String) As String
    StrToSQL = "注释:" + Replace(strValue, "注释:", "注释:注释:") + "注释:"
 End Function


  在写SQL时如有字符串数据,不管其中有没有单引号,都可以这样使用:


   strValue="First注释:Id"
   strSQL="Select * from MyTable Where ID="+StrToSQL(strValue)
三. 实例解析

  下面介绍一个实例,来消化以上的相关知识。这里我在一个程序界面下实现了DAO,ADO,ODBC,OLEDB四种数据库访问方式。

  程序代码分析:

注释:整个程序功能是选择不同的连接方式来进行显示工作,三种方式显示效果完全相同
注释:下面是主程序过程
Private Sub Command1_Click()
 Dim selitem As Integer
 注释:判断连接数据库的方式
 If Option1.Value = True Then
  selitem = 1
 Else
  If Option2.Value = True Then
   selitem = 2
  Else
   selitem = 3
  End If
 End If

 注释:选取不同的数据库连接方式
 Select Case selitem
 Case 1:
  注释:使用DAO的数据库连接方式
  Call ShowByDAO
 Case 2:
  注释:使用ADO的数据库连接方式
  Call ShowByADO
 Case 3:
  注释:使用ODBC的数据库连接方式
  Call ShowByODBC
 Case 4:
  注释:使用OLEDB的数据库连接方式
  Call ShowByOLEDB
 End Select
End Sub

Private Sub ShowByDAO()
 注释:使用DAO的数据库连接方式
 Dim db As Database
 Dim rs As Recordset
 Dim sqlstr$ 注释:存放查询语句
 Set db = OpenDatabase(App.Path & "\db1.mdb")
 sqlstr = "select * from 成绩表"
 Set rs = db.OpenRecordset(sqlstr)
 注释:显示结果
 Call GridShow(rs)
End Sub

Sub ShowByADO()
 Dim conn As New ADODB.Connection
 Dim rs As New ADODB.Recordset
 注释:使用数据源来连接数据库
 conn.Open "dsn=data"
 rs.CursorType = adOpenKeyset
 rs.LockType = adLockOptimistic
 rs.Open "select * from 成绩表", conn
 Call GridShowOfADO(rs)
End Sub

Sub ShowByODBC()
 Dim conn As New ADODB.Connection
 Dim rs As New ADODB.Recordset
 注释:使用数据源来连接数据库
 conn.Open "Provider=MSDASQL.1;Persist Security Info=False;Data Source=data"
 rs.Open "select * from 成绩表", conn
 注释:显示结果
 Call GridShowOfADO(rs)
End Sub

Sub ShowByOLEDB()
 Dim conn As New ADODB.Connection
 Dim rs As New ADODB.Recordset
 注释:使用数据源来连接数据库
 conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + App.Path & "\db1.mdb" + ";Persist Security Info=False"
 rs.Open "select * from 成绩表", conn

 注释:显示结果
 Call GridShowOfADO(rs)
End Sub

Sub GridShow(rs As Recordset)
 注释:对dao方式进行显示工作
 MSFlexGrid1.TextMatrix(0, 0) = "姓名"
 MSFlexGrid1.TextMatrix(0, 1) = "性别"
 MSFlexGrid1.TextMatrix(0, 2) = "语文"
 MSFlexGrid1.TextMatrix(0, 3) = "数学"
 MSFlexGrid1.TextMatrix(0, 4) = "英语"
 rs.MoveLast
 MSFlexGrid1.Rows = rs.RecordCount + 1
 MSFlexGrid1.Cols = rs.Fields.Count
 Dim i%
 i = 1
 rs.MoveFirst
 While (Not rs.EOF)

  MSFlexGrid1.TextMatrix(i, 0) = rs.Fields(0)
  MSFlexGrid1.TextMatrix(i, 1) = rs.Fields(1)
  MSFlexGrid1.TextMatrix(i, 2) = rs.Fields(2)
  MSFlexGrid1.TextMatrix(i, 3) = rs.Fields(3)
  MSFlexGrid1.TextMatrix(i, 4) = rs.Fields(4)
  rs.MoveNext
  i = i + 1
  注释:If (rs.EOF = True) Then
  注释: Exit For
 Wend
End Sub

Sub GridShowOfADO(rs As ADODB.Recordset)
 注释:对ado方式进行显示工作
 MSFlexGrid1.TextMatrix(0, 0) = "姓名"
 MSFlexGrid1.TextMatrix(0, 1) = "性别"
 MSFlexGrid1.TextMatrix(0, 2) = "语文"
 MSFlexGrid1.TextMatrix(0, 3) = "数学"
 MSFlexGrid1.TextMatrix(0, 4) = "英语"
 注释:注意recordcount属性必须在当前记录指针在最后一条记录时才会返回正确的值
 rs.MoveLast
 MSFlexGrid1.Rows = rs.RecordCount + 1
 MSFlexGrid1.Cols = rs.Fields.Count
 Dim i%
 i = 1
 rs.MoveFirst
 While (Not rs.EOF)
  MSFlexGrid1.TextMatrix(i, 0) = rs.Fields(0)
  MSFlexGrid1.TextMatrix(i, 1) = rs.Fields(1)
  MSFlexGrid1.TextMatrix(i, 2) = rs.Fields(2)
  MSFlexGrid1.TextMatrix(i, 3) = rs.Fields(3)
  MSFlexGrid1.TextMatrix(i, 4) = rs.Fields(4)
  rs.MoveNext
  i = i + 1
 Wend
End Sub

Private Sub Command2_Click()
End
End Sub


  上述代码已经在Windows 2000 professional和Visual Basic 6.0的环境下调试成功。

四.小结

  本文通过对数据库访问相关技术的分析与总结,提出若干有价值的经验。借鉴这些经验,会给开发带来一定的便利。

posted @ 2008-11-26 07:18 大鸟 阅读(308) | 评论 (0)编辑 收藏
Dim dataname As String
Private Sub Command1_Click()
d.DialogTitle = "打开一个Access数据库进行编辑"
d.FileName = ""
d.InitDir = App.Path
d.Filter = "Access数据库文件MDB后缀|*.mdb"
d.ShowOpen
If d.FileName = "" Then Exit Sub
list1.Clear
Set link1 = New ADODB.Connection                 '创建ADO连接
link1.Open "Provider=Microsoft.Jet.OLEDB.4.0;data source=" & d.FileName
Set tables = link1.OpenSchema(adSchemaColumns)   '创建数据库记录集为了得到数据库中所有表名
oldtablename = ""
Do While Not tables.EOF
If tables("table_name") <> oldtablename Then
oldtablename = tables("table_name"): list1.AddItem oldtablename
End If
tables.MoveNext
Loop
If list1.ListCount = 0 Then MsgBox "数据库打开失败,或数据库不存在表", vbCritical, "错误": Exit Sub
dataname = d.FileName
list1.Enabled = True: Command2.Enabled = True
list1.ListIndex = 0: list1_click
End Sub
Private Sub Command2_Click()
ldc.Recordset.Update    '更新ldc记录集
End Sub
Private Sub Form_Resize()
edit.Width = Me.ScaleWidth - 200
edit.Height = Me.ScaleHeight - edit.Top - 50
End Sub
Private Sub list1_click()
'ldc控件连接数据源
ldc.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;data source=" & dataname & ";Persist Security Info=False"
'ldc控件使用SQL命令,GET数据源数据
ldc.RecordSource = "select * from " & list1.Text
ldc.Refresh: Label1.Caption = "共" & ldc.Recordset.RecordCount & "条记录," & ldc.Recordset.Fields.Count & "个分类字段"
End Sub
posted @ 2008-11-26 07:16 大鸟 阅读(381) | 评论 (0)编辑 收藏
仅列出标题
共3页: 上一页 1 2 3 下一页