ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] 窗体自定义日期控件

[复制链接]

TA的精华主题

TA的得分主题

发表于 2017-3-23 23:24 | 显示全部楼层 |阅读模式
本帖最后由 marchwen01 于 2017-3-24 08:46 编辑

纯动态添加窗体控件,去除系统控件的兼容问题。原创代码。

QQ截图20170323225010.jpg
QQ截图20170323225446.jpg

自定义日期控件.rar

35.27 KB, 下载次数: 940

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-3-23 23:26 | 显示全部楼层
窗体代码:
窗体名称:UsFormDateControl

  1. Option Explicit

  2. Private clsDC As New DateControl
  3. Private co As New Collection
  4. Public sLabelName As String

  5. '窗体加载
  6. Private Sub UserForm_Initialize()
  7.     With Me
  8.         .Width = 214
  9.     End With
  10.     AddHead Date
  11.     AddLabel_Week
  12.     AddLabel_Day Date
  13.     Me.Controls("ComboBoxYear").SetFocus
  14. End Sub

  15. '添加 头部控件
  16. Private Sub AddHead(ByVal myDate As Date)
  17.     Dim i As Integer
  18.     Dim conCommandButton As MSForms.CommandButton
  19.     Dim conComboBox As MSForms.ComboBox
  20.    
  21.     '添加 年列表 左按钮
  22.     Set conCommandButton = Me.Controls.Add("Forms.CommandButton.1", "Year-")
  23.     With conCommandButton
  24.         .Width = 25
  25.         .Height = 18
  26.         .Caption = "<<<"
  27.     End With
  28.     clsDC.ReceiveCommandButton conCommandButton
  29.     co.Add clsDC
  30.     Set clsDC = Nothing
  31.    
  32.     '添加 年列表
  33.     Set conComboBox = Me.Controls.Add("Forms.ComboBox.1", "ComboBoxYear")
  34.     With conComboBox
  35.         For i = 1900 To 2999
  36.             .AddItem i
  37.         Next
  38.         .Left = 25
  39.         .Width = 60
  40.         .Height = 18
  41.         .Value = Year(myDate)
  42.         .Font.Size = 12
  43.         .ListWidth = 60
  44.         .ColumnWidths = 18
  45.         .Style = fmStyleDropDownList
  46.     End With
  47.     clsDC.ReceiveComboBox conComboBox
  48.     co.Add clsDC
  49.     Set clsDC = Nothing
  50.    
  51.     '添加 年列表 右按钮
  52.     Set conCommandButton = Me.Controls.Add("Forms.CommandButton.1", "Year+")
  53.     With conCommandButton
  54.         .Left = 85
  55.         .Width = 25
  56.         .Height = 18
  57.         .Caption = ">>>"
  58.     End With
  59.     clsDC.ReceiveCommandButton conCommandButton
  60.     co.Add clsDC
  61.     Set clsDC = Nothing
  62.    
  63.     '添加 月列表 左按钮
  64.     Set conCommandButton = Me.Controls.Add("Forms.CommandButton.1", "Month-")
  65.     With conCommandButton
  66.         .Left = 120
  67.         .Width = 25
  68.         .Height = 18
  69.         .Caption = "<<<"
  70.     End With
  71.     clsDC.ReceiveCommandButton conCommandButton
  72.     co.Add clsDC
  73.     Set clsDC = Nothing
  74.    
  75.     '添加 月列表
  76.     Set conComboBox = Me.Controls.Add("Forms.ComboBox.1", "ComboBoxMonth")
  77.     With conComboBox
  78.         For i = 1 To 12
  79.             .AddItem i
  80.         Next
  81.         .Left = 145
  82.         .Width = 40
  83.         .Height = 18
  84.         .Value = Month(myDate)
  85.         .Font.Size = 12
  86.         .ListWidth = 40
  87.         .ColumnWidths = 18
  88.         .Style = fmStyleDropDownList
  89.     End With
  90.     clsDC.ReceiveComboBox conComboBox
  91.     co.Add clsDC
  92.     Set clsDC = Nothing
  93.    
  94.     '添加 月列表 右按钮
  95.     Set conCommandButton = Me.Controls.Add("Forms.CommandButton.1", "Month+")
  96.     With conCommandButton
  97.         .Left = 185
  98.         .Width = 25
  99.         .Height = 18
  100.         .Caption = ">>>"
  101.     End With
  102.     clsDC.ReceiveCommandButton conCommandButton
  103.     co.Add clsDC
  104.     Set clsDC = Nothing
  105. End Sub

  106. '添加星期标签
  107. Private Sub AddLabel_Week()
  108.     Dim iCol As Integer         '列数
  109.     Dim vWeek As Variant        '星期几
  110.     Dim vForeColor As Variant   '前景色(文本颜色)
  111.     '初始化 星期几 数组
  112.     vWeek = WeekName
  113.     '初始化 Label 前景色
  114.     vForeColor = myColor
  115.    
  116.     '添加星期标签
  117.     For iCol = LBound(vWeek) To UBound(vWeek)
  118.         With Me.Controls.Add("Forms.Label.1", vWeek(iCol))
  119.             .Top = 19
  120.             .Left = iCol * 30
  121.             .Width = 30
  122.             .Height = 11
  123.             .Caption = vWeek(iCol)
  124.             .ForeColor = vForeColor(iCol)
  125.             .BorderStyle = fmBorderStyleSingle
  126.         End With
  127.     Next
  128. End Sub

  129. '添加日期标签
  130. Public Sub AddLabel_Day(ByVal myDate As Date)
  131.     Dim i As Long               '循环变量
  132.     Dim iCol As Integer         '列数
  133.     Dim iRow As Integer         '行数
  134.     Dim vForeColor As Variant   '前景色(文本颜色)
  135.     Dim datStartDay As Date     '开始日期
  136.     Dim datLastDay As Date      '结尾日期
  137.     Dim conLabel As control
  138.    
  139.     'Set co = Nothing
  140.    
  141.     '设置窗体的Caption
  142.     Me.Caption = myDate
  143.    
  144.     '删除原有的日期标签
  145.     For Each conLabel In Controls
  146.         If conLabel.Name Like "LabelDay*" Then Controls.Remove conLabel.Name
  147.     Next

  148.     '初始化 Label 前景色
  149.     vForeColor = myColor

  150.     '取得开始日期
  151.     datStartDay = DateSerial(Year(myDate), Month(myDate), 1)
  152.     datStartDay = datStartDay - WeekDay(datStartDay) + 1
  153.     '取得结尾日期
  154.     datLastDay = DateSerial(Year(myDate), Month(myDate) + 1, 0)
  155.     datLastDay = datLastDay + 7 - WeekDay(datLastDay)
  156.    
  157.     For i = datStartDay To datLastDay
  158.         iCol = (i - datStartDay) Mod 7
  159.         iRow = Int((i - datStartDay) / 7)
  160.         Set conLabel = Me.Controls.Add("Forms.Label.1", "LabelDay" & i)
  161.         With conLabel
  162.             .Top = iRow * 13 + 30
  163.             .Left = iCol * 30
  164.             .Width = 30
  165.             .Height = 13
  166.             .Caption = Day(i)
  167.             .Font.Size = 12
  168.             .Font.Bold = True
  169.             .TextAlign = fmTextAlignCenter
  170.             .BorderStyle = fmBorderStyleSingle
  171.             
  172.             '设置前景色,如果日期不在本月的,设成灰色
  173.             If Month(i) = Month(myDate) Then
  174.                 .ForeColor = vForeColor(iCol)
  175.             Else
  176.                 .ForeColor = RGB(150, 150, 150)
  177.             End If
  178.             
  179.             '设置当前日期标签的背景色
  180.             If i = myDate Then
  181.                 .BackColor = RGB(0, 100, 250)
  182.                 sLabelName = .Name      '当前日期标签的名称赋给变量备用
  183.             End If
  184.         End With
  185.         clsDC.ReceiveLabel conLabel
  186.         co.Add clsDC
  187.         Set clsDC = Nothing
  188.     Next
  189.     Me.Height = (iRow + 1) * 13 + 30 + 24
  190. End Sub

  191. '初始化 星期几 数组
  192. Private Function WeekName()
  193.     WeekName = Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六")
  194. End Function

  195. '初始化 前景色
  196. Private Function myColor()
  197.     myColor = Array(vbRed, 0, 0, 0, 0, 0, vbRed)
  198. End Function
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2017-3-24 07:36 来自手机 | 显示全部楼层
要是能加个时间选择就好了。

TA的精华主题

TA的得分主题

发表于 2017-3-24 08:09 | 显示全部楼层
学习大师优秀作品。提个建议:当在窗体上选择【年】或【月】增减时,下面日期立即变动就更完美了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-3-24 08:45 | 显示全部楼层
本帖最后由 marchwen01 于 2017-3-24 08:53 编辑
鄂龙蒙 发表于 2017-3-24 08:09
学习大师优秀作品。提个建议:当在窗体上选择【年】或【月】增减时,下面日期立即变动就更完美了。

本来是这样做的,后来改了一个地方地,结果 ComboBox 的 Change 事件响应了却没更新到,现在可以了。谢谢提醒

现在加了一个选择日期后退出窗体的,这样如果想重选就得重新激活窗体的了。

自定义日期控件.rar

35.54 KB, 下载次数: 627

这是选择日期后退出窗体的

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-3-24 10:46 | 显示全部楼层
类模块代码:
类模块名称:DateControl
  1. Option Explicit

  2. Private WithEvents conLabel As MSForms.Label
  3. Private WithEvents conComboBox As MSForms.ComboBox
  4. Private WithEvents conCommandButton As MSForms.CommandButton

  5. Property Get myDate() As Date
  6.     With UsFormDateControl
  7.         myDate = CDate(.Caption)
  8.     End With
  9. End Property

  10. Public Sub ReceiveLabel(ByVal reLabel As MSForms.Label)
  11.     Set conLabel = reLabel
  12. End Sub

  13. Public Sub ReceiveComboBox(ByVal reComboBox As MSForms.ComboBox)
  14.     Set conComboBox = reComboBox
  15. End Sub

  16. Public Sub ReceiveCommandButton(ByVal reCommandButton As MSForms.CommandButton)
  17.     Set conCommandButton = reCommandButton
  18. End Sub

  19. Private Sub conComboBox_Change()
  20.     With UsFormDateControl
  21.         .AddLabel_Day DateSerial(.Controls("ComboBoxYear").Value, .Controls("ComboBoxMonth").Value, Day(.Caption))
  22.     End With
  23. End Sub

  24. Private Sub conCommandButton_Click()
  25.     Dim iTmp As Integer
  26.     With UsFormDateControl
  27.         Select Case conCommandButton.Name
  28.             Case "Year-"
  29.                 iTmp = .Controls("ComboBoxYear").Value
  30.                 If iTmp <> 1900 Then .Controls("ComboBoxYear").Value = iTmp - 1
  31.             Case "Year+"
  32.                 iTmp = .Controls("ComboBoxYear").Value
  33.                 If iTmp <> 2999 Then .Controls("ComboBoxYear").Value = iTmp + 1
  34.             Case "Month-"
  35.                 iTmp = .Controls("ComboBoxMonth").Value
  36.                 .Controls("ComboBoxMonth").Value = IIf(iTmp - 1 Mod 12, iTmp - 1, 12)
  37.             Case "Month+"
  38.                 iTmp = .Controls("ComboBoxMonth").Value
  39.                 .Controls("ComboBoxMonth").Value = IIf(iTmp Mod 12, iTmp + 1, 1)
  40.         End Select
  41.     End With
  42. End Sub

  43. Private Sub conLabel_Click()
  44.     Dim sTmp As String
  45.    
  46.     With UsFormDateControl
  47.         .Caption = CDate(Replace(conLabel.Name, "LabelDay", ""))
  48.         
  49.         sTmp = .sLabelName
  50.      
  51.         conLabel.BackColor = RGB(0, 100, 250)
  52.         If sTmp <> conLabel.Name And Len(sTmp) > 0 Then
  53.             On Error Resume Next
  54.             .Controls(sTmp).BackColor = RGB(230, 230, 230)
  55.             On Error GoTo 0
  56.         End If
  57.         .sLabelName = conLabel.Name
  58.         
  59.         '如果选中其他月份的标签,重置日期。
  60.         If Month(.Caption) <> Val(.Controls("ComboBoxMonth").Value) Then
  61.             .AddLabel_Day myDate
  62.             .Controls("ComboBoxMonth").Value = Month(.Caption)
  63.         End If
  64.     End With
  65.    
  66.     If TypeName(Selection) = "Range" Then
  67.         Selection = myDate
  68.     End If
  69. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2017-3-24 18:24 | 显示全部楼层
marchwen01 发表于 2017-3-24 10:46
类模块代码:
类模块名称:DateControl

我也学习大师优秀作品。也提个建议:当冻结窗口以后,窗体还能跟随鼠标就更完美了。

TA的精华主题

TA的得分主题

发表于 2017-10-25 14:25 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2019-4-27 11:53 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2019-7-16 22:28 | 显示全部楼层
marchwen01 发表于 2017-3-24 08:45
本来是这样做的,后来改了一个地方地,结果 ComboBox 的 Change 事件响应了却没更新到,现在可以了。谢谢 ...

请问大师,我要把这个自定义控件应用在用户窗体中的文本框中,怎么修改代码?乞求回复,不胜感激!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-17 18:56 , Processed in 0.048325 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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