在excel 的sheet中畫座標軸及函數圖像

一、參數的窗體配置

 

二、窗體中三個按鈕的代碼:

Private Sub CommandButton1_Click()
    Dim X0 As Single, Y0 As Single, X1 As Single, Y1 As Single, X2 As Single, Y2 As Single
    Dim nX1 As Integer, nX As Integer, nY1 As Integer, nY As Integer, nL As Integer, nB As Integer, i As Integer, T1 As Integer
    Dim XLine As Shape, YLine As Shape, MyTextbox As Shape
    Dim ct As Single, M As Byte, MyValue As Single, ModValue As Byte
  
    On Error Resume Next ''忽略錯誤
    ''必要數據判斷
    If Me.TextBox1 = "" Or Int(Me.TextBox1) <> Me.TextBox1 * 1 Or Me.TextBox1 * 1 <= 0 Then MsgBox "請輸入正整數! ", vbInformation: Exit Sub
    If Me.TextBox2 = "" Or Int(Me.TextBox2) <> Me.TextBox2 * 1 Or Me.TextBox2 * 1 <= 0 Then MsgBox "請輸入正整數! ", vbInformation: Exit Sub
    If Me.TextBox3 = "" Or Int(Me.TextBox3) <> Me.TextBox3 * 1 Or Me.TextBox3 * 1 < 0 Then MsgBox "請輸入自然數! ", vbInformation: Exit Sub
    If Me.TextBox4 = "" Or Int(Me.TextBox4) <> Me.TextBox4 * 1 Or Me.TextBox4 * 1 <= 0 Then MsgBox "請輸入正整數! ", vbInformation: Exit Sub
    If Me.TextBox5 = "" Or Int(Me.TextBox5) <> Me.TextBox5 * 1 Or Me.TextBox5 * 1 < 0 Then MsgBox "請輸入自然數! ", vbInformation: Exit Sub
    If Me.TextBox6 = "" Or Int(Me.TextBox6) <> Me.TextBox6 * 1 Or Me.TextBox6 * 1 <= 0 Then MsgBox "請輸入正整數! ", vbInformation: Exit Sub
    If Me.TextBox3 * 1 > Me.TextBox1 * 1 Or Me.TextBox6 * 1 > Me.TextBox2 * 1 Then MsgBox "無效數據!", vbInformation: Exit Sub
 
    Application.ScreenUpdating = False
    ''計算座標軸交點及端點座標,釐米轉換爲磅數,兩端加長畫箭頭
    X0 = Application.CentimetersToPoints(Me.TextBox1)   '橫軸原點的位置

    Y0 = Application.CentimetersToPoints(Me.TextBox2)'縱軸原點的位置
    T1 = Me.TextBox3 * 1
    X1 = X0 - Application.CentimetersToPoints(Me.TextBox3 + VBA.IIf(T1 > 0, 1, 0))  '負軸長爲0時不加長
    X2 = X0 + Application.CentimetersToPoints(Me.TextBox4 + 1)
  
    T1 = Me.TextBox5 * 1
    Y1 = Y0 + Application.CentimetersToPoints(Me.TextBox5 + VBA.IIf(T1 > 0, 1, 0))
    Y2 = Y0 - Application.CentimetersToPoints(Me.TextBox6 + 1)
  
    With ActiveSheet                 'ActiveDocument
        '改名避免重複命名值出錯
        BeforeShapes = .Shapes.Count   ''獲取工作之前的圖形總數
        If BeforeShapes >= 1 Then
              .Shapes.SelectAll: Selection.Delete
        End If

       
        '畫軸
        Set XLine = .Shapes.AddLine(X1, Y0, X2, Y0)
        Set MyTextbox = .Shapes.AddTextbox(msoTextOrientationHorizontal, X2 - 5, Y0 + 2, 10, 15)
        With MyTextbox    ''設置X軸文本框
            .Line.Visible = msoFalse
            .TextFrame.MarginBottom = 0
            .TextFrame.MarginLeft = 0
            .TextFrame.MarginRight = 0
            .TextFrame.MarginTop = 0
            .TextFrame.TextRange.Font.Name = "Arial"
            .TextFrame.TextRange.Font.Size = 10
            .TextFrame.Characters.Text= "x"
        End With
        With XLine    ''設置箭頭形狀
            .Line.EndArrowheadStyle = msoArrowheadTriangle
            .Line.EndArrowheadLength = msoArrowheadLengthMedium
            .Line.EndArrowheadWidth = msoArrowheadWidthMedium
        End With
      
        Set YLine = .Shapes.AddLine(X0, Y1, X0, Y2)
        Set MyTextbox = .Shapes.AddTextbox(msoTextOrientationHorizontal, X0 - 12, Y2 - 5, 10, 15)
        With MyTextbox    ''設置Y軸文本框
            .Line.Visible = msoFalse
            .TextFrame.MarginBottom = 0
            .TextFrame.MarginLeft = 0
            .TextFrame.MarginRight = 0
            .TextFrame.MarginTop = 0
            .TextFrame.TextRange.Font.Name = "Arial"
            .TextFrame.TextRange.Font.Size = 10
           .TextFrame.Characters.Text= "y"
        End With
        With YLine    ''設置箭頭形狀
            .Line.EndArrowheadStyle = msoArrowheadTriangle
            .Line.EndArrowheadLength = msoArrowheadLengthMedium
            .Line.EndArrowheadWidth = msoArrowheadWidthMedium
        End With
        Set MyTextbox = .Shapes.AddTextbox(msoTextOrientationHorizontal, X0 - 10, Y0 - 1, 15, 15)
        With MyTextbox    ''設置原點O文本框
            .Line.Visible = msoFalse
            .TextFrame.MarginBottom = 0
            .TextFrame.MarginLeft = 0
            .TextFrame.MarginRight = 0
            .TextFrame.MarginTop = 0
            .TextFrame.TextRange.Font.Name = "Arial"
            .TextFrame.TextRange.Font.Size = 8
           .TextFrame.Characters.Text= "O"
            .ZOrder msoSendToBack
        End With
      
        ''畫刻度線
        If Me.OptionButton1.Value = True Then Call SelAllShapes: End: Exit Sub '未選刻度值退出
        If Me.OptionButton2.Value = True Then MyValue = 1: ModValue = 1
        If Me.OptionButton3.Value = True Then MyValue = 0.5: ModValue = 2
        If Me.OptionButton4.Value = True Then MyValue = 0.1: ModValue = 10
      
        nX1 = Me.TextBox1 * 1 - Me.TextBox3    '橫軸上第一個刻度的位置
        nY1 = Me.TextBox2 * 1 + Me.TextBox5    '縱軸上第一個刻度的位置  (x0,y0)爲原點
        nL = Me.TextBox3 * ModValue     '橫軸原點處於第多少個刻度的位置
        nB = Me.TextBox5 * ModValue    '縱軸原點處於第多少個刻度的位置
        nX = (Me.TextBox3 * 1 + Me.TextBox4) * ModValue    '橫軸刻度數量
        nY = (Me.TextBox5 * 1 + Me.TextBox6) * ModValue   '縱軸刻度數量
        
        For i = 0 To nX
            M = VBA.IIf(i Mod ModValue = 0, 6, 3)         '整點刻度爲6像素長,非整點刻度爲3像素長
            ct = Application.CentimetersToPoints(nX1 + i * MyValue)
            .Shapes.AddLine ct, Y0 - M, ct, Y0
            If M = 6 And i <> nL Then   ''忽略 0 值(與零點合)
                ''對X軸刻度
                Set MyTextbox = .Shapes.AddTextbox(msoTextOrientationHorizontal, ct - 2, Y0 + 3, 16, 16)
                With MyTextbox    ''設置刻度文本框及值
                    .Line.Visible = msoFalse
                    .TextFrame.MarginBottom = 0
                    .TextFrame.MarginLeft = 0
                    .TextFrame.MarginRight = 0
                    .TextFrame.MarginTop = 0
                    .TextFrame.TextRange.Font.Name = "Arial"
                    .TextFrame.TextRange.Font.Size = 8
                    .TextFrame.Characters.Text= (i - nL) / ModValue
                    .ZOrder msoSendToBack
                End With
            End If
        Next
      
          For i = 0 To nY
            M = VBA.IIf(i Mod ModValue = 0, 6, 3)
            ct = Application.CentimetersToPoints(nY1 - i * MyValue)
            .Shapes.AddLine X0, ct, X0 + M, ct
            If M = 6 And i <> nB Then ''忽略 0 值(與零點合)
               ''對Y軸刻度
                Set MyTextbox = .Shapes.AddTextbox(msoTextOrientationHorizontal, X0 - 12, ct - 8, 16, 16)
                With MyTextbox    ''設置刻度文本框及值
                    .Line.Visible = msoFalse
                    .TextFrame.MarginBottom = 0
                    .TextFrame.MarginLeft = 0
                    .TextFrame.MarginRight = 0
                    .TextFrame.MarginTop = 0
                    .TextFrame.TextRange.Font.Name = "Arial"
                    .TextFrame.TextRange.Font.Size = 8
                    .TextFrame.Characters.Text= (i - nB) / ModValue
                    .ZOrder msoSendToBack
                End With
            End If
        Next
        Call SelAllShapes  ''組合新加的圖形並全選(SelAllShapes)
    End With
    Application.ScreenUpdating = True
    End
End Sub
''----------------------
Private Sub CommandButton2_Click()
    Me.TextBox1 = 10
    Me.TextBox2 = 10
    Me.TextBox3 = 4
    Me.TextBox4 = 4
    Me.TextBox5 = 4
    Me.TextBox6 = 4
    Me.OptionButton1.Value = False
    Me.OptionButton2.Value = True
    Me.OptionButton3.Value = False
    Me.OptionButton4.Value = False
End Sub
''----------------------
 
Private Sub CommandButton3_Click()
    End
End Sub
''----------------------
Private Sub UserForm_Activate()
    Me.TextBox3.SetFocus
    Me.CommandButton1.Default = True
End Sub

 

三、類模塊中的代碼

'* --------------------------------------------------------------------------
'^The Code CopyIn [標準模塊-模塊 1]^'
'* -----------------------------------------------------------------

Public BeforeShapes As Integer
Sub 畫座標系()
    userform1.Show
End Sub
''----------------------
Sub SelAllShapes()
    Dim AllShapes(), ShapeCount As Integer, N As Shape, Y As Integer
    ShapeCount = ActiveSheet.Shapes.Count
    Y = 0
    ''定義一維上標可變數組,從 0 開始
    ReDim AllShapes(ShapeCount - BeforeShapes - 1)
    With ActiveSheet
        For Each N In .Shapes
            If N.Name Like "已有圖形*" = False Then
                AllShapes(Y) = N.Name
                Y = Y + 1
            End If
        Next N
        With .Shapes.Range(AllShapes).Group
            .ZOrder msoSendToBack
            .Select
            ''   .Name = "座標系"
        End With
    End With
End Sub

 

四、繪製函數圖像

第二步:繪製拋物線,適當修改係數、區間及原點位置

 

''----------------------
'在excel中畫拋物線
Sub DrawParabola()
  Dim a As Single, b As Single, c As Single, m As Single, n As Single, x As Single
  Dim sngArray(1 To 100, 1 To 2) As Single
 
  a = 0.5 '係數a,b,c
  b = -1
  c = -1.5
  m = -2.5 '指定區間[m,n]
  n = 4.5
 
  For i = 1 To 100
    x = m + i * (n - m) / 100
    sngArray(i, 1) = CentimetersToPoints(10 + x) '以釐米爲單位,原點位置(10,10)
    sngArray(i, 2) = CentimetersToPoints(10 - (a * x * x + b * x + c))'二次函數解析式
  Next
    '添加貝塞爾曲線
    Activesheet.Shapes.AddCurve SafeArrayOfPoints:=sngArray
End Sub

 

 


 

 

 

 

 

 

發佈了54 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章