返回列表 上一主題 發帖

[發問] 如何應用 VBA 將股票圖完整的呈現出來?

這個也是我一直想了解的, 看看大家是如何解決的
konantw

TOP

回復 17# alexliou
    ActiveSheet.Shapes(chartname).Left = Cells(xRow + cHeight, yCol).Left  
    ActiveSheet.Shapes(chartname).Top = Cells(xRow + cHeight, yCol).Top
這樣的銜接方式蠻不錯的,不僅密合又美觀,再加上
        .Axes(xlValue, xlPrimary).MinimumScale = Int(sMin / 10) * 10
        .Axes(xlValue, xlPrimary).MaximumScale = Int(sMax / 10) * 10
        .Axes(xlValue, xlSecondary).MinimumScale = .Axes(xlValue, xlPrimary).MinimumScale
        .Axes(xlValue, xlSecondary).MaximumScale = .Axes(xlValue, xlPrimary).MaximumScale
的左右對稱,實在太感謝您有這樣的 Idea!

TOP

股票圖表.zip (29.56 KB) 我嘗試把兩個圖表連在一起
Alex

TOP

回復 13# GBKEE
回復 14# alexliou

謝謝兩位的指導與幫忙,到目前為止,對於圖形的表達也有更深層地體會,
事後我會再反覆練習及捉摸體會,再次向兩位說聲 "感激兩位先進"!

TOP

本帖最後由 alexliou 於 2012-4-25 08:24 編輯

回復 11# c_c_lai
1.  先提醒一下
.SeriesCollection.Add Source:=Range("統計圖表!$H$1:統計圖表!$J$" & totalRows)
.SeriesCollection.Add Source:=Range("統計圖表!$G$1:統計圖表!$G$" & totalRows)
這兩行的$H$1和$G$1 要改為 $H$2和$G$2, 要不然會造成和股價資料的不Match
C2會對應到H1和G1
這是因為用  .SeriesCollection.Add 方法時, 它不會幫你考慮到標題列

2.  在這個問題裡, 總共有三個 ChartGroups
第一個是股價開高收低的 漲跌圖 (其實也是折線圖的延伸)
第二個是5MA, 20MA, 60MA的折線圖
第三個是成交量的直條圖
(在成交量直條圖加入後, 直條圖變chartgroups(1), 漲跌圖變chartgroups(2), 折線圖變chartgroups(3),
我猜測 Excel給不同的圖形Type指定不同的優先順序)
       
如果漲跌圖和折線圖如果能共用一個數值座標軸, 而成交量用副座標軸, 那這個問題就算完美解決了       
但我試了幾次, 漲跌圖組一定要獨用一個數值座標軸 (把別的圖組指定使用漲跌圖組的座標軸都會發生錯誤訊息)       
所以均線圖組只能和成交量圖組共用一個座標軸
但這兩組資料的數值大小差異很大
而且均線圖組的座標軸刻度還要和漲跌圖組的座標軸刻度一樣 (看起來才有意義)
       
在這些限制條件下, 單用EXCEL的chart功能, 目前我找不出完美的解決方法
       
3. 另一個方法是把它拆成兩個圖, 漲跌和均線在一個圖上, 成交量在一個圖上, 然後把兩個圖上下連在一起

股票圖表.zip (27.72 KB)

Alex

TOP

回復 12# c_c_lai
在圖表中 數列數大於2才可以指定副座標軸( Y座標)
AxisGroup 屬性XlAxisGroup 可以是這些 XlAxisGroup 常數之一。
xlPrimary             1  ( X座標 )
xlSecondary        2  ( Y座標)
  1. For Each E In ActiveSheet.Shapes
  2.                 If InStr(E.Name, "Option Button") Then
  3.                     If E.OLEFormat.Object.Value = 1 Then 副座標 = E.TopLeftCell(1, 0)
  4.                 End If
  5.             Next
  6.          ' 以上程式碼的目的在尋找 指定為 副座標 數列 的名稱
  7.             For xi = 1 To .SeriesCollection.Count
  8.                 With .SeriesCollection(xi)
  9.                    ' If .Name = "成交量" And .Parent.SeriesCollection.Count > 1 Then .AxisGroup = 2
  10.                     If .Name = 副座標 And .Parent.SeriesCollection.Count > 1 Then .AxisGroup = 2
  11.                     .Border.ColorIndex = Int(55 * Rnd) + 1  '亂數產生數列底色
  12.                     .Border.Weight = xlThin
  13.                     .Border.LineStyle = xlContinuous
  14.                     .MarkerStyle = xlNone
  15.                     .MarkerBackgroundColorIndex = xlNone
  16.                     .MarkerForegroundColorIndex = xlNone
  17.                     .MarkerStyle = xlNone
  18.                     .Smooth = False
  19.                     .MarkerSize = 2
  20.                     .Shadow = False
  21.                 End With
  22.             Next
複製代碼

TOP

回復 10# GBKEE
這些觀念說明對我的確非常有幫助,
上頭我有一些撰寫認知上的瓶頸,請再幫我解惑吧!
謝謝您!

TOP

回復 9# alexliou
我想要表達的是 ( '**************************************************************************************** ):
(1)  Range("統計圖表!$B$1:統計圖表!$B$" & totalRows & ", 統計圖表!$C$1:統計圖表!$F$" & totalRows)  
       是指向 "時間軸、以及  開盤價、最高價、最低價、收盤價" 等。   
(2) Range("統計圖表!$H$1:統計圖表!$J$" & totalRows)
       是分別為 "5MA、20MA、以及 60MA" 等。
(3) Range("統計圖表!$G$1:統計圖表!$G$" & totalRows)
      是為  成交量。

目前我想將  (1) 和 (2) 設成  主座標軸, (3) 想將它設定為 副座標軸。
在此範例中,應如何正確去設定  .SeriesCollection(#).AxisGroup = 1 or 2 呢?
以及應該位在何處宣告始正確得宜?
敬請指教,謝謝您!
  1.     With ActiveChart
  2.         .SetSourceData Source:=Range("統計圖表!$B$1:統計圖表!$B$" & totalRows & ", 統計圖表!$C$1:統計圖表!$F$" & totalRows)
  3.         '.SetSourceData Source:=Range(" 統計圖表!$C$1:統計圖表!$F$" & totalRows)
  4.         ' .ChartType = xlStockVOHLC              ' 股票圖   ( 會造成 記憶體不足 )
  5.         .ChartType = xlStockOHLC                 ' 股票圖
  6.         .SeriesCollection(1).AxisGroup = 1  ' ****************************************************************************************
  7.                           
  8.         .SeriesCollection.Add Source:=Range("統計圖表!$H$1:統計圖表!$J$" & totalRows)
  9.         .SeriesCollection(5).Name = "=統計圖表!$H$1"
  10.         .SeriesCollection(5).ChartType = xlLine
  11.         .SeriesCollection(6).Name = "=統計圖表!$I$1"
  12.         .SeriesCollection(6).ChartType = xlLine
  13.         .SeriesCollection(7).Name = "=統計圖表!$J$1"
  14.         .SeriesCollection(7).ChartType = xlLine
  15.         ' .SeriesCollection(2).AxisGroup = 1 '****************************************************************************************
  16.         
  17.         With .ChartGroups(1)
  18.              .UpBars.Format.Fill.ForeColor.RGB = RGB(255, 0, 0)
  19.              .DownBars.Format.Fill.ForeColor.RGB = RGB(0, 32, 96)
  20.         End With
  21.         
  22.         
  23.         .SeriesCollection.Add Source:=Range("統計圖表!$G$1:統計圖表!$G$" & totalRows)
  24.         .SeriesCollection(8).Name = "=統計圖表!$G$1"
  25.         .SeriesCollection(8).ChartType = xlColumnClustered
  26.         .SeriesCollection(8).AxisGroup = 2 '****************************************************************************************
  27.         
  28.         ' With .ChartGroups(2)      '注意, ChartGroup在插入成交量直條後變成 2 了
  29.         '     .UpBars.Interior.Color = RGB(255, 0, 0)
  30.         '     .DownBars.Interior.Color = RGB(0, 32, 96)
  31.         ' End With
  32.    
  33.                              
  34.         .Axes(xlCategory).CategoryType = xlCategoryScale
  35.         .Axes(xlCategory).TickLabels.NumberFormatLocal = "hh:mm"
  36.         .Axes(xlCategory).MajorTickMark = xlNone
  37.         .Axes(xlCategory).TickLabelPosition = xlLow
  38.             
  39.         .Axes(xlValue).TickLabels.NumberFormatLocal = "0_ "                     ' 代表物件的格式代碼。
  40.    
  41.     End With
複製代碼
執行後,目前圖形變成如下之狀態:

TOP

回復 8# c_c_lai
(1)   E 指的是 D1 往右到最後有資料的範圍 ,  [d1].End(xlToRight)  如工作表上按下 Ctrl+-> 右方向鍵

(2)  Rng(1).Columns(Application.Match(Ar(xi), Rng(1).Rows(1), 0)) 指的是甚麼?   Rng(1).Columns(找到的欄)
Application.Match(Ar(xi), Rng(1).Rows(1), 0)->  工作表Match函數 在 Rng(1).Rows(1)-> Rng(1)的第一列  尋找 Ar(xi)

(3)   .ChartType = xlColumnClustered    有些屬性 並不是所有的圖形  都可以用的

(4) 當圖表不存在時,程式 (制定資料區) 執行到 .ChartObjects.Delete 會產生 "執行階段錯誤 '1004'"
2003版 不會有 是你的版本較嚴謹

(5) 捲軸 可縮短資料數, 直接打上數值也可以縮短資料數.

TOP

本帖最後由 alexliou 於 2012-4-24 18:54 編輯

回復 5# c_c_lai
要增加5MA, 20MA, 50MA就和把成交量加上去一樣
可利用 SeriesCollection.Add 方法
假設5MA, 20MA, 50MA分別在H, I, J 欄

ActiveChart.SeriesCollection.Add Source:=Range("H2:J" & totalrows)
ActiveChart.SeriesCollection(6).ChartType = xlLine
ActiveChart.SeriesCollection(7).ChartType = xlLine
ActiveChart.SeriesCollection(8).ChartType = xlLine

資料序列6,7,8 (即5MA, 20MA, 50MA) 會與資料序列5(成交量)共用副座標軸
但5MA, 20MA, 50MA的刻度應與股價一致
所以需將副座標軸的刻度與主座標軸的刻度設為相同  
缺點是當成交量與股價的規模差太多時  
圖會看起來很奇怪 (所以成交量要取適當的單位, 讓它的值和股價不會差太多)
但我還找不出方法讓5MA, 20MA, 50MA與股價漲跌圖共用同一座標軸
Alex

TOP

        靜思自在 : 待人退一步,愛人寬一寸,就會活得很快樂。
返回列表 上一主題