Excel VBA:数据管理与维护

最近做了一个使用Excel VBA管理库存数据的小练习。附代码:

 

Public Function WorksheetActivate(ByVal Cancel As Boolean)
    'This function is defined to add new line to sheet2, and it can only be used in sheet3-18
    If Cancel Then
        Exit Function
    End If
    
    Dim r, c, i, rr, key As Long
    Dim flag As Boolean
    Dim dump As Integer
    
    r = ActiveSheet.UsedRange.Rows.Count
    c = ActiveSheet.UsedRange.Columns.Count
    dump = 0
    For i = 2 To r
        
        flag = True
        For j = 2 To c
            If ActiveSheet.Cells(i, j).text <> "" Then
                flag = False
                Exit For
            End If
        Next j
        If flag Then
            dump = dump + 1
        Else
            dump = 0
        End If
        
        If ActiveSheet.Cells(i, 1).text = "" Then
            For j = 2 To c
                If ActiveSheet.Cells(i, j).text <> "" Then
                    newLine ActiveSheet.Index, i, 2
                    Exit For
                End If
            Next j
        End If
        
        If dump > 20 Then
            MsgBox "Error occurs 3.", vbOKOnly, "Alarm"
            Exit For
        End If
    Next i
End Function

Public Function Worksheet2Activate()
    Dim r, rn, mn, ibl As Long
    Dim key As String
    mn = 0
    rn = ActiveSheet.UsedRange.Rows.Count
    For r = 2 To rn
        If ActiveSheet.Cells(r, 1).Font.Bold = False Or ActiveSheet.Cells(r, 1).Interior.ColorIndex = 0 Then
            mn = r - 1
            Exit For
        End If
    Next r
    If mn = 0 Then
        mn = rn
    End If
    If mn < 10 And mn <> rn Then
        Application.ScreenUpdating = False
        For r = 2 To mn
            key = ActiveSheet.Cells(r, 1).text
            If key = "" Then
                MsgBox "Error occurs 0.", vbOKOnly, "Error"
            Else
                ibl = getInsertBeforeLoc(2, key, mn + 1, rn)
                ActiveSheet.Rows(ibl).Insert shift:=xlDown
                ActiveSheet.Rows(r).Copy ActiveSheet.Cells(ibl, 1)
            End If
        Next r
        If mn - 1 > 2 Then
            ActiveSheet.Rows("2:" + Trim(Str(mn))).Delete shift:=xlUp
        End If
        Application.ScreenUpdating = True
    Else
        ActiveSheet.Columns("A:" + num2Snum(ActiveSheet.UsedRange.Columns.Count)).Sort _
        key1:=Range("A1:A" + Trim(Str(rn))), order1:=xlAscending, Header:=xlYes
    End If
End Function

Private Function newLine(ByVal idx As Integer, ByVal row As Long, ByVal tidx As Integer)
    Dim key, ibf As Long
    Dim skey As String
    key = getKeyNum(idx) + 1
    skey = ActiveSheet.Name + "_" + Str(key)
    ibf = 2
    Sheets(tidx).Rows(ibf).Insert shift:=xlDown
    Sheets(idx).Cells(row, 1).Value = key
    Sheets(idx).Rows(row).Copy Sheets(tidx).Cells(ibf, 1)
    Sheets(tidx).Cells(ibf, 1).Value = skey
    Sheets(tidx).Range("A" & ibf, num2Snum(Sheets(tidx).UsedRange.Columns.Count) & ibf).Interior.ColorIndex = 5
    Sheets(tidx).Range("A" & ibf, num2Snum(Sheets(tidx).UsedRange.Columns.Count) & ibf).Font.Bold = True
    delHyperlinks tidx
End Function

Private Function delHyperlinks(ByVal tidx As Integer)
    Dim flag As Boolean
    flag = False
    For Each hl In Sheets(tidx).UsedRange.Hyperlinks
        If Not flag Then
            flag = True
        Else
            hl.Delete
        End If
    Next
End Function
Private Function getInsertBeforeLoc(ByVal idx As Integer, ByVal skey As String, ByVal fidx As Long, ByVal eidx As Long) As Long
    Dim midx As Long, text As String
    midx = (fidx + eidx) / 2
    text = Sheets(idx).Cells(midx, 1).text
    If text = "" Or fidx > eidx Then
        getInsertBeforeLoc = fidx
    Else
        If text < skey Then
            getInsertBeforeLoc = getInsertBeforeLoc(idx, skey, midx + 1, eidx)
        ElseIf text > skey Then
            getInsertBeforeLoc = getInsertBeforeLoc(idx, skey, fidx, midx - 1)
        Else
            MsgBox "Error occurs 1.", vbOKOnly, "Error"
        End If
    End If
End Function

Private Function getKeyNum(ByVal idx As Integer) As Long
    Dim r, i, temp, result As Long
    
    r = Sheets(idx).UsedRange.Rows.Count
    result = 0
    For i = r To 2 Step -1
            temp = Sheets(idx).Cells(i, 1).Value
            If temp <> "" And result < temp Then
                result = temp
            End If
    Next i
    getKeyNum = result
End Function

Public Function WorksheetDeactivate()
    'This function is defined to delete those empty rows
    Dim r, c, rn, cn, key, temp, damn As Long
    Dim hasValue As Boolean
    Dim skey As String
    damn = 0
    rn = ActiveSheet.UsedRange.Rows.Count
    cn = ActiveSheet.UsedRange.Columns.Count
    For r = 2 To rn
        If ActiveSheet.Cells(r, 1).text <> "" Then
            hasValue = False
            For c = 2 To cn
                If ActiveSheet.Cells(r, c).text <> "" Then
                    hasValue = True
                    Exit For
                End If
            Next c
            If Not hasValue Then
                If IsNumeric(ActiveSheet.Cells(r, 1).text) Then
                    damn = damn + 1
                    key = ActiveSheet.Cells(r, 1).text
                    skey = ActiveSheet.Name + "_" + Str(key)
                    ActiveSheet.Rows(r).Delete shift:=xlUp
                    temp = find(2, skey)
                    If temp <> 0 Then
                        Sheet2.Rows(temp).Delete shift:=xlUp
                    End If
                End If
            Else
                damn = 0
            End If
        Else
            ActiveSheet.Rows(r).Delete shift:=xlUp
        End If
        If damn > 20 Then
            MsgBox "Error occurs 3.", vbOKOnly, "Alarm"
            Exit For
        End If
    Next r
End Function

Private Function find(ByVal idx As Integer, ByVal skey As String) As Long
    Dim r, rn, mn As Long
    rn = Sheets(idx).UsedRange.Rows.Count
    For r = 2 To rn
        If Sheets(idx).Cells(r, 1).Font.Bold Then
            If Sheets(idx).Cells(r, 1).text = skey Then
                find = r
                Exit Function
            End If
        Else
            mn = r
            Exit For
        End If
    Next r
    find = dichotomy(idx, skey, mn, rn)
End Function

Public Function WorksheetChange(ByVal Target As Range)
    Dim r, c, tr, key As Long
    Dim skey As String
    Dim hasValue As Boolean
    If Target.Column = 1 Then
        Exit Function
    End If
    For r = Target.row To (Target.row + Target.Rows.Count - 1)
        If ActiveSheet.Cells(r, 1).text = "" And r > 1 Then
            hasValue = False
            For c = 2 To ActiveSheet.UsedRange.Columns.Count
                If ActiveSheet.Cells(r, c).text <> "" Then
                    hasValue = True
                    Exit For
                End If
            Next c
            If hasValue Then
                newLine ActiveSheet.Index, r, 2
            End If
        ElseIf IsNumeric(ActiveSheet.Cells(r, 1).text) Then
            key = ActiveSheet.Cells(r, 1).text
            skey = ActiveSheet.Name + "_" + Str(key)
            tr = find(2, skey)
            If tr <> 0 Then
                For c = Target.Column To (Target.Column + Target.Columns.Count - 1)
                    Sheet2.Cells(tr, c).Value = ActiveSheet.Cells(r, c).text
                    Sheet2.Cells(tr, c).Interior.ColorIndex = 5
                    Sheet2.Cells(tr, c).Font.Bold = True
                    Sheet2.Cells(tr, 1).Interior.ColorIndex = 5
                    Sheet2.Cells(tr, 1).Font.Bold = True
                Next c
                Sheet2.Rows(2).Insert shift:=xlDown
                Sheet2.Rows(tr + 1).Copy Sheet2.Cells(2, 1)
                Sheet2.Rows(tr + 1).Delete shift:=xlUp
            End If
        End If
    Next r
End Function

Private Function dichotomy(ByVal sidx As Integer, ByVal key As String, ByVal fidx As Long, ByVal eidx As Long) As Long
    Dim midx As Long, text As String
    midx = (fidx + eidx) / 2
    text = Sheets(sidx).Cells(midx, 1).text
    If fidx >= eidx And text <> key Then
        dichotomy = 0
    Else
        If text = key Then
            dichotomy = midx
        ElseIf text < key Then
            dichotomy = dichotomy(sidx, key, midx + 1, eidx)
        Else
            dichotomy = dichotomy(sidx, key, fidx, midx - 1)
        End If
    End If
End Function

Public Function WorksheetSelectionChange(ByVal Target As Range)
    If Target.Worksheet.Index = ActiveSheet.Index And Target.Column = 1 Then
            If Target.row > 1 Or Target.Rows.Count > 1 Then
                ActiveSheet.Range(num2Snum(Target.Column + 1) & _
                Target.row, num2Snum(Target.Column + Target.Columns.Count - 1) _
                & (Target.row + Target.Rows.Count - 1)).Select
            End If
     End If
End Function

Private Function StateMachinery(ByVal ok As Boolean, ByVal idx As Integer)
    Dim r, rr, c, cc As Long
    If ok Then
        rr = Sheets(idx).UsedRange.Rows.Count
        For r = 1 To rr
            If Sheets(idx).Cells(r, 1).Font.Bold Then
                Sheets(idx).Rows(r).Font.Bold = False
            End If
            If Sheets(idx).Cells(r, 1).Interior.ColorIndex <> 0 Then
                Sheets(idx).Range("A" & r, num2Snum(Sheets(idx).UsedRange.Columns.Count) & r).Interior.ColorIndex = 0
            End If
        Next r
    End If
End Function

Private Function num2Snum(ByVal c As Long) As String
    Alphas = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", _
    "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z")
    If c > 26 Then
        num2Snum = num2Snum((c - 1) / 26) + Alphas((c - 1) Mod 26)
    Else
        num2Snum = Alphas((c - 1) Mod 26)
    End If
End Function


<p>Public Sub MarkRead()
    'StateMachinery True, 2
    Dim sresult As String
    sresult = InputBox("Please input your password:", "Password")
    If sresult = "xiexiaoyan" Then
        Worksheet2Activate
        StateMachinery True, 2
        ActiveSheet.Rows(1).Select
    End If
End Sub</p><p>
 </p>

 

代码的主要目的是维持汇总表单和各分表单数据的一致性,并将分表的新建数据及更新数据显示在汇总表的顶端。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值