前几天给老爹写了一个Excel自动运算脚本,能自动根据产品编号取产品名称,自动统计相同编号产品的进货、发货量。
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Source As Range) Dim columnLingshou, columnPifa As Variant Dim columnShouhuo, columnChuhuo As String '############# 销售清单零售编号列名 ############### columnLingshou = Array("AK", "BC", "BU", "CM") '############# 销售清单批发编号列名 ############### columnPifa = Array("AT", "BL", "CD", "CV") '############# 收货清单编号列名 ############### columnShouhuo = "EU" '############# 出货清单编号列名 columnChuhuo = "FI" Dim column As String Dim rowNum As Long If Source.Count = 1 Then '单独修改一个 rowNum = Val(GetRow(Source)) column = GetColumn(Source) If CheckRowInRange(Sh, rowNum, column, columnLingshou, columnPifa, columnShouhuo, columnChuhuo) = False Then Exit Sub End If Call UpdateCells(Sh, rowNum, column, Source, columnLingshou, columnPifa, columnShouhuo, columnChuhuo) Else '一次修改多个 '取第一个单元格地址 Dim firstAddress As String Dim firstRange As Range firstAddress = Mid(Source.address, 1, InStr(1, Source.address, ":") - 1) Set firstRange = Sh.Range(firstAddress) '循环取地址 Dim addressCount As Integer addressCount = UBound(Source.Value2) For i = 0 To addressCount Dim addressNow As Range Set addressNow = firstRange.Offset(i, 0) rowNum = Val(GetRow(addressNow)) column = GetColumn(addressNow) If CheckRowInRange(Sh, rowNum, column, columnLingshou, columnPifa, columnShouhuo, columnChuhuo) = True Then Call UpdateCells(Sh, rowNum, column, addressNow, columnLingshou, columnPifa, columnShouhuo, columnChuhuo) End If Next End If End Sub '获取列号 Function GetColumn(rng As Range) As String GetColumn = Mid(rng.address, 2, InStr(2, rng.address, "$") - 2) End Function '获取行号 Function GetRow(rng As Range) As String GetRow = Mid(rng.address, InStr(2, rng.address, "$") + 1) End Function '更新单元格 Sub UpdateCells(ByVal Sh As Object, ByVal rowNum As Long, ByVal column As String, ByVal address As Range, _ columnLingshou As Variant, columnPifa As Variant, ByVal columnShouhuo As String, ByVal columnChuhuo As String) If IsInArray(column, columnLingshou) Or IsInArray(column, columnPifa) Or column = columnShouhuo Or column = columnChuhuo Then Dim productInfoRow As Long productInfoRow = 0 '更新产品名称 Dim productName As String productName = GetProductName(Sh, Sh.Cells(rowNum, column).Value, productInfoRow) If productName = Null Then Exit Sub End If Call SetProductName(Sh, address, productName) Dim sellCount As Long '销售清单 If IsInArray(column, columnLingshou) Or IsInArray(column, columnPifa) Then '############# 数量相比编号的偏移量 3 ############### sellCount = Sh.Cells(GetRow(address), GetColumn(address.Offset(0, 3))).Value If productInfoRow > 3 Then '更新零售汇总 If IsInArray(column, columnLingshou) Then '############# 零售汇总列名 Q ############### Sh.Cells(productInfoRow, "Q").Value = Sh.Cells(productInfoRow, "Q").Value + sellCount '更新批发汇总 ElseIf IsInArray(column, columnPifa) Then '############# 批发汇总列名 R ############### Sh.Cells(productInfoRow, "R").Value = Sh.Cells(productInfoRow, "R").Value + sellCount End If End If ElseIf column = columnShouhuo Or column = columnChuhuo Then '############# 数量相比编号的偏移量 2 ############### sellCount = Sh.Cells(GetRow(address), GetColumn(address.Offset(0, 2))).Value If productInfoRow > 0 Then '更新进货汇总 If column = columnShouhuo Then '############# 进货汇总列名 N ############### Sh.Cells(productInfoRow, "N").Value = Sh.Cells(productInfoRow, "N").Value + sellCount '更新出货汇总 ElseIf column = columnChuhuo Then '############# 出货汇总列名 R ############### Sh.Cells(productInfoRow, "O").Value = Sh.Cells(productInfoRow, "O").Value + sellCount End If End If End If End If End Sub '获取指定编号的产品名称 Function GetProductName(ByVal Sh As Object, code As String, ByRef productInfoRow As Long) As String If code = "" Then Exit Function End If Dim i As Long Dim rows As Long rows = Sh.UsedRange.rows.Count For i = 4 To rows If Sh.Cells(i, 1).Value = code Then GetProductName = Sh.Cells(i, 2).Value productInfoRow = i Exit For End If Next End Function '填充产品名称 Sub SetProductName(ByVal Sh As Object, ByVal Source As Range, productName As String) Sh.Cells(GetRow(Source.Offset(0, 1)), GetColumn(Source.Offset(0, 1))).Value = productName End Sub '检查行号是否在范围内 Function CheckRowInRange(ByVal Sh As Object, ByVal rowNum As Long, ByVal column As String, _ ByVal columnLingshou As Variant, ByVal columnPifa As Variant, ByVal columnShouhuo As String, ByVal columnChuhuo As String) As Boolean Dim rows As Long rows = Sh.UsedRange.rows.Count If rowNum > rows Then CheckRowInRange = False Exit Function End If Dim rowIndex As Integer If IsInArray(column, columnLingshou) Or IsInArray(column, columnPifa) Then rowIndex = (rowNum - 5) Mod 26 If rowIndex > 8 And rowIndex < 23 Then CheckRowInRange = True Exit Function Else CheckRowInRange = False Exit Function End If ElseIf column = columnShouhuo Or column = columnChuhuo Then rowIndex = (rowNum - 3) Mod 33 If rowIndex > 0 And rowIndex < 31 Then CheckRowInRange = True Exit Function Else CheckRowInRange = False Exit Function End If End If End Function '判断字符串是否包含在数组内 Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1) End Function