Mysql 的rank 函數(shù)如何實(shí)現(xiàn)
表特征:
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)
現(xiàn)在,我們以a分組,查詢b列最大的2個(gè)值。 這條sql要怎么寫了?
1.創(chuàng)建表
Create Table: CREATE TABLE `sam` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
2.插入模擬數(shù)據(jù)
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實(shí)現(xiàn)
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.結(jié)果:
+------+------+--------+------+
| 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 大鳥(niǎo) 閱讀(4048) |
評(píng)論 (2) |
編輯 收藏
記得剛參加工作時(shí)(那是97年),中國(guó)的IT剛剛興起,那時(shí),作為一個(gè)IT人士是一件很光榮的事,而那時(shí)的我正在做電氣和電子相關(guān)的工作。99年第一次跳槽,進(jìn)入了IT行業(yè)做軟件開(kāi)發(fā)。至今,中國(guó)的IT已經(jīng)走過(guò)了十多年。但昔日的“光榮一員”卻成為了現(xiàn)在的“IT農(nóng)民工”,這究竟是怎么了?是中國(guó)的IT發(fā)展已經(jīng)很好了所造成的嗎?不是!在我看來(lái)中國(guó)的IT還比較的原始,還有很大的提升空間。我認(rèn)為造成這一切的都是我們自己,是人!是我們的意識(shí)和方法問(wèn)題。還記得剛從事軟件行業(yè)時(shí),當(dāng)時(shí)有一句話很流行,這句話現(xiàn)在應(yīng)當(dāng)還能聽(tīng)到,那就是:做IT是吃青春飯。說(shuō)實(shí)現(xiàn)在的,一直以來(lái)我對(duì)于這句話一點(diǎn)都不認(rèn)同,但最近慢慢的覺(jué)得有道理。這種意識(shí)的轉(zhuǎn)變不是因?yàn)樽约涸诼殬I(yè)生崖上出現(xiàn)了什么問(wèn)題,而是觀察身邊的人發(fā)現(xiàn)這句話還真有道理。由于不注意方法和不轉(zhuǎn)變意識(shí),我們當(dāng)中的不少人過(guò)著“有工作沒(méi)有生活”的日子,被工作壓得失去了激情。接下來(lái),讓我說(shuō)說(shuō)我能想到或是看到的一些問(wèn)題。
1)我們從學(xué)校畢業(yè)以后,覺(jué)得學(xué)習(xí)到此結(jié)束,應(yīng)當(dāng)是享受人生的時(shí)候了。其實(shí),學(xué)習(xí)和享受生活是“正交”的,我們完全可以即學(xué)好又生活好。毫無(wú)疑問(wèn)我們是生活在競(jìng)爭(zhēng)的環(huán)境中的,那競(jìng)爭(zhēng)的依據(jù)是什么呢?就是我們的能力。大家參加工作后應(yīng)當(dāng)知道,我們學(xué)校所學(xué)的東西在現(xiàn)實(shí)工作中不足以成為我們的核心竟?fàn)幜ΑR蛟熳约旱暮诵木範(fàn)幜Γ仨殞W(xué)習(xí),而且是在自己的業(yè)余時(shí)間學(xué)習(xí)。當(dāng)然,工作也是一種學(xué)習(xí)方式,只是這種學(xué)習(xí)方式不容易創(chuàng)造很大的能力區(qū)分度。此外,學(xué)習(xí)是保持激情的有效方法。我工作近12年了,在軟件行業(yè)干了大約10年,但是至今我還保持著非常好的工作激情,這是我很多同事對(duì)于我的評(píng)價(jià),這一點(diǎn)我想與我保持學(xué)習(xí)很是相關(guān)。學(xué)習(xí)是我從學(xué)校畢業(yè)開(kāi)始一直沒(méi)有放棄去做的事!學(xué)得多了,自然會(huì)想去改變些什么,進(jìn)而使得我們有激情。我在面試別人的時(shí)候,我一定會(huì)問(wèn)題的一個(gè)問(wèn)題是:你平時(shí)看書嗎?看些什么書?一個(gè)不看書的人,其能力不可能很高,看問(wèn)題的深度也不會(huì)深到哪兒去。通過(guò)看書,能讓我們更快的積累知識(shí)和經(jīng)驗(yàn)。有些彎路我們不是需要自己去走、有些錯(cuò)誤我們不是非得犯了才知道、有些好方法和想法也不是一定要我們自己去想,看書能讓我們站得更高、看得更遠(yuǎn)。當(dāng)然,學(xué)習(xí)過(guò)了的東西應(yīng)當(dāng)轉(zhuǎn)化為我們自己的東西(參見(jiàn)第14、15點(diǎn))。
2)認(rèn)為自己的能力與工作的年份是成正比的一條直線。在有些行業(yè)可能是,但在IT行業(yè),這種想法是不對(duì)的。如果你了解三極管,我想我們的能力與工作年份的關(guān)系更像是一條伏安特性曲線。在開(kāi)始的一段時(shí)間是線性的(因?yàn)槲覀儎偖厴I(yè)什么都不會(huì)),但之后從某一點(diǎn)開(kāi)始永遠(yuǎn)是一個(gè)飽和區(qū),到了飽和區(qū)后,能力的變化就非常的小了。這里要指出來(lái)的是,這條曲線的出現(xiàn)是因?yàn)槲覀儚膮⒓庸ぷ饕詠?lái),都是采用同一種原始的方法去對(duì)待我們的工作的。如果我們善于改變自己的工作和學(xué)習(xí)方法,那么就不會(huì)得到一條伏安特性曲線,而有可能是一條接近直線的線。一個(gè)工作了七、八年左右的人,如果沒(méi)有形成自己的一些思想(比如,設(shè)計(jì)思想),那么我認(rèn)為很是有問(wèn)題,自己得多去想想為什么。我們真正學(xué)習(xí)的黃金時(shí)間就是前面的七、八年左右。
3)不明白練“內(nèi)功”的重要性。這里的內(nèi)功是指系統(tǒng)性的分析和看待問(wèn)題,或是其它的一些能力(比如軟件設(shè)計(jì)的能力)。有些人今天學(xué)這個(gè)、明天學(xué)那個(gè),總喜歡學(xué)“新”技術(shù),但忘記了將所學(xué)的東西串起來(lái)從而系統(tǒng)性的去掌握這些技術(shù)背后的東西。其實(shí),一旦學(xué)精了一樣,很多東西是相通的,如此一來(lái),我們很容易快速的去掌握新的東西。再說(shuō)說(shuō)軟件開(kāi)發(fā),其實(shí)學(xué)習(xí)編程語(yǔ)言是簡(jiǎn)單的,是基本功而且不是軟件開(kāi)發(fā)的全部,軟件開(kāi)發(fā)要學(xué)習(xí)的是如何設(shè)計(jì)好一個(gè)軟件,這一點(diǎn)要掌握一定原則和方法,比如我在
《一個(gè)好的設(shè)計(jì)應(yīng)當(dāng)具備哪些要素》中提到到的“四性”就可以作為我們?cè)O(shè)計(jì)時(shí)的一些原則。軟件設(shè)計(jì)能力是本質(zhì),而編語(yǔ)言只是一種表達(dá)設(shè)計(jì)的工具。當(dāng)我們“內(nèi)功”好了以后,學(xué)什么都快、做得也好、看得也深,這與練功夫是一樣的道理。
4)害怕變化。擁抱變化往往能帶給我們提高的機(jī)會(huì)。我們都有自己的舒適圈,我們害怕變化打破我們的舒適圈,但舒適圈的打破不是使得我們沒(méi)有了舒適圈,相反意味著我們的舒適圈越來(lái)越大。我敢說(shuō),現(xiàn)在還有人在用Visual C++ 6.0做開(kāi)發(fā),而現(xiàn)在最新的是Visual Studio 2008(2010馬上也要上市了),這不是因?yàn)閂isual C++ 6.0比Visual Studio 2008好用,而是我們不想改變,還找個(gè)借口說(shuō)“Visual C++太經(jīng)典了”。而事實(shí)是,Visual Studio 2008能幫助我們更快的找出問(wèn)題,不信試試看!我認(rèn)為,一個(gè)勇于擁抱變化的人,他(她)的能力往往更容易提高。
5)過(guò)于埋頭苦干。有的人一接到任務(wù)那可就埋頭苦干起來(lái)了,有時(shí)應(yīng)當(dāng)停下來(lái)想一想:我這樣做的方法是不是很有效率?能不能通過(guò)學(xué)一點(diǎn)別的工具或是方法來(lái)使我的工作更高效?我能從中學(xué)到新的東西呢?還是只是一種重復(fù)性的體力勞動(dòng)?還存在一種人,這種人的確很能干,因此領(lǐng)導(dǎo)什么事都讓他(她)出馬,這樣一來(lái)再苦再累都扛下來(lái)。這個(gè)人,從上司的角度來(lái)看,很好,但從個(gè)人的發(fā)展來(lái)看不一定是一件好事。你想,這個(gè)團(tuán)隊(duì)沒(méi)有你就不行了?我想可能性很小。那如果是這樣為什么什么事都要你干呢?有的工作其實(shí)干過(guò)了一遍就沒(méi)有什么可學(xué)的,只是上司因?yàn)榉判哪悴艑⑹虑榻唤o你,在這種情況下,花再多的時(shí)間去干對(duì)于自己來(lái)講可能是在浪費(fèi)時(shí)間。如果不干,省出來(lái)的時(shí)間我們可以去學(xué)其它的東西。可能有人會(huì)想,我如果不答應(yīng)上司(參見(jiàn)第12點(diǎn)),那會(huì)不會(huì)對(duì)我的績(jī)效不大好呢?其實(shí),這種想法大可不必了,加上有時(shí)績(jī)效并不是真正的公平(其實(shí)世上不存在完全的公平)。今年績(jī)效好是一個(gè)短期利益,如果多學(xué)一點(diǎn)提高自己則是一種長(zhǎng)期的利益。再說(shuō),我們不干的話還可以給別人創(chuàng)造一些鍛煉的機(jī)會(huì)。真的是雙贏!
6)不善于思考。對(duì)于工作有時(shí)就是一個(gè)應(yīng)聲蟲,別人怎么說(shuō),我們就怎么做。有時(shí)更為可怕的是:為什么那么做?合不合理?這種做法與我想到的做法有什么不同?這些問(wèn)題全都不去想。一個(gè)沒(méi)有自己思想的人,不可能在工作中比別人出色,能力自然也不會(huì)太高。
7)不明白高效的完成工作對(duì)于我們自己意味著什么。高效意味著我們可以花節(jié)約下來(lái)的時(shí)間去學(xué)習(xí)、生活,畢竟工作不是我們?nèi)松娜俊N覀儠r(shí)刻應(yīng)當(dāng)警覺(jué)自己是不是在做無(wú)效率的工作,如果是,想盡辦法找出自己無(wú)效率的原因并改善它。有時(shí)我們會(huì)找借口,說(shuō)現(xiàn)在太忙了,沒(méi)有時(shí)間去改善,但真相不是這樣的。我們完全可以通過(guò)一段時(shí)間的努力找到一種好的解決方法,將自己解放出來(lái)。的確,在忙的時(shí)候,如果為了解決無(wú)效率問(wèn)題而花時(shí)間去學(xué)習(xí)其它的東西,那會(huì)讓我們更加的忙。但這種更加的忙(短期的)是有回報(bào)的,而且往往回報(bào)很不錯(cuò)(長(zhǎng)期的),不要總是想“等我有時(shí)間時(shí)再來(lái)改善”,“亂中求冶”永遠(yuǎn)是王道!
8)見(jiàn)難就退,而不是迎難而上。容易意味著我們所學(xué)到的東西很少,或是根本就沒(méi)有。做一百件容易的事,不如做一件難的事所學(xué)到的東西多。難的事多做一件,信心也會(huì)更強(qiáng)一點(diǎn)。
9)不善于表達(dá)我們對(duì)問(wèn)題的不同看法。有些人在工作中不敢去表達(dá)自己與別人相左的想法。我想,如果存在相左的意見(jiàn),說(shuō)明當(dāng)中有可能會(huì)是別人有些東西沒(méi)有想到,或是我們自己有些東西沒(méi)有想到,而通過(guò)交流我們有可能相互提高。擁有一個(gè)開(kāi)放的態(tài)度面對(duì)相左的意見(jiàn)!
10)缺乏創(chuàng)新。一說(shuō)到創(chuàng)新,比較容易讓我們想到那種改變?nèi)澜绲拇笈e,其實(shí)不然,任何一種能改善我們生活的行為都可以認(rèn)為是一種創(chuàng)新。創(chuàng)新也是一種思考和行動(dòng),是一種勇于改變現(xiàn)狀的思考和行動(dòng)。有的人在做一項(xiàng)工作時(shí),其中有很多的重復(fù)(動(dòng)作),即使煩,他(她)也不會(huì)想想是否可以寫一個(gè)腳本去改變、或是采用什么方式解放自己。這一點(diǎn)或許與害怕變化(參見(jiàn)第4點(diǎn))有關(guān)!
11)不善于記筆記和總結(jié)。對(duì)于我們IT人士,筆記不一定要寫在本子上,可以寫成一個(gè)Word文檔,或是其它的什么文件。在筆記中將自己碰到的問(wèn)題寫下來(lái),這便于我們需要用的時(shí)候馬上能找到。有了筆記我們能更高效的工作以及更高興的工作。好處很明顯,干嗎不記筆記呢?通過(guò)筆記我們也能很好的總結(jié)自己,發(fā)現(xiàn)一些有待于提高的部分。
12)不善于與上司溝通。通過(guò)溝通,一是可以從上司那得知他(她)對(duì)于我們的期望是什么,從而,我們可以得知自己的工作方式、方法是否與上司的期望是一致。如果不一致要想想,是不是自己可以改善,或是反過(guò)來(lái)改變上司原來(lái)的想法。第二就是要告訴上司你所期望的。比如,你想升級(jí)(職),那可以與上司說(shuō)一說(shuō),當(dāng)然,前提是你覺(jué)得自己的確能勝任。可能這一次上司并不會(huì)答應(yīng)我們的要求,那也正常,因?yàn)樗ㄋ┯凶约旱目紤],此時(shí)上司可能會(huì)與你說(shuō)原因。我們不能報(bào)著不同意就離職的態(tài)度來(lái)提要求。一次不同意,那我下次再提。在這種情況下,上司如果有一個(gè)名額,那很有可能就考慮到你了。溝通即簡(jiǎn)單也不簡(jiǎn)單,你所想的、做的不一定就是上司所想要的,如果這樣的話結(jié)果自然也不會(huì)令自己滿意。
13)少了一點(diǎn)追求完美的執(zhí)著。人是不完美的,所以我們要去追求完美。追求完美的人更容易出色、更具責(zé)任心,做事往往也顯得更專業(yè)。
14)不明白模仿的重要性。人天生就是模仿者,模仿多了,我們就會(huì)形成一定的思考和行事習(xí)慣,慢慢的也就轉(zhuǎn)化成了自己的能力。我想很多人看過(guò)《設(shè)計(jì)模式》,可能在看時(shí)也有一種同感:其實(shí),不少模式我們平時(shí)都在用。我做設(shè)計(jì)時(shí),從來(lái)不去套《設(shè)計(jì)模式》中的模式,我能憑自己的直覺(jué)找到一種好的設(shè)計(jì),當(dāng)然,有時(shí)我得進(jìn)行多次的反復(fù)。但是不是每一個(gè)人都有很好的直覺(jué),這種直覺(jué)其實(shí)是一種能力,是長(zhǎng)期的學(xué)習(xí)、思考和模仿所積累的能力。在我看來(lái)模仿是將所學(xué)東西轉(zhuǎn)換為自己的能力的很好的一種方法。
15)只求知其然,不求知其所以然。學(xué)習(xí)不能只是表面化的“學(xué)過(guò)了”,還要從深層次去想其背后的思想和原理是什么,這往往使得我們更加容易的去分析和解決問(wèn)題。想得多了,自己的層次才有可能提高,如果只是停留在被動(dòng)的接受,那很難有所提高。
16)少了那么一點(diǎn)堅(jiān)持。我們有可能在學(xué)習(xí)過(guò)程中少了那么一點(diǎn)堅(jiān)持,本來(lái)已經(jīng)做(學(xué))到了90%,再堅(jiān)持一下我們就能上一個(gè)臺(tái)階,能力也會(huì)有一個(gè)質(zhì)的飛躍。但是很可惜,就是因?yàn)椴欢鄨?jiān)持那么一點(diǎn),最后很有可能前功盡棄,最為可怕的是會(huì)打擊我們的自信心 — 下次就不學(xué)了!人與人能力的區(qū)別或許可以說(shuō)是能否堅(jiān)持的區(qū)別!
17)不熱愛(ài)自己的職業(yè)。這一點(diǎn)可能是一些綜合性的因素造成的,或是在工作中沒(méi)有找到成就感、或是自己不適合這個(gè)行業(yè),等等。有時(shí)好好的想想,問(wèn)問(wèn)自己是什么原因造成的這種狀況。如果是因?yàn)樽约旱囊恍┓绞交蚍椒ú粚?duì),那么看看是否能改變。如果的確是因?yàn)樽约簩?duì)行業(yè)沒(méi)有興趣,那我想長(zhǎng)痛不如短痛,還是應(yīng)當(dāng)轉(zhuǎn)行去做自己有興趣的工作。快樂(lè)的工作著是重要的!
此外,除了注意個(gè)人的提高,我想我們還要注意“金字塔原理”。無(wú)論我們能力多高,但我們還是處于金字塔中的一層,也就是說(shuō)能力強(qiáng)的人的數(shù)量總是相對(duì)的少,我們不可能人人都在頂上。即然這樣的話,我們是不是就不應(yīng)當(dāng)去提高了呢?我想不是的,畢竟提高能改善我們的生活,而生活,是自己的。
看了上面的這些,是不是覺(jué)得有些道理呢?千萬(wàn)別看過(guò)就完了,而是要有所行動(dòng)!擁抱變化!
本文出自 “李云” 博客,請(qǐng)務(wù)必保留此出處http://yunli.blog.51cto.com/831344/169937
本文出自 51CTO.COM技術(shù)博客
posted @
2010-02-06 08:35 大鳥(niǎo) 閱讀(164) |
評(píng)論 (0) |
編輯 收藏
下面是我所掌握的使用ADO對(duì)數(shù)據(jù)庫(kù)操作的一些常用方法,主要是提供給初學(xué)者作為參考,有不對(duì)的地方請(qǐng)指正。如有補(bǔ)充不勝榮幸
準(zhǔn)備工作
========
Dim conn As New ADODB.Connection '創(chuàng)建一個(gè) Connection 實(shí)例,在這里使用New等于將Dim和Set合并為一段代碼執(zhí)行
Dim rs As ADODB.Recordset '創(chuàng)建一個(gè) Recordset 實(shí)例,不使用New 是因?yàn)椋?jīng)常需要重復(fù)使用Set,因此沒(méi)必要在這里使用
Dim CnStr As String, Sql As String '創(chuàng)建兩個(gè)字符串變量分別存放兩個(gè)集合的SQL語(yǔ)句代碼段
1、裝載數(shù)據(jù)庫(kù)(不屬于Recordset集合)
=============
Dim FileNamw$, DbIp$, DbName$, DbUser$, DbPw$
'以上5個(gè)字符串變量分別表示文件路徑和文件名、數(shù)據(jù)庫(kù)地址、數(shù)據(jù)庫(kù)名、數(shù)據(jù)操作員用戶名、操作員密碼
FileName = App.Path & "\'數(shù)據(jù)庫(kù)名'"
DbIp = "數(shù)據(jù)庫(kù)地址"
DbName = "數(shù)據(jù)庫(kù)名"
DbUser = "數(shù)據(jù)操作員用戶名"
DbPw = "操作員密碼"
'以上變量根據(jù)數(shù)據(jù)庫(kù)類型的不同而不同,有可能只需要1至兩個(gè)變量
'1)連接Access數(shù)據(jù)庫(kù):
'-------------------
CnStr = "PROVIDER=microsoft.jet.oledb.3.51;persist security info =false;data source=" & FileName & ";Jet OLEDB:Database Password=" & DbPw
'2)連接Oracle數(shù)據(jù)庫(kù):
'-------------------
CnStr = "PROVIDER=MSDAORA.1;Password=" & DbPw & ";User ID=" & DbUser & ";Data Source=" & FileName & ";Persist Security Info=True"
'其中:
'PASSword: 密碼
'User ID: 用戶號(hào)
'Data Source: 數(shù)據(jù)庫(kù)名
'Persist Security Info:
'Provider:
'3)連接VF的DBF庫(kù):
'----------------
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的數(shù)據(jù)庫(kù)
'------------------
CnStr = "PROVIDER=MSDataShape;Data PROVIDER=MSDASQL;uid=" & DbUser & ";pwd=" & DbPw & ";DRIVER=SQL Server;DATABASE=" & DbName & ";WSID=GQSOFT;SERVER=" &
DbIP
'也可以使用這段簡(jiǎn)易代碼 CnStr = "Provider=SQLOLEDB;Data Source=" & DbIp & ";DATABASE=" & DbName & ";UID=" & DbUser & ";pwd=" & DbPw
Conn.Open cnstr '使用 Connection 集合的 Open 方法 與數(shù)據(jù)庫(kù)建立連接
2、Recordset集合的常用方法
==========================
'1)打開(kāi)一個(gè)表
'------------
Sql = "select * from 表名" 'SQL查詢語(yǔ)句
Set rs = New ADODB.Recordset '新建一個(gè)實(shí)例
rs.Open SQL, conn '使用 Open 方法打開(kāi)數(shù)據(jù)庫(kù)中的一個(gè)表
'注意,這種打開(kāi)方式只能使用 rs.MoveNext (即,向后移動(dòng)行坐標(biāo))而不能像其他方向,并且不能修改數(shù)據(jù)內(nèi)容
'
'rs.Open SQL, conn,1 '雖然只加了個(gè)“1”,但這種方法可以向任何方向移動(dòng)行坐標(biāo)。
'
'以下參數(shù)代表了這個(gè)可選值的含義
'0 = adOpenForwardOnly (默認(rèn)值)打開(kāi)僅向前類型游標(biāo)。
'1 = adOpenKeyset 打開(kāi)鍵集類型游標(biāo)。
'2 = adOpenDynamic 打開(kāi)動(dòng)態(tài)類型游標(biāo)。
'3 = adOpenStatic 打開(kāi)靜態(tài)類型游標(biāo)。
'
'雖然使用以上方法可以可以實(shí)現(xiàn)行坐標(biāo)(游標(biāo))的任意移動(dòng),但是仍然無(wú)法寫入數(shù)據(jù)。因此需要進(jìn)一步的對(duì)Open 方法進(jìn)行完善
'rs.Open SQL, conn, 1, 3 '后面的3是確定讀寫權(quán)限的
'以下參數(shù)代表了這個(gè)可選值的含義
'1 = adLockReadOnly (默認(rèn)值)只讀 — 不能改變數(shù)據(jù)。
'2 = adLockPessimistic 保守式鎖定(逐個(gè)) — 在編輯時(shí)立即鎖定數(shù)據(jù)源的記錄。
'3 = adLockOptimistic 開(kāi)放式鎖定(逐個(gè)) — 只在調(diào)用 Update 方法時(shí)才鎖定記錄
'4 = adLockBatchOptimistic 開(kāi)放式批更新 — 用于批更新模式(與立即更新模式相對(duì))。
'
'2)讀寫數(shù)據(jù)
'----------
'增加一行記錄并對(duì)新記錄的內(nèi)容進(jìn)行修改并保存可以如下寫法
rs.AddNew '增加一行記錄
rs("...")="..." '數(shù)據(jù)讀寫操作
...
rs.UpDate '保存寫入資料,如果使用只讀權(quán)限,則不能使用這個(gè)方法
rs.Close '這個(gè)方法用來(lái)關(guān)閉你所代開(kāi)的表,如果不使用這個(gè)方法也可以,但是數(shù)據(jù)庫(kù)仍然認(rèn)為你在對(duì)標(biāo)進(jìn)行鎖定,可造成數(shù)據(jù)庫(kù)負(fù)擔(dān)過(guò)重
2、對(duì)數(shù)據(jù)進(jìn)行篩選和排序
=======================
Sql = "select * from 表名" 'SQL查詢語(yǔ)句
'以上為打開(kāi)一個(gè)表的所有內(nèi)容
Sql = "select top 50 * from 表名" 'SQL查詢語(yǔ)句
'以上為只打開(kāi)前50行的記錄
Sql = "select top 50 列名1,列名2,列名5 from 表名" 'SQL查詢語(yǔ)句
'以上為只打開(kāi)前50行的記錄,并且只打開(kāi)第1、2、5列數(shù)據(jù)
Sql = "select * from 表名 where 列名1='" & 字段 & "'" 'SQL查詢語(yǔ)句
'以上為一個(gè)簡(jiǎn)單的篩選,表示打開(kāi)的內(nèi)容必須符合[列名1='" & 字段 & "'"]的內(nèi)容
'需要注意的是,數(shù)據(jù)庫(kù)列的類型必須匹配,比如字符串類型需要以單引號(hào)括起
'而數(shù)字類型則不能用單引號(hào)括起
'另外SQL語(yǔ)句還支持通配符,例如 列名1 like '%" & 字段 & "%'" 表示包含[字段]
'在表達(dá)式中的匹配
'? _(下劃線) 任何單一字符
'* or % 零個(gè)或多個(gè)字符
'# 任何單一數(shù)字(0 — 9)
'[charlist] 任何在字符表中的單一字符
'[!charlist] 任何不在字符表中的單一字符
'注:根據(jù)數(shù)據(jù)庫(kù)的不同?、_和*、%的應(yīng)用有所差別,比如SQL只使用% 和 _ 分別代表多個(gè)字符和單一字符
SQL = "select * from 表名 where 列名1='" & 字段 & "' ORDER BY 字段1 ASC" '對(duì)查詢結(jié)果進(jìn)行升序排列
SQL = "select * from 表名 where 列名1='" & 字段 & "' ORDER BY 字段1 DESC" '對(duì)查詢結(jié)果進(jìn)行降序排列
SQL = "select * from 表名 where 列名1='" & 字段 & "' ORDER BY 字段1 DESC, ORDER BY 字段2 DESC" '對(duì)查詢結(jié)果進(jìn)行多維降序排列(速度奇慢,不推薦使用)
3、Recordset集合的常用屬性方法
==============================
rs.BOF '是否游標(biāo)在最上邊
rs.EOF '是否游標(biāo)在最下邊
rs.RecordCount '記錄集的行數(shù)(如果使用像前類型的游標(biāo),可能返回不準(zhǔn)確)
rs.AddNew '新建一行記錄
rs.Update '保存當(dāng)前行被修改的記錄
rs.Delete '刪除當(dāng)前行
rs.Close '關(guān)閉記錄集
4、Fields集合的一些屬性的解釋
=============================
'以下為簡(jiǎn)寫,正常情況需要rs.Fileds.。。。但是Fields屬于Recordset的一個(gè)默認(rèn)集合,因此可以省略
rs() '括號(hào)內(nèi)可以是列名也可以是列的序號(hào)例如:rs("姓名")、rs(3) 都是是可以的
rs(3).Name '返回列名
rs(3).Type '返回列的類型
rs(3).Value '返回當(dāng)前行的值
rs.Fields.Count '返回列數(shù)
posted @
2008-11-26 07:30 大鳥(niǎo) 閱讀(309) |
評(píng)論 (0) |
編輯 收藏
VB應(yīng)用程序的打包
使用VB開(kāi)發(fā)軟件的最后一項(xiàng)工作就是打包應(yīng)用程序生成安裝包,利用VB本身提供的打包程序可以實(shí)現(xiàn)打包,但是如果軟件中包含了其他非VB的文件,打包程序不能將這些文件也添加進(jìn)來(lái)。根據(jù)個(gè)人的使用經(jīng)驗(yàn),特總結(jié)了以下兩種打包的方法:
方法一、VB打包程序+Winrar
1、首先利用VB的“打包和展開(kāi)向?qū)?#8221;進(jìn)行打包:
在VB的“外接程序”菜單里選擇“外接程序管理器”命令,在“外接程序管理器”對(duì)話框中選擇“打包和展開(kāi)向?qū)?#8221;:選中“加載行為”中的“加載/卸載”選項(xiàng),點(diǎn)擊“確定”關(guān)閉“外接程序管理器”對(duì)話框。
再在VB的“外接程序”菜單里選擇“打包和展開(kāi)向?qū)?#8221;,在“向?qū)?#8221;對(duì)話框中選擇“打包”功能:在接下來(lái)的對(duì)話框中選擇“編譯”功能,生成.exe文件;“選擇包類型”為“標(biāo)準(zhǔn)安裝包”;指定包的存儲(chǔ)位置;其他選項(xiàng)根據(jù)自己的需要進(jìn)行設(shè)定即可。 打包結(jié)束,并閉VB。
2、利WinRar制作安裝包:
將生成的包文件夾和軟件中所需的所有文件放在一個(gè)文件夾中,并用Winrar對(duì)該文件夾進(jìn)行壓縮:選擇建立“自解壓文件”;在高級(jí)選項(xiàng)里,設(shè)定解壓的目標(biāo)文件夾(如C:)和解壓完成后自動(dòng)執(zhí)行包文件中的setup.exe文件;完成壓縮。
經(jīng)過(guò)以上兩步生成的壓縮包,在解壓后會(huì)自動(dòng)進(jìn)行安裝,實(shí)現(xiàn)軟件的安裝。
方法二、VB打包程序+setup factory
1、首先利用VB的“打包和展開(kāi)向?qū)?#8221;進(jìn)行打包,方法同上。
2、啟動(dòng)setup factory將包文件中“Support”文件夾的文件全部添加進(jìn)行,并添加軟件中所要包含的所有文件,按照向?qū)У囊罂梢苑浅7奖愕赝瓿砂惭b包的制作。
比較以上兩種方法,方法一在沒(méi)有專門的安裝包制作軟件的情況下也可以實(shí)現(xiàn)安裝包的制作,但是對(duì)不同操作系統(tǒng)的支持性較差,在Windows2000下可用,在WindowsXP下可能會(huì)出現(xiàn)“路徑錯(cuò)誤”;方法二制作的安裝包卻更加專業(yè),更加美觀,支持各種操作系統(tǒng),而且簡(jiǎn)單易用。
此外,在應(yīng)用程序當(dāng)中在訪問(wèn)文件時(shí)要使用相對(duì)路徑,否則可能會(huì)導(dǎo)致文件訪問(wèn)錯(cuò)誤。
posted @
2008-11-26 07:26 大鳥(niǎo) 閱讀(8593) |
評(píng)論 (1) |
編輯 收藏
使用ADO控件可以方便的在VB6中訪問(wèn)ODBC數(shù)據(jù)庫(kù),但是通過(guò)直接放置ADODS控件來(lái)獲得ADO的數(shù)據(jù)連接比較麻煩,我們可以在VB工程中創(chuàng)建一個(gè)公共數(shù)據(jù)模塊,將ADO控件的初始化、建立連接、關(guān)閉連接等操作都寫到函數(shù)中,這樣就可以在工程的其他模塊中共享調(diào)用這個(gè)ADO連接。
一次完整的ADO調(diào)用操作分為如下幾個(gè)步驟:
1.打開(kāi)ADO到數(shù)據(jù)庫(kù)的連接,初始化ADO RECORDSET集。
2.通過(guò)寫入SQL語(yǔ)句執(zhí)行查詢并返回查詢結(jié)果RECORDSET集;或者可以通過(guò)寫入SQL語(yǔ)句執(zhí)行相應(yīng)數(shù)據(jù)庫(kù)操作。
3.釋放RECORDSET集,關(guān)閉數(shù)據(jù)庫(kù)連接。
需要注意的是,每個(gè)動(dòng)態(tài)創(chuàng)建的ADO同時(shí)只能被一個(gè)過(guò)程調(diào)用,如果需要進(jìn)行多表并行操作,可能需要在公共數(shù)據(jù)模塊中建立多個(gè)動(dòng)態(tài)ADO。
下面是相關(guān)的代碼:
'-----------------------------------------------------------------
'如下代碼保存在名為my.bas的工程模塊中
Public CONN As Adodb.Connection '定義ADO CONNECTION對(duì)象
Public RS As Adodb.Recordset '定義ADO RECORDSET對(duì)象
'****************************
'打開(kāi)數(shù)據(jù)庫(kù)連接
'****************************
Function ConnOpen()
Dim ASTR As String
Set CONN = New Adodb.Connection
ASTR = GetDatabasePath 'MDB文件數(shù)據(jù)庫(kù)路徑
CONN.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ASTR & ";Persist Security Info=False"
'本例的ODBC連接為JET4.0的直接到MDB文件的連接,如果使用ODBC數(shù)據(jù)源可以使用如下CONNECTION串:
'Provider=MSDASQL.1;Password="";Persist Security Info=True;Data Source=數(shù)據(jù)源名稱;Initial Catalog=數(shù)據(jù)表庫(kù)名稱
CONN.Open
Set RS = New Adodb.Recordset
With RS Do
ActiveConnection = CONN
CursorType = adOpenDynamic
LockType = adLockOptimistic
End With
End Function
'****************************
'關(guān)閉數(shù)據(jù)庫(kù)
'****************************
Function ConnClose()
Set RS = Nothing
CONN.Close
Set CONN = Nothing
End Function
'**********************************************************
' 獲得數(shù)據(jù)庫(kù)路徑
' 本例數(shù)據(jù)庫(kù)保存在程序目錄下的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對(duì)象執(zhí)行SELECT語(yǔ)句
'TableName和FieldName分別為表名和字段名
'查詢結(jié)果保存在數(shù)組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對(duì)象執(zhí)行UPDATE/DELETE/INSERT語(yǔ)句
'SQL語(yǔ)句放在變量sSQL中
Private Sub RunSqlCommand()
Dim sSQL as String
Call my.ConnOpen
my.CONN.Execute sSQL
Call my.ConnClose
End sub
'對(duì)于DATAGRID和DATAREPORT這些需要DATASOURCE的控件可以做如下操作
'使用SELECT語(yǔ)句打開(kāi)RS的數(shù)據(jù)集
Set OBJ.Datasource=my.RS
'---------------------------------------------------------------------
這個(gè)方法對(duì)于開(kāi)發(fā)簡(jiǎn)單小型的MIS系統(tǒng)很實(shí)用,也可以在報(bào)表和數(shù)據(jù)表中使用,缺點(diǎn)是在多表操作和函數(shù)嵌套調(diào)用時(shí),一個(gè)動(dòng)態(tài)ADO對(duì)象不能同時(shí)執(zhí)行兩個(gè)工作,后一個(gè)寫入的SQL語(yǔ)句會(huì)覆蓋先寫入的SQL語(yǔ)句,當(dāng)在回到前一個(gè)過(guò)程時(shí),會(huì)因?yàn)樽侄握也坏蕉鲥e(cuò)。因此如果可能需要進(jìn)行多表操作,可以嘗試多定義幾個(gè)CONN 和RS對(duì)象。
posted @
2008-11-26 07:24 大鳥(niǎo) 閱讀(362) |
評(píng)論 (0) |
編輯 收藏
>> 將文本賦值給MsFlexGrid的單元格
MsFlexGrid.TextMatrix(3,1)=”Hello”
>> 在MsFlexGrid控件單元格中插入背景圖形
Set MsFlexGrid.CellPicture=LoadPicture(“C:\temp\1.bmp”)
>>選中某個(gè)單元
MsFlexGrid.Row=1
MsFlexGrid.Col=1
>>用粗體格式化當(dāng)前選中單元
MsFlexGrid.CellFontBold=True
>> 添加新的一行
使用AddItem方法,用Tab字符分開(kāi)不同單元格的內(nèi)容
dim row as string
row=”AAA”&vbtab&”bbb”
MsFlexFrid1.addItem row
>>怎樣來(lái)實(shí)現(xiàn)MSFlexGrid控件單數(shù)行背景為白色,雙數(shù)的行背景為藍(lán)色?
Dim i As Integer
With MSFlexGrid1
.AllowBigSelection = True ’ 設(shè)置網(wǎng)格樣式
.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有無(wú)滾動(dòng)條
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 ’判斷水平滾動(dòng)條的可見(jiàn)性
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 ’判斷垂直滾動(dòng)條的可見(jiàn)性
Dim i As Long
HeScroll = False
i = GetScrollRange(MshGrid.hWnd, SB_VERT, lpMinPos, lpMaxPos)
If lpMaxPos <> lpMinPos Then HeScroll = True
End Function
>>程序運(yùn)行時(shí),想動(dòng)態(tài)增加MSFlexgrid的列數(shù)
在第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中的對(duì)齊功能的使用
設(shè)置MSFlexGrid1.ColAlignment(index)=n
>>得到MSFlexGrid控件中當(dāng)前選中的一行
msflexgrid1.rowsel就是當(dāng)前選中行
>> 如何通過(guò)代碼調(diào)節(jié)列寬度
msflexgrid1.colwidth(i)=4000
增加 MsFlexGrid 的編輯功能
概述
MsFlexGrid 控件沒(méi)有提供文本編輯的功能,下面的例子演示了如何利用一個(gè)TextBox 實(shí)現(xiàn)編輯當(dāng)前網(wǎng)格的功能。
在按下一個(gè)鍵后, 就把TextBox 移動(dòng)到當(dāng)前的位置, 并激活。 在鍵入回車或移動(dòng)到其他網(wǎng)格時(shí), 就把TextBox 中的內(nèi)容放到網(wǎng)格中。
實(shí)現(xiàn)步驟
1 打開(kāi) VB5, 開(kāi)啟一個(gè)新的工程。
2 在菜單“工程” 中選擇 “部件”, 在列表中選中 “Microsoft FlexGrid Control ..”
3 放一個(gè) MsFlexGrid 控件和一個(gè)TextBox 控件(Text1)到 Form1。 修改MsFlexGrid 控件的名稱為 Grid1, 設(shè)置Grid1 的行,列 為 4, 固定行,列為 0。 設(shè)置 Text1 的 Visiable 為 False, BorderStyle 為 None(0)。
4 在Form1 的代碼中增加聲明:
Const ASC_ENTER = 13 '回車
Dim gRow As Integer
Dim gCol As Integer
5 增加代碼到 Grid_KeyPress 過(guò)程:
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 過(guò)程:
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 過(guò)程:
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 大鳥(niǎo) 閱讀(2158) |
評(píng)論 (1) |
編輯 收藏
VB利用ADO控件連接access數(shù)據(jù)庫(kù)
今天告訴大家VB利用ADO控件連接access數(shù)據(jù)庫(kù)的兩種方法:
一種是在 adodc1的屬性里設(shè)置數(shù)據(jù)庫(kù)文件的路徑,這種方法的優(yōu)點(diǎn)是簡(jiǎn)單易操作,缺點(diǎn)是,當(dāng)源文件換了地方后,要重新設(shè)置數(shù)據(jù)庫(kù)的路徑,否則連接不上數(shù)據(jù)庫(kù)了。
一種是用代碼設(shè)置數(shù)據(jù)庫(kù)的路徑,這種方法的優(yōu)點(diǎn)就是只要源文件和數(shù)據(jù)庫(kù)在同一文件夾下,無(wú)論移動(dòng)到哪里都能連接上。
如果沒(méi)有建立好數(shù)據(jù)庫(kù)的話,先建立一個(gè)數(shù)據(jù)庫(kù),然后建立一個(gè)表比如我們建的表名為message,然后把里面的字段名稱和數(shù)據(jù)類型都按自己的需要設(shè)置好.然后保存就可以了.
打開(kāi)Microsoft Visual Basic6.0 我用的是VB6.0,在需要調(diào)用數(shù)據(jù)庫(kù)的窗體上加入一個(gè)adodc控件,默認(rèn)名稱為:Adodc1。默認(rèn)的情況下工具欄里是沒(méi)有這個(gè)控件的,可以打開(kāi)工程---部件(快捷鍵CTRL+T),去掉只顯示選定項(xiàng)的勾,然后勾上Microsoft ADO Data Control(OLEDB),然后確定,工具欄就會(huì)多了一個(gè)adodc的控件。
第一種方法:設(shè)置adodc1的屬以連接數(shù)據(jù)庫(kù).在adodc1控件上右鍵--Adodc屬性--使用連接字符串--生成--Microsoft Jet 4.0 OLE DB Provider--下一步--選擇或輸入數(shù)據(jù)庫(kù)名稱---找到要連接的數(shù)據(jù)庫(kù)后,確定.然后記錄源設(shè)置屬性. 如果要把內(nèi)容提交到數(shù)據(jù)庫(kù)一般使用adCmdTable. 表選擇要連接的表。
設(shè)置完畢后就可以了.
如果我們想把內(nèi)容提交到數(shù)據(jù)庫(kù).舉個(gè)例子..
在窗體建立一個(gè)文本框,設(shè)置屬性中的DataSource為adodc1 DataField為要連接的數(shù)據(jù)庫(kù)的字段名。如果數(shù)據(jù)庫(kù)中有字段,會(huì)讓你選擇。
設(shè)置好后在窗體加一個(gè)添加記錄和一個(gè)提交的按鈕,設(shè)置代碼:
Private Sub Command1_Click()
Adodc1.Recordset.Update '保存
Adodc1.Refresh '刷新
End Sub
添加按鈕代碼:
Private Sub Command2_Click()
Adodc1.Recordset.AddNew '添加新紀(jì)錄
Adodc1.Recordset("姓名").Value = Text1.Text
End Sub
第二種方法:
在窗體添加Adodc控件一個(gè)text控件 一個(gè)添加記錄按鈕一個(gè)提交按鈕
在窗體設(shè)置代碼:
Private Sub Form_Load()
Adodc1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + App.Path + "\db1.mdb;Persist Security Info=False" '設(shè)置數(shù)據(jù)庫(kù)路徑
Adodc1.CommandType = adCmdText '設(shè)置記錄源
Adodc1.RecordSource = "select * from message" '連接數(shù)據(jù)庫(kù)的message表文件
Set Text1.DataSource = Adodc1
text1.DataField = "姓名"
End Sub
添加記錄按鈕代碼:
Private Sub Command1_Click()
Adodc1.Recordset.AddNew '添加新紀(jì)錄
End Sub
提交代碼:
Private Sub Command2_Click()
Adodc1.Recordset.Update '保存
Adodc1.Refresh '刷新
End Sub
好了連接方法講完了,我都在機(jī)子上測(cè)試過(guò)了,因該沒(méi)有什么問(wèn)題的。如果有問(wèn)題請(qǐng)多看幾遍,或看些別人寫的程序代碼,會(huì)有很大進(jìn)步的,我的VB也不好,因?yàn)椴皇怯?jì)算機(jī)專業(yè)的,老師也沒(méi)有教很多,高手莫笑。好了我再給大家?guī)讉€(gè)查詢數(shù)據(jù)庫(kù)常用的代碼:
首記錄按鈕的代碼:
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 "已經(jīng)無(wú)記錄", , "提示"
End If
End Sub
如果有什么不對(duì)的地方,請(qǐng)大家指正。
posted @
2008-11-26 07:19 大鳥(niǎo) 閱讀(2347) |
評(píng)論 (0) |
編輯 收藏
DataGrid 控件是一種類似于電子數(shù)據(jù)表的綁定控件,可以顯示一系列行和列來(lái)表示 Recordset 對(duì)象的記錄和字段。可以使用 DataGrid 來(lái)創(chuàng)建一個(gè)允許最終用戶閱讀和寫入到絕大多數(shù)數(shù)據(jù)庫(kù)的應(yīng)用程序。DataGrid 控件可以在設(shè)計(jì)時(shí)快速進(jìn)行配置,只需少量代碼或無(wú)需代碼。當(dāng)在設(shè)計(jì)時(shí)設(shè)置了DataGrid 控件的 DataSource 屬性后,就會(huì)用數(shù)據(jù)源的記錄集來(lái)自動(dòng)填充該控件,以及自動(dòng)設(shè)置該控件的列標(biāo)頭。然后您就可以編輯該網(wǎng)格的列;刪除、重新安排、添加列標(biāo)頭、或者調(diào)整任意一列的寬度。
在運(yùn)行時(shí),可以在程序中切換 DataSource 來(lái)察看不同的表,或者可以修改當(dāng)前數(shù)據(jù)庫(kù)的查詢,以返回一個(gè)不同的記錄集合。
注意 DataGrid 控件與 Visual Basic 5.0中的 DBGrid 是代碼兼容的,除了一個(gè)例外:DataGrid 控件不支持 DBGrid 的“解除綁定模式”概念。DBGrid 控件包括在 Visual Basic 的 Tools 目錄中。
可能的用法
查看和編輯在遠(yuǎn)程或本地?cái)?shù)據(jù)庫(kù)中的數(shù)據(jù)。
與另一個(gè)數(shù)據(jù)綁定的控件(諸如 DataList 控件)聯(lián)合使用,使用 DataGrid控件來(lái)顯示一個(gè)表的記錄,這個(gè)表通過(guò)一個(gè)公共字段鏈接到由第二個(gè)數(shù)據(jù)綁定控件所顯示的表。
使用 DataGrid 控件的設(shè)計(jì)時(shí)特性
可以不編寫任何代碼,只通過(guò)使用 DataGrid 控件的設(shè)計(jì)時(shí)特性來(lái)創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)應(yīng)用程序。下面的說(shuō)明概要地說(shuō)明了在實(shí)現(xiàn) DataGrid 控件的典型應(yīng)用時(shí)的一般步驟。完整的循序漸進(jìn)的指示,請(qǐng)參閱主題“DataGrid 方案1: 使用 DataGrid 控件創(chuàng)建一個(gè)簡(jiǎn)單數(shù)據(jù)庫(kù)應(yīng)用程序”。
要在設(shè)計(jì)時(shí)實(shí)現(xiàn)一個(gè) DataGrid 控件
1. 為要訪問(wèn)的數(shù)據(jù)庫(kù)創(chuàng)建一個(gè) Microsoft 數(shù)據(jù)鏈接 (.MDL) 文件。請(qǐng)參閱“創(chuàng)建 Northwind OLE DB 數(shù)據(jù)鏈接”主題,以獲得一個(gè)示例。
2. 在窗體上放置一個(gè) ADO Data 控件,并將其 ConnectionString 屬性設(shè)置為在第 1 步中所創(chuàng)建的OLE DB 數(shù)據(jù)源。
3. 在這個(gè) Ado Data 控件的 RecordSource 屬性中輸入一條將返回一個(gè)記
錄集的 SQL 語(yǔ)句。例如,Select * From MyTableName Where CustID = 12
4. 在窗體上放置一個(gè) DataGrid 控件,并將其 DataSource 屬性設(shè)置為這個(gè) ADO Data 控件。
5. 右鍵單擊該 DataGrid 控件,然后單擊“檢索字段”。
6. 右鍵單擊該 DataGrid 控件,然后單擊“編輯”。
7. 重新設(shè)置該網(wǎng)格的大小、刪除或添加網(wǎng)格的列。
8. 右鍵單擊該 DataGrid 控件,然后單擊“屬性”。
9. 使用“屬性頁(yè)”對(duì)話框來(lái)設(shè)置該控件的適當(dāng)?shù)膶傩裕瑢⒃摼W(wǎng)格配置為所需的外觀和行為。
在運(yùn)行時(shí)更改顯示的數(shù)據(jù)
在創(chuàng)建了一個(gè)使用設(shè)計(jì)時(shí)特性的網(wǎng)格后,也可以在運(yùn)行時(shí)動(dòng)態(tài)地更改該網(wǎng)格的數(shù)據(jù)源。下面介紹實(shí)現(xiàn)這一功能的通常方法。
更改 DataSource 的RecordSource
更改所顯示的數(shù)據(jù)的最通常方法是改變?cè)?DataSource 的查詢。例如,如果DataGrid 控件使用一個(gè)ADO Data控件作為其 DataSource,則重寫RecordSource和刷新該ADO Data 控件都將改變所顯示的數(shù)據(jù)。
' ADO Data 控件連接的是 Northwind 數(shù)據(jù)庫(kù)的' Products 表。新查詢查找所有
' SupplierID = 12 的記錄。
Dim strQuery As String
strQuery = "SELECT * FROM Suppliers WHERE SupplierID = 12"
Adodc1.RecordSource = strQuery
Adodc1.Refresh
更改 DataSource
在運(yùn)行時(shí),可以將 DataSource 屬性重新設(shè)置為一個(gè)不同的數(shù)據(jù)源。例如,您可能具有若干個(gè) ADO Data 控件,每個(gè)控件連接不同的數(shù)據(jù)庫(kù),或設(shè)置為不同的 RecordSource 屬性。可以簡(jiǎn)單地將 DataSource 從一個(gè) ADO Data控件重新設(shè)置為另一個(gè) ADO Data 控件:
' 將 DataSource 重新設(shè)置為一個(gè)連接到 Pubs 數(shù)據(jù)庫(kù)的、
' 使用 Authors 表的 ADO Data 控件。
Set DataGrid1.DataSource = adoPubsAuthors
重新綁定 DataSource
當(dāng)將 DataGrid 控件用于一個(gè)遠(yuǎn)程數(shù)據(jù)庫(kù),諸如 SQLServer 時(shí),可以改變表的結(jié)構(gòu)。例如,可以給這個(gè)表添加一個(gè)字段。在這種情形下,可以調(diào)用Rebind 方法根據(jù)新的結(jié)構(gòu)來(lái)重新創(chuàng)建該網(wǎng)格。注意,如果已經(jīng)在設(shè)計(jì)時(shí)改變了這個(gè)列的布局,DataGrid 控件將會(huì)試圖重新創(chuàng)建當(dāng)前的布局,包括任何空的列。不過(guò),通過(guò)首先調(diào)用 ClearFields 方法,可以強(qiáng)制該網(wǎng)格重新設(shè)置所有的列。
從 DataGrid 返回值
在 DataGrid 被連接到一個(gè)數(shù)據(jù)庫(kù)后,可能想要監(jiān)視用戶單擊了哪一個(gè)單元。可以使用 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 方法
當(dāng)一個(gè)列使用 NumberFormat 屬性設(shè)置格式后,CellText 和 CellValue 屬性是很有用的。NumberFormat 屬性不必更改實(shí)際的數(shù)據(jù)格式就可以更改任何包含數(shù)字的列的格式。例如,給定一個(gè)網(wǎng)格,其中包含一個(gè)名為 ProductID的、包含整數(shù)的列。下面的代碼將使 DataGrid 以"P-0000" 的格式來(lái)顯示數(shù)據(jù)。換句話說(shuō),盡管在 ProductID 字段中所包含的實(shí)際數(shù)值為 "3",但該網(wǎng)格所顯示的值將是 "P-0003"。
Private Sub Form_Load()
DataGrid1.Columns("ProductID").NumberFormat = "P-0000"
End Sub
要返回?cái)?shù)據(jù)庫(kù)中所包含的實(shí)際值,應(yīng)使用 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 屬性作為一個(gè)參數(shù),功能才正確。
相反地,如果要返回該字段的格式化的值,應(yīng)使用 CellText 方法:
Private Sub DataGrid1_RowColChange(LastRow As Variant, ByVal LastCol As Integer)
Debug.Print _
DataGrid1.Columns("ProductID").CellText(DataGrid1.Bookmark)
End Sub
注意 上面的 CellText 方法等價(jià)于使用 DataGrid 控件的 Text 屬性。
下一步
要閱讀關(guān)于使用該控件創(chuàng)建簡(jiǎn)單的應(yīng)用程序的一個(gè)循序漸進(jìn)的過(guò)程,請(qǐng)參閱“使用 DataGrid 控件創(chuàng)建簡(jiǎn)單的數(shù)據(jù)庫(kù)應(yīng)用程序”,或“創(chuàng)建一個(gè)連接DataList 控件的 DataGrid”。
要了解關(guān)于 Split 對(duì)象以及如何對(duì)其編程的詳細(xì)信息,請(qǐng)參閱“操作DataGrid 視圖”。
創(chuàng)建 Northwind 的OLE DB 數(shù)據(jù)鏈接
訪問(wèn)數(shù)據(jù)的一個(gè)重要步驟是為想要訪問(wèn)的每個(gè)數(shù)據(jù)庫(kù)都創(chuàng)建一個(gè) OLE DB數(shù)據(jù)源。下面的步驟為 Visual Basic 所提供的Nwind.mdb (Northwind) 數(shù)據(jù)庫(kù)創(chuàng)建這樣一個(gè)對(duì)象。這個(gè)數(shù)據(jù)源被用于 Visual Basic 文檔所提供的一些示例過(guò)程。在一個(gè)計(jì)算機(jī)上只需要?jiǎng)?chuàng)建一次OLE DB數(shù)據(jù)源。
要?jiǎng)?chuàng)建 Northwind 的OLE DB 數(shù)據(jù)源
1. 打開(kāi) Windows Explorer或 Windows NT Explorer。
2. 打開(kāi)您想要?jiǎng)?chuàng)建 OLE DB 數(shù)據(jù)源的目錄。在該示例中,打開(kāi) ProgramFiles、Microsoft Visual Studio和VB98。
3. 右鍵單擊 Explorer 的右邊窗格,然后單擊上下文菜單上的“新建”。從文件類型列表中單擊“Microsoft 數(shù)據(jù)鏈接”。
4. 重命名新文件 Northwind.MDL。
5. 右鍵單擊文件并單擊上下文菜單上的“屬性”,以顯示“Northwind.MDLProperties”對(duì)話框。
6. 單擊“連接”選項(xiàng)卡。
7. 單擊“提供方”框并選擇“Microsoft Jet 3.51 OLE DB Provider”。
8. 在Data Source 框中輸入nwind.mdb文件的路徑。
9. 單擊“測(cè)試連接”,檢測(cè)連接。
10. 如果連接通過(guò),單擊“確定”。
注意 也可以通過(guò)在“控制面板”中單擊“數(shù)據(jù)鏈接”圖標(biāo)創(chuàng)建一個(gè) OLE DB數(shù)據(jù)源。在“管理數(shù)據(jù)鏈接文件”對(duì)話框中,單擊“新建”創(chuàng)建一個(gè)新的數(shù)據(jù)源。
使用 DataGrid 和 ADO Data控件創(chuàng)建一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)應(yīng)用程序
只使用一個(gè) DataGrid 和一個(gè) ADO Data 控件,可以創(chuàng)建一個(gè)允許最終用戶閱讀和寫入記錄集的數(shù)據(jù)庫(kù)應(yīng)用程序。
要使用 ADO 數(shù)據(jù)控件來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)應(yīng)用程序
1. 為 Northwind 數(shù)據(jù)庫(kù)創(chuàng)建一個(gè)OLE DB 數(shù)據(jù)源。如果還沒(méi)有創(chuàng)建數(shù)據(jù)源,請(qǐng)按照“創(chuàng)建 Northwind 的OLE DB Data Link”中的步驟操作。
2. 在Visual Basic 中創(chuàng)建一個(gè)新的標(biāo)準(zhǔn)的 EXE 工程。如果 DataGrid 控件不在“工具箱”中,則用右鍵單擊“工具箱”,然后使用“部件”對(duì)話框來(lái)添加控件。同時(shí)也載入 ADO 控件。
3. 在空窗體上各放置控件的一個(gè)實(shí)例。
4. 將 ADO 控件的ConnectionString 屬性設(shè)置為 Northwind 的數(shù)據(jù)源。單擊并選定該 ADO Data 控件,并按 F4 鍵出現(xiàn)“屬性”窗口。單擊“ConnectionString”,然后單擊 OLE DB File。單擊 Northwind 的數(shù)據(jù)源。
5. 設(shè)置 ADO 控件的 RecordSource 屬性。在“屬性”窗口中,單擊“記錄源”并輸入一條 SQL 語(yǔ)句來(lái)填充 DataGrid
控件。在本例中,輸入“Select * From Products”。
6. 將 DataGrid 控件的 DataSource 屬性設(shè)置為這個(gè) ADO Data 控件。單擊并選定該 DataGrid 控件。在其“屬性”窗口中,單擊“數(shù)據(jù)源”將出現(xiàn)一個(gè)包含所有數(shù)據(jù)控件的下拉列表——在本例中只有 ADO Data 控件。單擊這個(gè)控件。
7. 按 F5 鍵運(yùn)行這個(gè)工程。
創(chuàng)建一個(gè)連接 DataList 控件的 DataGridData
Grid 的通常用法是顯示數(shù)據(jù)庫(kù)的一個(gè)表所提供的“詳細(xì)內(nèi)容”。例如,Northwind (Nwind.mdb) 數(shù)據(jù)庫(kù)包括兩個(gè)表,一個(gè)名為 "Suppliers",另一個(gè)名為 "Products"。在本例中,我們使用 DataList 控件來(lái)顯示 "Suppliers" 表中的供應(yīng)商的公司名稱。當(dāng)用戶單擊任意一個(gè)公司名稱時(shí),這個(gè) DataList 控件將提供該公司的 SupplierID。使用這個(gè)標(biāo)識(shí)符,就可以構(gòu)造一個(gè)查詢,在 "Products" 表中檢索具有相匹配的 SupplierID 的所有記錄。換句話說(shuō),當(dāng)用戶單擊一個(gè)公司時(shí)(在 DataList 控件中),該公司生產(chǎn)的所有產(chǎn)品將出現(xiàn)在 DataGrid 控件中。
要使用一個(gè)指定供應(yīng)商的產(chǎn)品填充一個(gè) DataGrid 控件
1. 確認(rèn)在機(jī)器上已為 Northwind 數(shù)據(jù)庫(kù)建立了一個(gè)OLE DB 數(shù)據(jù)源;如果還沒(méi)有創(chuàng)建這樣的一個(gè)數(shù)據(jù)源,請(qǐng)按照“創(chuàng)建 Northwind 的OLE DBData連接”的步驟操作。
2. 在Visual Basic 中創(chuàng)建一個(gè)新的標(biāo)準(zhǔn)的 EXE 工程。
如果 DataGrid、DataList 和 ADO Data 控件不在“工具箱”中,則右鍵單擊“工具箱”,然后單擊“部件”。在“部件”對(duì)話框中雙擊“MicrosoftDataGrid Control”、“Microsoft DataList Controls”以及“Microsoft ADOControl”。
3. 在一個(gè)空窗體中各放置一個(gè) DataGrid 和 DataList 控件的實(shí)例。將 DataList 控件放置在該窗體的左上角,然后將 DataGrid 控件放在它的下面的某處。
4. 在窗體放置兩個(gè) ADO Data 控件實(shí)例。選擇第一個(gè) ADO Data 控件,并按 F4 鍵來(lái)顯示其“屬性頁(yè)”。將該控件的 Name 屬性設(shè)置為 adoSuppliers。選擇第二個(gè) ADO Data 控件并將其 Name 屬性設(shè)置為 adoProducts。將第一個(gè)控件直接放在 DataList 控件的下面,把第二個(gè)控件直接放在 DataGrid 控件的下面。
5. 將這兩個(gè) ADO Data 控件的 ConnectionString 屬性設(shè)置為 Northwind的OLE DB 數(shù)據(jù)源。選擇名為 adoSuppliers 的控件,然后將其ConnectionString 屬性設(shè)置為Northwind 的OLE DB data source (Northwind.mdl)。選擇名為 adoProducts的控件,并重復(fù)該操作。
6. 設(shè)置這兩個(gè) ADO Data 控件的 RecordSource 屬性。選擇 adoSuppliers 并在其“屬性頁(yè)”上單擊“RecordSoure”。輸入 Select* From Suppliers。這個(gè)查詢將指示該 ADO Data 控件返回 Suppliers 表中的所有記錄。選擇 adoProducts,單擊“RecordSoure”,并輸入 Select *From Products。這個(gè)查詢將返回在 Products 表中的所有記錄。
7. 將 DataList 控件的 RowSource 屬性設(shè)置為 adoSuppliers。
RowSource 屬性決定由哪一個(gè)數(shù)據(jù)源為 ListField 屬性供應(yīng)數(shù)據(jù)。
8. 將 DataList 控件的 ListField 屬性設(shè)置為 CompanyName。
ListField 屬性被設(shè)置成名為 Suppliers 的表中的字段名稱。在運(yùn)行時(shí),DataList 控件顯示在這個(gè)屬性中所指定的字段的值。在本例中,該屬性將顯示在 Suppliers 表中找到的一個(gè)公司名稱。
9. 將 DataList 控件的 BoundColumn 屬性設(shè)置為 SupplierID。
BoundColumn 屬性被設(shè)為 Suppliers 表中的第二個(gè)字段。在本例中,這個(gè)屬性就被設(shè)為 SupplierID 字段。當(dāng)單擊 DataList 控件時(shí),BoundText屬性返回與在 DataList 控件中所顯示的公司相關(guān)聯(lián)的 SupplierID 字段的值。這個(gè)值將用于對(duì) Products 表的查詢,該查詢?yōu)?DataGrid 控件提供數(shù)據(jù)。
10. 將 DataGrid 控件的 DataSource 屬性設(shè)置為 adoProducts。
DataSource 屬性為該控件指定數(shù)據(jù)源。在本例中,該屬性被設(shè)置為名為adoProducts 的 ADO Data 控件,這將返回 Products 表中的所有記錄。
11. 在窗體的代碼模塊中,添加下述內(nèi)容:
Private Sub Datalist1_Click()
' 聲明一個(gè)用來(lái)包含新查詢的字符串變量。這個(gè)新的
' 查詢使用 DataList 控件的BoundText屬性
' 來(lái)提供一個(gè) SupplierID 值。新查詢查找所有
' 具有相同的 SupplierID 的產(chǎn)品。這個(gè)查詢被
' 指定給名為 adoProducts 的 ADO Data 控件
' 的 RecordSource 屬性。在刷新控件后,DataGrid
' 將使用包含由同一個(gè)公司供應(yīng)的所有產(chǎn)品的新
' 記錄集來(lái)更新。
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. 運(yùn)行該工程。
單擊 DataList 控件中的任意公司名稱,將自動(dòng)用該公司所供應(yīng)的產(chǎn)品更新 DataGrid 控件。
使用列
通過(guò)更改 DataSource 屬性,可以動(dòng)態(tài)地更改在 DataGrid 控件中顯示的數(shù)據(jù)。例如,可以顯示同一個(gè)數(shù)據(jù)庫(kù)的不同表。如果這樣做,則 DataGrid 控件將只根據(jù)默認(rèn)的屬性顯示數(shù)據(jù)。
添加、刪除或隱藏列
通過(guò)使用 Columns 集合和 Column 對(duì)象的屬性和方法,可以在程序中添加、刪除或隱藏列。
添加和刪除一列
要在運(yùn)行時(shí)添加一列,可以使用 Add 方法。如果首先聲明一個(gè)變量,并將新對(duì)象賦給該變量,就可以用簡(jiǎn)明的代碼設(shè)置各種屬性。
Private Sub AddColumn()
' 在最右邊的位置添加一列。然后設(shè)置其 Visible、Width、
' Caption以及 Alignment 屬性。DataField 屬性則指定
' 該列將綁定到哪一個(gè)字段。
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
可以使用方法來(lái)刪除任意一列。請(qǐng)確保使用 ColIndex 參數(shù)來(lái)指定要?jiǎng)h除的列。下面的代碼將刪除被單擊的列。
Private Sub DataGrid1_HeadClick(ByVal ColIndex As Integer)
DataGrid1.Columns.Remove ColIndex
End Sub
隱藏一列
通過(guò)將 Visible 屬性設(shè)置為 False,可以隱藏任意一列。當(dāng)想要限制用戶可以查看或編輯的列時(shí)這一功能特別有用。下面的示例在 Columns 集合中循環(huán),隱藏除少數(shù)列之外的所有列。
Private Sub HideColumns()
' 使用 DataField 屬性來(lái)判別正在測(cè)試的是哪一列。
' 只顯示三列: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" ' 更改這個(gè)列的標(biāo)頭。
Case Else ' 隱藏其它所有的列。
c.Visible = False
End Select
Next c
End Sub
操作 DataGrid 視圖
一個(gè)“拆分”的網(wǎng)格使最終用戶對(duì)相同的數(shù)據(jù)可以擁有多個(gè)視圖。例如,假設(shè)有一個(gè)由十個(gè)字段組成的大表。在這種情況下,在控件中察看的記錄集將有十列寬,除非窗體非常寬,否則用戶將無(wú)法同時(shí)看見(jiàn)所有列的內(nèi)容。,而且,假設(shè)用戶只對(duì)第一列和最后一列感興趣(例如,第一列是名字,最后一列是電話號(hào)碼)。為了能同時(shí)看到在兩端的列(不重新安排列的順序),可以對(duì)網(wǎng)格進(jìn)行拆分。
創(chuàng)建一個(gè) Split 對(duì)象
在設(shè)計(jì)時(shí),可以創(chuàng)建一個(gè)拆分,具體步驟是:右鍵單擊網(wǎng)格,單擊“編輯”,再單擊右鍵,然后單擊“拆分”。通過(guò)右鍵單擊該控件,并單擊“屬性”來(lái)顯示“屬性頁(yè)”對(duì)話框,可以編輯這個(gè)拆分。可以使用“拆分”選項(xiàng)卡來(lái)自定義拆分。要?jiǎng)h除一個(gè)拆分,右鍵單擊該拆分,并單擊“刪除”。
在運(yùn)行時(shí),最終用戶也可以通過(guò)單擊位于這個(gè)網(wǎng)格控件的左下邊的右邊的選項(xiàng)卡,以手工方式來(lái)拆分該網(wǎng)格(除非不允許這個(gè)操作),如下圖所示:
默認(rèn)情況下,DataGrid 控件包含一個(gè) Split 對(duì)象。防止最終用戶添加拆分的代碼為:
DataGrid1.Splits(0).AllowSizing = False
在程序中添加和刪除拆分
DataGrid 控件包含一個(gè) Split 對(duì)象的集合。要在程序中添加拆分,可以使用 Add 方法,如下所示:
DataGrid1.Splits.Add 1
注意 Add 方法需要新的拆分索引作為其參數(shù)。要添加一個(gè)拆分,應(yīng)將這個(gè)索引參數(shù)設(shè)置為 Splits 集合的 Count 屬性值。
使用 Split 集合的 Add 方法,可以在程序中按照實(shí)際需要添加拆分。由于添加多于兩個(gè)以上的拆分將使網(wǎng)格很難使用,可以使用該集合的 Count 屬性來(lái)限制拆分的數(shù)目。
If DataGrid1.Splits.Count < 3 Then ' 添加一個(gè)拆分。
DataGrid1.Splits.Add DataGrid1.Splits.Count
End If
使拆分同步
當(dāng)拆分多于一個(gè)時(shí),可能希望控制這些拆分如何滾動(dòng)。例如,在一個(gè)具有三個(gè)拆分的網(wǎng)格中,可以決定只讓第一個(gè)和第三個(gè)拆分同步,而讓中間的拆分獨(dú)立地滾動(dòng)。要同步任何兩個(gè)(或多個(gè))拆分,只需將每個(gè) Split 對(duì)象的 ScrollGroup 屬性設(shè)置為同一個(gè)值。
' 使第一個(gè)和第三個(gè) Split 對(duì)象同步。
With DataGrid1
.Splits(0)
.ScrollGroup = 1
.Splits(1).ScrollGroup = 2
.Splits(2).ScrollGroup = 1
End With
通過(guò)設(shè)置 Scrollbars 屬性,使同步的拆分組只顯示一個(gè)滾卷?xiàng)l,從而進(jìn)一步自定義拆分的外觀。
控制 Tab 鍵和箭頭鍵的行為
使用 WrapCellPointer、TabAcrossSplits以及 TabAction 屬性,可以決定當(dāng)最終用戶按下 tab 鍵或箭頭鍵時(shí)網(wǎng)格的行為。
在這三個(gè)屬性中,TabAction 屬性級(jí)別最高,它決定 WrapCellPointer 和TabAcrossSplits 這兩個(gè)屬性是否能生效。TabAction 有三個(gè)設(shè)置值: ControlNavigation、Column Navigation 和 Grid Navigation。當(dāng)該屬性設(shè)置為 ControlNavigation 時(shí),按 Tab 鍵根據(jù) TabIndex 將焦點(diǎn)切換到下一個(gè)控件。這一設(shè)置優(yōu)先于 WrapCellPointer 和 TabAcrossSplits。
WrapCellPointer 屬性決定在任何單個(gè)的拆分中 tab 鍵和箭頭鍵的行為。如果該屬性設(shè)置為 True,且當(dāng)前單元位于最后一列,這時(shí)最終用戶按 tab 鍵則使第一列的下一行變成當(dāng)前的單元。不過(guò),如果當(dāng)前單元位于最后一行的最后一列時(shí),這時(shí)就沒(méi)有地方可以“換行”。
TabAcrossSplits 屬性決定當(dāng)網(wǎng)格中存在兩個(gè)或多個(gè)拆分時(shí) tab 和箭頭鍵的行為。如果該屬性設(shè)置為 True,且當(dāng)前單元位于任何一個(gè)拆分的最后一列,則按Tab或箭頭鍵將使當(dāng)前單元“跳” 到下一個(gè)拆分的第一列。當(dāng)前單元仍保持相同的行位置。
注意 如果 WrapCellPointer 和 TabAcrossSplits 屬性都設(shè)置為 True,則只有當(dāng)前單元位于最后一個(gè)拆分的最后一列時(shí)才會(huì)換行。這時(shí)當(dāng)前單元將換到第一個(gè)拆分的第一列中的下一行。
自定義列集合
每一個(gè) Split 對(duì)象都有一個(gè) Columns 屬性,允許用戶來(lái)操作一個(gè) Column對(duì)象的集合。通過(guò)這樣做,可以更改每個(gè) Split 對(duì)象的外觀。例如,可以用一個(gè)拆分包含顯示姓氏字段和名字字段的兩個(gè)列,而第二個(gè)拆分則顯示電話字段和地址字段。要實(shí)現(xiàn)這一目標(biāo),需要將其它的每一列的 Visible 屬性設(shè)置為 False,如下所示:
' 枚舉 Columns 集合,對(duì)每一個(gè) Column 對(duì)象的 DataField 屬性
' 進(jìn)行測(cè)試。如果測(cè)試失敗,則隱藏這一列。
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 提供了標(biāo)記記錄的一種手段。當(dāng)編寫應(yīng)用程序中的特定功能(諸如允許最終用戶手工地選擇多個(gè)不相鄰的記錄,進(jìn)行所選記錄的大批更新)時(shí),這就很有必要。在這些情形中,需要標(biāo)記哪些記錄已被選擇,因此可以使用 SelBookmarks 集合及其屬性。
有兩個(gè)函數(shù),分別是 CellText 和 CellValue 方法,需要標(biāo)記才能正確執(zhí)行。
標(biāo)記用戶的選擇
SelBookmarks 集合包含所有選定的記錄的書簽。當(dāng)最終用戶手工選擇記錄時(shí)(即在單擊時(shí)按住 CTRL 鍵),每一個(gè)選定的記錄的書簽都會(huì)加入到該集合中。使用標(biāo)準(zhǔn)的循環(huán),用戶可以知道已經(jīng)選定了什么,也可以保存書簽(因?yàn)榭赡苄枰謴?fù)某個(gè)值),以及執(zhí)行操作:
Dim i as Integer ' 計(jì)數(shù)器
Dim intCount As Integer
intCount = DataGrid1.SelBookmarks.Count - 1
ReDim arrSelBK(intCount) ' 聲明用于保存書簽的數(shù)組。
For i = 0 To intCount
ArrSelBK(i) = DataGrid1.SelBookmarks(i)
' 在此處執(zhí)行操作。如果該操作必須被
' 取消,則退出該循環(huán),然后使用該數(shù)
' 組來(lái)取消這些更改。
Next i
通過(guò)在程序中添加到 SelBookmarks 集合來(lái)選擇記錄
通過(guò)將記錄添加到這個(gè)集合,也可以在程序中選定記錄。例如,可能有一個(gè)顯示指定的客戶所有訂貨的網(wǎng)格。如果要高亮顯示該客戶花費(fèi)超過(guò) $100的所有記錄,則對(duì)記錄進(jìn)行過(guò)濾,并將結(jié)果書簽添加到 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
顯示計(jì)算結(jié)果字段
假設(shè)在表中有一個(gè)名為 "Price" 的字段,并且想使用本地稅率來(lái)計(jì)算表中每一項(xiàng)的稅費(fèi)。這就是一個(gè)計(jì)算結(jié)果字段,可以通過(guò)修改 DataSource 的查詢來(lái)計(jì)算這個(gè)值,并把這個(gè)值返回給 DataGrid 控件。
要在 DataGrid 控件中創(chuàng)建一個(gè)計(jì)算結(jié)果字段
1. 確認(rèn)在機(jī)器上已為 Northwind 數(shù)據(jù)庫(kù)建立了一個(gè)OLE DB 數(shù)據(jù)源;如果還沒(méi)有創(chuàng)建這樣的一個(gè)數(shù)據(jù)源,請(qǐng)按照“創(chuàng)建 Northwind 的OLE DBData 連接”的步驟操作。
2. 在窗體上放置一個(gè) ADO Data 控件和一個(gè) DataGrid 控件。
3. 將 ADO Data 控件的ConnectionString 屬性設(shè)置為 Northwind 的數(shù)據(jù)源。
4. 設(shè)置 ADO Data 控件的 RecordSource 屬性。在“屬性”窗口中,單擊“記錄源”并輸入 Select ProductName, UnitPrice,(UnitPrice * .082) As Tax From Products。
5. 將 DataGrid 控件的 DataSource 屬性設(shè)置為這個(gè) ADO Data 控件。
6. 運(yùn)行該工程。
與類模塊一起使用 DataGrid 控件
如果想要訪問(wèn)以自定義格式或以 ODBC 驅(qū)動(dòng)程序不直接支持的格式存放的數(shù)據(jù),可以創(chuàng)建一個(gè)類來(lái)封裝該數(shù)據(jù)。然后可以編寫該類的自定義函數(shù)來(lái)檢索這些數(shù)據(jù)。這樣該類就變成了一種數(shù)據(jù)源,可以被任何數(shù)據(jù)使用者(如DataGrid 控件)使用。
在這個(gè)類模塊的Initialize 事件中,首先通過(guò)聲明一個(gè)作為 New ADODB.Recordset的變量,來(lái)創(chuàng)建一個(gè) ADODB recordset 對(duì)象。在創(chuàng)建了這個(gè) recordset 對(duì)象后,再添加字段,每個(gè)數(shù)據(jù)源中的每個(gè)字段都要加入。然后使用合適的數(shù)據(jù)填充這個(gè)記錄集。
注意 也可以使用 OLEDB 示例提供者來(lái)創(chuàng)建一個(gè)數(shù)據(jù)源。關(guān)于 OLEDB示例提供者的詳細(xì)信息,請(qǐng)參閱“創(chuàng)建帶有數(shù)據(jù)提供方的部件”。
類模塊有一個(gè) GetDataMember 事件,只要當(dāng)數(shù)據(jù)使用者(諸如 DataGrid 控件)需要數(shù)據(jù)時(shí)就產(chǎn)生該事件。在這個(gè)事件中,Data 參數(shù)被設(shè)置為在Initialize 事件中所創(chuàng)建的 recordset 對(duì)象。
如果要使用這個(gè)類模塊,應(yīng)創(chuàng)建一個(gè)具有一個(gè) DataGrid 控件的窗體。在該窗體的 Load 事件的代碼中,將該控件的 DataSource 屬性設(shè)置為這個(gè)類。
注意 數(shù)據(jù)類模塊在設(shè)計(jì)時(shí)是不可用的。例如,如果使用 DataGrid 控件,則當(dāng)用戶在“屬性”窗口中單擊“數(shù)據(jù)源”時(shí),所有可用的數(shù)據(jù)源都會(huì)出現(xiàn)在一個(gè)下拉列表中。但其中不會(huì)有這個(gè)數(shù)據(jù)類模塊,它只能在代碼中設(shè)置。
使用類模塊創(chuàng)建一個(gè)數(shù)據(jù)源
下面的示例使用一個(gè)類模塊來(lái)創(chuàng)建一個(gè)簡(jiǎn)單數(shù)據(jù)源。然后通過(guò) DataSource屬性將 DataGrid 控件綁定到該模塊。
要?jiǎng)?chuàng)建一個(gè)用于DataGrid 的類
1. 創(chuàng)建一個(gè)新的標(biāo)準(zhǔn) Exe 工程。
2. 給窗體添加一個(gè) DataGrid 控件。如果DataGrid控件不在“工具箱”中,則在“工程”菜單中單擊“部件”,
再單擊“Microsoft DataGrid Control”,然后單擊“確定”。
3. 在“工程”菜單中,單擊“引用”。在“引用”對(duì)話框中,單擊“MicrosoftActiveX Data Objects 2.0 Library”。
4. 在“工程”菜單中,單擊“添加類模塊”來(lái)給工程添加一個(gè)數(shù)據(jù)類模塊。
5. 在“工程資源管理器”窗口中,單擊并選定“類”圖標(biāo),并按 F4 鍵顯示“屬性”窗口。
6. 在“屬性”窗口中,將類的名稱更改為NamesData。
7. 在“屬性”窗口中,單擊“DataSourceBehavior”并將該屬性更改為vbDataSource。
8. 在該類模塊的 Declarations 部分,創(chuàng)建一個(gè) ADODB Recordset變量,如下所示:
Option Explicit
Private WithEvents rsNames As ADODB.RecordSet
使用 WithEvents 關(guān)鍵詞來(lái)聲明該變量,使用戶可以對(duì) RecordSet 對(duì)象的事件編程。
9. 在該類的 Initialize 事件中,添加下述代碼:
Private Sub Class_Initialize()
' 將新的數(shù)據(jù)成員的名稱添加到 DataMember 集合
' 這使其它對(duì)象可以看見(jiàn)這些可用的
DataMembersDataMembers.Add "Names"
Set rsNames = New ADODB.RecordSet ' 設(shè)置對(duì)象變量。
' 創(chuàng)建一個(gè)具有兩個(gè)字段的 recordset,并打開(kāi)該 recordset。
' 第一個(gè)記錄具有一個(gè)整數(shù)的數(shù)據(jù)類型,第二個(gè)記錄是一個(gè)最大可
' 達(dá) 256 個(gè)字符的字符串。CursorType 被設(shè)置為 OpenStatic
' —— 一個(gè)可更新的對(duì)一組記錄的快照。LockType 被設(shè)置為
' LockOptimistic,以允許對(duì)該 recordset 進(jìn)行更新。
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 ' 移到該記錄集的開(kāi)始。
End Sub
這部分代碼首先創(chuàng)建 recordset 對(duì)象,然后給該對(duì)象添加兩個(gè)字段。代碼接著給 recordset 添加十條記錄。
10. 在該類的 GetDataMember 事件中,添加下述代碼 :
Private Sub Class_GetDataMember(ByVal DataMember As String, _
Data As Object)
Set Data = rsNames
End Sub
只要發(fā)生該事件——即當(dāng)該類對(duì)象被綁定到一個(gè)數(shù)據(jù)使用者,如 DataGrid控件時(shí),代碼將返回該 recordset 對(duì)象。
11. 在 Form 對(duì)象的代碼模塊中,聲明一個(gè)數(shù)據(jù)類的對(duì)象變量:
Option Explicit
Private datNames As NamesData ' 類變量
12. 在 Form 對(duì)象的 Load 事件的代碼中,將 DataGrid 控件的 DataSource設(shè)置為該類對(duì)象。
Private Sub Form_Load()
' 創(chuàng)建一個(gè)新的 NamesData 對(duì)象
Set datNames = New NamesData
' 將這個(gè) DataGrid 綁定到新的數(shù)據(jù)源 datNames
Set DataGrid1.DataSource = datNames
End Sub
13. 按 F5 鍵運(yùn)行該工程。
RecordSet事件的編程
也可以對(duì)這個(gè) Recordset 對(duì)象的事件進(jìn)行編程。在該類模塊中,單擊“對(duì)象”框(在位于左上角),然后單擊“rsNames”。在“過(guò)程/事件”框(在右上角)中,下拉列表將顯示這個(gè) Recordset 對(duì)象的所有事件。
給類添加一個(gè)屬性
類模塊也可以進(jìn)行修改,來(lái)響應(yīng)事件或函數(shù)調(diào)用。下面的代碼演示了如何先給類添加屬性。當(dāng)從其它對(duì)象調(diào)用該對(duì)象時(shí),這一屬性將返回該類的RecordCount。
Public Property Get RecordCount() As Long
RecordCount = rsNames.RecordCount
End Sub
使用 DataMember 屬性
GetDataMember 事件也包括 DataMember 參數(shù)。使用這個(gè)參數(shù),可以在類模塊中包括多個(gè)記錄集,并使用帶 DataMember 參數(shù)的 Select Case 語(yǔ)句來(lái)返回相應(yīng)的記錄集:
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
' 設(shè)置一個(gè)默認(rèn)的數(shù)據(jù)成員
Set Data = rsYears
End Select
End Sub
如果要指定所需的 DataMember,請(qǐng)將數(shù)據(jù)使用者的 DataMember 屬性設(shè)置為適當(dāng)?shù)淖址缓笕缙匠R粯釉O(shè)置 DataSource。對(duì)于 DataGrid 控件,可以采用如下方法:
Private Sub Form_Load()
' 創(chuàng)建一個(gè)新的 NamesData 對(duì)象
Set datNames = New NamesData
' 指定所需的 DataMember,然后設(shè)置 DataSource。
DataGrid1.DataMember = "Names"
Set DataGrid1.DataSource = datNames
End Sub
posted @
2008-11-26 07:19 大鳥(niǎo) 閱讀(315) |
評(píng)論 (0) |
編輯 收藏
引言
作為微軟旗下一款優(yōu)秀的RAD工具,VB在數(shù)據(jù)庫(kù)應(yīng)用開(kāi)發(fā)方面的能力十分強(qiáng)大。微軟設(shè)計(jì)了多種數(shù)據(jù)庫(kù)訪問(wèn)方法,下面通過(guò)對(duì)VB訪問(wèn)數(shù)據(jù)庫(kù)的多種技術(shù)進(jìn)行深入剖析,并總結(jié)出實(shí)際開(kāi)發(fā)中的幾點(diǎn)經(jīng)驗(yàn)。希望能夠?qū)δ荲B的初學(xué)者有所幫助。(注意,文中所有的描述均在Windows 2000 professional和Visual Basic 6.0的環(huán)境下進(jìn)行的)
一. DAO、RDO、ODBC和ADO
在VB的開(kāi)發(fā)環(huán)境中,可以使用三種數(shù)據(jù)庫(kù)訪問(wèn)方式,它們分別是:數(shù)據(jù)訪問(wèn)對(duì)象(DAO)、遠(yuǎn)程數(shù)據(jù)對(duì)象(RDO)和ADO對(duì)象模型。
DAO:
數(shù)據(jù)訪問(wèn)對(duì)象是用來(lái)顯露了Microsoft Jet數(shù)據(jù)庫(kù)引擎(最早是給Microsoft Access 所使用,現(xiàn)在已經(jīng)支持其它數(shù)據(jù)庫(kù)),并允許開(kāi)發(fā)者通過(guò)ODBC直接連接到其他數(shù)據(jù)庫(kù)一樣,直接連接到 Access 表。DAO 最適用于單系統(tǒng)應(yīng)用程序或在小范圍本地分布使用。其內(nèi)部已經(jīng)對(duì)Jet數(shù)據(jù)庫(kù)的訪問(wèn)進(jìn)行了加速優(yōu)化,而且其使用起來(lái)也是很方便的。所以如果數(shù)據(jù)庫(kù)是Access數(shù)據(jù)庫(kù)且是本地使用的話,建議使用這種訪問(wèn)方式。
VB已經(jīng)把DAO模型封裝成了Data控件,分別設(shè)置相應(yīng)的DatabaseName屬性和RecordSource屬性就可以將Data控件與數(shù)據(jù)庫(kù)中的記錄源連接起來(lái)了。以后就可以使用Data控件來(lái)對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。
RDO
RDO(Remote Data Objects)遠(yuǎn)程數(shù)據(jù)對(duì)象是一個(gè)到ODBC的、面向?qū)ο蟮臄?shù)據(jù)訪問(wèn)接口,它同易于使用的DAO style組合在一起,提供了一個(gè)接口,形式上展示出所有ODBC的底層功能和靈活性。盡管RDO在很好地訪問(wèn)Jet或ISAM數(shù)據(jù)庫(kù)方面受到限制,而且它只能通過(guò)現(xiàn)存的ODBC驅(qū)動(dòng)程序來(lái)訪問(wèn)關(guān)系數(shù)據(jù)庫(kù)。但是,RDO已被證明是許多SQL Server、Oracle 以及其他大型關(guān)系數(shù)據(jù)庫(kù)開(kāi)發(fā)者經(jīng)常選用的最佳接口。RDO提供了用來(lái)訪問(wèn)存儲(chǔ)過(guò)程和復(fù)雜結(jié)果集的更多和更復(fù)雜的對(duì)象、屬性,以及方法。
和DAO一樣,在VB中也把其封裝為RDO控件了,其使用方法與DAO控件的使用方法完全一樣。
ODBC
ODBC(Open Database Connectivity,開(kāi)放數(shù)據(jù)庫(kù)互連)是微軟公司開(kāi)放服務(wù)結(jié)構(gòu)(WOSA,Windows Open Services Architecture)中有關(guān)數(shù)據(jù)庫(kù)的一個(gè)組成部分,它建立了一組規(guī)范,并提供了一組對(duì)數(shù)據(jù)庫(kù)訪問(wèn)的標(biāo)準(zhǔn)API(應(yīng)用程序編程接口)。這些API利用SQL來(lái)完成其大部分任務(wù)。ODBC本身也提供了對(duì)SQL語(yǔ)言的支持,用戶可以直接將SQL語(yǔ)句送給ODBC。
一個(gè)基于ODBC的應(yīng)用程序?qū)?shù)據(jù)庫(kù)的操作不依賴任何DBMS,不直接與DBMS打交道,所有的數(shù)據(jù)庫(kù)操作由對(duì)應(yīng)的DBMS的ODBC驅(qū)動(dòng)程序完成。也就是說(shuō),不論是FoxPro、Access還是Oracle數(shù)據(jù)庫(kù),均可用ODBC API進(jìn)行訪問(wèn)。由此可見(jiàn),ODBC的最大優(yōu)點(diǎn)是能以統(tǒng)一的方式處理所有的數(shù)據(jù)庫(kù)。
一個(gè)完整的ODBC由下列幾個(gè)部件組成:
1. 應(yīng)用程序(Application)
ODBC管理器(Administrator)。該程序位于Windows 95控制面板(Control Panel)的32位ODBC內(nèi),其主要任務(wù)是管理安裝的ODBC驅(qū)動(dòng)程序和管理數(shù)據(jù)源。
驅(qū)動(dòng)程序管理器(Driver Manager)。驅(qū)動(dòng)程序管理器包含在ODBC32.DLL中,對(duì)用戶是透明的。其任務(wù)是管理ODBC驅(qū)動(dòng)程序,是ODBC中最重要的部件。
2. ODBC API
ODBC 驅(qū)動(dòng)程序。是一些DLL,提供了ODBC和數(shù)據(jù)庫(kù)之間的接口。
數(shù)據(jù)源。數(shù)據(jù)源包含了數(shù)據(jù)庫(kù)位置和數(shù)據(jù)庫(kù)類型等信息,實(shí)際上是一種數(shù)據(jù)連接的抽象。
ODBC連接目前僅僅限于關(guān)系型數(shù)據(jù)庫(kù),對(duì)于其他數(shù)據(jù)源比如EXCEL、文本文件都不能進(jìn)行訪問(wèn),而且有很多DBMS(數(shù)據(jù)庫(kù)管理系統(tǒng))都不能充分的支持其所有的功能。相比之下,OLEDB可以存取任何形式的數(shù)據(jù),所以其功能是相當(dāng)?shù)膹?qiáng)大,它也指導(dǎo)了目前技術(shù)發(fā)展的方向。
ADO
ADO(ActiveX Data Object)是DAO/RDO的后繼產(chǎn)物。ADO 2.0在功能上與RDO更相似,而且一般來(lái)說(shuō),在這兩種模型之間有一種相似的映射關(guān)系。ADO"擴(kuò)展"了DAO和 RDO 所使用的對(duì)象模型,這意味著它包含較少的對(duì)象、更多的屬性、方法(和參數(shù)),以及事件。
作為最新的數(shù)據(jù)庫(kù)訪問(wèn)模式,ADO的使用也是簡(jiǎn)單易用,所以微軟已經(jīng)明確表示今后把重點(diǎn)放在ADO上,對(duì)DAO/RDO不再作升級(jí),所以ADO已經(jīng)成為了當(dāng)前數(shù)據(jù)庫(kù)開(kāi)發(fā)的主流。
ADO涉及的數(shù)據(jù)存儲(chǔ)有DSN(數(shù)據(jù)源名稱)、ODBC(開(kāi)放式數(shù)據(jù)連接)以及OLE DB三種方式。后面的例程將詳細(xì)講解這三種方式的具體訪問(wèn)實(shí)現(xiàn)。
要使用ADO,必須清楚ADO的對(duì)象層次結(jié)構(gòu),其大體上分為以下7個(gè)對(duì)象層次:
1、 Command 對(duì)象:包含關(guān)于某個(gè)命令,例如查詢字符串、參數(shù)定義等的信息。Command 對(duì)象在功能上和 RDO的rdoQuery 對(duì)象相似。
2、 Connection 對(duì)象:包含關(guān)于某個(gè)數(shù)據(jù)提供程序的信息。Connection 對(duì)象在功能上和 RDO 的 rdoConnection 對(duì)象是相似的,并且包含了關(guān)于結(jié)構(gòu)描述的信息。它還包含某些 RDOEnvironment 對(duì)象的功能,例如transaction 控件。
3、 Error對(duì)象:包含數(shù)據(jù)提供程序出錯(cuò)時(shí)的擴(kuò)展信息。Error 對(duì)象在功能上和 RDO 的rdoError 對(duì)象相似。
4、 Field 對(duì)象:包含記錄集中數(shù)據(jù)的某單個(gè)列的信息。Field 對(duì)象在功能上和 RDO的rdoColumn 對(duì)象相似。
5、 Parameter 對(duì)象:包含參數(shù)化的Command對(duì)象的某單個(gè)參數(shù)的信息。該 Command對(duì)象有一個(gè)包含其所有Parameter 對(duì)象的 Parameters 集合。Parameter 對(duì)象在功能上和 RDO 的 rdoParameter 對(duì)象相似。
6、 Property對(duì)象:包含某個(gè) ADO 對(duì)象的提供程序定義的特征。沒(méi)有任何等同于該對(duì)象的RDO,但DAO有一個(gè)相似的對(duì)象。
7、Recordset對(duì)象:用來(lái)存儲(chǔ)數(shù)據(jù)操作返回的記錄集。此對(duì)象和Connection對(duì)象是所有對(duì)象最重要的兩個(gè)對(duì)象。
當(dāng)然,對(duì)于初級(jí)用戶來(lái)說(shuō),我們只需要掌握其中的Connection對(duì)象和RecordSet對(duì)象就可以實(shí)現(xiàn)基本的數(shù)據(jù)庫(kù)操作,在后面的經(jīng)驗(yàn)介紹里面我將給出詳細(xì)的介紹。
二. 開(kāi)發(fā)經(jīng)驗(yàn)小結(jié):
前面總體上介紹了一下當(dāng)前在VB平臺(tái)下的數(shù)據(jù)庫(kù)訪問(wèn)技術(shù),這些技術(shù)也是當(dāng)前數(shù)據(jù)庫(kù)技術(shù)的主流。下面筆者結(jié)合近幾年的開(kāi)發(fā)經(jīng)驗(yàn),給出一些開(kāi)發(fā)經(jīng)驗(yàn)和小技巧,以供參考:
經(jīng)驗(yàn)一:如果數(shù)據(jù)量不大,而且要求開(kāi)發(fā)周期短的情況,建議使用DAO+Access雖然DAO功能并不強(qiáng)大,但是其對(duì)Jet引擎進(jìn)行了加速優(yōu)化處理,所以這種搭配應(yīng)該是比較好的選擇。
經(jīng)驗(yàn)二:RDO當(dāng)前已經(jīng)用的很少了,一般用ADO來(lái)替代。
經(jīng)驗(yàn)三:(本經(jīng)驗(yàn)很重要)使用ADO開(kāi)發(fā)時(shí),連接數(shù)據(jù)庫(kù)的方式有三種(前面已經(jīng)敘述了),其中DSN需要用戶首先使用要將所要操縱的數(shù)據(jù)庫(kù)設(shè)置為數(shù)據(jù)庫(kù)源并給其命名。方法是在控制面板->管理工具->數(shù)據(jù)源(ODBC)下面進(jìn)行配置。比如設(shè)置的數(shù)據(jù)源名稱為data,那么可以通過(guò)下面幾行代碼來(lái)連接數(shù)據(jù)庫(kù):
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
注釋:連接數(shù)據(jù)庫(kù)
conn.Open "dsn=data"
注釋:打開(kāi)數(shù)據(jù)源(即選定操作的數(shù)據(jù)對(duì)象)
rs.Open SQL語(yǔ)句, conn
但是如果是使用ODBC和OLEDB的方式進(jìn)行連接,那么大家一定知道在連接字符串上那一長(zhǎng)串的代碼,不要說(shuō)對(duì)于初學(xué)者,就是對(duì)于那些經(jīng)驗(yàn)豐富的程序員來(lái)說(shuō),也很難記住這一串代碼。那么如何可以記住這一串代碼呢?其實(shí),方法很簡(jiǎn)單,只要添加一個(gè)ADO Data控件,然后在其屬性框中使用向?qū)нM(jìn)行設(shè)置后,那么最后向?qū)Ь蜁?huì)自動(dòng)生成一段ConnectionString,只需要將這一行代碼拷貝下來(lái)然后放到conn.open之后的連接字符串參數(shù)的位置上就可以了。這條經(jīng)驗(yàn)希望讀者能夠記住,實(shí)際開(kāi)發(fā)中很實(shí)用。
經(jīng)驗(yàn)四:前面講到手動(dòng)設(shè)置ODBC數(shù)據(jù)源,這里可以通過(guò)程序來(lái)進(jìn)行動(dòng)態(tài)設(shè)置。首先要清楚的是ODBC的詳細(xì)信息全部存放在注冊(cè)表的下述鍵值內(nèi):"HKEY_LOCAL_MACHINE\SOFTWARE\ODBC",通過(guò)調(diào)用Win32函數(shù)WriteProfileString來(lái)對(duì)相應(yīng)的鍵值進(jìn)行修改即可達(dá)到目的。
經(jīng)驗(yàn)五:通常將數(shù)據(jù)庫(kù)的連接代碼和資源釋放代碼放入各自特定的函數(shù)里面,因?yàn)橐话愦笠稽c(diǎn)的程序里需要經(jīng)常對(duì)這兩個(gè)功能模塊進(jìn)行調(diào)用,這樣做就可以提高效率,當(dāng)然很多時(shí)候都需要寫成連接池的形式。
經(jīng)驗(yàn)六:使用VB在SQL中處理含單引號(hào)的字符串時(shí),對(duì)字符串?dāng)?shù)據(jù)都用單引號(hào)引起來(lái),如:
Select * from MyTable Where ID=注釋:FirstID注釋:
若其中的FirstID為First注釋:ID,即中間多出一個(gè)單引號(hào),則上述寫法將導(dǎo)致錯(cuò)誤,解決的辦法是將字符串中的每一個(gè)單引號(hào)用兩雙引號(hào)替換,下面的函數(shù)StrToSQL完成該功能,并用單引號(hào)將處理后的字符串引起來(lái):
Private Function StrToSQL(ByVal strValue As String) As String
StrToSQL = "注釋:" + Replace(strValue, "注釋:", "注釋:注釋:") + "注釋:"
End Function
在寫SQL時(shí)如有字符串?dāng)?shù)據(jù),不管其中有沒(méi)有單引號(hào),都可以這樣使用:
strValue="First注釋:Id"
strSQL="Select * from MyTable Where ID="+StrToSQL(strValue)
三. 實(shí)例解析
下面介紹一個(gè)實(shí)例,來(lái)消化以上的相關(guān)知識(shí)。這里我在一個(gè)程序界面下實(shí)現(xiàn)了DAO,ADO,ODBC,OLEDB四種數(shù)據(jù)庫(kù)訪問(wèn)方式。
程序代碼分析:
注釋:整個(gè)程序功能是選擇不同的連接方式來(lái)進(jìn)行顯示工作,三種方式顯示效果完全相同
注釋:下面是主程序過(guò)程
Private Sub Command1_Click()
Dim selitem As Integer
注釋:判斷連接數(shù)據(jù)庫(kù)的方式
If Option1.Value = True Then
selitem = 1
Else
If Option2.Value = True Then
selitem = 2
Else
selitem = 3
End If
End If
注釋:選取不同的數(shù)據(jù)庫(kù)連接方式
Select Case selitem
Case 1:
注釋:使用DAO的數(shù)據(jù)庫(kù)連接方式
Call ShowByDAO
Case 2:
注釋:使用ADO的數(shù)據(jù)庫(kù)連接方式
Call ShowByADO
Case 3:
注釋:使用ODBC的數(shù)據(jù)庫(kù)連接方式
Call ShowByODBC
Case 4:
注釋:使用OLEDB的數(shù)據(jù)庫(kù)連接方式
Call ShowByOLEDB
End Select
End Sub
Private Sub ShowByDAO()
注釋:使用DAO的數(shù)據(jù)庫(kù)連接方式
Dim db As Database
Dim rs As Recordset
Dim sqlstr$ 注釋:存放查詢語(yǔ)句
Set db = OpenDatabase(App.Path & "\db1.mdb")
sqlstr = "select * from 成績(jī)表"
Set rs = db.OpenRecordset(sqlstr)
注釋:顯示結(jié)果
Call GridShow(rs)
End Sub
Sub ShowByADO()
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
注釋:使用數(shù)據(jù)源來(lái)連接數(shù)據(jù)庫(kù)
conn.Open "dsn=data"
rs.CursorType = adOpenKeyset
rs.LockType = adLockOptimistic
rs.Open "select * from 成績(jī)表", conn
Call GridShowOfADO(rs)
End Sub
Sub ShowByODBC()
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
注釋:使用數(shù)據(jù)源來(lái)連接數(shù)據(jù)庫(kù)
conn.Open "Provider=MSDASQL.1;Persist Security Info=False;Data Source=data"
rs.Open "select * from 成績(jī)表", conn
注釋:顯示結(jié)果
Call GridShowOfADO(rs)
End Sub
Sub ShowByOLEDB()
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
注釋:使用數(shù)據(jù)源來(lái)連接數(shù)據(jù)庫(kù)
conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + App.Path & "\db1.mdb" + ";Persist Security Info=False"
rs.Open "select * from 成績(jī)表", conn
注釋:顯示結(jié)果
Call GridShowOfADO(rs)
End Sub
Sub GridShow(rs As Recordset)
注釋:對(duì)dao方式進(jìn)行顯示工作
MSFlexGrid1.TextMatrix(0, 0) = "姓名"
MSFlexGrid1.TextMatrix(0, 1) = "性別"
MSFlexGrid1.TextMatrix(0, 2) = "語(yǔ)文"
MSFlexGrid1.TextMatrix(0, 3) = "數(shù)學(xué)"
MSFlexGrid1.TextMatrix(0, 4) = "英語(yǔ)"
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)
注釋:對(duì)ado方式進(jìn)行顯示工作
MSFlexGrid1.TextMatrix(0, 0) = "姓名"
MSFlexGrid1.TextMatrix(0, 1) = "性別"
MSFlexGrid1.TextMatrix(0, 2) = "語(yǔ)文"
MSFlexGrid1.TextMatrix(0, 3) = "數(shù)學(xué)"
MSFlexGrid1.TextMatrix(0, 4) = "英語(yǔ)"
注釋:注意recordcount屬性必須在當(dāng)前記錄指針在最后一條記錄時(shí)才會(huì)返回正確的值
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
上述代碼已經(jīng)在Windows 2000 professional和Visual Basic 6.0的環(huán)境下調(diào)試成功。
四.小結(jié)
本文通過(guò)對(duì)數(shù)據(jù)庫(kù)訪問(wèn)相關(guān)技術(shù)的分析與總結(jié),提出若干有價(jià)值的經(jīng)驗(yàn)。借鑒這些經(jīng)驗(yàn),會(huì)給開(kāi)發(fā)帶來(lái)一定的便利。
posted @
2008-11-26 07:18 大鳥(niǎo) 閱讀(317) |
評(píng)論 (0) |
編輯 收藏
Dim dataname As String
Private Sub Command1_Click()
d.DialogTitle = "打開(kāi)一個(gè)Access數(shù)據(jù)庫(kù)進(jìn)行編輯"
d.FileName = ""
d.InitDir = App.Path
d.Filter = "Access數(shù)據(jù)庫(kù)文件MDB后綴|*.mdb"
d.ShowOpen
If d.FileName = "" Then Exit Sub
list1.Clear
Set link1 = New ADODB.Connection
'創(chuàng)建ADO連接
link1.Open "Provider=Microsoft.Jet.OLEDB.4.0;data source=" & d.FileName
Set tables = link1.OpenSchema(adSchemaColumns) '創(chuàng)建數(shù)據(jù)庫(kù)記錄集為了得到數(shù)據(jù)庫(kù)中所有表名
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 "數(shù)據(jù)庫(kù)打開(kāi)失敗,或數(shù)據(jù)庫(kù)不存在表", vbCritical, "錯(cuò)誤": 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控件連接數(shù)據(jù)源
ldc.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;data source=" & dataname & ";Persist Security Info=False"
'ldc控件使用SQL命令,GET數(shù)據(jù)源數(shù)據(jù)
ldc.RecordSource = "select * from " & list1.Text
ldc.Refresh: Label1.Caption = "共" & ldc.Recordset.RecordCount & "條記錄," & ldc.Recordset.Fields.Count & "個(gè)分類字段"
End Sub
posted @
2008-11-26 07:16 大鳥(niǎo) 閱讀(392) |
評(píng)論 (0) |
編輯 收藏