|
楼主 |
发表于 2021-4-22 11:14
|
显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
因为打包下载后出现问题,所以,这里使用最笨的方法,一点点地上传。
插入一个类模块,命名为:类_日历按钮
然后复制下面的代码到 类_日历按钮 中
Option Explicit
Private WithEvents 类_日按钮 As MSForms.CommandButton
Attribute 类_日按钮.VB_VarHelpID = -1
'
'初始化,将控件绑定到类
Public Sub Init(ctrl_按钮 As MSForms.CommandButton)
Set 类_日按钮 = ctrl_按钮
End Sub
'
'控件的Click事件
Private Sub 类_日按钮_Click()
With 类_日按钮
'将选中的日期传递给 窗体上的文本框
窗体_Main.txb_日.Text = .Caption
Call 模块_日历相关.响应类事件(.Name)
End With
End Sub
'注销类
Private Sub Class_Terminate()
Set 类_日按钮 = Nothing
End Sub
插入一个模块,命名为:模块_日历相关"
然后复制下面的代码到 模块_日历相关
Option Explicit
Private 窗体日历控件_日按钮(1 To 42) As 类_日历按钮
'***************** 响应 类 发来的事件的入口 **********************
Public Sub 响应类事件(ByVal str_Name As String)
Dim int_选中日期 As Integer '记录选中的日期,用于修改年、月后,保持该选中日期
With 窗体_Main
'判断是否为本月:不是本月,则要修改 年、月的 复合框内的信息
'判断依据为字体是否有浅色
If .Controls(str_Name).ForeColor = 8421504 Then
'当字体为浅色时,说明所选的为非本月的日期
int_选中日期 = .Controls(str_Name).Caption
'非本月日期,可能为上个月,也可能为下个有。
'以数字的大小来判断是上个月还是下个月。
If int_选中日期 > 20 Then '此时为上个月
If .复合框_日历_月 = 1 Then
.复合框_日历_月 = 12
.复合框_日历_年 = .复合框_日历_年 - 1
Else
.复合框_日历_月 = .复合框_日历_月 - 1
End If
Else '此时为下个月
If .复合框_日历_月 = 12 Then
.复合框_日历_月 = 1
.复合框_日历_年 = .复合框_日历_年 + 1
Else
.复合框_日历_月 = .复合框_日历_月 + 1
End If
End If
Call 设置背景颜色_选中非本月时(str_Name)
Else
Call 设置背景颜色(str_Name)
End If
End With
End Sub
'选中非本月后,修改选中日的背景颜色
Private Sub 设置背景颜色_选中非本月时(ByVal str_Name As String)
Dim int_首日星期 As Integer
Dim int_位置 As Integer
'获取本月首日的星期
With 窗体_Main
int_首日星期 = Format(.复合框_日历_年 & "/" & .复合框_日历_月 & "/1", "w") '因为系统默认周日是第一天
End With
With 窗体_Main.Controls(str_Name)
'换年、月前,选中的按钮是深色的。将它恢复为非选中色
If .ForeColor = 8421504 Then
.BackColor = vbButtonFace
Else
.BackColor = RGB(204, 204, 204)
End If
End With
'将选中的日期的背景设置为深色
With 窗体_Main
If int_首日星期 = 2 Then
int_位置 = int_首日星期 + CInt(.txb_日.Text) + 5
Else
int_位置 = int_首日星期 + CInt(.txb_日.Text) - 2
End If
.Controls("日" & int_位置).BackColor = -2147483632 '按钮阴影
.Controls("日" & int_位置).SetFocus '获取焦点
End With
End Sub
'设置背景颜色
Private Sub 设置背景颜色(ByVal str_Name As String)
Dim I As Integer
'根据是否为本月日期,重新设置相关按钮的背景色
With 窗体_Main
For I = 1 To 42
With .Controls("日" & I)
'判断是否为本月:即 字体颜色是否为浅色
If .ForeColor = 8421504 Then
.BackColor = vbButtonFace
Else '此时说明字体的颜色不是浅色
.BackColor = RGB(204, 204, 204)
End If
End With
Next
'根据类返回的值,将选中的按钮设置为深色
.Controls(str_Name).BackColor = -2147483632 '按钮阴影
End With
End Sub
'================= 模块响应窗体等发来的事件的入口 ==============
Sub Main(ByVal str_Init As String, ByVal int_年 As Integer, ByVal int_月 As Integer)
Dim I As Integer
If str_Init = "Yes" Then
Call 添加日历_日按钮(0)
Call 添加标签(0)
'向 复合框_日历_年 加入 年信息
With 窗体_Main.复合框_日历_年
For I = 2019 To 2030
.AddItem I
Next
.Value = Year(Date) '设定默认值
End With
'向 复合框_日历_月 加入 月信息
With 窗体_Main.复合框_日历_月
For I = 1 To 12
.AddItem Str(I)
Next
.Value = Month(Date) '设定默认值
End With
Call 设置按钮_显示当前月的日期(int_年, int_月)
Else
Call 设置按钮_显示当前月的日期(int_年, int_月)
End If
End Sub
'
'为按钮设置日期
Private Sub 设置按钮_显示当前月的日期(ByVal int_年 As Integer, ByVal int_月 As Integer)
Dim int_首日星期 As Integer
Dim int_本月总天数 As Integer
Dim int_上月总天数 As Integer
Dim int_开始写入位置 As Integer
'获取本月首日的星期
int_首日星期 = Format(int_年 & "/" & int_月, "w") '因为系统默认周日是第一天
'获取本月的总天数
int_本月总天数 = Format(DateSerial(int_年, int_月 + 1, 1) - 1, "d")
'获取上月的总天数
int_上月总天数 = Format(DateSerial(int_年, int_月, 1) - 1, "d")
'在第一行写入上个月的日期:如果本月的第一天为星期一,则从第二行开始写本月信息
If int_首日星期 = 2 Then
int_开始写入位置 = 设置按钮_写入日期(1, 7, int_上月总天数 - 6, "浅")
Else
int_开始写入位置 = 设置按钮_写入日期(1, int_首日星期 - 2, int_上月总天数 - int_首日星期 + 3, "浅")
End If
'写入本月信息
int_开始写入位置 = 设置按钮_写入日期(int_开始写入位置, int_开始写入位置 + int_本月总天数 - 1, 1, "")
'在剩余位置写入下月日期
Call 设置按钮_写入日期(int_开始写入位置, 42, 1, "浅")
End Sub
'
'为按钮写入日期
Private Function 设置按钮_写入日期(ByVal int_开始位置 As Integer, ByVal int_结束位置 As Integer, ByVal int_开始值 As Integer, ByVal str_色 As String) As Integer
Dim I As Integer
For I = int_开始位置 To int_结束位置
With 窗体_Main.Controls("日" & I)
'With 窗体_Main.Frame_日期选择.Controls("日" & I)
'虽然按钮控件添加到了框架中(Frame),但系统依然认为是窗体内的控件。
'所以,这里可以省略 “.Frame_日期选择”。
'开始时并没有意识到这个,所以仍然添加了“.Frame_日期选择”,后来发现了
'就没有再使用。此处,既然已经写了,就没有删除,而是作为注释标注一下
'以方便初学者。
.Caption = int_开始值
int_开始值 = int_开始值 + 1
If str_色 = "浅" Then
.BackColor = vbButtonFace
.ForeColor = 8421504 '将字体颜色调淡些
Else
.BackColor = RGB(204, 204, 204)
.ForeColor = vbBlack
'设置字体颜色
'因为之前曾调淡了非本月的日期的字体颜色
'所以,当调整年或月时,要重新设置本月的字体颜色
If I Mod 7 = 6 Then '此时为周六
.ForeColor = 32768
ElseIf I Mod 7 = 0 Then '此时为周日
.ForeColor = vbRed '8421631
Else '此时为工作日
.ForeColor = vbBlack
End If
End If
End With
Next
设置按钮_写入日期 = I
End Function
'在日历框架中,添加标识星期的标签
Private Sub 添加标签(ByVal int_T As Integer)
Dim ctrl_标签(1 To 7) As MSForms.Label
Dim str_星期() ' As String
Dim I As Integer
'中文星期
str_星期 = Array("一", "二", "三", "四", "五", "六", "日")
With 窗体_Main.Frame_日期选择.Controls
For I = 1 To 7
Set ctrl_标签(I) = .Add("Forms.label.1", "lbl_" & I)
With ctrl_标签(I)
.Caption = str_星期(I - 1)
.AutoSize = False
.BorderStyle = fmBorderStyleSingle
.BackColor = RGB(204, 204, 204)
.TextAlign = fmTextAlignCenter
.Move (I - 1) * 28, 30, 27, 15
'参数说明:Move [ Left [, Top [, Width [, Height [, Layout ]]]]]
End With
Next
'设置周六和周日的颜色
ctrl_标签(6).BackColor = 32768
ctrl_标签(7).BackColor = 8421631
End With
End Sub
'
Private Sub 添加日历_日按钮(ByVal int_T As Integer)
Dim I As Integer
Dim J As Integer
Dim int_Day As Integer
Dim ctrl_按钮通用 As MSForms.CommandButton ' 通过一个通用的按钮变量,实现动态添加按钮控件
int_Day = 1
For I = 1 To 6
For J = 1 To 7
'添加按钮控件 到相应窗体的框架(Frame)中
Set ctrl_按钮通用 = 窗体_Main.Frame_日期选择.Controls.Add("Forms.CommandButton.1", "日" & int_Day)
'语法:Set Control = object.controls.Add(ProgID [, Name [, Visible ]] )
'语法:Set 控件名 = 对象(这里是容器,如窗体、框架等). Add(“ProgID为VBA常量,可查看微软帮助信息”, “Name最好不要省略,以方便在代码中调用”)
'使用下述代码亦可正常运行,原因不详!
'Set ctrl_按钮通用 = 窗体_Main.Frame_日期选择.Controls.Add("Forms.CommandButton.1", "日" & Str(int_Day))
'设置按钮控件标题和位置
With ctrl_按钮通用
.Caption = int_Day
.Move (J - 1) * 28, (I - 1) * 23 + 45, 28, 21
'参数说明:Move [ Left [, Top [, Width [, Height [, Layout ]]]]]
'设置周六和周日字体颜色
If J = 6 Then
.ForeColor = 32768
ElseIf J = 7 Then
.ForeColor = 128
End If
End With
'创建cCB类实例
Set 窗体日历控件_日按钮(int_Day) = New 类_日历按钮
'将控件赋给类实例
窗体日历控件_日按钮(int_Day).Init ctrl_按钮通用
'最后为 int_Day 赋新值
int_Day = int_Day + 1
Next
Next
End Sub
|
|