ARTICLE · 1130514
用Excel绘制国旗
Option Explicit' =====延时API声明=====#If VBA7 ThenDeclare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)#ElseDeclare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)#End If'============================================================' 绘制中华人民共和国国旗(五星红旗)—— 按《国旗法》标准制图' 【修改版:运行前清空工作表所有形状 + 分步延时绘制】'============================================================Sub DrawNationalFlag()Const GRID As Double = 15 ' 每格边长(点)。改这个值可整体缩放,比例自动保持 3:2Const FLAGW As Double = 30 * GRID ' 旗宽 = 30 格Const FLAGH As Double = 20 * GRID ' 旗高 = 20 格Const DELAY_MS As Long = 800 ' 每步延时毫秒,800=0.8秒;调大更慢,调小变快' =========新增:清空当前工作表全部形状(图形、图片、文本框全部删除)=========Dim shp As ShapeFor Each shp In ActiveSheet.Shapesshp.DeleteNext shpDoEvents' 旗面左上角放到的位置(点,相对 A1 左上角),可自行改大Dim lft As Double, tp As Doublelft = 50tp = 50' ---- 第 1 步:红色旗面矩形 ----Dim rect As ShapeSet rect = ActiveSheet.Shapes.AddShape(msoShapeRectangle, lft, tp, FLAGW, FLAGH)With rect.Fill.ForeColor.RGB = RGB(222, 41, 16) ' 国旗红(约 #DE2910).Line.ForeColor.RGB = RGB(222, 41, 16) ' 边框同色,不露白边.Name = "国旗旗面"End WithDoEventsSleep DELAY_MS ' 暂停,看旗面Debug.Print "已绘制:红色旗面"' 大五角星:中心在格(4.5,4.5),半径 3 格Dim bCx As Double, bCy As Double, bR As DoublebCx = lft + 4.5 * GRIDbCy = tp + 4.5 * GRIDbR = 3 * GRID' ---- 第 2 步:大五角星(一角朝正上方,无需旋转)----Dim s As ShapeSet s = BuildStar(bCx, bCy, bR, 0)s.Name = "大五角星"DoEventsSleep DELAY_MSDebug.Print "已绘制:大五角星"' ---- 第 3 步:四颗小五角星,各有一角尖正对大星中心 ----' 小五角星1:格中心(9.5,1.5),半径 1 格Set s = BuildStar(lft + 9.5 * GRID, tp + 1.5 * GRID, GRID, _StarRotationDeg(bCx, bCy, lft + 9.5 * GRID, tp + 1.5 * GRID))s.Name = "小五角星1"DoEventsSleep DELAY_MSDebug.Print "已绘制:小五角星1"' 小五角星2:格中心(11.5,3.5)Set s = BuildStar(lft + 11.5 * GRID, tp + 3.5 * GRID, GRID, _StarRotationDeg(bCx, bCy, lft + 11.5 * GRID, tp + 3.5 * GRID))s.Name = "小五角星2"DoEventsSleep DELAY_MSDebug.Print "已绘制:小五角星2"' 小五角星3:格中心(11.5,6.5)Set s = BuildStar(lft + 11.5 * GRID, tp + 6.5 * GRID, GRID, _StarRotationDeg(bCx, bCy, lft + 11.5 * GRID, tp + 6.5 * GRID))s.Name = "小五角星3"DoEventsSleep DELAY_MSDebug.Print "已绘制:小五角星3"' 小五角星4:格中心(9.5,8.5)Set s = BuildStar(lft + 9.5 * GRID, tp + 8.5 * GRID, GRID, _StarRotationDeg(bCx, bCy, lft + 9.5 * GRID, tp + 8.5 * GRID))s.Name = "小五角星4"DoEventsSleep DELAY_MSDebug.Print "已绘制:小五角星4"MsgBox "标准国旗绘制完成!", vbInformation, "完成"End Sub'============================================================' 生成一颗黄色正五角星' cx,cy: 中心坐标(点);R: 外接圆半径(点);rotationDeg: 旋转角(度)'============================================================Function BuildStar(cx As Double, cy As Double, R As Double, rotationDeg As Double) As ShapeConst PI As Double = 3.14159265358979Dim rad As Doublerad = 0.381966 * R ' 内接圆半径 = R * (3-√5)/2 ≈ 0.382R' 预计算 10 个顶点(外顶点与内顶点交替,从 -90°即正上方起,每 36° 一个)Dim pts(9, 1) As DoubleDim i As Long, ang As DoubleFor i = 0 To 9ang = (rotationDeg - 90 + i * 36) * PI / 180If i Mod 2 = 0 Thenpts(i, 0) = cx + R * Cos(ang)pts(i, 1) = cy + R * Sin(ang)Elsepts(i, 0) = cx + rad * Cos(ang)pts(i, 1) = cy + rad * Sin(ang)End IfNext i' 用 Freeform 精确描出五角星轮廓(保证各角尖完全标准)Dim fb As FreeformBuilderSet fb = ActiveSheet.Shapes.BuildFreeform(msoEditingAuto, pts(0, 0), pts(0, 1))For i = 1 To 9fb.AddNodes msoSegmentLine, msoEditingAuto, pts(i, 0), pts(i, 1)Next iDim shp As ShapeSet shp = fb.ConvertToShapeWith shp.Fill.ForeColor.RGB = RGB(255, 222, 0) ' 五星黄(约 #FFDE00).Line.ForeColor.RGB = RGB(255, 222, 0)End WithSet BuildStar = shpEnd Function'============================================================' 计算小五角星旋转角(度),使其一个角尖正对大五角星中心'============================================================Function StarRotationDeg(bigCx As Double, bigCy As Double, smallCx As Double, smallCy As Double) As DoubleDim dx As Double, dy As Doubledx = bigCx - smallCxdy = bigCy - smallCy' Excel ATAN2(dx,dy) 返回该向量相对 X 轴的角度(弧度)Dim angRad As DoubleangRad = Application.WorksheetFunction.Atan2(dx, dy)' 转成度,并把默认朝上的尖角转到指向大星方向StarRotationDeg = angRad * 180 / (4 * Atn(1)) + 90End Function