淺談使用VBA處理不同語言時的亂碼問題
在《全民一起VBA 之 提高篇》的第八回「文本字元也是數字、編碼函數兩界穿梭」中,我們為大家介紹了最基本的字符集和字元編碼知識。當時這一章發布不久,果然就有同學在工作中遇到了相關的問題:「楊老師,有個關於字符集的問題想請教您一下。我的工作中需要對EXCEL中的法語進行操作,但是VBA識別不了有些字母。請問,有什麼方法能實現這些操作?」
看到這個問題時,楊老師的感受就是:終於,終於有人問到這個問題了,讓我靜靜先(不是因為激動,而是因為鬱悶)……
為什麼呢?因為不同語言中的字元編碼,可以說是所有程序員的最大噩夢之一!我們先看一下問題的產生原因:簡單的說,就像我們在《提高篇》裡面講過的,每個字元都是由一個數字代表的,那麼除了最通用的英文外,其他各種語言都由各個國家自己規定了數字編碼方案,所以同樣一個23423,在漢語系統中可能代表某個漢字,而在法語系統中可能就代表某個「戴帽子」的字母。
為了解決這個問題,後來大家推出了Unicode編碼方案,把常用語言都編到一套大的數字方案中,互不衝突。不過可惜的是,VBA的代碼編輯器VBE並沒有默認支持Unicode,而是仍然使用一種相對老舊的方案稱之為「代碼頁」。大概意思就是,我們在windows系統的設置中需要指定一個「代碼頁」,而每個代碼頁都針對一種特定的文字系統。這樣當需要把一個數字翻譯成文字時,就按照當前代碼頁的內容進行翻譯(大家可以想像一下二戰時候各國軍隊使用的「密碼本」,原理很相似)。所以,假如windows當前的代碼頁是「中文」,那麼一個數字比如23423,就按中國方案翻譯成漢字;如果代碼頁改成了「法文」,那麼就把這個數字按法國方案翻譯成某個字母。所以,當我們的系統設定為中文/英文代碼頁時,一個本來打算表示法文字元的數字代碼,就會被VBE翻譯成中文/英文代碼頁中對應該數字的字元,也就是某個莫名其妙的東西或者乾脆就是一個問號了。
下面這個圖示就是這種情況。由於WEB瀏覽器支持Unicode而不使用代碼頁,所以一個表示發文的數字代碼,可以在瀏覽器中正確顯示為法文。但是把這段內容拷貝到VBE中以後,由於VBE不支持Unicode而是使用代碼頁,而我的Windows當前默認的是中英文代碼頁,所以VBE強行把這些數字代碼按照中英文的文字系統進行翻譯,得到了很多特殊字元。
說到這裡,樓主這個問題的解決辦法就出來了:修改windows的代碼頁。具體做法是,打開「控制面板」——「語言與地區」,在設置窗口中找到「管理」——「修改系統地區」 (不好意思,我的系統是英文版Windows7,所以上述幾個名字是我自己看著翻譯的,可能與中文版系統上面顯示的不一樣)。在裡面把地區改成「法國」,然後重啟電腦。這回在運行VBA就可以用mid等函數取出法語字元串的每一位了。我在自己的電腦(英文版Win7+中文支持)上親測成功。
不過這種方法的缺陷在於,改一次代碼頁只能支持有限幾種非英文語言,比如改成法文後再看中文可能就會遇到麻煩。現在我們中國企業都在全球布局,說不定你的一份數據就要涵蓋英法俄德奧意美日(不知道現在中學歷史書裡面八國聯軍是否還是按這個順序背?),順便帶上西班牙葡萄牙印度馬來西亞。這個時候用代碼頁的方式肯定是不夠用了。
那麼怎麼辦?根本辦法當然是寄希望於微軟公司在未來版本Office中為VBE添加Unicode支持了。不過歷史證明美帝資本家是不會聆聽我們勞苦大眾內心呼喚的,所以現在還要自己想些辦法。
首先,提出這個問題的同學找到了一個方法,其原理在於,雖然VBE不支持法文,但是他的Excel的單元格中書寫法文是不亂碼的。所以他的方案是:「由於只是在做報告自動化的時候需要處理一下法文,而在日常工作中還是使用中文和英文,所以沒有採用修改代碼頁的方法。 另外,我發現可以把這些特殊的法文字元放到一張EXCEL表里,需要的時候用VBA從單元格里讀取,然後再應用到EXCEL中。這樣 的方法是可行的,(也就是說不在VBE中直接寫這些字元,)這樣的操作是可以的。 這個方法比較簡單,所以採取了這種方法。」
這是一個很好的方法,也是實際工作中大家很常用的技巧。在這個思路中,所有VBE不能顯示的字元都寫在單元格中,而VBA本身扮演搬運工角色,只負責把單元格內容複製到別的單元格中,完全不嘗試解析/處理/變換單元格中的內容,所以避免了VBE無法顯示/轉碼出錯的問題。麻煩的地方在於需要多寫一些代碼,不過大家可以把嘗試根據自己日常工作的需求,把這個方法做一個比較通用的子程序,多次使用時就會更加方便了。事實上,在我們使用J2EE/C++等開發專業的軟體系統時,就是使用類似的思路解決文本國際化問題的。即把不同語言的文本寫在不同的文本文件中,而Java程序代碼中完全不輸出任何文字內容,只是根據客戶的語言需求,把相應文本文件中的內容輸出顯示。
另外一個辦法是我在TD銀行工作時,看到一些國外同事經常使用的。就是遇到英文法文混雜時(TD銀行的主要業務集中在加拿大等英法雙語國家),先在Excel表格(不是VBA)中將它們替換成英文形式(就是把戴帽子的各種字母替換成相近的英文字母),然後再用VBA處理。這樣的好處是可以在VBA代碼中進行各種字元處理而不出錯,不過使用英文字母替換法文字母也丟失了一些語言精確性(我不懂法語,猜測可能是二者差別不大,替換後也能讀懂吧)。具體在表格中替換法語的辦法,大家可以上網搜一下資料。
好,關於多語言的問題我們先說到這裡。如果大家有其他好辦法也請到我們官網論壇http://forum.yycollege.com留言交流,謝謝!
推薦閱讀:
※數據狗如何做出一份讓老闆稱讚的數據報表?
※一個案例,教你搞定99%的人都不會的「郵件合併」功能
※優化VBA效率 之 優化錄製宏
※Excel VAB入門(二)數組和字典
※Excel圖表進階之路
TAG:VBA | MicrosoftOffice | MicrosoftExcel |