快速開發平臺--自定義類CodeGenerator



快速開發平臺--自定義類CodeGenerator

來源:www.accessoft.com  點擊數:1003  評論數:0 評論 | 收藏 | 複製



時 間:2013-12-18 18:51:45
作 者:Aaron   ID:20267  城市:閔行
摘 要:自定義類CodeGenerator,可以代替平臺的GetAutoNumber函數,更靈活
正 文:


自定義類CodeGenerator,可以代替平臺的GetAutoNumber函數

類的調用:

Private Sub btnAutoCode_Click()
     Dim clsAutoCode As CodeGenerator
     Set clsAutoCode = New CodeGenerator
     With clsAutoCode
 '        .RuleName = "InventoryCode"
         .Domain = "tblInventory"
         .Field = "InventoryCode"
         .Prefixal = "CM0501"
         .Digit = 3
         .ReplenishOffNo = True
         MsgBox .CodeGenerator
     End With
     Set clsAutoCode = Nothing
 End Sub

--------------------------------------------

類代碼:




Option Compare Database
 Option Explicit

'//字段變量
Private mstrRuleName As String
 Private mstrDomain As String
 Private mstrField As String
 Private mstrPrefixal As String
 Private mstrDateFormat As String
 Private mstrNumberDate As String
 Private mlngDigit As Long
 Private mblnReplenishOffNo As Boolean
 '//模塊變量
Private mblnHasRule As Boolean
 Private mblnCorrectData As Boolean
 Private mstrWrongMessage As String
 Public Event InvalidData(strMessage As String)

'//RuleName屬性,只可寫
Public Property Let RuleName(ByVal astrRuleName As String)
     Dim rstRules As ADODB.Recordset
     Dim strRules As String
     mstrRuleName = astrRuleName
     strRules = "Select * FROM Sys_AutoNumberRules Where RuleName='" & mstrRuleName & "'"
     Set rstRules = OpenADORecordset(strRules, adLockOptimistic, CurrentProject.Connection)
     With rstRules
         If .EOF Then
             MsgBox "自動編號規則 <" & mstrRuleName & ">不存在!", vbCritical, "自動編號類"
             mblnHasRule = False
             GoTo ExitHere
         End If
         '//將規則參數讀入到類變量中
        '//採用屬性的方式來讀入,是防止表中的數據不合法
        Me.Domain = Nz(!Domain, "")
         Me.Field = Nz(!Field, "")
         Me.Prefixal = Nz(!Prefixal, "")
         Me.DateFormat = Nz(!DateFormat, "")
         Me.Digit = Nz(!Digit, 0)
         Me.ReplenishOffNo = !ReplenishOffNo
         mblnHasRule = True
     End With
 ExitHere:
     rstRules.Close
     Set rstRules = Nothing
     Exit Property
 End Property

'//Domain屬性
Public Property Get Domain() As String
     Domain = mstrDomain
 End Property
 Public Property Let Domain(ByVal astrDomain As String)
     mstrDomain = astrDomain
 End Property

'//Field屬性
Public Property Get Field() As String
     Field = mstrField
 End Property
 Public Property Let Field(ByVal astrField As String)
     mstrField = astrField
 End Property

'//Prefixal屬性
Public Property Get Prefixal() As String
     Prefixal = mstrPrefixal
 End Property
 Public Property Let Prefixal(ByVal astrPrefixal As String)
     mstrPrefixal = astrPrefixal
 End Property

'//DateFormat屬性
Public Property Get DateFormat() As String
     DateFormat = mstrDateFormat
 End Property
 Public Property Let DateFormat(ByVal astrDateFormat As String)
     mstrDateFormat = astrDateFormat
 End Property

'//NumberDate屬性
Public Property Get NumberDate() As String
     NumberDate = mstrNumberDate
 End Property
 Public Property Let NumberDate(ByVal astrNumberDate As String)
     mstrNumberDate = astrNumberDate
 End Property

'//Digit屬性
Public Property Get Digit() As Long
     Digit = mlngDigit
 End Property
 Public Property Let Digit(ByVal alngDigit As Long)
     If Abs(CLng(alngDigit)) = alngDigit Then
         mlngDigit = alngDigit
     Else
         MsgBox "自增字段位數參數錯誤!使用默認值3!", vbCritical, "參數錯誤"
         mlngDigit = 3
     End If
 End Property

'//ReplenishOffNo屬性
Public Property Get ReplenishOffNo() As Boolean
     ReplenishOffNo = mblnReplenishOffNo
 End Property
 Public Property Let ReplenishOffNo(ByVal ablnReplenishOffNo As Boolean)
     mblnReplenishOffNo = ablnReplenishOffNo
 End Property

Public Function CodeGenerator() As String
     Dim rstCodeSource As DAO.Recordset
     Dim strCodeSource As String
     If mblnHasRule = False Then
         strCodeSource = "Select " & mstrField & " FROM " & mstrDomain _
                       & " Where " & mstrField & " LIKE '" & mstrPrefixal & "*' " _
                       & "ORDER BY " & mstrField
         On Error GoTo SourceError
         Set rstCodeSource = CurrentDb.OpenRecordset(strCodeSource)
         On Error GoTo ErrorHandler
         With rstCodeSource
             If .EOF Then
                 CodeGenerator = mstrPrefixal & FormatNumber(1, mlngDigit)
             Else
                 If mblnReplenishOffNo Then
                     CodeGenerator = mstrPrefixal & FormatNumber(ReplenishTable(rstCodeSource), mlngDigit)
                 Else
                     .MoveLast    '//不查找斷碼的話,直接移動到最後一條記錄
                    CodeGenerator = Replace(.Fields(mstrField), mstrPrefixal, "")
                     If IsNumeric(CodeGenerator) Then
                         CodeGenerator = CodeGenerator + 1
                         CodeGenerator = mstrPrefixal & FormatNumber(CLng(CodeGenerator), mlngDigit)
                     Else
                         MsgBox "請檢查輸入的前綴參數!", vbCritical, "參數"
                         CodeGenerator = ""
                         GoTo ExitHere
                     End If
                 End If
             End If
         End With
     Else
         CodeGenerator = GetAutoNumber(mstrRuleName)
     End If
 ExitHere:
     If Not (rstCodeSource Is Nothing) Then
         rstCodeSource.Close
         Set rstCodeSource = Nothing
     End If
     Exit Function
 SourceError:
     MsgBox "請檢查輸入的表與字段參數!"
     Exit Function
 ErrorHandler:
     MsgBox Err.Description
     Resume ExitHere
 End Function

Private Function FormatNumber(lngNumber As Long, lngDigit As Long) As String
     Dim intRepeat As Integer
     If lngNumber >( 10 ^ lngDigit-1) Then
         MsgBox "自增序號溢出,請檢查自增數字段的位數!", vbCritical, "溢出"
         FormatNumber = ""
         Exit Function
     End If
     intRepeat = lngDigit - Len(CStr(lngNumber))
     FormatNumber = Space(intRepeat) & lngNumber
     FormatNumber = Replace(FormatNumber, Space(1), "0")
 End Function

'//-----------------二分法查找斷碼---------------------------------
 Private Function ReplenishTable(rstArea As DAO.Recordset) As Long
     Dim lngStart As Long
     Dim lngMax As Long

    On Error GoTo ErrorHandler

    With rstArea
         If .RecordCount = 0 Then
             ReplenishTable = 1
             GoTo ExitHere
         End If
         .MoveLast
         lngMax = Replace(.Fields(0), mstrPrefixal, "")
         If Not IsNumeric(lngMax) Then
             MsgBox "請檢查前綴和表的字段!", vbCritical, "提示"
             GoTo ExitHere
         End If
         '        ReplenishTable = LossNumber(TableName, FieldName, 1, lngMax)
         ReplenishTable = LossNumber(rstArea, 1, lngMax)
     End With
 ExitHere:
     If Not (rstArea Is Nothing) Then
         rstArea.Close
         Set rstArea = Nothing
     End If
     Exit Function
 ErrorHandler:
     ReplenishTable = -1
     MsgBox Err.Number & Err.Description
     Resume ExitHere
 End Function

Private Function LossNumber(rstArea As DAO.Recordset, _
                            Optional StartNumber As Long = -1, _
                            Optional EndNumber As Long = -1, _
                            Optional LastEnd As Long = -1 _
                            ) As Long

    Dim lngCountRecords As Long
     Dim lngCalRecords As Long
     Dim lngNextStart As Long, lngNextEnd As Long, lngNextLast As Long

    If StartNumber = -1 Then StartNumber = 1

    lngCountRecords = CountRecords(rstArea, StartNumber, EndNumber)
     lngCalRecords = CalRecords(StartNumber, EndNumber)
     If lngCountRecords > 0 Then
         If lngCountRecords = lngCalRecords Then
             If LastEnd = -1 Then
 '                MsgBox "沒有斷碼!"
                 LossNumber = lngCalRecords + 1
                 Exit Function
             Else
                 '//後半區間
                lngNextStart = EndNumber + 1
                 lngNextEnd = LastEnd
                 lngNextLast = LastEnd
             End If
         Else
             '//前半區間
            lngNextStart = StartNumber
             lngNextEnd = CLng((EndNumber - StartNumber) / 2) + StartNumber
             lngNextLast = EndNumber
         End If
         LossNumber = LossNumber(rstArea, lngNextStart, lngNextEnd, lngNextLast)
     Else
         LossNumber = StartNumber
     End If
 End Function

'//返回區間內的實際記錄數
 Private Function CountRecords(rstArea As DAO.Recordset, StartNumber As Long, EndNumber As Long) As Long
     Dim strFilter As String
     Dim strStartField As String
     Dim strEndField As String
     Dim rstFiltered As DAO.Recordset
     strStartField = mstrPrefixal & FormatNumber(StartNumber, mlngDigit)
     strEndField = mstrPrefixal & FormatNumber(EndNumber, mlngDigit)
     strFilter = "(" & mstrField & " >= '" & strStartField & "' ) AND (" & mstrField & "<='" & strEndField & "')"
     With rstArea
         .Filter = strFilter
         Set rstFiltered = .OpenRecordset
     End With
     With rstFiltered
         If .EOF Then
             CountRecords = 0
             Exit Function
         End If
         .MoveLast
         .MoveFirst
         CountRecords = .RecordCount
         .Close
         Set rstFiltered = Nothing
     End With
 End Function

'//返回區間內如果無斷碼情況時的記錄數
 Private Function CalRecords(StartNumber As Long, EndNumber As Long) As Long
     CalRecords = EndNumber - StartNumber + 1
 End Function


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章