網上教程 - 讓我們共同學習VBS


來源: 兄弟工作組按鍵精靈討論區(歡迎大家來討論)
作者: redorange
標題: 讓我們共同學習VBS

現在看到很多朋友都不明白VBS,但我也沒有時間全部寫完,所以一天寫一些,邊寫邊和大家交流,也希望有朋友能接著寫或指出我的錯誤。


今天我就從總體上對VBS進行介紹,希望能給大家一個直觀的印象。另外,講解與按鍵官網的按鍵精靈教程(李悅製作)相結合,幫大家看懂這個東東。

一、概述
要讓計算機做事情就必須由人給它指令。原來的指令很複雜,都是些0011001之類的東西,後來逐漸簡化,指令也更接近於人類的語言。VBS(Microsoft(R) Visual Basic(R) Scripting)也是高級語言的一種,和其他高級語言相比,它有簡單易學的特點,是電腦初學者涉足編程領域的良好入口。
如果說從低級語言進化到高級語言是人類控制計算機的戰略問題,那麼具體的設置變量、循環就是控制計算機的具體戰術問題。我們現在學習的也就是用VBS讓計算機為我們工作的戰術。
二、從最簡單的東西入手。
網路叫賣腳本:
vbs i
vbs i=10
while i>0
SayString 賣XXX,價格面議。
vbs i=i-1
delay 10000
endfor
看到這個腳本很多人就嗤之以鼻了,實現不斷叫賣的方法很多,有的比這個腳本簡單幾倍。但隨著講解的進行,我們會發覺VBS提供給我們的是一個強大的工具。下面先來這幾行都是什麼意思。
vbs i //告訴計算機有個叫i的變量。
vbs i=10 //這個變量為10
while i>0 //當這個變量大於0的時候就執行下面直到看見第一個endfor的地方。
SayString 賣XXX,價格面議。 //按鍵語句:輸出文字
vbs i=i-1 //這個變量減去1,然後又把減1後的數作為i的值。
delay 10000 //按鍵語句:暫停10秒(10000毫秒)
endfor //回到while處
效果:叫賣10次後就結束。
現在我要花點力氣解釋一下為什麼要折騰出這麼多麻煩的東西。
變量的用處和重要性
其實這個程序完全可以寫成
SayString 賣XXX,價格面議。
delay 10000
SayString 賣XXX,價格面議。
delay 10000
……重複N次
SayString 賣XXX,價格面議。
delay 10000
其實再複雜的程序段都能被還原成順序的程序,用很多複雜的東東不是為了顯示編程能力,而是為了給自己方便。
當我們一直賣XXX的時候可能沒有什麼感覺,但當我們賣YYY的時候呢?要全部改過嗎?或者我們要重複1000次,後來只重複500次了,難道要認真地數500下,然後刪除後面的嗎?當然,我們編這個小程序改起來還比較愜意。但要提高發展就得做大程序,還必須要依靠我們的變量朋友。
變量其實是一個字符代號,像你我的名字一樣,為的是把各個變量區別開來,讓他們分頭工作。為變量取名字的時候可以用數字、字符、和下劃線,但不可以用漢字、空格和其它奇奇怪怪的符號,另外數字不能用於第一個字符。
在使用變量之前要先寫一個象vbs i這樣的語句,意思是現在本人指派一變量,取名為i,參加到這個程序運行中。其實你可以不用履行這樣的報名程序,直接在程序的某處使用i,但實踐證明這是一個不好的習慣,讓你寫大程序的時候寸步難行。
然後vbs i=10則告訴程序,這個變量i現在的值為10,以後凡是用到i的地方,就相當於是10在那裡。比如vbs j=i+1其實就相當於j=10+1,所以j的值為11。
變量的魅力不僅在於它可以代替數字,而且還可以代替字符,但和數字比起來,字符有其特殊性。
比如:
vbs i="字符"
vbs j="串接"
vbs a=i & j
此時a就是字符串接。注意這裡出現的兩個新符號:"號和&符號。可能有人已經猜出來他們的作用了。"號之間的內容為字符。電腦對vbs i=10和vbs i="10"有著截然不容的理解。&號為字符串接號。如果a=j & i,那麼a就是串接字符。
知道了變量的用法後,我們就可以把叫賣程序改得更有趣。比如我們想讓程序說不同的話,先說10次賣XXX,再說10次賣YYY。那我們就可以寫成:
vbs i
vbs i=10
while i>0
ifexpression i<=5
SayString 賣XXX,價格面議。
endif
ifexpression i>5
SayString 賣YYY,價格面議。
endif
vbs i=i-1
delay 10000
endfor
其實我們用了個編程的小技巧,就是用變量i的大小控制程序的走向。可見前5次賣YYY,後5次賣XXX。
或者我們先叫XXX一次,再叫YYY一次,然後重複前面的動作:
vbs i
vbs i=10
while i>0
ifexpression i mod 2 = 0
SayString 賣XXX,價格面議。
endif
ifexpression i mod 2 = 1
SayString 賣YYY,價格面議。
endif
vbs i=i-1
delay 10000
endfor
這裡也用了一個用i控制程序運行的方法。mod是和+、-、*一樣的運算符號,作用是取餘數。如10 mod 2 = 0的意思是10除以2,其餘數是0。同樣9 mod 2 = 1,8 mod 2 = 0,7 mod 2 = 1,6 mod 2 = 0,5 mod 2 = 1……

哎呀,暫時寫到這裡。

先說長變量名的問題。和人名一樣,人少的時候,用一個字還行,比如堯、舜、禺。人多了就必須用多一點字了,比如帕爾多帕契夫斯基。今後為了閱讀程序的方便,還是多寫幾個字吧。

vbscall 和 vbs 一樣都是標誌。前者表示將用一個函數。至於什麼是函數,可以看以後的帖子。現在先解釋一下函數是什麼。如果還沒有忘記數學的話我們應該知道函數就是x->y的一種關係(映射)。即特定的x一定會得到特定的y,而不是相同的x,前後兩次計算得到不同的y。
VBSCall GetCursorPos(y,h)@<stdlib.vbs>可以看成三部分。
VBSCall是標誌,提醒電腦這句話是個按鍵精靈的函數。
@<stdlib.vbs>可以不用管他,通常理解為函數庫頭文件名稱。將來也許會出現其他的比如iostring.vbs。這個文件在按鍵精靈安裝文件夾的script文件夾裡。
最重要的就是中間的GetCursorPos(y,h)了。我們會發現所有VBSCall打頭的句子都是中間的這部分不一樣。
還記得數學裡函數是怎麼表示的嗎?f(x)=y或者是f(x)=一串計算式,比如ax2+bx+c。
f的意思是founction(函數)的頭字母,在計算機裡f可以是這個函數的名字,比如GetCursorpos(是get cursor position,得到鼠標位置的意思。瞧這裡也涉及到取名的問題,這個名字是不是取得不錯,比起只有一個兩個字母的名字,這個名字既直觀又相對較短)。
x自然就是括號裡的東西,有時我們有幾個x,他們就用,號隔開。比如GetCursorPos(y,h)的第一個x是變量y,第二個x是變量h。
這時,你會發現少了f(x)=y中的y,也就是特定的x對應的特定的y。在這裡有y,但對本函數來說已經不重要了,我們需要的是函數把y變成鼠標的橫坐標值,h變成鼠標的縱坐標值。
實際上這裡不是真正意義上的函數,從函數庫stdlib.vbs中來看,這裡的所謂函數其實是QMDispatch.QMFunction對象的一個方法。算了,這個問題以後再說。
同樣的道理,FindColor(y-200,h-200,y+200,h+200,"ffaa8c",g,k)有七個x,要做的工作是在前四個x的範圍內找到第五個x指定的顏色值,把發現第五個x指定值的顏色點的x坐標放到第六x,y坐標放到第七個x。f(x)=y中的y就不管了。

FindColor的前四個參數組成一個小於等於屏幕的方框,查詢的顏色就在這個小方框內進行。依次代表屏幕左邊到尋色方框左邊框的距離,上邊到尋色方框上邊的距離,左邊到尋色方框右邊的距離,上邊邊到尋色方框下邊的距離。注意上下左右都是怎麼說的。如果是0,0,1,1的話,說明是左上角一個像素點範圍內查詢。如果是0,0,800,600的話,說明是800*600這麼大快區域。至於什麼是像素點,請看我的簽名處提到的那個帖子。

dim 不是變量。是VBS的保留字,保留字的意思是VBS語言的一部分,不能被用戶作為變量、函數的名字。dim的意思是提醒計算機它後面跟的是將來要用的變量,可以不寫。

我們從1樓知道了變量的重要性,現在總結一下。變量在彙編語言(低級語言)的時候就已經出現了。現在到了VBS這樣的高級語言,變量將發揮更重要的作用。
作用1:替代數字或字符。
在程序裡有些數字或字符會用到很多次,編輯和修改的時候一次要改很多,而且容易漏掉某些地方。現在我們先用變量把他們定義了,讓變量代替他們到程序裡去折騰,將來編輯修改時會很方便。方便的後果是,你的程序更不容易出錯。
作用2:參加運算。這是變量之所以叫「變」的原因。
它能隨時被賦予新的含義。但需要注意的是,你的變量原來是數字的最好不要中途變成了字符或者相反的變換。這會讓電腦不知所措的。具體的原因等你學習了更多的東西自然就知道了。另外字符的運算只能是連接,就是&號,使前後兩字符串連接在一起。同時數字與字符不能在一起運算。
幸運的是我上面說的那麼多禁止的地方很多都是老皇歷了。在VBS裡有些禁忌是無所謂的。比如數字和字符,VBS會根據運算符號來確認到底參加運算的應該看成數字好還是看成字符好。i=10和i="10"有時候VBS分的不是那麼清楚,它會根據是+還是&來判斷結果應該是什麼。
作用3:控制程序走向。
通過1樓,我們看到了最後的兩個叫賣腳本。它通過條件的不同來產生不同的叫賣效果。這裡的效果實際上是程序根據不同的條件走向了不同的地方。前一個例子是我們通過變量的大小來決定叫賣哪一句,後一個例子是我們通過變量除以2的餘數來決定叫賣哪一句。
這一貼我們著重說一說用變量來控制程序的走向。
電腦讀腳本如同我們讀書一樣。注意:這裡我們寫的東西確實是程序,卻老是說成腳本。這裡先解釋一下:一般我們說的程序是直接能被電腦運行的文件。比如Qmacro.exe文件。當我們雙擊它的時候按鍵精靈就跳出來了。你嘗試過將這個文件用記事本打開嗎?其實記事本可以打開任何文件。打開後,我們會發現很多亂七八糟的符號,這些符號是只有計算機才能讀懂的。我們能讀懂的並且計算機能直接運行的(只是看起來是直接可以運行)只有腳本,即Script。
試驗過用記事本打開程序文件後千萬不要改動並保存啊,改了一小點都不能運行了。
好了,只需要記住,電腦讀腳本和我們讀腳本沒什麼兩樣。只是它讀的比我們快,並且是以行作為讀取單位。電腦是一邊讀腳本一邊按照腳本的意思來執行命令。
既然如此,我們在寫腳本的時候就能充分發揮我們的文學細胞,運用插敘、倒敘、順序、註釋等多種寫法來完成我們的腳本。電腦裡大概有註釋、順序、選擇序、循環序和跳轉序幾種讀腳本的方法。
先說註釋。註釋的作用是讓讀者更明白文中的意思。腳本裡的註釋有點不一樣,電腦可不需要什麼註釋,它只負責按命令執行。我們在腳本中加入註釋的目的是為了自己方便。比如我們的程序寫長了,這時可以在腳本裡加入點註釋,提醒自己誰誰誰是幹什麼的。
加入方法:Rem 註釋語句。
程序在遇到Rem 的時候就視而不見了。但後面我會告訴你,電腦還是看得見用Rem 打頭的語句的。
註釋使我們能控制電腦哪句可以執行,哪句不能。比如你修改你的腳本的時候,原來的那句話也許將來還能用上,於是你在添加新語句的時候不必將原來的刪除,而是在它前面直接加上註釋的Rem 。這樣程序就不執行了,而且將來好改動。
次說順序。
其實只要沒有什麼特殊的情況電腦都會老老實實按順序讀下去。這就沒有什麼多講的了。
再次說選擇序。
很奇怪,電腦看腳本有時候還真有些不求甚解,它可以根據你的命令有選擇讀一些語句,而放棄讀一些語句。這有利於我們控制它按我們的意思根據不同情況來行動。而不同的情況其實很大程度上說的是變量的情況。比如變量是否大於10。
要實現選擇序,我們就先要判斷一下條件。在按鍵精靈裡只有一個語句負責判斷。
ifexpression。這個語句是if expression(如果表達式[是否為真])的意思。
這裡解釋一下什麼叫表達式,其實也沒有什麼解釋的必要,就是算式。但這裡的算式比數學算式的含義多得多。除了1+1=2,1+2=3什麼的;還包括變量參與的運算,比如a+1>b,b+2<c;甚至還包括沒有運算,比如就只有變量a放在ifexpression後面。
然後我們解釋中括號裡的[是否為真]是什麼意思。在VBS裡用1和VBTRUE來表示真,用0和VBFALSE來表示假。ifexpression的意思是,如果後面的那個算式是成立的,那麼我就執行我下面的語句直到遇到第一個endif的地方。
那麼什麼樣的算式才叫成立呢?也就是說為1或VBTRUE呢?
1+1=2成立,為1或VBTRUE,1+1=3不成立,為0或VBFALSE。a+b>10就看a和b運行到此的值是多少了。只有一個變量a呢?當a的值為0時,就不成立,當a不為0時就成立。
另外說一下VBTURE和VBFALSE是什麼東東。其實就是1和0。作用是便於閱讀和防止冒失鬼把用於判斷的變量中途放到其他算式裡去參加運算,使原變量值改變了。
1樓的最後兩個腳本都是通過ifexpression來控制程序走向,產生不同效果。
可見ifexpression 1這個語句永遠成立。ifexpression 0永遠不成立。當然我們也可以用ifexpression VBTRUE來實現永遠成立。ifexpression 1+1=2永遠成立,ifexpression 1+1=3永遠不成立。
具體格式:
ifexpression 表達式
中間語句(可以又有一到N個ifexpression和while)
endif
然後我們說循環序。
和選擇序一樣,它也要作一個判斷;與之不同的是循環序是在判斷了後面的表達式是否為真後執行到第一個endfor語句,然後又回到原來判斷的那個語句,再判斷一次,如果成立,又執行下面的。這樣一直循環下去,直到有一天它發現判斷表達式不成立了,腳本就接著endfor後面的語句執行。
比如while 1這個語句就會無限循環下去。
在1樓的第一個腳本就是通過循環語句來實現不斷叫賣,而且通過變量大小能控制腳本叫賣多少次。
具體格式:
while 表達式
中間語句(可以又有一到N個ifexpression和while)
endfor
最後說跳轉序。
一個是Goto 標記。意思是當讀到這句時就到標記處繼續執行。這裡的標記其實是我們第一個介紹的老朋友Rem註釋語句。
比如前面你寫了Rem aa
後面就可以用Goto aa來實現回到Rem aa這一行來繼續執行。
另一個是Gosub 子程序標記。意思是當讀到這句時就到子程序標記處繼續執行。當讀到第一個Return語句時回到Gosub那一句。子程序標記是Sub 。
這個東東最好以後再說。
以上所有的控制語句,都可以在按鍵精靈編輯窗口左邊的「控制動作」一欄找到。
以後我們進一步說表達式成立到底是什麼意思,以及子程序是什麼東東,它和函數有什麼關係。

確切的講,子程序和跳轉如同插敘一樣,或者說是「下轉xxx頁」。和跳轉不一樣的是,跳轉會直接運行下去,而子程序到了return 語句的時候會回到調用這個子程序的地方,接著下一句繼續運行。
子程序的作用可以將程序分成明顯的幾個功能塊,便於你調試、閱讀。這在寫大程序或者和別人合作寫一個腳本的時候特別有用。比如你本人寫找礦程序,當找到礦後調用「移動到礦邊」子程序。這時你可以讓你的朋友來寫這個子程序。或者讓你的程序顯得更有邏輯性。
另外,子程序和函數的區別也很簡單。子程序其實是一段腳本,你可以在不同的地方重複執行這一段腳本。函數是一個關係映射。函數有x和y,即通過特定的x來得到特定的y,而子程序不存在這些。但他們都可以被看成是一個功能模塊。
子程序和函數的更深層次的區別是對待變量的不同態度。子程序是一段腳本,和調用它的主程序是一家人。適用於主程序的變量同樣適合於子程序(特別注意:這句話僅適用於按鍵精靈腳本)。函數則和調用它的主程序是兩家人,相互不承認對方的家庭成員(變量)。要想在主程序和函數之間共用變量,就必須經過傳遞這一道手續。我們寫在函數名後面括號內的變量或數字、字符就是履行發送任務,在函數內部,要履行接收任務。不過請放心,在按鍵精靈腳本裡沒有必要寫自己的函數。我們只需要用好按鍵精靈提供給我們的函數,比如findcolor。但看了前面的說明,你應該明白,在findcolor等函數後面括號裡的參數順序和大小是多麼重要。

等把什麼是表達式成立講清楚後,VBS基本上就可以用來寫腳本了。前面的都是些死記硬背的東西,後面將講一些編程技巧,然後用一個識別數字腳本的整個產生過程來總結這些技巧。

現在你去看官網上的那個關於VBS的教程應該可以輕鬆一點了。先前我們講了函數,那麼我們就只看那個教程裡第五個題目《函數》。這時你會發現VBS為我們準備了些什麼好禮物。
名詞解釋:
返回值:其實就是特定x輸入後得到的特定y。這個y可以賦予給變量。
比如:Abs取絕對值函數。
Dim MyNumber
MyNumber = Abs(50.3 ) '返回 50.3。
MyNumber = Abs(-50.3) '返回 50.3。
同樣,你可以用到三角函數、時間函數、字符處理系列函數等等。VBS為我們提供了一個強大的功能函數模塊,盡情使用吧。
至於什麼是方法,留待以後再說。

多說一句,方法是對象的一個動作。(頭暈了嗎?聽我慢慢講)
我先前說計算機讀腳本想人讀書,這種情形是從上到下的一個程序執行過程,無論有多少循環和跳轉,其實都是一個依一定邏輯規則的執行過程。這被稱為面向過程的程序設計。
另外有一種程序設計思想叫面向對象的程序設計,即程序編寫者將邏輯思維轉變成形象思維,把萬事萬物看成對象,這些對像有屬性和行為。比如花,它的屬性有紅色、白色等,有大、小等,有各種形狀;同時當一定條件來臨時花會按自身的規律發生變化,比如春來花開,秋到花謝等。我們把屬性仍叫屬性,把行為叫方法。
在VBS裡有7個對象。詳見官網VBS教程第7個目錄:《對像》。目前來看對我們最有用的是FileSystemObject 對象。那一串英文翻譯過來時「文件系統對像」的意思。也就是說,VBS將文件系統看成是一個東西,這個東西有自己的屬性和行為方式。我們可以利用它的屬性或者讓它按照我們的要求做一些事情。
多的以後再說。