網頁

2013年4月11日 星期四

迴圈只能有一層嗎?

之前已經教過,如何做到這樣:


那如果要做到這樣呢:



依照目前所教,可以這樣寫:

Sub loop_2()
    For i = 1 To 9
        Cells(i, 1).Value = 1
    Next
    For i = 1 To 9
        Cells(i, 2).Value = 1
    Next
End Sub

有沒有發現,還是有重複? 而迴圈的目的之一,就是要去除重複。所以這兩個迴圈可以合併成一個:

Sub loop_2()
    For i = 1 To 9
        Cells(i, 1).Value = 1
    Next
    For i = 1 To 9
        Cells(i, 2).Value = 1
    Next
End Sub

變成這樣:

Sub loop_2()
    For i = 1 To 9
        Cells(i, 1).Value = 1
        Cells(i, 2).Value = 1
    Next
End Sub

2013年3月27日 星期三

執行程式時的一些選項

寫完一段 Sub 之後,想執行,就把滑鼠游標移至該 Sub 內的任何一個位置,然後用滑鼠左鍵點一下,讓滑鼠游標(一般而言,是那個 I 字型的游標,而不是箭頭那個游標)停在該 Sub 區塊之內,然後按下 F5。

因為一個 Module 之內,可以有不止一個 Sub,所以按下 F5 時,會執行到哪一個 Sub,是看當時游標停在哪個 Sub 之內。

此外,如果你的程式會要執行一會兒,想一邊看著執行結果,可以把 VBA 環境那個視窗大小,縮放成螢幕的一半,並讓 Excel 操作環境也縮放成螢幕的一半(這兩者間的視窗大小比例,當然可以自訂)。

還有一個也是執行的按鈕,是 F8,與 F5 不同的是,F8 是一步一步執行,亦即一行一行程式碼執行,執行一行(ㄏㄤˊ)就停一下,此時 VBA 環境一般會以黃色橫條標示出目前執行到哪一行。這種方式非常貼心,可以一窺程式執行的細部過程,我非常建議初學者常用這個功能。F8 對程式碼的除錯(debug,找出錯誤)也很有幫助,即使是老手、高手,寫程式也難免出錯,可能是打錯字、可能是想錯...,F8 讓你一步一步看著執行結果,因此容易找到是錯在哪裡。當然,有些程式上的錯誤,不需要按下 F8,也會讓程式執行(暫時)停下來,例如指令打錯、或有 if 卻沒相對應的 end if、有 for 卻沒相對應的 next...等。

而不論是按下 F8 手動暫停程式,或因為程式出錯被 VBA 強制暫停,都可以到 Ctrl+G 這個即時運算視窗,輸入某個變數,查看當時的內容。

2013年3月22日 星期五

生命中的叉路

俗語說,人生不如意之事十之八九,人算不如天算,計畫趕不上變化,變化趕不上一通電話。然而,我們事先計畫得愈多,總是可以掌握愈多變化,做很多事情,並非無條件的一成不變,而是要依照當時的需求,選擇性、動態的決定該怎麼做。

程式設計反映真實世界,自然也有這種基本的機制,就是 "如果事情變得怎樣...,那我們就怎樣應對..." 的機制,指令(或說語法)是 if:

如果我們為了某些原因,想要在遇到 5 的時候,跳過不印,之前這個例子,可以加一道動態的條件關卡:

Sub cell_2()
    For i = 1 To 9
        If i <> 5 Then
            Cells(i, 1).Value = 1
        End If
    Next
End Sub

<> 是 "不等於" 的意思,如果 i 不等於 5,就印,否則會跳過。在 if...end if 區塊內的程式碼,想要執行,必須先通過 i <> 5 這道檢驗。

當然,if...end if 區塊內的程式碼,可以不只一行:

Sub cell_3()
    For i = 1 To 9
        If i <> 5 Then
            Cells(i, 1).Value = 1
            Cells(i, 2).Value = 2
        End If
    Next
End Sub

2013年3月21日 星期四

設定背景資訊,然後開始動作

在 "回到未來" 這部電影中,馬提要從過去回到未來、或從未來回到過去時,都要先設定時光車的時速,然後才開始動作。在現實生活中,我們做許多事情的動作模式也是如此,而即使你不會寫 Excel 程式,在 Excel 的操作環境中使用公式時,也可能會先設定某 cell 的值為 100,另一個 cell 的值為 200,然後讓第三個 cell 的公式等於第一加第二個 cell 的總和。

寫程式大抵也是如此,先設定某些變數的值,然後做動作,動作可能是呼叫另一個 Sub/Function、或直接在設定完後接著做。

來個操作儲存格的練習:

Sub cell_1()
    Cells(1, 1).Value = 1
    Cells(2, 1).Value = 1
    Cells(3, 1).Value = 1
    Cells(4, 1).Value = 1
    Cells(5, 1).Value = 1
    Cells(6, 1).Value = 1
    Cells(7, 1).Value = 1
    Cells(8, 1).Value = 1
    Cells(9, 1).Value = 1
End Sub

跟之前的 MsgBox 例子幾乎一樣(甚至更簡單),只是變成操作 cells 罷了。

也一樣沒有效率,所以用迴圈來化約它、精簡它、抽象化它:

Sub cell_1()
    For i = 1 To 9
        Cells(i, 1).Value = 1
    Next
End Sub

2013年3月19日 星期二

操作儲存格

Excel 是儲存格的大集合體,在 Excel 環境寫程式,只要可以操縱/操作儲存格,讓儲存格乖乖聽你的設定,事情就完成了一大半。

到 VBA 的即時運算視窗環境,輸入:

cells(1,1).value = 199

切換到 Excel 操作環境(非程式環境),儲存格 A1 的內容,變成 199 了。上述指令翻譯成中文,就是:

第一列第一欄這個儲存格的內容等於 199。分別解釋如下:

cells ==> 儲存格。
(1,1) ==> 第一列第一欄。
cells(1,1) ==> 第一列第一欄這個儲存格。
. ==> 的。
value ==> 內容。內容是儲存格這個大顆粒變數蘊含的單純變數之一。還有其它單純變數,之後會再提到。

現在,試著輸入像是:

cells(2,3).value = 200
cells(4,12).value = "Hello"
cells(8,2).value = #2013/1/23#

然後切回操作環境,看看執行結果。目前還是不脫幾個基本觀念: 資料類型、變數、大顆粒變數、單純變數、迴圈。

你就是一個大顆粒變數

是的,你就是一個變數,一個大顆粒變數。你的寵物也是,你的桌子也是、你吃的食物也是...。

每個大顆粒變數裡,都蘊含著(通常)不止一個的單純變數,你的身高是單純的數字變數、生日是單純的日期變數、姓名是單純的文字變數。

同理,Excel 的每一個儲存格(cell),也是一個大顆粒變數,儲存格的內容、顏色、框線、有無註解、大小...等,就是每一個儲存格蘊含的單純變數。

Excel 的每個工作表(sheet or worksheet)也是大顆粒變數,每個工作表蘊含約 256*65535(視版本而定)個儲存格,所以,一個大顆粒變數,不止可以蘊含很多的單純變數,也可以蘊含很多個大顆粒變數

又例如你居住的房子,是大顆粒變數,其內蘊含多個房間,每個房間蘊含多件傢俱,每件傢俱又蘊含著多個文具或衣服...,你可以依照自己的需求,繼續一層一層蘊含下去。

程式設計反映真實世界,先把觀念弄清楚,基本的程式設計,並非難事。

2013年3月13日 星期三

變數的顆粒

自然界的東西有大有小,物理學上的粒子有大有小,程式語言裡的變數,也是有大有小。

像是一般的數字、文字、日期等變數,稱為純量變數,先不管這個專有名詞,這種一般的小顆粒變數,就是單純的變數,你可以將之想成單細胞生物。

單純變數很單純,就內含一個值,或內容,它是資訊的基本單位。例如,如果 a 是一個數字變數,它可能是 1、可能是 100、可能是 -22...等。如果 b 是一個文字變數,它可能是 "abc"、"defxyz"、"台灣"、"地球只有一顆"...等,日期同理可推。

你的體重,是一個單純的數字變數;你今晚可能會去的餐廳,是一個單純的文字變數;你中樂透的那一天(如果有的話),是一個單純的日期變數。你的生日則是一個日期常數,因為已經不會變動了(除非戶口報錯)。

你自己這個變數(今天的你跟昨天的你不會完全一樣,不只外貌、體重、想法...),是由許多基本資訊組合起來的,就是一個不單純的大顆粒變數,也叫做一個東西