搜尋此網誌

2023年3月23日 星期四

VBA 初試

緣起:


    前幾天跑去接了一個 VBA 的任務,雖然昨天跟協理討論後,最後是決定公司沒有要接這個案子,但我前幾天這樣邊做邊學也是學到了點東西,所以想寫個文章記錄。

    我的筆電上面只有 LibreOffice,所以只能在我公司的電腦上使用 Microsoft Office。廠商有個要求是,以一份表單裡的編號欄位跟計劃名稱來產生對應名稱的表 2。我有把這功能做出來,所以想以它來為例題,紀錄我從這個功能學到的東西。


開啟 VBA 功能:


    在 excel 的 "檔案" 那邊 -> 選項


    把 "開發人員" 的選項打勾


    就可以在工具列看到了



Hello World:


    在開發人員的工具列點擊 Visual Basic,就會開啟寫程式的視窗


    可以對 VBAProject 點右鍵,然後插入 -> 模組


    它就會新增一個模組,右邊會多一個模組視窗,程式碼可以寫在那裡。

    打程式


    然後點工具列的綠色三角型就能執行程式
    


    也可以在開發人員的工具列那邊點巨集


    在新開的視窗選擇對應的 sub,然後按執行,一樣能跑程式


    昨天在討論時,我們的工程師有教我說,VBA 盡量跟表格寫在一起比較好。

    在 vba 專案視窗雙擊我們的工作表,可以開啟視窗來寫這張表的 VBA 



程式需求:


    假設這個 Excel 只有個工作表 1,長這樣


    我們要根據工作表的內容來產生其它工作表,以此張表為範本,複製出 4 張其它的工作表,名稱是 "工作表2_編號_名字" 。


基礎:


    一開始比較重要的是 WorkBook 、WorkSheet 的觀念跟操作它們的方法,我是在這邊學的。再來是對於每個儲存格的操作,學完這些後我也就開始動手操作了,Visual Basic 的那些語法我大略還記得。


開始:


    設定變數


    然後寫個 while 迴圈一直往下讀,讀到空白才停止。VBA 的 while 迴圈最後是需要加個 Wend。VBA 字串的比對,使用 StrComp。WorkSheets("工作表名稱") 可以取得對應名稱的 WorkSheet,然後再透過 Cells(列, 行) 來取得特定儲存格,Value 可以拿到儲存格的內容。


    取出那列的 "編號" (A -> 1) 跟 "名字" (B -> 1),記到變數中


    WorkSheet 有 Copy 的方法能複製自已,然後再用 Before 跟 After 決定複製的那份 WorkSheet 要放在哪份的前面或後面。教學


    我們 Copy 一份 WorkSheet 後,目前作用的 WorkSheet 就會是剛複製的那份,所以可以透過 ActiveSheet 來取得,然後再指定它的 Name 屬性來改名。VB 的字串相加是用 "&"。最後 row_index 要加 1 ,Visual Basic 好像不能寫 ++ 或 +=。


    執行程式後可以看到,成功新增一模一樣的 WorkSheet,名字也按照工作表1的內容來命名


    

自動刪除 WorkSheet:


    我還在測試生成 WorkSheet 的程式時就發現,我需要先寫個刪除 WorkSheet 的程式才對,不然每次測試後都要手動刪那堆自動生成的表格也太麻煩,所以也寫了一個自動刪除的程式。

    可以用 WorkSheets 來取得所有 WorkSheet,它是一個集合 (吧,VBA 有 For Each 可以使用,讓我們可以逐一取得所有 WorkSheet。For Each 的最後要加 Next 變數。


    再來要刪除那些 "工作表2",用 InStr 來確認目前 WorkSheet 的名字裡有沒有 "工作表2",有的話,回傳值不會是 0。找到後再用 Worksheet 的 Delete 來刪除此 WorkSheet。


    如果程式就這樣直接執行的話,它在刪表格前都還會再跳一個確認的視窗出來,這樣就不是我們想要的自動化了,所以需要把 Application.Display 設成 False,然後作業完成後再開啟,這樣就能達成我們的需求了。



沒有留言:

張貼留言