嵌入式圖表和圖表工作表
圖表在工作表中有兩種存在方式:
- 嵌入式圖表與工作表的數據在一起,或者與其他的嵌入式圖表在一起。
- 圖表工作表是特定的工作表,只包含單獨的圖表。
(1)嵌入式圖表
當希望圖表作為工作表的一部分,與數據或其他圖表在一起時,嵌入式圖表是最好的選擇。Chart對象代表每一個嵌入式圖表,包含在ChartObject對象里。
每個Excel工作表都有一個ChartObjects集合,包含工作表中每個嵌入式圖表。為了在工作表中添加新的嵌入式圖表,在集合中添加ChartObject對象,其語法為:
WorksheetObject.ChartObjects.Add(Left,Top,Width,Height) |
其中,參數Left和參數Top指定圖表左上角的位置,參數Width和參數Height指定圖表尺寸。所有4個參數都以磅為單位。該方法返回對新創建的ChartObject對象的引用,使用Chart屬性引用所包含的圖表。例如:
Dim co As ChartObject Dim ch As Chart Set co = Worksheets("Sheet1").ChartObjects.Add(50, 50, 250, 165) Set ch = co.Chart |
執行上述代碼后,在工作表Sheet1中放置一個新的空嵌入式圖表,使用變量ch來引用該圖表。
(2)圖表工作表
當希望圖表顯示最大尺寸,而且不會妨礙數據或其他圖表時,使用圖表工作表。Chart對象代表圖表工作表。與嵌入式圖表不同,不需要ChartObject對象,因為圖表工作表的位置是固定的,其尺寸取決於工作表的尺寸。每個工作簿都有一個Charts集合,包含該工作簿中的所有圖表工作表。
注意,工作簿的Charts集合不會引用嵌入式圖表,僅僅是圖表工作表。相反,工作表的ChartObjects集合僅僅引用嵌入式圖表。要添加新的圖表工作表,使用Add方法:
Charts.Add |
該方法返回對新圖表的引用。下面的代碼在活動工作簿中添加新的圖表工作表,並且包含對新圖表的引用:
Dim ch As Chart Set ch = ActiveWorkbook.Charts.Add |
執行上述代碼后,使用變量ch操控圖表。
Chart對象
以下圖所示的工作表為例,簡要介紹Chart對象及其應用。
要指定圖表數據,需要調用Chart對象的SetSourceData方法。語法為:
SetSourceData(Source,PlotBy) |
其中,參數Source是包含數據的工作表區域,可以通過行列標識符或者名稱來指定該參數值。參數PlotBy是一個常量,指定數據系列是行區域(xlRows)還是列區域(xlColumns)。
如上圖所示的工作表,設置圖表源數據的代碼如下:
ch.SetSourceData Source:=Worksheets("Sheet1").Range("B3:F6"),PlotBy:=xlRows |
假設ch引用Chart對象。下面的過程基於上圖工作表數據創建一個嵌入式圖表:
Sub CreateEmbeddedChart() Dim co As ChartObject Dim ch As Chart Set co = Worksheets("Sheet1").ChartObjects.Add(50, 100, 250, 165) Set ch = co.Chart ch.SetSourceData Source:=Worksheets("Sheet1").Range("B3:F6"), PlotBy:=xlRows End Sub |
說明:
- 圖表中自動添加了數據系列和類別標簽。
- 在水平軸中繪制類別;垂直軸中繪制數值。
- 自動創建圖表圖例,以識別數據系列。
- 圖表的垂直軸根據數據值自動縮放。
- 在沒有指定圖表類型時,默認使用簇狀柱形圖。
生成的圖表如下圖所示。
下面,來指定圖表的類型。
Chart對象的ChartType屬性控制圖表的類型,並且Excel提供了一組預定義常量指定該屬性。每個常量不僅指定基本類型(例如條形圖、柱狀圖或折線圖),而且也指定每種類型的子類型,包括圖表是否作為二維或三維顯示。
下表列出了一些經常使用的類型。
常量 | 說明 |
---|---|
xlBar | 條形圖 |
xlLine | 折線圖 |
xlArea | 面積圖 |
xlPie | 餅圖 |
xlColumn | 柱狀圖 |
xlPyramid | 棱錐圖 |
下面的示例代碼演示了如何設置圖表類型,使用了上圖工作表的數據,指定帶標記的折線圖。
Sub CreateChartSheet() Dim ch As Chart Set ch = ActiveWorkbook.Charts.Add ch.SetSourceData Source:=Worksheets("Sheet1").Range("B3:F6"), PlotBy:=xlRows ch.ChartType = xlLineMarkers End Sub |
生成的圖表如下圖所示。
控制圖表外觀
除了圖表的類型外,還有許多選項用來控制圖表看起來的樣子,其中一些選項僅僅為表現外觀,而另一些選項則表現圖表傳遞給查看者的信息。
1、顯示圖表標題
在圖表上方可以顯示圖表標題。下面列出的Chart對象的兩個屬性控制圖表標題:
- HasTitle屬性。True/False值,指定是否顯示標題。
- ChartTitle,控制標題的詳細信息。
要顯示圖表標題,必須設置ChartTitle對象的屬性並且設置HasTitle為True。下面的代碼在圖表中顯示標題“家電銷售量”:
ch.HasTitle = True ch.ChartTitle.Text = "家電銷售量" |
其中,變量ch引用已經存在的圖表。注意,在設置ChartTitle對象的任何屬性之前,必須將HasTitle屬性設置為True,否則,會發生錯誤。
本例中,簡單地設置圖表標題文本后,將采用默認的字體、位置等設置,可以使用下表列出的ChartTitle對象屬性來修改圖表標題的外觀。
屬性 | 說明 |
---|---|
AutoScaleFont | True/False,指定標題的字體尺寸是否隨圖表尺寸而自動改變。默認值為True。 |
HorizontalAlignment | 指定標題的左-右對齊。設置為xlLeft、xlCenter(默認值)或xlRight |
Left | 從標題的左邊緣到圖表區的左邊緣的距離,以磅為單位 |
Top | 從標題的頂邊緣到圖表區的頂邊緣的距離,以磅為單位 |
Text | 標題的文本。默認為空 |
2、圖表坐標軸文本
大多數Excel圖表都有兩個坐標題,餅圖除外。水平坐標軸是類別軸,垂直坐標軸是數值軸。默認情況下,坐標軸沒有標題,但可以添加標題。
以Chart對象的Axes集合的方式引用圖表的坐標軸。通過使用常量xlCategory和xlValue指定坐標軸。例如,代碼:
圖表對象.Axes(xlCategory) |
引用圖表的類別坐標軸。而代碼:
圖表對象.Axes(xlValue) |
引用數值坐標軸。
要對坐標軸添加標題,設置HasTitle屬性為True,然后使用AxisTitle.Text屬性來設置標題。例如,假設變量ch引用已存在的圖表:
ch.Axes(xlValue).HasTitle=True ch.Axes(xlValue).AxisTitle.Text="銷售量" |
要移除坐標軸標題,只須設置HasTitle屬性為False。要修改已有的坐標軸標題,改變AxisTitle.Text屬性的值。
注意,通過設置HasTitle為False移除坐標軸標題,將徹底刪除標題,而不是簡單地隱藏標題。在試圖處理AxisTitle對象之前,確保設置HasTitle為True,否則會發生錯誤。
下面列出的程序改進了上文中的程序,不僅創建了圖表,而且也添加了圖表標題和坐標軸標題:
Sub CreateEmbeddedChartWithTitles() Dim co As ChartObject Dim ch As Chart Set co = Worksheets("Sheet1").ChartObjects.Add(50, 100, 250, 165) Set ch = co.Chart ch.SetSourceData Source:=Worksheets("Sheet1").Range("B3:F6"), PlotBy:=xlRows '添加圖表標題 ch.HasTitle = True ch.ChartTitle.Text = "家電銷售量" '添加類別軸標題 ch.Axes(xlCategory).HasTitle = True ch.Axes(xlCategory).AxisTitle.Text = "期間" '添加數值軸標題 ch.Axes(xlValue).HasTitle = True ch.Axes(xlValue).AxisTitle.Text = "銷售量" End Sub |
結果如下圖所示。
處理圖表中的字體
可以編寫VBA代碼來修改圖表中任何文本的字體。與特定項(圖表標題、坐標軸標題等)相關的Font對象控制文本外觀。圖表中的文本項和相關的Font對象如下表所示。
文本項 | FONT對象 |
---|---|
圖表標題 | Chart.ChartTitle.Font |
類別坐標軸標題 | Chart.Axes(xlCategory).AxisTitle.Font |
數值坐標軸標題 | Chart.Axes(xlValue).AxisTitle.Font |
圖例文本 | Chart.Legend.Font |
類別坐標軸刻度標簽 | Chart.Axes(xlCategory).TickLabels.Font |
數值坐標軸刻度標簽 | Chart.Axes(xlValue).TickLabels.Font |
上表列出的所有對象都有AutoScaleFont屬性,默認值為True,表明當圖表尺寸改變時字體尺寸自動改變。因此,設置字體尺寸僅僅設置了當時相對於圖表尺寸的初始字體尺寸,如果圖表本身調整的話,實際字體尺寸也變化。
下面的代碼修改圖表標題為14磅Arial類型的粗體。
With 圖表對象.ChartTitle.Font .Name="Arial" .Bold=True .Size=14 End With |
下面的代碼將圖表圖例文本修改為10磅、紅色的Times New Roman字體。
With 圖表對象.Legend.Font .Name="Times New Roman" .Color=RGB(255,0,0) .Size=10 End With |
下表列出了Font對象通常使用的屬性。
屬性 | 說明 |
---|---|
Bold | True/False,指定字體是否為粗體。 |
Color | 字體的顏色,一個RGB值。 |
Italic | True/False,指定字體是否為斜體。 |
Name | 字體的名字。 |
下面的代碼對上文中的示例作了進一步的改進,修改了字體以獲得更好的外觀。
Sub CreateEmbeddedChart() Dim co As ChartObject Dim ch As Chart Set co = Worksheets("Sheet1").ChartObjects.Add(50, 100, 250, 165) Set ch = co.Chart ch.SetSourceData Source:=Worksheets("Sheet1").Range("B3:F6"), PlotBy:=xlRows '添加圖表標題 ch.HasTitle = True ch.ChartTitle.Text = "家電銷售量" '修改字體 With ch.ChartTitle.Font .Name = "Arial" .Size = 14 .Color = RGB(0, 0, 255) End With '添加類別坐標軸標題並設置其字體. '同時修改刻度標簽. With ch.Axes(xlCategory) .HasTitle = True .AxisTitle.Text = "期間" .AxisTitle.Font.Name = "Arial" .AxisTitle.Font.Size = 10 .TickLabels.Font.Name = "Arial" .TickLabels.Font.Size = 8 End With '添加數值坐標軸標題並設置其字體. '同時修改刻度標簽的字體. With ch.Axes(xlValue) .HasTitle = True .AxisTitle.Text = "銷售量" .AxisTitle.Font.Name = "Arial" .AxisTitle.Font.Size = 10 .TickLabels.Font.Name = "Arial" .TickLabels.Font.Size = 8 End With '修改圖例字體 With ch.Legend.Font .Name = "Arial" .Size = 10 .Color = RGB(255, 0, 0) End With End Sub |
結果如下圖所示。
ChartWizard方法
如果你在Excel中創建過圖表,那么可能使用過圖表向導。在經過一系列的對話框選擇后,創建圖表。這對應於VBA中的ChartWizard方法。ChartWizard方法指定圖表數據、圖表類型、以及圖表的外觀。有時,使用該方法比每次分別設置Chart對象的單個屬性更容易。ChartWizard方法的語法如下:
圖表對象.ChartWizard(Source,Gallery,Format,PlotBy, _ CategoryLabels,SeriesLabels,HasLegend,Title,CategoryTitle,ValueTitle,ExtraTitle) |
其中,參數Source指定繪制圖表的數據區域,Range對象。
參數Gallery是一個xlChartType常量,指定圖表的類型:xlArea、xlBar、xlColumn、xlLine、xlPie、xlRadar、xlXYScatter、xlCombination、xl3DArea、xl3DBar、xl3DColumn、xl3DLine、xl3DPie、xl3DSurface、xlDoughnut、xlDefaultAutoFormat。
參數Format是一個1-n范圍的數字值,指定內置的自動格式或者圖表子類型。自動格式的類型和數值,n的最大值取決於參數Gallery。
參數PlotBy,取值為xlRows(默認值)或者xlColumns,指定數據系列是行還是列。
參數CategoryLabels,包含分類標簽的列數(如果PlotBy=xlRows)或者行數(如果PlotBy=xlColumns)。
參數SeriesLabels,包含數據系列標簽的行數(如果PlotBy=xlRows)或者列數(如果PlotBy=xlColumns)。
參數HasLegend,包括圖例時值為True,否則為False。默認值為True。
參數Title,圖表的標題文本。默認沒有標題。
參數CategoryTitle,分類坐標軸標題文本。默認沒有標題。
參數ValueTitle,數值坐標軸標題文本。默認沒有標題。
命名和引用圖表
- 在創建圖表工作表時,Excel自動為圖表命名,默認的名字是Chart1、Chart2,等等。同樣,嵌入式圖表也被賦予了名字,默認為圖表 1、圖表 2,等等,注意數字之前有一個空格。
- 通過給Name屬性賦新的名字,能夠重命名ChartObject對象。
- 使用Workbook對象的Charts屬性引用一個已存在的圖表工作表。Charts屬性返回一個集合,包含工作簿中每個圖表工作表,可以通過在集合中的位置來引用圖表工作表,但通過圖表工作表的名字來引用可能更好一些:
Charts(圖表工作表名稱)
例如,下面的代碼打印指定的圖表工作表:
Charts("銷售圖表").PrintOut
- 要引用指定的嵌入式圖表,必須使用ChartObject對象。例如,下面的代碼刪除工作表Sheet1中指定的圖表:
Worksheets("Sheet1").ChartObjects("匯總圖").Delete
鎖定圖表
默認情況下,用戶可以修改Excel中的圖表,然而有時我們可能不想讓用戶對圖表作修改。這時,可以鎖定或保護圖表,使得不能修改圖表,但仍然能夠查看和打印圖表。
要鎖定和保護圖表,調用Chart對象的Protect方法:
圖表對象.Protect(password) |
其中,參數password可選,用於指定保護密碼。
下面的代碼取消對圖表的保護:
圖表對象.UnProtect(password) |
ChartObject對象
ChartObject對象代表嵌入式圖表,除圖表本身的特性外,還控制着圖表的位置和大小。下表列出了ChartObject對象的屬性和方法。
屬性 | 說明 |
---|---|
BottomRightCell | 返回Range對象,引用圖表右下角的工作表單元格。只讀 |
Chart | 返回對包含的圖表的引用 |
Height | 圖表的高度,以磅為單位 |
Left | 圖表左側相對於工作表左邊緣的位置,以磅為單位 |
Placement | 指定ChartObject如何粘附於其下方的工作表單元格。允許設置值為xlMoveAndSize、xlMove、xlFreeFloating |
PrintObject | 如果為True(默認),那么在打印工作表時打印圖表。如果為False,則不打印圖表 |
Top | 圖表頂部相對於工作表頂部的位置,以磅為單位 |
TopLeftCell | 返回Range對象,引用圖表左上角的工作表單元格。只讀 |
Visible | True/False,指定圖表是否可見 |
Width | 圖表的寬度,以磅為單位 |
方法 | 說明 |
---|---|
BringToFront | 在所有重疊的圖表上方顯示圖表 |
Copy | 將ChartObject復制到Windows剪貼板 |
CopyPicture | 復制圖表的圖像到Windows剪貼板 |
Cut | 將ChartObject剪切到Windows剪貼板 |
Delete | 刪除ChartObject |
SendToBack | 在所有重疊的圖表后面顯示圖表 |
當添加或刪除嵌入式圖表下方區域的單元格時,Placement屬性起作用。例如,假設圖表跨列B至列F,在該區域插入兩個新列,此時的結果取決於Placement屬性的設置:
- xlMoveAndSize。圖表的大小和位置改變以適應添加或刪除的行/列。
- xlMove。圖表的位置改變以適應添加或刪除的行/列,但大小保持不變。
- xlFreeFloating。大小和位置都不會發生改變。
下面的示例程序演示了ChartObject的一些屬性和方法。程序遍歷當前工作簿中的所有工作表,將所有嵌入式圖表復制到新工作表中,並且程序指定了新工作表的名字以及所復制的圖表的大小。
- 使用Worksheets.Add方法在工作簿中添加新工作表。
- 設置新工作表的Name屬性。
- 遍歷工作簿的Worksheets集合。
- 檢查每個工作表的Name屬性,以避免處理新工作表。
- 遍歷每個工作表的ChartObjects集合。
- 使用Copy方法復制每個ChartObject到剪貼板。
- 使用Worksheet.Paste方法將ChartObject粘貼到新工作表中。
示例程序清單如下:
Sub CopyEmbeddedChartsToNewSheet(name As String, width As Integer, height As Integer) '復制當前工作簿中所有嵌入式圖表到指定名稱的新工作表 '復制的圖表指定了寬度和高度並且在單列中排列 '圖表之間的垂直距離 Const SPACE_BETWEEN_CHARTS = 20 Dim newWS As Worksheet Dim oldWS As Worksheet Dim co As ChartObject Dim yPos As Integer Dim count As Integer '關閉屏幕更新,避免在復制圖表時屏幕閃爍 Application.ScreenUpdating = False '添加和命名新工作表 Set newWS = Worksheets.Add newWS.name = name For Each oldWS In Worksheets '不要從新工作表中復制 If oldWS.name <> name Then '遍歷該工作表中的ChartObjects For Each co In oldWS.ChartObjects '復制到剪貼板 co.Copy newWS.Range("A1").Select '粘貼到新工作表 newWS.Paste Next End If Next '圖表的位置和大小 count = 0 For Each co In newWS.ChartObjects co.width = width co.height = height '距工作表左邊緣的距離 co.Left = 30 '距工作表頂部的距離 co.Top = count * (height + SPACE_BETWEEN_CHARTS) + SPACE_BETWEEN_CHARTS count = count + 1 Next '打開屏幕更新 Application.ScreenUpdating = True End Sub Sub TestCopyEmbeddedCharts() CopyEmbeddedChartsToNewSheet "所有圖表", 240, 140 End Sub |
在程序代碼中,每次粘貼操作之前為什么要選擇新工作表中的單元格A1,這是因為當粘貼圖表到工作表中時,會選擇所粘貼的圖表。此時,當試圖粘貼下一圖表時,Excel會認為要將其粘貼到所選擇的圖表中,這會導致錯誤。
由於CopyEmbeddedChartsToNewSheet過程包含參數,因此不能直接調用該過程,必須從另一過程調用。
程序運行后的結果如下圖所示。
使用散點圖
散點圖,又稱作XY圖,不同於Excel中的其他類型的圖表。大多數圖表根據分類繪制數值,而散點圖繪制值對,水平軸和垂直軸都是值。很多情形都適合於用散點圖來表現。
散點圖中的每一點都有X值和Y值,X值決定點的水平位置,Y值決定點的垂直位置。
散點圖的數據組織與其他圖表類型的數據類似,不同點在於分類標簽被X值取代。下圖所示的工作表中為准備繪制散點圖的數據,第1列包含的是X值,另外2列包含的是Y值。
創建散點圖的VBA代碼不同於創建其他類型的圖表,必須指定源數據區域和圖表類型,也可以應用可選的格式諸如圖表和坐標軸標簽。下面是基於上圖所示的數據創建的嵌入式散點圖的VBA代碼:
Sub CreateScatterChart() Dim co As ChartObject Dim ch As Chart Set co = Worksheets("Sheet2").ChartObjects.Add(50, 200, 250, 165) Set ch = co.Chart ch.SetSourceData Source:=Worksheets("Sheet2").Range("B3:D9"), PlotBy:=xlColumns ch.ChartType = xlXYScatterLines '添加圖表標題 ch.HasTitle = True ch.ChartTitle.Text = Worksheets("Sheet2").Range("A1").Value '添加分類軸標題 With ch.Axes(xlCategory) .HasTitle = True .AxisTitle.Text = "相對人數" End With '添加數值軸標題 With ch.Axes(xlValue) .HasTitle = True .AxisTitle.Text = "獲勝概率" End With End Sub |
結果如下圖所示。
1、散點圖的類型
Excel支持幾種類型的散點圖,如下表所示。
CHARTTYPE常量 | 說明 | |
---|---|---|
xlXYScatter | 數據點作為標記,沒有線條 | |
xlXYScatterLines | 數據點作為標記,通過直線連接 | |
xlXYScatterLinesNoMarkers | 沒有標記,只是直線 | |
xlXYScatterSmooth | 數據點作為標記,通過平滑線條連接 | |
xlXYScatterSmoothNoMarkers | 沒有標記,通過平滑線條連接數據點 |
2、改變坐標軸區域
觀察上面繪制的散點圖,可能會注意到X軸的刻度不合適,其范圍從0到10而繪制的數據范圍從1到6,結果是圖表區的1/3是空的並且被浪費了,這是Excel的默認情形。下面,我們來改變這種情形。
Axis對象的MaximumScale屬性和MinimumScale屬性控制着坐標軸的最大值和最小值。例如,要設置圖表中數值軸(垂直軸)的比例值,可以編寫下面的代碼:
With 圖表對象.Axes("xlValue") .MinimumScale=5 .MaximumScale=20 End With |
對於上面的程序來說,只需修改水平坐標軸的最小值為1,代碼為:
ch.Axes(xlCategory).MinimumScale = 1 |
將這行代碼插入到設置ChartType屬性的代碼之后。現在,運行程序后的結果如下圖。
注意,即便散點圖中的水平軸不是真正的分類坐標軸,仍然使用xlCategory常量來引用。並且,人工設置坐標軸刻度時,如果最小值太大或者最大值太小,將不會繪制一些數據。
打印圖表
可以使用PrintOut方法來打印Excel圖表。
打印的內容 | 調用 |
---|---|
單個的嵌入式圖表或圖表工作表 | 與相應的Chart對象一致的PrintOut方法 |
工作表中所有的嵌入式圖表(與其他工作表內容一起) | Worksheet對象中的PrintOut方法 |
活動工作表中所有嵌入式圖表(與其他工作表內容一起) | ActiveSheet對象的PrintOut方法 |
工作簿中所有圖表工作表 | 工作簿的Charts集合的PrintOut方法 |
可能已經注意到,沒有直接的方法用來打印工作表中所有嵌入式圖表而不打印其他工作表內容,然而可以使用簡短的VBA代碼來實現,如下所示。
Sub PrintAllEmbeddedChartsOnSheet(ws As Worksheet) '打印指定工作表中所有嵌入式圖表 Dim co As ChartObject For Each co In ws.ChartObjects co.Chart.PrintOut Next End Sub Sub testPrintAllCharts() PrintAllEmbeddedChartsOnSheet ActiveSheet End Sub |
上述過程接受一個工作表變量作為其參數,然后遍歷該工作表的ChartObjects集合,調用每個包含的圖表中的PrintOut方法。如果該工作表沒有包含嵌入式圖表,則不會發生什么。
注意,在打印工作表時,ChartObject的PrintObject屬性決定是否指定的嵌入式圖表與其他工作表內容一起打印。
注:以上內容改編自《Excel Programming Weekend Crash Course》第17章和第18章,由完美Excel(excelperfect.com)整理,僅供學習參考。