快速浏览
实用案例
|日期控件||简单的收发存||收费管理系(Access改进版)|
|中医诊所收费系统(Excel版)||中医诊所收费系统(Access版)||银行对账单自动勾对|
收费使用项目
|财务管理系统||工资薪金和年终奖个税筹划||新税法下工资表模版|
内容提要
客户销售额查询分析(更新)|完整代码
1、在工作表“统计查看”里,工作表Selection Change事件,设置单元格数据验证;命令按钮点击事件,提取数据并写入工作表;自定义函数getData,根据年度从字典中提取数据到数组temp:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim arr()
If Target.Address = "$G$2" Then
Call checkDic
arr = dicYear.keys
Call SetDataValidation(arr, Target)
End If
End Sub
Private Sub CmdSum_Click()
Dim i As Integer, j As Integer
Dim rng As Range
Dim currYear As String
Dim temp, iRow As Integer, iCol As Integer
Dim dkey, sortType As String, sortKey As Range, strOrder As String, orderType As Integer
Call checkDic
currYear = Range("G2").Value
sortType = Range("J2").Value
strOrder = Range("L2").Value
iRow = UsedRange.Rows.Count
If iRow > 3 Then
Cells(4, 1).Resize(iRow, UsedRange.Columns.Count).Clear
End If
temp = getData(currYear)
iRow = UBound(temp)
iCol = UBound(temp, 2)
Set rng = Cells(3, 1).Resize(iRow, iCol)
With rng
.Value = temp
.Borders.LineStyle = 1
.Offset(1, 1).NumberFormat = "_ * #,##0.00_ ;_ * -#,##0.00_ ;_ * ""-""??_ ;_ @_ "
.Columns(iCol).Offset(1).NumberFormat = "_ * #,##0.00_ 元;_ * -#,##0.00_ 元;_ * ""-""??_ 元;_ @_ 元"
.Columns.AutoFit
'//排序
If sortType = "客户" Or sortType = "合计" Then
If sortType = "客户" Then
Set sortKey = .Columns(1)
Else
Set sortKey = .Columns(.Columns.Count)
End If
If strOrder = "降序" Then
orderType = 2
Else
orderType = 1
End If
.Resize(.Rows.Count - 1, .Columns.Count).Sort key1:=sortKey, Order1:=orderType, _
Header:=xlYes, OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End With
End Sub
Private Function getData(currYear As String) As Variant
Dim i As Integer, j As Integer
Dim temp(), iRow As Integer, iCol As Integer
Dim dkey
Call checkDic
iRow = dic.Count + 2
iCol = 14
ReDim temp(1 To iRow, 1 To iCol)
For i = 1 To 12
temp(1, i + 1) = monthText(i, 1)
Next
temp(1, 1) = "客户名称"
temp(1, iCol) = "合计"
temp(iRow, 1) = "合计"
i = 1
For Each dkey In dic.keys
i = i + 1
temp(i, 1) = dkey
If dic(dkey).exists(currYear) Then
For j = 1 To 12
temp(i, j + 1) = dic(dkey)(currYear)(j)
temp(iRow, j + 1) = temp(iRow, j + 1) + temp(i, j + 1)
temp(i, iCol) = temp(i, iCol) + temp(i, j + 1)
temp(iRow, iCol) = temp(iRow, iCol) + temp(i, j + 1)
Next
End If
Next
getData = temp
End Function
2、在工作表“客户单月数据”里,命令按钮点击事件;工作表Change事件,工作表Selection Change事件;ComboBox的Change事件,下拉箭头点击事件,addCombList自定义过程,添加List;getData自定义过程:
Private Sub CmdGetData_Click()
Call getDic
Call getData
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim arr(), key As Variant
Dim i As Long
Dim customer As String, currYear As String, preYear As String
Dim currMonth As Integer
Debug.Print Target.Address
If Target.Address = "$C$3" Or Target.Address = "$C$4" Or Target.Address = "$F$4" Then
Call getData
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim arr()
If Target.Address = "$C$3:$E$3" Or Target.Address = "$C$4" Or Target.Address = "$F$4" Then
Call checkDic
End If
If Target.Address = "$C$4" Or Target.Address = "$F$4" Then
Call checkDic
arr = dicYear.keys
Call SetDataValidation(arr, Target)
End If
End Sub
Private Sub ComboBox1_Change()
Call addCombList
Range("C3").Value = Me.ComboBox1.Text
End Sub
Private Sub addCombList()
Dim currValue As String
Dim arr(), temp(), sList As Object
Dim listCount As Integer
Set sList = CreateObject("System.Collections.SortedList")
currValue = Me.ComboBox1.Text
Call checkDic
arr = dic.keys
For i = 0 To UBound(arr)
If InStr(arr(i), currValue) > 0 Then
sList(arr(i)) = ""
listCount = listCount + 1
End If
Next
If listCount > 0 Then
ReDim temp(listCount - 1)
For i = 0 To listCount - 1
temp(i) = sList.getkey(i)
Next
Me.ComboBox1.List = temp
Else
Set sList = CreateObject("System.Collections.SortedList")
For i = 0 To UBound(arr)
sList(arr(i)) = ""
Next
For i = 0 To UBound(arr)
arr(i) = sList.getkey(i)
Next
Me.ComboBox1.List = arr
End If
End Sub
Private Sub ComboBox1_DropButtonClick()
With Me.ComboBox1
If .listCount = 0 Then
Call checkDic
End If
End With
Call addCombList
End Sub
Private Sub getData()
Dim arr(), key As Variant
Dim i As Long
Dim customer As String, currYear As String, preYear As String
Dim currMonth As Integer
customer = Range("C3").Value
currYear = Range("C4")
preYear = Range("F4")
Range("C6").Resize(12, 1) = 0
Range("F6").Resize(12, 1) = 0
Call checkDic
If dic.exists(customer) Then
'//左边年度
If dic(customer).exists(currYear) Then
i = 0
ReDim arr(1 To 12, 1 To 2)
For Each key In dic(customer)(currYear).keys
currMonth = key
i = i + 1
arr(i, 1) = monthText(currMonth, 2)
arr(i, 2) = dic(customer)(currYear)(key)
Next
Range("B6").Resize(12, 2) = arr
End If
'//右边年度
If dic(customer).exists(preYear) Then
i = 0
ReDim arr(1 To 12, 1 To 2)
For Each key In dic(customer)(preYear).keys
currMonth = key
i = i + 1
arr(i, 1) = monthText(currMonth, 2)
arr(i, 2) = dic(customer)(preYear)(key)
Next
Range("E6").Resize(12, 2) = arr
End If
End If
End Sub
Option Explicit
Public dic As Object
Public dicYear As Object
Sub getDic()
Dim i As Long, j As Long
Dim key1, key2, key3
Dim ws As Worksheet
Dim arr(), customer, currYear As String, currMonth As Integer
Dim sales As Double
Set dic = CreateObject("Scripting.Dictionary")
Set dicYear = CreateObject("Scripting.Dictionary")
For Each ws In ThisWorkbook.Sheets
With ws
If InStr(.Range("A1"), "年销售数据") > 0 Then
arr = .Range("A1").CurrentRegion
For i = 3 To UBound(arr)
customer = arr(i, 1)
currYear = Year(arr(i, 2)) & "年"
currMonth = Month(arr(i, 2))
sales = arr(i, 8)
dicYear(currYear) = ""
If Not dic.exists(customer) Then
Set dic(customer) = CreateObject("Scripting.Dictionary")
End If
If Not dic(customer).exists(currYear) Then
Set dic(customer)(currYear) = CreateObject("Scripting.Dictionary")
For j = 1 To 12
dic(customer)(currYear)(j) = 0
Next
End If
dic(customer)(currYear)(currMonth) = dic(customer)(currYear)(currMonth) + sales
Next
End If
End With
Next
End Sub
Sub checkDic()
If dic Is Nothing Or dicYear Is Nothing Then
Call getDic
ElseIf dic.Count = 0 Or dicYear.Count = 0 Then
Call getDic
End If
End Sub
Function monthText(currMonth As Integer, Optional mType As Integer = 0)
If mType = 0 Then
Select Case currMonth
Case Is = 1
monthText = "一月"
Case Is = 2
monthText = "二月"
Case Is = 3
monthText = "三月"
Case Is = 4
monthText = "四月"
Case Is = 5
monthText = "五月"
Case Is = 6
monthText = "六月"
Case Is = 7
monthText = "七月"
Case Is = 8
monthText = "八月"
Case Is = 9
monthText = "九月"
Case Is = 10
monthText = "十月"
Case Is = 11
monthText = "十一月"
Case Is = 12
monthText = "十二月"
Case Else
monthText = "无效月份"
End Select
ElseIf mType = 1 Then
Select Case currMonth
Case Is = 1
monthText = "一月份"
Case Is = 2
monthText = "二月份"
Case Is = 3
monthText = "三月份"
Case Is = 4
monthText = "四月份"
Case Is = 5
monthText = "五月份"
Case Is = 6
monthText = "六月份"
Case Is = 7
monthText = "七月份"
Case Is = 8
monthText = "八月份"
Case Is = 9
monthText = "九月份"
Case Is = 10
monthText = "十月份"
Case Is = 11
monthText = "十一月份"
Case Is = 12
monthText = "十二月份"
Case Else
monthText = "无效月份"
End Select
ElseIf mType = 2 Then
monthText = currMonth & "月份"
End If
End Function
Sub SetDataValidation(arr(), rng As Range)
'//设置单元格数据验证
Dim i As Integer, t As Integer
Dim listStr As String
Dim rngValue As String
rngValue = rng.Value
For i = LBound(arr) To UBound(arr)
listStr = listStr & arr(i) & ","
If rngValue = CStr(arr(i)) Then
t = 1
End If
Next
If t = 0 Then rng = ""
'//去掉结尾的 ","
listStr = Left(listStr, Len(listStr) - 1)
With rng.Validation
'//删除已有的数据验证
.Delete
'//添加数据验证,源为listStr
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, Formula1:=listStr
.IgnoreBlank = True
.InCellDropdown = True
.ShowInput = True
.ShowError = False '//不显示出错警告,改为TRUE则显示,同时不能输入不合验证的字符
End With
End Sub
安利小店 安利的牙膏非常不错,用了以后就不想再用其他的了;洗洁精、洗衣液也是日常必备,用过都说好! | |
合谷医疗 合谷医疗专攻各种疑难杂症,尤其擅长腰颈椎疾病、儿童神经发育异常、多动症、自闭孤独症治疗,可谓神乎其技!体验过的直呼早点来就好了! | |
我的付费知识星球:Excel活学活用 帮助VBA初学者提高VBA编程水平,欢迎加入! |
喜欢就点个赞、点在看、留言评论、分享一下呗!感谢支持!
Excel问题,请在文章下面留言讨论!或者加入我的付费交流群提问!
如需案例文件,请按当天另一篇文章末尾案例文件分享说明操作!