MS Word 有個功能,可以在搜尋時指定字型,例如我要找一個「標楷體」的文字,或是找一個「Times New Roman」的文字,底下就是搜尋時的畫面。不過過去看到字型有二個,單純以為一個是中文字的字型,一個是英文字的字型,後來遇到奇怪的結果,才知道並不完全是如此。
底下先解釋下圖的意義。
左邊有二個框,表示是要搜尋的內容。
綠框有中文有英文,它們全部都是設定為「標楷體」。
藍框也是有中文有英文,它是先全選之後設定為「標楷體」,再全選之後設定為「Times New Roman」(底下簡稱 Times),可以看出藍框的英文字和綠框的不同,看 i 最明顯,標楷體是等寬字型,i 的左右空白較多,藍框的中文依然是標楷體。
右邊是搜尋的界面,先選「尋找及取代」的「尋找」頁,選最底下的「格式」,再選「字型」,就會出現最右邊的字型界面,它有二個字型選項,一個是「中文字型」,一個是「字型」,底下會稱它為「英文字型」,以方便區隔。
二個概念
這裡要談二個概念,這二個是測試後自行理解想像出來的。
第一,某些字體同時有中文及英文,例如標楷體,它是中文字型,也有標楷體的英文字型,如上面的例子,它的英文是等寬字體。
某些字體可能只有英文,沒有中文,例如 Times New Roman (底下簡稱 Times),它只有英文,所以當藍框的標楷體中文設定為 Times 之後,中文依然是標楷體。如果原本是細明體,設為 Times 之後,依然是細明體,這表示 Times 不會改變中文字的字型。
第二個概念大概是本文最重要的概念,就是一個字(或者是一個字的位置)同時至少會有二個屬性:一個是中文字型,一個是英文字型。
以綠框而言,它的中文和英文都是「標楷體」,所以你在中文字的地方輸入英文字,出現的英文也是標楷體,而在英文的中間輸入中文,中文也是標楷體。
藍框就比較特殊了,它是處在「中文為標楷體,英文為 Times」的狀態。
意思是,若在中文之間輸入英文字,英文就是 Times,而不是標楷體。在英文之間輸入中文,中文就是標楷體。
下圖就是測試畫面,紅圈輸入的英文 i,就是等寬的標楷體。
橙圈的 i 就是 Times 字體。至於紫圈,都是標楷體了。
有了以上的概念後,就可以來看底下的搜尋設定會有什麼結果。
實際測試
搜尋時,中文字型設定「標楷體」:
二個框的內容都可以被搜尋到,因為二個框的中文字型屬性都是標楷體,包括 English is Times 那幾個英文字,因為它們的中文字型屬性都是標楷體。
(英文)字型設定「標楷體」:
只有綠框會被搜尋到,因為綠框的英文字型是標楷體,而藍框的英文是 Times。就算藍框中的中文字是標楷體,也不會被搜尋到。
(英文)字型設定「Times New Roman」:
只有藍框會被搜尋到,因為藍框的英文字型是 Times,而綠框的英文是 標楷體。就算藍框中的中文字是標楷體,也會被搜尋到。
中文字型設定「Times New Roman」:
這個情況不可能發生,中文字型框找不到「Times New Roman」。
也可以設定更嚴格的搜尋,也就是同時指定中文字型和英文字型,這可以視實際需要來設定了。
巨集設定
這是以前學巨集設定時,一個很簡單的「搜尋標楷體」功能。
Selection.find.ClearFormatting
With Selection.find
.Format = True
.Font.Name = "標楷體"
End With
Selection.find.Execute
測試後才知道,上面的 .Font.Name 就是上面文章中的「英文字型」。
一般的 Word 文件中,中英文字型都一樣,所以不會有大問題,但若遇到中文與英文字型不同時,就會發生明明有某個中文字型的字,卻找不到的問題了,因為那個中文字的英文字型可能是另一個字型。
如果尋找時要指定中文字型,上面的 .Font.Name 要改成
.Font.NameFarEast = "標楷體"
本文字型
最後補充一個額外的觀念,那就是 Word 有一個「標題與本文預設字型」的概念。以下只討論「本文」,應用在「標題」上應該也是同樣的概念。
如下圖,在選擇字型時,有一個「新細明體」,還有一個「新細明體(本文)」。可以記著一個簡單的概念,凡是有「本文」字樣的,不管它是什麼字體,一律當成是某個特殊字體,或稱為「本文字型」即可。
搜尋要指定字型時,也有「本文中文字型」。
簡單來說,若內文的字型是「新細明體(本文)」,而搜尋時指定中文字型是「新細明體」,這樣是找不到的。
同理,若內文的字型是「新細明體」,而搜尋時指定中文字型是「本文中文字型」,這樣也是找不到的。
總之,搜尋與被搜尋都要是相同的字型才行,把「本文字型」當成是一個獨立不同的字型,就不會混淆。
至於本文的字型,是可以自改變的,在主功能表的「設計」選「字型」,就可以指定「標題」與「內文」的「中文和英文字型」。
Word Font 五種字型名稱
前面提過,在字型有二種選擇,一種是「中文字型」,一種是「(英文)字型」,而在 Mac 上的 Word,直接就是寫「英文字型」。
根據線上說明,實際上 Font 有五個和字型名稱有關的屬性。
-
.Font.Name : 會傳回或設定指定之物件的名稱。 可讀寫的 String。
-
.Font.NameAscii : 會傳回或設定拉丁文字 (字元碼從 0 (零) 到 127 個字元) 所用的字型。 讀取/寫入的 String。
-
.Font.NameBi : 會傳回或設定由右至左語言文件中的字型名稱。 讀取/寫入的 String。
-
.Font.NameFarEast : 會傳回或設定東亞字型名稱。 讀取/寫入的 String。
-
.Font.NameOther : 會傳回或設定字元碼從 128 至 255 的字元所用的字型。 讀取/寫入的 String。
底下是各種測試。
這些是測試文字,有漢字、英文、Ascii < 127 符號,Ascii > 128 的符號,以及由右至左的語言,那是 ChatGpt 3.5 提供的範例。
底下的字型是全選後,先選「標楷體」,再選「Times New Roman」,漢字很好辨識,注意一下紅框的文字,都是非等寬的。
底下則是先選「微軟正黑體」,再選「Courier New」,注意一下紅框的文字,都是等寬的,和上面的差異應該很好辨識了。
以上是基本環境,因為界面沒有其它字型可以設定,所以寫了一個巨集如下:
Selection.WholeStory
Selection.Font.Name = "新細明體"
Selection.Font.NameFarEast = "標楷體"
Selection.Font.NameAscii = "微軟正黑體"
Selection.Font.NameOther = "Times New Roman"
Selection.Font.NameBi = "Courier New"
它的功能就是文字全選後,五個屬性分別設為不同的字體,執行後結果如下:
由上圖可以看出,漢字變成「標楷體」,英文和符號變成「微軟正黑體」,Ascii 大於 128 的變成「Times New Roman」,唯一意外的是,那些由右至左的語文沒有變成等寬的「Courier New」,卻是「微軟正黑體」,顯然被當成 Ascii 小於 127 的符號了?
為了要檢查究竟還有沒有文字的 .Font.Name 是「新細明體」,又寫了一個巨集,把 .Font.Name = "新細明體" 的文字變成紅色,結果沒有一個字是紅色的。
程式改成把
.Font.NameBi = "Courier New"
的文字變成紅色,則有如下結果:
表示這些字的 .Font.NameBi 都是「Courier New」,除了少數幾個黑色的字。
這也表示這些字的 .Font.Name 都不是「新細明體」。
同樣的程式,用這三組去檢查,畫面也是一樣,幾乎全都是紅色,黑色是固定那幾個字。
.Font.NameFarEast = "標楷體"
.Font.NameAscii = "微軟正黑體"
.Font.NameOther = "Times New Roman"
意思就是這些字都有四個屬性:
.Font.NameFarEast = "標楷體"
.Font.NameAscii = "微軟正黑體"
.Font.NameOther = "Times New Roman"
.Font.NameBi = "Courier New"
既然沒有一個字的 .Font.Name 是「新細明體」,那它們的這個屬性究竟為何?
寫一個巨集,搜尋「漢字範例」的「範」字,檢查它的 .Font.Name 屬性,發現是「標楷體」。
搜尋「eng」字,它的 .Font.Name 屬性是「微軟正黑體」。
搜尋「â」字,它的 .Font.Name 屬性是「Times New Roman」。
看來 .Font.Name 屬性在指定其它 Font Name 屬性後,也被修改了,而且是根據不同的文字有不同的結果。
到目前為止,還是情況不太明確,不知 .Font.Name 的處理規則。
五種屬性測試
再做一個測試,檢查在使用編輯界面將「範」指定各種字型後,看看這五個字型屬性有什麼變化。
首先,將「範」字設為「Times」再設為「微軟正黑體」,用巨集檢查此字的五個屬性,發現都變成「正黑體」了,只有 .Font.NameBi 不受中文字型影響,依然是 Times 字型,可以理解為中文字型不支援 .NameBi。(紅色那一行)
2.將「範」字設為「Courier New」,用巨集檢查此字的五個屬性,發現三個變成「正黑體」了,只有 .Font.Name 和 .Font.NameFarEast 不受英文字型影響,依然是「微軟正黑體」,可以理解為此字是漢字,所以漢字的 .Name 和 .NameFarEast 不受沒中文的字型影響。(藍色那行)
3.將「範」字設為「細明體」,和第一組一樣,只有 .NameBi 不受中文影響。(綠色那行)
再來試英文字母「E」
這次結果和「範」字類似,只是在第二步驟時,E 字換成 Courier New 字型後,.Font.Name 也變成 Courier New,這可以理解為 E 是英文字,所以 .Font.Name 會換成英文的字型。
再來試 Ascii 大於 128 的「â」,結果和「E」一樣。
奇怪的結果
上面的實驗,我發現一個奇怪的地方。
前面的章節中,只做二種字型的測試時,我們認為 .Font.Name 是英文字型,.Font.FarEast 是中文字型。
所以中文字在先選擇「標楷體」再選英文字型「Times」之後,我們認為這個字的屬性是:
.Font.Name = "Times New Roman"
.Font.FarEast = "標楷體"
因此巨集若用 .Font.Name = "標楷體",會找不到上面提到的中文字。
不過在五種屬性的測試時,雖然中文字「範」在第二步驟指定了英文字型「Courier New」,但它的 .Font.Name 卻依然是「微軟正黑體」,並不是最前面測試的英文字型,這不是很奇怪嗎?
再寫一個巨集測試,畫面如下,那個「範」字先設為「微軟正黑體」,再設為「Courier New」。
由畫面能看到的第一行,表明了要找的字是 "範" 字。
第二行指定要找的 .Font.Name 是「Courier New」
畫面最上面「範」字被反白了,表示有找到。
但偵測第四行 a1 的內容,卻是「微軟正黑體」。
實在被打敗了!
我要找「Courier New」,程式有找到,卻回報說找到「微軟正黑體」,實在無法理解。
如果把第二行改成
.Font.Name =「微軟正黑體」
反而會找不到了。
或許 Selection.find.Font.Name 和 Selection.Font.Name 的性質不太相同,暫時測試到這裡了。
或許不要用 .Font.Name,而是用 .Font.NameAscii 和 .Font.NameFarEast 比較安全一點。
找到問題點了
過了二天,突然有個靈感,猜想到問題發生的原因了。
前面最主要的關鍵問題是:
當一個漢字,指定「標楷體」(或其它中文字型),再指定「Times New Roman」(或其它非中文字型),此時用巨集檢查它的屬性是。
.Font.Name = "標楷體"
.Font.NameAscii = "Times New Roman"
.Font.NameFarEast = "標楷體"
但若要指定字型來搜尋,則必須是
.Font.Name = "Times New Roman"
.Font.NameAscii = "Times New Roman"
.Font.NameFarEast = "標楷體"
紅色就是矛盾的地方。
今天凌晨突然想到,在編輯界面中指定字型時,五個字型屬性都可能會被影響,那會不會在巨集中指定 .Font.Name 字型時,也同時會影響其它 Font Name 的內容?
立刻進行測試。
把之前尋找指定字型的巨集改了一下,一開始就先印出五種 Font Name,然後指定 .Font.Name = "Times New Roman",之後再印出五種 Font Name。
Debug.Print ("1.Name:" + .Font.Name)
Debug.Print ("1.NameAscii:" + .Font.NameAscii)
Debug.Print ("1.NameBi:" + .Font.NameBi)
Debug.Print ("1.NameFarEast:" + .Font.NameFarEast)
Debug.Print ("1.NameOther:" + .Font.NameOther)
Debug.Print ("設定 .Font.Name = Times New Roman")
.Font.Name = "Times New Roman"
Debug.Print ("2.Name:" + .Font.Name)
Debug.Print ("2.NameAscii:" + .Font.NameAscii)
Debug.Print ("2.NameBi:" + .Font.NameBi)
Debug.Print ("2.NameFarEast:" + .Font.NameFarEast)
Debug.Print ("2.NameOther:" + .Font.NameOther)
執行結果如下:
1.Name:
1.NameAscii:
1.NameBi:
1.NameFarEast:
1.NameOther:
設定 .Font.Name = Times New Roman
2.Name:
2.NameAscii:Times New Roman
2.NameBi:Times New Roman
2.NameFarEast:
2.NameOther:Times New Roman
這個結果果然和直覺想像的不同。
明明巨集是指定 .Font.Name 為 "Times New Roman",但在設定之後,.Font.Name 卻是空字串,反而是把 NameAscii、NameBi、NameOther 設為 "Times New Roman"。
如此一來,找到如下屬性的字就很正常了。
.Font.Name = "標楷體"
.Font.NameAscii = "Times New Roman"
.Font.NameFarEast = "標楷體"
因為 .NameAscii 符合 "Times New Roman",而要尋找的 .Name 及 .NameFarEast 為空字串,表示不在意,因此就找到了。
同樣的程式,再改成
.Font.Name = "標楷體"
試看看,結果如下:
1.Name:
1.NameAscii:
1.NameBi:
1.NameFarEast:
1.NameOther:
設定 .Font.Name = 標楷體
2.Name:
2.NameAscii:標楷體
2.NameBi:
2.NameFarEast:標楷體
2.NameOther:標楷體
這次 .Font.Name 為標楷體之後,依然是空字串,卻改變了 .NameAscii、.NameFarEast、.NameOther 。(註:若是用微軟正黑體測試,則 .NameOther 為空字串。)
在此,可以理解為標楷體是中文字型,同時它也有英文字型,所以支援 Ascii 、 FarEast 和 Other 這三個範圍,因此改變這三個屬性。
之前的 Times 字型是英文字型,沒有支援中文字型,所以沒有改變 FarEast,卻改變了 Ascii、Bi、Other 三者,表示它支援這三個範圍。
再來看為什麼指定 .Font.Name 為標楷體會搜尋不到?
因為要搜尋的條件變成:
2.Name:
2.NameAscii:標楷體
2.NameBi:
2.NameFarEast:標楷體
2.NameOther:標楷體
但文字的屬性卻是
.Font.Name = "標楷體"
.Font.NameAscii = "Times New Roman"
.Font.NameFarEast = "標楷體"
紅色就是不同的地方,難怪找不到了。
至此,大概可以有個結論:
.Font.Name 不是一個獨立的屬性,它會根據不同的字型,改變其它屬性。所以還是如前面所說,直接使用 .Font.NameAscii 和 .Font.NameFarEast 會比較安全一點。
底下就來列表整理一下,看看五種屬性修改之後,分別會有哪些影響。
以藍色那一欄來解釋,如果 .Font.Name 設為 Times,則實際上有三個屬性 Ascii、Bi、Other 會變成 Times,.Name 本身反而是空白。
綠色那三欄,若只設定 Ascii、Bi、Other,則只有相對應的屬性有改變,其它都空白。
至於 .NameFarEast 無法設定為 Times,因為 Times 沒有中文字型,指定會造成巨集執行錯誤。
再來看設為中文標楷體會有什麼不同?
藍色那一欄,表示 .Name 指定為標楷體後,變成 .NameAscii、.NameFarEast、.NameOther 是標楷體,其它為空字串。
綠色表示若指定其它四個屬性,則只有那四個會變化,不會影響其它。
這裡比較奇怪的是,既然標楷體也有支援 Bi,為會藍色那一欄的 Bi 不是標楷體呢?
最後再來測試同時指定二種字型會如何?
.Font.Name = "標楷體"
.Font.Name = "Times New Roman"
在一般程式的概念,同一個變數指定二次,後者會取代前者,但 .Font.Name 不是一般變數,它會有不同的作用,執行如果如下:
1.Name:
1.NameAscii:
1.NameBi:
1.NameFarEast:
1.NameOther:
設定 .Font.Name = 標楷體
設定 .Font.Name = Times New Roman
2.Name:
2.NameAscii:Times New Roman
2.NameBi:Times New Roman
2.NameFarEast:標楷體
2.NameOther:Times New Roman
這裡的結果和猜想一樣,應該是先將 Ascii、FarEast、Other 指定為標楷體,再把 Ascii、Bi、Other 指定為 Times 了。
反過來
.Font.Name = "Times New Roman"
.Font.Name = "標楷體"
執行結果:
1.Name:
1.NameAscii:
1.NameBi:
1.NameFarEast:
1.NameOther:
設定 .Font.Name = Times New Roman
設定 .Font.Name = 標楷體
2.Name:
2.NameAscii:標楷體
2.NameBi:Times New Roman
2.NameFarEast:標楷體
2.NameOther:標楷體
這也符合預測的結果了。
至此,應該沒什麼大問題了。
簡單的總結
一開始的問題在於,一個漢文字,先指定字型為「標楷體」,再指定字型為「Times New Roman」,它的五個 Font Name 屬性為:
Name = "標楷體"
NameAscii = "Times New Roman"
NameBi = "Times New Roman"
NameFarEast = "標楷體"
NameOther = "Times New Roman"
但在搜尋時,指定
.Font.Name = "標楷體"
無法搜尋到,反而是指定
.Font.Name = "Times New Roman"
才能找到,但明明該字的 .Font.Name 是 「標楷體」啊?
原來是因為在搜尋時,雖然指定
.Font.Name = "標楷體"
實際上五個屬性會變成如下:
Name = ""
NameAscii = "標楷體"
NameBi = ""
NameFarEast = "標楷體"
NameOther = "標楷體"
因此找不到屬性為下的字。
Name = "標楷體"
NameAscii = "Times New Roman"
NameBi = "Times New Roman"
NameFarEast = "標楷體"
NameOther = "Times New Roman"
空字串可以忽略,紅色是不同的地方,因此找不到。
搜尋時若指定
.Font.Name = "Times New Roman"
實際上五個屬性會變成如下:
Name = ""
NameAscii = "Times New Roman"
NameBi = "Times New Roman"
NameFarEast = ""
NameOther = "Times New Roman"
要找的字的屬性如下
Name = "標楷體"
NameAscii = "Times New Roman"
NameBi = "Times New Roman"
NameFarEast = "標楷體"
NameOther = "Times New Roman"
因為空字串可忽略,而 Ascii、Bi、Other 三者皆符合,所以反而找到了。
結論是,最好只用 .NameAscii 和 .NameFarEast 分別處理英文和中文,.Font.Name 會有什麼隱藏的細節若沒弄清楚,可能會有錯誤。
- 瀏覽次數:1274
發表新回應