程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB6 >> 基於VBA組卷中自動排版的實現

基於VBA組卷中自動排版的實現

編輯:VB6

一、引言

建立完善的題庫是課程建設的一項重要工作,當數據庫的形式進行題庫管理,通過編寫抽題程序,在分類明確、題量豐富的題庫支持下,實現自動組卷並非難事。試卷一般都采用Word文檔,若采用VBA編程,要用程序將試題寫入到Word文檔,可以通過引用 Microsoft Word 9.0 Object Library中的相關對象來實現:圖片、圖形、文本框及藝術字等可利用Shapes集合對象的相應方法加入到文檔中;表格也可以通過Tables集合對象的Add 方法加入,其大小、位置等排版信息都可以以參數的形式傳入;而文字部分的內容也能以字符串的形式通過調用Content對象的InsertAfter方法插入,排版時對其字型、字體、字號及段落格式則可以利用Font對象及Paragraph對象的屬性或方式進行設置。

選擇題是各類試卷中經常出現的題型,而它的排版有其特殊性,因為選擇題的四個選項根據其長度有可能排成四段(行),也可能排成兩行,每行兩個選項,且它對段落縮進及上、下行中選項的對齊等都有一定的要求。一份美觀的試卷中選擇題的格式如圖1所示。 

圖1 選擇題的排版效果

這裡要解決的幾個問題是:

1.題干部分的題號對齊,尤其是一位數題號與兩位數題號(如第9題與第10題);前、後題題干內容的第一個字符對齊;題干部分作為段落要采用懸掛縮進、且縮進量應合適。

2.若選項由四段(行)構成,則每段應有左縮進、縮進量與題干部分的懸掛縮進量相同,同時,選項內容的長度也有可以超過一行(如第10題中的選項C),所以對選項也要設置懸掛縮進、且縮進量應合適。

3.若選項由兩行構成(如第11題中的四個選項),則上一行的選項C與下一行的選項D應對齊。

二、定義選擇題的數據結構

程序設計中為了便於將選擇題作為函數的參數傳遞,應定義選擇題的數據類型的結構,選擇題的結構通常由題干及四個選項構成,具體定義如下:

Public Type Choice

Sentence As String '題干內容,不包括題號

ChoiceA As String   '選項A的內容

ChoiceB As String   '選項B的內容

ChoiceC As String   '選項C的內容

ChoiceD As String   '選項D的內容

End Type

三、頁面設置與段落格式

首先進行頁面設置,頁面上邊距、下邊距、左邊距、右邊距分別設為1英寸、1英寸、1.25英寸、1.25英寸, 默認制表位長度為0.33英寸。

With ActiveDocument.PageSetup

 .TopMargin = InchesToPoints(1)

 .BottomMargin = InchesToPoints(1)

 .LeftMargin = InchesToPoints(1.25)

 .RightMargin = InchesToPoints(1.25)

End With

ActiveDocument.DefaultTabStop = InchesToPoints(0.33)

為了對題干部分進行排版,先自定義一個過程insTabIndent,其功能是根據第一個參數str1傳入的題干內容及第二個參數Num傳入的本題題號,在題干內容前加上題號,若Num為0,則表示不加題號;在題號後設置一個制表位,使前、後題的題干內容的第一個字符對齊;對題干所在段落設置懸掛縮進一個制表。

Private Sub insTabIndent(str1 As String, Num As Integer)

 Dim s As String

 If Num < 10 Then s = " " + Trim(str(Num)) + "." Else s = Trim(str(Num)) + "."

 If Num = 0 Then s = ""

 Set myRange = appObj.ActiveDocument.Content

 myRange.Collapse Direction:=wdCollapseEnd

 myRange.InsertAfter s & vbTab & str1

 myRange.InsertParagraphAfter

 myRange.Font.Name = "宋體"

 myRange.Font.Size = 12

 myRange.ParagraphFormat.TabHangingIndent 1 '懸掛縮進1個制表位

End Sub

為了對選項進行排版,自定義一個過程insLeftAndHangingIndent,其功能是根據參數str1傳入的選項內容,將其作為段落寫入Word文檔,設置字型、字體、字號及左縮進和懸掛縮進。

Private Sub insLeftAndHangingIndent(str1 As String)

 Set myRange = ActiveDocument.Content

 myRange.Collapse Direction:=wdCollapseEnd

 myRange.InsertAfter str1

 myRange.InsertParagraphAfter

 myRange.Font.Name = "宋體"

myRange.Font.Size = 12      '小四

'設置左縮進與懸掛縮進

 myRange.ParagraphFormat.FirstLineIndent = CentimetersToPoints(-0.64)

 myRange.ParagraphFormat.LeftIndent = CentimetersToPoints(1.48)

End Sub

四、選擇題的寫入及排版

如果四個選項按四段(行)進行排版,則只要通過調用前面所定義的兩個過程就能實現,但四個選項要按兩行排版則有兩種方法可供選擇:一是分節分欄法:將四個選項按四段寫入Word文檔,並將它們設置成單獨的一節,再采用分成兩欄的方法實現;二是直接寫入排版法:在同一行的兩個選項之間插入若干個制表位實現對齊,編程中將涉及寫入點的定位問題。

1、分節分欄法

選擇題寫入Word文檔及排版操作在自定義過程insSelect中實現,傳入參數mObj內封裝了一道選擇題;題號通過參數n傳入;參數max傳入的值是選項內容字符數的臨界值,即當四個選項內容中字符數最多者如果超過了max,則四個選項排版成四段(行),否則排成兩行。其中用到的函數maxLen(mObj)返回值表示選擇題mObj的四個選項內容中字符數的最大值。

Private Sub insSelect(mObj As Choice, ByRef n As Integer, max As Integer)

insTabIndent mObj.Sentence, n   '寫入題干內容及題號

If maxLen(mObj) > max Then      '按四段(行)並采用左縮進及懸掛縮進寫入

 insLeftAndHangingIndent "A) " + mObj.ChoiceA

 insLeftAndHangingIndent "B) " + mObj.ChoiceB

 insLeftAndHangingIndent "C) " + mObj.ChoiceC

 insLeftAndHangingIndent "D) " + mObj.ChoiceD

 ActiveDocument.Content.InsertParagraphAfter

  n = n + 1

Else    '選項按縮進一個制表位形式寫入,為後面的分節分欄做准備

 Set tempRange = ActiveDocument.Content

 tempRange.Collapse Direction:=wdCollapseEnd

 tempRange.InsertAfter vbTab & "A) " & mObj.ChoiceA

 tempRange.InsertParagraphAfter

 tempRange.InsertAfter vbTab & "B) " & mObj.ChoiceB

 tempRange.InsertParagraphAfter

 tempRange.InsertAfter vbTab & "C) " & mObj.ChoiceC

 tempRange.InsertParagraphAfter

 tempRange.InsertAfter vbTab & "D) " & mObj.ChoiceD

 tempRange.InsertParagraphAfter

 tempRange.Font.Name = "宋體"

 tempRange.Font.Size = 12      '小四

 n = n + 1   '題號增1,為寫入下一題做准備

 tempRange.Select    '選定四個選項所在的區域

 If ActiveWindow.View.SplitSpecial <> wdPaneNone Then

   ActiveWindow.Panes(2).Close

 End If

 If ActiveWindow.ActivePane.View.Type <> wdPrintView Then

   ActiveWindow.ActivePane.View.Type = wdPrintView

 End If

 '在選定區域的起始位置和末尾位置插入分節符

ActiveDocument.Range(Start:=Selection.Start, End:=Selection.Start)._

 InsertBreak Type:=wdSectionBreakContinuous

 Selection.Start = Selection.Start + 1

ActiveDocument.Range(Start:=Selection.End, _

  End:=Selection.End).InsertBreak Type:=wdSectionBreakContinuous  '將選定的文本分成兩欄

 With Selection.PageSetup.TextColumns

   .SetCount NumColumns:=2

   .EvenlySpaced = True

   .LineBetween = False

   .Width = CentimetersToPoints(6.95)

   .Spacing = CentimetersToPoints(0)

 End With

 ActiveDocument.Content.InsertParagraphAfter

End If

End Sub

2、直接插入排版法

這種方法是將選項A與選項C作為同一行寫入、選項B與選項D作為同一行寫入,關鍵在於要求上一行的C選項與下一行的D選項要求對齊,定位方法是在選項A的末尾與選項C、選項B的末尾與選項D之間插入若干個制表位,模擬手工調整的方法進行對齊。但上、下行要分別插入多少個制表位才能對齊呢?這要借助於Selection對象的Information屬性進行檢測。Selection.Information(wdHorizontalPositionRelativeToPage)可以返回指定的所選內容或區域的水平位置,該位置是所選內容或區域的左邊與頁面的左邊之間的距離,以磅為單位(72磅 = 1英寸)。具體方法是每插入一個制表位就將選定區域收縮為選定區域後一個字符,同時檢測它距頁面的左邊之間的距離,直到距離達到某個設定值時就停止插入。具體程序如下:

insTabIndent "A) " + mObj.ChoiceA, 0 '寫入選項A

x = appObj.ActiveDocument.Content.Paragraphs.Count – 1

'x記錄下選項A所在的段落數

'每次循環插入一個制表位,並在循環條件中進行位置檢測

Do

Set tempRange = appObj.ActiveDocument.Range(appObj.ActiveDocument.Content.Paragraphs(x)._

Range.End - 1, appObj.ActiveDocument.Content.Paragraphs(x).Range.End)

tempRange.Select

Selection.TypeText vbTab '在選項A的內容後插入一個制表位

Set tempRange = appObj.ActiveDocument.Range(appObj.ActiveDocument.Content.Paragraphs(x)._

Range.End - 1, appObj.ActiveDocument.Content.Paragraphs(x).Range.End)

tempRange.Select '選定區域設為當前區域的最後位置

Loop While (Selection.Information(wdHorizontalPositionRelativeToPage) < 280)

'當檢測到寫入點位置距與頁面左邊的距離超過280磅時停止插入制表位

Selection.TypeText "C) " + mObj.ChoiceC '寫入選項C

'以下處理下一行的選項B和選項D,方法同上

insTabIndent "B) " + mObj.ChoiceB, 0 '寫入選項B

x = appObj.ActiveDocument.Content.Paragraphs.Count - 1

Do

Set tempRange = appObj.ActiveDocument.Range(appObj.ActiveDocument.Content.Paragraphs(x)._

Range.End - 1, appObj.ActiveDocument.Content.Paragraphs(x).Range.End)

tempRange.Select

Selection.TypeText vbTab

Set tempRange = appObj.ActiveDocument.Range(appObj.ActiveDocument.Content.Paragraphs(x)._

Range.End - 1, appObj.ActiveDocument.Content.Paragraphs(x).Range.End)

tempRange.Select

Loop While (Selection.Information(wdHorizontalPositionRelativeToPage) < 280)

Selection.TypeText "D) " + mObj.ChoiceD '寫入選項D

appObj.ActiveDocument.Content.InsertParagraphAfter

五、結語

前述兩種選擇題的排版方式均已在實際的試卷自動生成系統的排版應用中進行實測,測試表明兩種方法都能得到較為規范、美觀的排版效果。分節分欄法實現思想較為簡單,但由於生成的文檔中有大量的分節符,如果對於生成的文檔要作手工調整,可能會帶來一點麻煩;直接插入排版法的好處是不分節,便於後期的手工調整,但生成文檔的速度稍慢。

參考文獻

1.Microsoft Word 2000 Visual Basic 對象模型幫助系統[DK]

2.孟祥瑞.Visual Basic 6.0程序設計[M].華東理工大學出版社,2005

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved