ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 7332|回复: 13

借鸡生蛋,手绘"中国"!

[复制链接]

TA的精华主题

TA的得分主题

发表于 2009-7-9 22:26 | 显示全部楼层 |阅读模式
在论坛中,有人问起如何实时得到鼠标的坐标?如何实时手工绘制线条。
经过摸索,终于想到了“借鸡生蛋”的办法。本例中我们所借的"鸡"就是Label控件。
先请看代码:
      '撰写:老朽
      '网址:http://Club.ExcelHome.net
      '日期:2009-7-9 下午 10:24:42

Public X2, Y2
'先手工在工作表中通过控件工具箱插入一个Lable控件,将其设为透明

Private Sub CommandButton1_Click()
    Select
Case CommandButton1.Caption    '一个按钮,根据其显示的文字(Caption)来决定动作
'(本例为一个按钮,三种功效!)
    Case "开始画线"
        If
MsgBox("是否清除当前工作表中的所有线条?", vbYesNo + vbQuestion, "询问:") = vbYes Then
            For Each sh In ActiveSheet.DrawingObjects
                If
sh.Name Like "Line*" Then sh.Delete
            Next

            '使用循环的目的是为了保留Label和按钮
            '否则可以一条语句清除:ActiveSheet.DrawingObjects.Delete
        End If
        X2 = 0: Y2 = 0
        With
Label1
            .Enabled = True
    '设为可用
            .Visible = True     '设为可视
            .Top = 0    '置顶
            .Left = 0    '放置在最左边
            .BackStyle = fmBackStyleTransparent    '设为透明
            .Width = 2400    '设定宽度
            .Height = 2400    '设定高度
            '设定足够的宽度和高度,使之覆盖整个工作表可视范围
            '便于我们画线
        End With
        CommandButton1.Caption = "结束画线"    '改变按钮的显示文字(Caption),为下一个动作作准备
    Case "结束画线"
        With
Label1
            .Enabled = False
    '禁用Label
            .Visible = False     '不可见
        End With
        Application.StatusBar = ""    'Label已经不可用,所以得及时将状态栏清空,
        '否则还是一直显示Label禁用之前的坐标,造成误会
        CommandButton1.Caption = "显示坐标"
    Case
"显示坐标"
        With
Label1
            .Enabled = True

            .Visible = True
            .Top = 0
            .Left = 0
            .BackStyle = fmBackStyleTransparent
            .Width = 2400
            .Height = 2400
        End
With
        CommandButton1.Caption = "开始画线"
    End
Select
End Sub


Private Sub Label1_MouseDown(ByVal Button As Integer , ByVal Shift As Integer , ByVal X As Single , ByVal Y As Single )
    Application.ScreenUpdating = False

    If CommandButton1.Caption = "结束画线" Then
        Label1.Visible = False     '暂时不显示Label,以便能实时看到我们所绘的图形
        X2 = IIf(X2 = 0, X, X2)    '起点X座标,刚刚启动绘图时,X为0,
        Y2 = IIf(Y2 = 0, Y, Y2)    '起点Y座标
        ActiveSheet.Shapes.AddLine(X2, Y2, X, Y).Select    '绘制一条直线,使用Select方法是便于用户实时看到节点位置,
        '当然,我们完全可以通过 Set cc=ActiveSheet.Shapes.AddLine(X2, Y2, X, Y),这样用户将不能实时看到所绘线条的节点
        X2 = X: Y2 = Y    '将本次XY坐标作为下次的起点坐标
        Label1.Visible = True
    Else                         '有人可能会以为下面两行代码是画蛇添足
        Label1.Visible = False   '非也,通过以下步骤,可以快速返回控制权,否则较长时间内显示为空白
        Label1.Visible = True
    End If
    Application.ScreenUpdating = True
End Sub

Private Sub Label1_MouseMove(ByVal Button As Integer , ByVal Shift As Integer , ByVal X As Single , ByVal Y As Single )
'利用Label的MouseMove事件,得到X,Y坐标,将其显示在状态栏中

    Application.StatusBar = "当前坐标 X:" & X & "  Y:" & Y
End Sub


[ 本帖最后由 zldccmx 于 2009-7-9 22:34 编辑 ]

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-7-9 22:31 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
借鸡生蛋.PNG
这是效果图
手绘中国.rar (15.26 KB, 下载次数: 75)
这是附件!
手绘中国(自动封闭).rar (19.04 KB, 下载次数: 84)

[ 本帖最后由 zldccmx 于 2009-7-10 00:53 编辑 ]

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-7-9 22:39 | 显示全部楼层
代码并不复杂,关键是思路。思路到了,问题也就迎刃而解了!

TA的精华主题

TA的得分主题

发表于 2009-7-9 22:51 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-7-9 23:55 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
原帖由 bibisin 于 2009-7-9 22:51 发表
谢谢LZ分享
就是在封口的时候效果不好


呵呵,这个嘛,如果要强行封闭,是有办法的!

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-7-10 00:50 | 显示全部楼层
呵呵,受到奖励,更有动力了!经过进一步完善,增加了点右键自动封闭功能!

      '原创:老朽
      '网址:http://Club.ExcelHome.net
      '日期:2009-7-10 上午 12:45:19

Public X2, Y2, X0, Y0

'先手工在工作表中通过控件工具箱插入一个Lable控件

Private Sub CommandButton1_Click()
    Select
Case CommandButton1.Caption    '一个按钮,根据其显示的文字(Caption)来决定动作
'(本例为一个按钮,三种功效!)
    Case "开始画线"
        If
MsgBox("是否清除当前工作表中的所有线条?", vbYesNo + vbQuestion, "询问:") = vbYes Then
            For Each sh In ActiveSheet.DrawingObjects
                If
sh.Name Like "Line*" Then sh.Delete
            Next

            '使用循环的目的是为了保留Label和按钮
            '否则可以一条语句清除:ActiveSheet.DrawingObjects.Delete
        End If
        X2 = 0: Y2 = 0
        With
Label1
            .Enabled = True
    '设为可用
            .Visible = True     '设为可视
            .Top = 0    '置顶
            .Left = 0    '放置在最左边
            .BackStyle = fmBackStyleTransparent    '设为透明
            If .Width <> 2400 Then .Width = 2400    '设定宽度= 2400
            If .Height <> 2400 Then .Height = 2400    '设定高度= 2400
            '设定足够的宽度和高度,使之覆盖整个工作表可视范围
            '便于我们画线
        End With
        CommandButton1.Caption = "结束画线"    '改变按钮的显示文字(Caption),为下一个动作作准备
    Case "结束画线"
        With
Label1
            .Enabled = False
    '禁用Label
            .Visible = False     '不可见
        End With
        Application.StatusBar = ""    'Label已经不可用,所以得及时将状态栏清空,
        '否则还是一直显示Label禁用之前的坐标,造成误会
        CommandButton1.Caption = "显示坐标"
    Case
"显示坐标"
        With
Label1
            .Enabled = True

            .Visible = True
            .Top = 0
            .Left = 0
            .BackStyle = fmBackStyleTransparent
            If
.Width <> 2400 Then .Width = 2400
            If
.Height <> 2400 Then .Height = 2400
        End
With
        CommandButton1.Caption = "开始画线"
    End
Select
End Sub

Private Sub Label1_MouseDown(ByVal Button As Integer , ByVal Shift As Integer , ByVal X As Single , ByVal Y As Single )
    Application.ScreenUpdating = False

    If Button = 1 Then
        If CommandButton1.Caption = "结束画线" Then
            Label1.Visible = False     '暂时不显示Label,以便能实时看到我们所绘的图形
            '记录封闭点坐标
            X0 = IIf(X2 = 0, X, X0)    '原始起点X座标,刚刚启动绘图时,X2为0,
            Y0 = IIf(Y2 = 0, Y, Y0)    '原始起点Y座标
            X2 = IIf(X2 = 0, X, X2)    '起点X座标,刚刚启动绘图时,X2为0,
            Y2 = IIf(Y2 = 0, Y, Y2)    '起点Y座标
            ActiveSheet.Shapes.AddLine(X2, Y2, X, Y).Select    '绘制一条直线,使用Select方法是便于用户实时看到节点位置,
            '当然,我们完全可以通过 Set cc=ActiveSheet.Shapes.AddLine(X2, Y2, X, Y),这样用户将不能实时看到所绘线条的节点
            X2 = X: Y2 = Y    '将本次XY坐标作为下次的起点坐标
            Label1.Visible = True
        Else                         '有人可能会以为下面两行代码是画蛇添足
            Label1.Visible = False   '非也,通过以下步骤,可以快速返回控制权,否则较长时间内显示为空白
            Label1.Visible = True  '感兴趣的朋友可以不加这两行代码试验一下
        End If
    Else '如果按下的不是鼠标左键
        ActiveSheet.Shapes.AddLine(X2, Y2, X0, Y0).TopLeftCell.Activate    '强行封闭,焦点转移到工作表,避免线条处于选中状态
        CommandButton1_Click '结束画线
    End If
    Application.ScreenUpdating = True
End Sub

Private Sub Label1_MouseMove(ByVal Button As Integer , ByVal Shift As Integer , ByVal X As Single , ByVal Y As Single )
'利用Label的MouseMove事件,得到X,Y坐标,将其显示在状态栏中

    Application.StatusBar = "当前坐标 X:" & X & "  Y:" & Y
End
Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-7-10 00:55 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
原帖由 bibisin 于 2009-7-9 22:51 发表
谢谢LZ分享
就是在封口的时候效果不好


根据你的提醒,重新修订了代码 在 7楼
并补充了附件,在 2 楼

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-7-10 00:58 | 显示全部楼层
在绘图过程中,点右键则自动封闭!

封闭时,鼠标尽量不要停留在其它控件上,否则会弹出右键菜单,不过这时你按一下ESC键就OK
老朽没有禁用工作表的鼠标右键功能,不想太霸道,呵呵。

TA的精华主题

TA的得分主题

发表于 2009-7-10 19:01 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2009-7-11 09:13 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
楼主真是一高人啊。否能交个朋友
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-27 04:03 , Processed in 0.054162 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表